Skip to content

feat: restrict upstream merge to published GitHub releases only#150

Merged
anandgupta42 merged 4 commits intomainfrom
worktree-upstream-release-only
Mar 15, 2026
Merged

feat: restrict upstream merge to published GitHub releases only#150
anandgupta42 merged 4 commits intomainfrom
worktree-upstream-release-only

Conversation

@anandgupta42
Copy link
Contributor

What does this PR do?

Restricts the upstream merge tooling to only allow merging from published GitHub releases, replacing the previous system that accepted arbitrary commits or git tags.

  • New: script/upstream/utils/github.ts — GitHub Releases API utilities (fetch, validate, list releases via gh CLI)
  • Removed: --commit flag from merge.ts — no more arbitrary commit merges
  • Added: --include-prerelease flag for both merge.ts and list-versions.ts
  • Changed: list-versions.ts now uses GitHub Releases API instead of raw git tags
  • Fixed: validateRelease() properly supports --include-prerelease flag (caught by 6-model code review)
  • Fixed: Removed duplicate/dead getRelease() call in validateRelease()

Type of change

  • New feature (non-breaking change which adds functionality)

Issue for this PR

Closes #17642

How did you verify your code works?

  • 46 tests pass (bun test test/upstream/) covering:
    • GitHub API utilities (mocked execSync)
    • Release validation with includePrerelease option
    • Structural enforcement (merge.ts doesn't accept --commit, imports validateRelease, etc.)
  • TypeScript type checks pass (turbo typecheck)
  • 6-model code review (Claude, GPT 5.2 Codex, Gemini 3.1 Pro, Kimi K2.5, MiniMax M2.5, GLM-5) — consensus on critical bugs, all fixed before commit

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code where necessary
  • My changes generate no new warnings
  • New and existing tests pass locally

🤖 Generated with Claude Code

- Add `script/upstream/utils/github.ts` — GitHub Releases API utilities
  that fetch, validate, and list published releases via `gh` CLI
- Remove `--commit` flag from merge.ts — arbitrary commit merges no longer allowed
- Add `--include-prerelease` flag for both `merge.ts` and `list-versions.ts`
- Replace git tag listing with GitHub Releases API in `list-versions.ts`
- Validate versions against GitHub releases before merging (not just git tags)
- Fix: `validateRelease()` accepts `includePrerelease` option to properly
  support the `--include-prerelease` flag (caught by multi-model code review)
- Fix: Remove duplicate `getRelease()` call (dead code) in `validateRelease()`
- Add 46 tests covering GitHub API utilities, release validation, and
  structural enforcement of the release-only policy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anandgupta42 anandgupta42 force-pushed the worktree-upstream-release-only branch from 6c8b4c4 to e32c2b1 Compare March 15, 2026 20:06
`gh api --paginate` outputs concatenated JSON arrays (`[...][...]`) when
results span multiple pages, which `JSON.parse` cannot handle. Use
`--slurp` to combine all pages into a single array, then `flatten` the
result before filtering.

Also reorders the jq pipeline to filter before slicing, so `--limit N`
returns N stable releases rather than N total (which could include
pre-releases that get filtered out).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
`gh api` does not support `--slurp` — it's a jq-only flag. Instead,
use `--jq '.[]'` to unpack each page's array into individual JSON
objects, then pipe to external `jq -s` to slurp them into a single
array for filtering and slicing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment on lines +194 to +196
const releases = await fetchReleases(config.upstreamRepo, {
includePrerelease: Boolean(args["include-prerelease"]),
})

This comment was marked as outdated.

The `limit` from CLI args was not passed to `fetchReleases`, so it
always defaulted to 100 internally. Now `list-versions.ts` passes the
limit through, and `--all` passes `undefined` to skip the jq slice.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anandgupta42 anandgupta42 merged commit 1caa711 into main Mar 15, 2026
8 checks passed
anandgupta42 added a commit that referenced this pull request Mar 17, 2026
* feat: restrict upstream merge to published GitHub releases only

- Add `script/upstream/utils/github.ts` — GitHub Releases API utilities
  that fetch, validate, and list published releases via `gh` CLI
- Remove `--commit` flag from merge.ts — arbitrary commit merges no longer allowed
- Add `--include-prerelease` flag for both `merge.ts` and `list-versions.ts`
- Replace git tag listing with GitHub Releases API in `list-versions.ts`
- Validate versions against GitHub releases before merging (not just git tags)
- Fix: `validateRelease()` accepts `includePrerelease` option to properly
  support the `--include-prerelease` flag (caught by multi-model code review)
- Fix: Remove duplicate `getRelease()` call (dead code) in `validateRelease()`
- Add 46 tests covering GitHub API utilities, release validation, and
  structural enforcement of the release-only policy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: handle paginated `gh api` output with `--slurp` in `fetchReleases`

`gh api --paginate` outputs concatenated JSON arrays (`[...][...]`) when
results span multiple pages, which `JSON.parse` cannot handle. Use
`--slurp` to combine all pages into a single array, then `flatten` the
result before filtering.

Also reorders the jq pipeline to filter before slicing, so `--limit N`
returns N stable releases rather than N total (which could include
pre-releases that get filtered out).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace `--slurp` with `jq -s` pipe for `gh api` pagination

`gh api` does not support `--slurp` — it's a jq-only flag. Instead,
use `--jq '.[]'` to unpack each page's array into individual JSON
objects, then pipe to external `jq -s` to slurp them into a single
array for filtering and slicing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: pass CLI `--limit`/`--all` to `fetchReleases`

The `limit` from CLI args was not passed to `fetchReleases`, so it
always defaulted to 100 internally. Now `list-versions.ts` passes the
limit through, and `--all` passes `undefined` to skip the jq slice.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anandgupta42 anandgupta42 deleted the worktree-upstream-release-only branch March 17, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant