Skip to content

feat: support publishing packages from GitHub organizations (completes #138)#140

Open
nepinhum wants to merge 9 commits into
vlang:masterfrom
nepinhum:feat/organization-support-fixed
Open

feat: support publishing packages from GitHub organizations (completes #138)#140
nepinhum wants to merge 9 commits into
vlang:masterfrom
nepinhum:feat/organization-support-fixed

Conversation

@nepinhum

Copy link
Copy Markdown

This picks up #138 (@meiseayoung), which implemented organization based package publishing but went unanswered after Codex requested changes and the pr sat without follow up. All findings from that review are addressed here. The original feature and its intent are unchanged.

Summary (original, by @meiseayoung)

VPM only allowed publishing packages from a user's personal GitHub account. This adds support for publishing from GitHub organizations a user is a member of.

Solution

  • Fetch the user's organization memberships during GitHub OAuth login (/user/orgs)
  • Store memberships in a new UserOrganization table
  • Validate package URLs against both the user's account and their organizations
  • Use the organization as the package prefix when the URL belongs to one (e.g. v-hono.hono instead of meiseayoung.hono)

What changed since #138

  • OAuth scope + pagination: login_link() now requests read:org (without it /user/orgs returns 403 and no orgs are ever stored). Org fetching is paginated (per_page=100, follows pages) instead of only reading GitHub's default first-30.
  • Fixed an authorization bypass: the org/account check used starts_with() on a formatted URL prefix, so membership in acme would incorrectly authorize acme-inc/some-repo. Replaced with exact, case insensitive comparison of the URL's actual owner segment.
  • Fixed editing organization packages: the edit path still called the old check_vcs()/username-only prefix logic, so updating even just the description of an org package would fail (or, if bypassed, silently move it back into the user's personal namespace). Creation and editing now share one resolve_owner_prefix() resolver and OrganizationsRepo is injected into UseCase instead of being wired up ad hoc per call site.
  • Error handling: save_user_organizations() no longer swallows delete/insert failures; a failed org refresh during login now fails closed.

Test plan

  • v test repo/ usecase/package/ - all passing, including new regression tests for the prefix bypass fix (acme vs acme-inc, both org and personal account sides) and the shared prefix resolver.
  • v . - full project builds clean.

qinqiuxia and others added 6 commits January 12, 2026 21:16
- Add UserOrganization entity to store user's org memberships
- Fetch user's organizations during OAuth login via GitHub API
- Modify check_vcs() to accept URLs from user's organizations
- Automatically use organization name as package prefix when publishing from org repos

This allows users who are members of GitHub organizations to publish
packages from organization repositories. The package name will use
the organization name as prefix (e.g., 'v-hono.hono' instead of
'meiseayoung.hono' when publishing from v-hono organization).

Closes #XXX
- Add tests for extract_owner_from_url function
- Add tests for check_vcs backward compatibility
- Add tests for check_vcs_with_orgs new functionality
- Add tests for is_valid_mod_name validation
- Add tests for UserOrganization entity and membership logic

All 2 test files pass with 20+ test cases covering:
- Own account publishing (existing behavior)
- Organization member publishing (new feature)
- Non-member organization rejection
- Admin bypass
- Edge cases and error handling
@medvednikov

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 20e8aab2e2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread auth.v Outdated
Comment on lines +108 to +109
orgs_repo.save_user_organizations(user_id, org_names) or {
println('failed to save orgs: ${err}')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed when saving refreshed org memberships

If this write fails during login (for example a transient DB error, deadlock, or failed insert), the callback still sets the auth cookies and leaves whatever UserOrganization rows were already in the database. Since package create/update authorization reads those cached rows, a user who was removed from an organization can retain org publishing access until a later successful refresh; return/redirect on this error instead of continuing the login with stale memberships.

Useful? React with 👍 / 👎.

@medvednikov

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9750f30362

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread usecase/package/packages.v Outdated
Comment on lines +255 to +256
if owner == org.to_lower() {
return vcs.name

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require repo-level access for org submissions

For GitHub organizations with members who cannot write/administer every repo, accepting any owner that appears in the user's org list lets a read-only org member publish a package for any public repo under that org; the later http.get only proves the repo exists. This broadens the previous ownership check from personal repos to all org repos, so please verify the user's permission on the specific repository before returning success here.

Useful? React with 👍 / 👎.

@nepinhum

nepinhum commented Jul 14, 2026

Copy link
Copy Markdown
Author

@medvednikov Is the hardcoded medvednikov bypass still intentionally used for publishing packages from repositories you don't own or is it just legacy behavior? (ty, you answered in discord)

@nepinhum

Copy link
Copy Markdown
Author

could someone review the latest changes?

@meiseayoung meiseayoung left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants