Skip to content

ci(release): publish any prerelease tag under its own dist-tag - #91

Merged
not-matthias merged 2 commits into
mainfrom
chore/beta-releases
Aug 27, 2026
Merged

ci(release): publish any prerelease tag under its own dist-tag#91
not-matthias merged 2 commits into
mainfrom
chore/beta-releases

Conversation

@not-matthias

@not-matthias not-matthias commented Aug 27, 2026

Copy link
Copy Markdown
Member

Problem

The publish step matched only -alpha in the tag name:

if [[ "${{ github.ref }}" == *"-alpha"* ]]; then
  pnpm publish -r --access=public --no-git-checks --tag=alpha
else
  pnpm publish -r --access=public --no-git-checks   # v5.8.0-beta.1 lands here
fi

Any other prerelease identifier fell through to the else branch and moved the latest dist-tag, so a beta or rc would have been installed by every consumer on ^5. Beta was also unreachable in the first place: scripts/release.sh forwards a single positional to lerna version with no --preid, and lerna defaults the prerelease identifier to alpha, which is precisely why the workflow only ever needed to check for -alpha.

Changes

  • Derive the dist-tag from the tag's prerelease identifier rather than hardcoding one channel. beta, rc and next are covered by the same rule, and latest is now reserved for plain vX.Y.Z tags — the fail-closed direction, where an unrecognised suffix gets its own tag instead of clobbering latest. This also drops the loose substring match: v5.8.0-alphabet.1 previously published as alpha.
  • Flag the draft GitHub release --prerelease when the version contains a - (this was missing for alpha too).
  • scripts/release.sh takes an optional second argument forwarded as --preid, so ./scripts/release.sh prerelease beta produces 5.7.2-beta.0 and the matching tag.

Both shell snippets avoid [[ ... ]] && VAR=... as a final command, since workflow steps run under bash -e where a false test fails the step.

Verification

No release was performed. pnpm, gh and git were replaced with echo-only stubs, and the workflow bodies were extracted verbatim from the YAML file, so these are the argv the shipped text builds:

git tag publish command
v5.8.0 pnpm publish -r --access=public --no-git-checks
v5.8.0-alpha.0 ... --tag=alpha
v5.8.0-beta.1 ... --tag=beta
v5.8.0-rc.0 ... --tag=rc
v5.8.0-next.3 ... --tag=next
v5.8.0-alphabet.1 ... --tag=alphabet
  • Draft release: 5.8.0 gets no flag, 5.8.0-beta.1 and 5.8.0-alpha.0 get --prerelease. All steps exit 0.
  • release.sh argv checked with printf '%q' and an argument count: patch and prerelease both yield 6 arguments with no empty element, prerelease beta yields 8 with --preid beta in position. 0 or 3+ arguments print usage and exit 1.
  • bash -n clean, workflow still parses as valid YAML with all four build run-steps intact.

Existing alpha behaviour is unchanged: v*-alpha* still publishes to the alpha dist-tag.

Not included

npm trusted publishing needs no per-channel setup — the OIDC exchange is dist-tag agnostic, and provenance is unaffected. Cross-package deps also already work: workspace:^5.7.1 is rewritten at publish time to ^5.8.0-beta.0, and a caret range whose comparator carries a prerelease matches prereleases of that same version tuple, so @codspeed/vitest-plugin@beta resolves @codspeed/core@beta.

Consuming prerelease versions of the benchmark frameworks themselves (for example vitest@4.0.0-beta.1 against the vitest: "^3.2 || ^4" peer range) is a separate concern and untouched here.

Consistency with the other CodSpeed repos

Beta is the normal prerelease channel elsewhere; codspeed-node was the only repo that could not produce one.

repo prereleases supported how it is cut GitHub release flagged prereleases historically shipped
runner yes, first-class cargo release --execute beta yes, announcement_is_prerelease from cargo-dist 39 -beta, 24 -alpha tags
pytest-codspeed yes uvx bumpver update --minor --tag beta no 9 -beta tags
codspeed-rust no not supported by scripts/release.sh no 4 -alpha tags, 2023 only
codspeed-node (before) alpha only, by accident not reachable through scripts/release.sh no 2 -alpha tags

Details worth carrying over or noting:

  • The runner keeps a prerelease from becoming the default install by gating gh release edit --latest and the downstream CodSpeedHQ/action version bump on announcement_is_prerelease (.github/workflows/post-announce.yml:24-50). npm's dist-tag gives us the equivalent for free, which is what this PR wires up.
  • Both the runner (scripts/pre-release.sh:6-10) and pytest-codspeed (scripts/pre-release.sh:6-8) skip changelog generation for alpha/beta/rc. Not applicable here: this repo generates no changelog.
  • scripts/release.sh in this repo is a sibling of the codspeed-rust one, which explains the shared <major|minor|patch>-only shape. codspeed-rust has the same gap if it ever needs a prerelease.
  • The missing --prerelease on the draft GitHub release is not unique to us: pytest-codspeed and codspeed-rust omit it too.

The CONTRIBUTING.md added here follows the structure of the runner and pytest-codspeed guides, and documents what the prerelease identifier is, since neither of those explains it.

@not-matthias
not-matthias marked this pull request as ready for review August 27, 2026 13:17
@not-matthias

Copy link
Copy Markdown
Member Author

@greptileai review

@codspeed-hq

codspeed-hq Bot commented Aug 27, 2026

Copy link
Copy Markdown

Merging this PR will regress 5 benchmarks

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 9 improved benchmarks
❌ 5 regressed benchmarks
✅ 224 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory wait 500ms 20.3 KB 64.2 KB -68.32%
Memory end 2.1 KB 2.7 KB -23.43%
WallTime test_recursive_fibo_10 1.9 µs 2.4 µs -17.86%
WallTime fibo darwin 7.8 ms 8.8 ms -11.72%
Simulation wait 1sec 57.5 ms 64.3 ms -10.49%
Simulation test_recursive_fibo_10 11,112.5 µs 274.1 µs ×41
Memory test sync baz 100 25,080 B 656 B ×38
Simulation wait 1sec 57.9 ms 40.7 ms +42.5%
Memory short body 784 B 656 B +19.51%
WallTime switch 2 96 ns 84 ns +14.29%
WallTime short body 2.1 µs 1.9 µs +11.95%
WallTime test sync baz 100 228 ns 204 ns +11.76%
WallTime test sync baz 10 120 ns 108 ns +11.11%
Memory long body 1.3 KB 1.2 KB +10.39%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing chore/beta-releases (0433753) with main (3735985)

Open in CodSpeed

@not-matthias
not-matthias marked this pull request as draft August 27, 2026 13:25
@not-matthias
not-matthias marked this pull request as ready for review August 27, 2026 13:25
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes prerelease publishing fail closed by deriving and validating an npm dist-tag from the version, while reserving latest for stable releases.

  • Marks draft GitHub releases as prereleases when appropriate.
  • Documents stable and prerelease release procedures.
  • Expands the release helper’s accepted version forms.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
.github/workflows/release.yml Safely routes prereleases to validated non-latest dist-tags and marks their draft GitHub releases as prereleases.
CONTRIBUTING.md Documents the lockstep release process and uses the repository-required pnpm tooling.
scripts/release.sh Documents and accepts explicit prerelease versions while preserving the existing branch and working-tree safeguards.

Reviews (4): Last reviewed commit: "fixup! docs: document release bump level..." | Re-trigger Greptile

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread CONTRIBUTING.md Outdated
@not-matthias

Copy link
Copy Markdown
Member Author

@greptileai review again

Comment thread .github/workflows/release.yml Outdated
The publish step only special-cased "-alpha", so a v5.8.0-beta.1 tag fell
through to the else branch and moved the "latest" dist-tag, shipping a
prerelease to every consumer on ^5. Derive the dist-tag from the tag's
prerelease identifier instead, which covers beta and rc without a branch per
channel, and reserve "latest" for plain vX.Y.Z tags.

The draft GitHub release is now flagged --prerelease for those versions too.

release.sh gains an optional preid argument: lerna defaults the prerelease
identifier to "alpha", so beta was previously unreachable through the script.
The release process was undocumented outside of a one-line usage comment, and
the prerelease identifier is the part a maintainer has to get right: it selects
the npm dist-tag consumers install from, and lerna silently defaults it to
"alpha".

Adds a CONTRIBUTING.md with the release and prerelease commands, following the
structure used in the runner and pytest-codspeed repos, and expands the usage
header of release.sh with the bump levels and worked examples.
@not-matthias
not-matthias merged commit 0433753 into main Aug 27, 2026
51 of 53 checks passed
@not-matthias
not-matthias deleted the chore/beta-releases branch August 27, 2026 14:29
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.

2 participants