Skip to content

ci(release): Move to Craft auto versioning - #117

Merged
BYK merged 14 commits into
mainfrom
ci/craft-auto-versioning
Nov 7, 2026
Merged

BYK merged 14 commits into
mainfrom
ci/craft-auto-versioning

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

BYK asked to move the Craft repos to the latest Craft release workflow with the full bump set, the same as getsentry/junior. Review feedback then asked to remove the release-tag workarounds.

What changed

Release workflow

  • release.yml now uses getsentry/craft@v3 and no longer uses getsentry/action-prepare-release@v1. It passes these inputs:
    • version: ${{ inputs.version || inputs.bump }}
    • force
    • llm_api_key: ${{ github.token }}
  • release.yml also gets the copilot-requests: write permission.
  • New inputs:
    • bump: auto (default), pre, patch, minor, major
    • version: an optional exact version
    • force
  • Removed inputs: prerelease and prerelease_id.
    • Use pre for an alpha prerelease of the version that auto would release.
    • For a beta or rc line, set version, for example 0.19.0-beta.0.
  • scripts/calculate-release-version.mjs is removed. Craft now computes the version.

Action bundle on main

  • github-reporter/dist/action/index.js is now committed. It is no longer gitignored, .gitattributes marks it linguist-generated, and Biome skips it.
  • CI keeps the bundle fresh. The release bot key is never used on pull_request:
    • action-bundle (test.yml) checks out the PR head with persist-credentials: false, installs, and runs scripts/check-action-bundle.sh (pnpm build:action) with no secrets. On same-repo PRs that Dependabot did not open, a stale bundle is uploaded as the action-bundle artifact. On fork PRs, Dependabot PRs, and main, a stale bundle fails the job. A stale bundle can only reach main past a failing check.
    • The test job, which builds the PR merge commit, also runs scripts/check-action-bundle.sh in fail-only mode. A bundle that is fresh on the branch but stale after the merge with main cannot go green. To fix it, merge or rebase on main, and CI then rebuilds the bundle.
    • push-action-bundle.yml runs on workflow_run when Test completes. GitHub always runs this file from main, so a PR cannot change it.
      • It reads the PR's identity from the workflow_run payload: head_sha, head_branch, head_repository. It runs only when the event is pull_request, the head repo is this repo, the actor is not Dependabot, and the branch is not the default branch or release/*.
      • It runs only scripts from the default-branch checkout: scripts/find-action-bundle-artifact.sh and scripts/push-action-bundle.sh. The PR is checked out in a separate directory at head_sha with persist-credentials: false. No PR code runs.
      • It downloads the artifact from that exact run (actions: read) and treats it as untrusted data. The push script accepts only regular files and directories under action/, so symlinks, special files and extra entries fail. It also checks that the checkout is at head_sha.
      • It creates the app token last. The commit and push run with hooks turned off. The push is fast-forward only on top of head_sha, so a moved branch is rejected and the new head gets its own run. The app token push starts CI again, and that run finds no change because the build always gives the same bytes.
      • This closes Warden VRG-9C6, XHC-8WM and VJW-URC. workflow_run only runs from the default branch, so the first real run happens after this merges.
  • The old flow is removed:
    • the detached "Build github-reporter action" commits
    • the vX.Y.Z-src tags
    • the force-move of vX.Y.Z
    • the local tag remap before craft prepare
  • Craft now tags the release commit, which already contains the bundle. Craft merges the release branch back with --no-ff, so vX.Y.Z is reachable from main.
  • v0 now moves through Craft's github target, floatingTags: ["v{major}"], and minVersion is 3.11.1. scripts/update-major-tag.sh and update-action-tag.yml are deleted. Craft 3.11.1 (fix(github): Skip prereleases and ignore floating tags in version lookup craft#969) fixes the two bugs that blocked this before. Prereleases do not move floating tags. The previous-release lookup (getLatestTag, getLatestStableTag, getChangelogBaseTag) skips tags without a full major.minor.patch, such as v0. v0 lands on the release commit, which already contains the bundle, so @v0 users get it.
  • merge-jobs.yml runs sh scripts/check-action-bundle.sh on release/* instead of only building. A stale bundle on a release branch fails a status check, so Craft does not publish it.
  • pnpm release:check now fails if the action entrypoint is not committed. Its fixture and a new test cover this.

First-release baseline guard

  • scripts/check-release-baseline.sh runs in a new "Check release baseline" step in release.yml, only when version is empty. The checkout fetches tags.
  • The step stops the release unless the latest tag that main reaches and that matches v[0-9]*.[0-9]*.[0-9]* is v<version> from packages/vitest-evals/package.json, the file the release bumps. Prerelease tags count, because publish merges a prerelease version into main. v0 does not match the pattern. The error says to pass an exact version.
  • Without the guard, Craft 3.11.1 reads 0.18.0-src on today's main. auto, patch and minor would then fail with "Nothing to commit", major would release 1.0.0, and pre would probably publish a -src prerelease.

Merge of main

Why the old flow existed

The bundle was gitignored, so update-action-tag.yml built it after Craft published. The workflow committed the bundle on a commit outside main, then force-moved vX.Y.Z and vX to that commit. As a result, main could reach only the vX.Y.Z-src tags. Craft parses those tags as prereleases. A dry run on today's main gives auto → 0.18.0-src -> 0.18.0, which is a release that already exists.

Transition (one time)

main still reaches only -src tags, so the baseline guard stops any release without version. For the first release after this merges, set version to an exact version, for example 0.18.1. That release creates v0.18.1 on a commit that main can reach. After that, auto and the bump types work.

After the first release, run git ls-remote origin refs/tags/v0 and check that v0 points at the v0.18.1 commit. Craft moves floating tags on a best-effort basis: if the move fails, it only logs a warning. The README documents both steps. This PR does not push, move, or delete any tags.

Changelog preview uses the same tag lookup, so it lists the full history until that first release. After the first release it works normally. There is no Craft setting that fixes this before then, so the changelog-preview workflow is unchanged.

Verification

  • actionlint 1.7.12: the only new finding is the unknown copilot-requests scope. junior's live workflow gets the same finding.
  • shellcheck --shell=sh --enable=check-extra-masked-returns: passes on both new scripts.
  • I ran both new scripts under dash:
    • Both jobs' scripts, simulated against a local bare remote:
      • With a fresh bundle, the check passes and sets no output.
      • With a stale bundle, the check fails on a fork PR or main, and sets stale=true on a same-repo PR.
      • The push script pushes a bundle whose blob matches a fresh build.
      • The push is rejected (non-fast-forward) when the branch moved after the build.
  • check-action-bundle.sh without CAN_PUSH exits 1 after a change to src/action/main.ts, and it passes on the committed bundle.
  • Craft 3.11.1 (npx @sentry/craft@3.11.1 prepare --dry-run), in a scratch repo with v0 and v0.18.1 on the same commit (where raw git describe returns v0): auto → 0.18.1 -> 0.19.0, patch → 0.18.2, pre → 0.19.0-alpha.0. On today's main, auto still gives 0.18.0-src -> 0.18.0, so the transition note still applies.
  • Baseline guard under dash, against scratch repos:
    • Today's main (only -src tags): fails with the exact-version error.
    • With an exact version: the step is skipped.
    • After a simulated stable v0.18.1 release, with v0 on the same commit: passes.
    • After a simulated prerelease: passes.
    • No tags: fails.
  • push-action-bundle.sh under dash, against a local bare remote, run from outside the PR checkout:
    • A stale bundle is pushed. A fresh bundle exits 0 with no commit.
    • A wrong head_sha, a symlink, an extra top-level file and a FIFO in the artifact are each rejected.
    • A moved branch is rejected as non-fast-forward.
    • A planted pre-commit hook does not run. The token never appears in .git/config.
  • find-action-bundle-artifact.sh against a fake gh: it sets found only when the artifact exists, and fails on an API error.
  • CI on e83288c: test, action-bundle, CodeQL, Secret Scan, Socket and the reporter smoke test pass. The new workflow_run workflow has not run yet, because it only runs from main.
  • The bundle build is deterministic: two builds give the same bytes.
  • I ran craft prepare --dry-run (Craft master build, before 3.11.1):
    • On today's tags, 0.18.1 is accepted.
    • After a simulated merged v0.18.1 release and a feat commit:
      • auto → 0.19.0
      • pre → 0.19.0-alpha.0
      • patch → 0.18.2
  • pnpm release:check, the release-config tests (6/6), pnpm lint, and pnpm build pass.
  • pnpm test:ci: 409 tests pass. One test fails: report-ui "returns 500 when asset reads fail". That test needs chmod 000 to block reads, and my sandbox ignores file permissions. That failure is not related to this PR.

I did not run the Release workflow.

via @BYK.

--

View Session [Sentry]

Replace getsentry/action-prepare-release with getsentry/craft@v3 and pass
the full bump set (auto, pre, patch, minor, major) plus an exact version
override. Craft now computes the version, so the local version calculator
is gone.

Craft reads the reachable vX.Y.Z-src source tags as prereleases, so the
release job now points local vX.Y.Z tags at their source commits before
Craft runs. The previous source-tag checks move into the same script.
@vercel

vercel Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
vitest-evals-docs Ready Ready Preview Nov 7, 2026 1:13am UTC

Request Review

Comment thread .github/workflows/release.yml Resolved

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread .github/workflows/release.yml Resolved
Commit github-reporter/dist/action/index.js on main and check in CI that it
matches a fresh build, the standard pattern for JavaScript actions. Craft
now tags release commits that already contain the bundle, so the detached
bundle commits, vX.Y.Z-src source tags, and the local tag remap before
craft prepare all go away. The action tag workflow only moves vX on
stable releases.
Pointing v0 at the release commit lets git describe return v0 once main
reaches that commit, and Craft then cannot parse the latest version. Point
v0 at a child commit with the release tree instead, the same fix as
getsentry/warden#567.
On same-repo pull requests, rebuild github-reporter/dist and push it back
with the release bot token so CI runs again on the new commit. Fork PRs,
Dependabot, and main cannot be pushed to here, so the job still fails when
the bundle is stale.

Keep the update-action-tag workflow instead of Craft floatingTags: Craft
puts the floating tag on the release commit, so git describe returns v0
and auto versioning starts from 0.0.0. It also moves v0 on prereleases.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Comment thread .github/workflows/test.yml Resolved
The bundle job ran pnpm install and the build in the same job as the
release bot token, so a compromised dependency could read the token. Build
and compare with read-only credentials, pass a stale bundle as an artifact,
and push it from a separate job that only runs git.
Comment thread .github/workflows/release.yml Resolved

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread .github/workflows/test.yml Resolved
BYK added a commit to getsentry/craft that referenced this pull request Nov 6, 2026
…kup (#969)

Fixes two `floatingTags` bugs that keep repos with `v`-prefixed release
tags from using it.

**Prereleases moved floating tags.** `updateFloatingTags` had no
prerelease check, so a `pre` release like `0.54.0-alpha.0` moved `v0` to
the alpha for everyone pinned to `@v0`. It now skips (and logs) when the
version has a semver prerelease identifier.

**Floating tags hid the previous release.** `git describe --tags --match
'v*'` also matches `v0`. When `v0` and `v0.53.0` are on the same commit,
git picks `v0`, Craft can't parse a version from it, and `auto` computes
from `0.0.0` (a vitest-evals dry run gave `0.0.0 -> 0.1.0`).
`findLatestTag` now skips tags with no version after the prefix (`v0`,
`v0.53`, `latest`) by excluding them and describing again, the same loop
it already used to skip prereleases. `getLatestTag` goes through it too,
so `prepare`, auto/pre versioning, the changelog base, and `craft
changelog` all get the fix. Prefixed monorepo tags and prerelease
handling are unchanged.

Tests cover a prerelease leaving floating tags alone, a stable release
still moving them, and a real git repo where `v0` and `latest` sit on
the `v0.53.0` commit, which now resolves to `v0.53.0` for every lookup.
The GitHub target docs mention both behaviors.

This unblocks getsentry/warden#567 and getsentry/vitest-evals#117
replacing their `update-major-tag.sh` scripts with `floatingTags:
["v{major}"]`.

<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3A5177a1a88a2e80b15a376402e26b19da -->

--

[View
Session](https://junior-prod.sentry.dev/conversations/agent%3A5177a1a88a2e80b15a376402e26b19da)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A5177a1a88a2e80b15a376402e26b19da/?project=4510944073809921)

<!-- junior-session-footer:end -->

---------

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread .craft.yml Resolved
Comment thread .github/workflows/test.yml Resolved
Comment thread .github/workflows/test.yml Resolved
Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e83288c. Configure here.

@BYK
BYK merged commit 4d9125f into main Nov 7, 2026
17 checks passed
@BYK
BYK deleted the ci/craft-auto-versioning branch November 7, 2026 14:52

This branch was successfully deployed

1 active deployment
Preview — db7fd356 Deployed Nov 7, 2026 by vercel[bot]
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