Skip to content

refactor(scripts): split release-pipeline along its sections - #518

Closed
Vivswan wants to merge 3 commits into
ci/release-resolve-verifyfrom
refactor/split-release-pipeline
Closed

Vivswan wants to merge 3 commits into
ci/release-resolve-verifyfrom
refactor/split-release-pipeline

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 6, 2026

Copy link
Copy Markdown
Owner

What this changes

.github/scripts/release-pipeline.ts        1562 lines, every section in one file
->
.github/scripts/release-pipeline.ts         205  the header, the step constants, main()
.github/scripts/release-pipeline/git.ts     136  the git helpers every section shares, ancestry, position, manifest
.github/scripts/release-pipeline/tags.ts    522  packaged commits and the refs that name them (build tags, vX.Y.Z, latest, vX)
.github/scripts/release-pipeline/anchor.ts  223  release-please's boundary: the anchor, the boundary check, the anchor check
.github/scripts/release-pipeline/npm.ts     514  the pre-release version, the verdicts, the publish, the floor
.github/scripts/release-pipeline/draft.ts    45  the draft release's source and assets

test/scripts/release-pipeline.test.ts      2204 lines
->
test/scripts/release-pipeline.test.ts      1237  tags, anchor, draft, config
test/scripts/release-pipeline-npm.test.ts   997  the npm half

How

  • Pure moves: every function keeps its text. Only imports, exports, and file headers are new.
  • One entry file stays at the path the workflows and the test fixture invoke, holding main() alone.
  • A directory, not lib siblings: lib/ holds helpers several scripts share, and these sections belong to one script.
  • Every importer follows: the build test, the two workflow tests, and the comments that named the old file.

Proof

  • Census: test( and test.each( call sites 71 before and after (47 + 24). Exports 37 before, all 37 still exported from their new modules, plus 12 helpers exported for cross-module use (listed below). Lines 1562 to 1645 for the script, 2204 to 2234 for the tests, the difference being headers and imports.
  • Tests: the six touched test files 221 green, typecheck, biome, knip, and arch lint green.

Depends on #513, #515, and #517.

Technical details
  • Newly exported from release-pipeline/git.ts: assertFullHistory, BOT_IDENTITY, FULL_SHA, git, gitOrNo, gitWithEnv, isAncestor, manifestVersionAt, push, resolveCommit, tryGit; from draft.ts: RELEASE_ASSETS (read by main).
  • mainPosition moved to git.ts rather than npm.ts: tags.ts names build tags by it, so it is shared, not npm's.
  • Moved text keeps its long lines (25 over 150 columns across the modules and the npm test); no moved line was edited.
  • Library: none applies to a move.
  • Outside this PR: CONTRIBUTING.md line 60 still names .github/scripts/release-pipeline.ts as where the topology lives. The entry file still exists, so the sentence stays true.
  • Files: .github/scripts/release-pipeline.ts, .github/scripts/release-pipeline/{git,tags,anchor,npm,draft}.ts, .github/workflows/{update-release,update-release-pr}.yml (comments), test/scripts/release-pipeline{,-npm,-build}.test.ts, test/workflows/{checks-workflow,post-green-workflow,npm-publish-workflows}.test.ts.

release-please-config.json was parsed in three places (the anchor, the boundary check, the anchor check), each as an untyped object, so a file that was not JSON failed with a bare parse error naming no file, and a boundary that was not a commit sha (an array config, a number) was read as a stale boundary and answered with a repair value. One reader now parses the file and refuses a missing or malformed one, or a last-release-sha that is no 40-hex sha, naming the file and the fix; an absent boundary stays the pre-first-release state. The config is release-please's and the user's, so nothing is repaired.
release-pipeline.ts held every section of the release pipeline in one 1562-line file. Its sections move to sibling modules under .github/scripts/release-pipeline/: git.ts (the git helpers every section shares, with ancestry, a commit's position on main, and the manifest read), tags.ts (packaged commits and the refs that name them), anchor.ts (release-please's boundary), npm.ts (the pre-release version, the verdicts, the publish, the floor), and draft.ts (the draft release's source and assets). The entry file keeps its path, the one the workflows and the test fixture invoke, and holds main() alone.

The test file splits the same way: its npm half becomes test/scripts/release-pipeline-npm.test.ts. Every function keeps its text; only imports, exports, and file headers are new, and every importer and comment that named the old file follows the move.
@Vivswan

Vivswan commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

Closed until #513, #515, and #517 are on main: this branch is a merge of two unlanded branches, so its diff cannot be a clean stack. The split is rebuilt on main and reopened once they land.

@Vivswan Vivswan closed this Oct 6, 2026
@Vivswan
Vivswan deleted the refactor/split-release-pipeline branch October 6, 2026 12:13
@Vivswan

Vivswan commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #519: the head branch was rebuilt on #517's new head, and GitHub refuses to reopen a PR whose recorded head no longer exists.

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.

1 participant