Skip to content

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

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

BYK merged 16 commits into
mainfrom
ci/release-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 auto and the full bump set. This makes warden's Release workflow match getsentry/junior, and lets Craft read warden's release tags with no workarounds.

What changed

  • release.yml now uses getsentry/craft@v3 (floating v3 tag) instead of getsentry/action-prepare-release, with version: ${{ inputs.version || inputs.bump }}.
  • Inputs: bump (auto, pre, patch, minor, major; default auto), an optional exact version, and force. Craft now resolves the version.
  • Added permissions (contents: read, copilot-requests: write) and llm_api_key: ${{ github.token }}, the same as junior. This does nothing until .craft.yml sets changelog.aiSummary.
  • .craft.yml gets minVersion: 3.11.1. Older Craft rejects bump types and auto (2.14.0), pre (3.9.0), and moves floating tags on prereleases (fixed in 3.11.1).
  • The Action bundle is now committed to main. dist/action/ (the ncc bundle files only) is tracked and marked linguist-generated in .gitattributes. The CI build job rebuilds it and bin/check-action-dist.sh fails when the result differs from the committed files, including new or removed chunks. Fork and Dependabot PRs can't get the auto-commit, so contributors there run pnpm build:action and commit dist/action/ (CONTRIBUTING.md, AGENTS.md).
  • Same-repo PRs get the bundle committed back, in two workflows (1143078).
    • action-dist.yml runs on pull_request with no secrets. Its build job runs the PR install and build. On a same-repo, non-Dependabot PR with a stale bundle, it uploads dist/action as an artifact.
    • commit-action-dist.yml runs on workflow_run when action-dist.yml completes. It takes the PR's identity (head SHA, head branch, head repository) from the workflow_run payload, not from the artifact. It skips unless the event is pull_request, the head repo is this repo, the actor is not Dependabot, and the branch is not main or release/*. It downloads the artifact from that run id and treats it as untrusted data: it fails if the artifact holds anything other than regular files and directories (such as symlinks or FIFOs), then copies it into dist/action/. It runs no code from the PR. bin/commit-action-dist.sh and bin/push-action-dist.sh come from the default-branch checkout, and the PR checkout has persist-credentials: false and hooks off (core.hooksPath=/dev/null). It creates the release bot app token as the last step, so CI runs again on the new commit, and pushes on top of the head SHA. If the branch moved, the push is not a fast-forward and fails.
    • No pull_request workflow uses the release bot key now. workflow_run runs only from the default branch, so the first real run happens after merge.
  • No more detached release tags, and Craft moves v0. update-major-tag.yml and bin/update-major-tag.sh are removed. Craft's github target tags the release commit, which main reaches after Craft merges the release branch back. On stable releases it also moves v0 there (floatingTags: ['v{major}']). Since Craft 3.11.1 (getsentry/craft#969), a prerelease never moves v0, and the previous-release lookup skips tags without a full major.minor.patch, so v0 on the release commit does not hide v0.53.0. The release commit has the committed dist/action/, so @v0 and @vX.Y.Z run the same bundle.
  • CodeQL moved to advanced setup (0afc598). .github/workflows/codeql.yml scans actions, javascript-typescript and python (the same languages as default setup) on pull_request, push to main and a weekly schedule. .github/codeql/codeql-config.yml ignores dist/**, so the committed bundle gives no alerts. A repo admin must turn off default setup under Settings → Code security. Until then, GitHub rejects the advanced uploads and the CodeQL jobs fail. CodeQL is not a required check.
  • Removed bin/craft-release-tags.sh (and its release.yml step) and bin/publish-action-bundle.sh. specs/release-process.md describes the new flow.

Why the old flow existed

dist/ was gitignored, so the bundle could only live on a commit off main. After each release, a workflow built it, committed it on top of the release tag, and force-moved vX.Y.Z and v0 there. It left vX.Y.Z-src on the source commit. main reached only those -src tags, which Craft reads as prereleases, so this PR first needed a tag remap script. Committing the bundle to main (the actions/typescript-action pattern) removes the need for all of it.

First release after merge

main still reaches only the old v0.52.0-src and v0.46.0 tags. Existing tags are not changed.

  • Run the first release with an exact version, for example 0.53.0. Craft bumps from the latest tag, prereleases included, which is v0.52.0-src on main. auto, patch and minor would give 0.52.0, pre 0.52.0-src.0, and major 1.0.0. A new Check release baseline step (bin/check-release-baseline.sh) runs when version is empty. It fails when the latest version tag is not v plus the packages/warden/package.json version, so these runs stop before Craft.
  • Its changelog starts at v0.46.0, the latest stable tag main reaches, so it repeats the 0.47.0 to 0.52.0 entries. Trim them on the release/0.53.0 branch before you approve the publish request.
  • After the first release, confirm that git ls-remote origin refs/tags/v0 points to the v0.53.0 commit. Craft logs only a warning when it cannot move a floating tag. From the next release on, auto works, because v0.53.0 is on main.

Verification

  • pnpm build:action output is deterministic, the same on Node 22 and Node 24, and byte-identical to the dist/action on the published v0.52.0 tag (all 50 files).
  • bin/check-action-dist.sh passes on the committed bundle after a rebuild, and fails on a changed file and on an untracked new chunk.
  • git check-ignore confirms .d.ts and .map output and packages/*/dist stay ignored.
  • validate-action-layout --require-dist passes.
  • Craft 3.11.1 (npx @sentry/craft@3.11.1 changelog) in a scratch repo with v0 and v0.53.0 on the same commit (both annotated, and both lightweight): git describe --tags --match 'v*' returns v0, and Craft picks v0.53.0 as the base. Craft source at 3.11.1 skips floating tags for prereleases in updateFloatingTags.
  • Local simulation of commit-action-dist.yml's scripts against a local bare remote: no artifact and an empty artifact make no commit, symlinks and FIFOs in the artifact are rejected, unchanged content makes no commit, a changed and a new chunk are committed and pushed, hooks do not run, and a push after the branch moved is rejected as non-fast-forward. The real workflow_run path is not verified until after merge.
  • actionlint 1.7.12 passes. Its only finding is copilot-requests, a scope it doesn't know yet (same on junior's release.yml). shellcheck --shell=sh --enable=check-extra-masked-returns passes on the new scripts.
  • pnpm lint and typecheck pass. pnpm test: 2091 pass. The 9 src/skills/remote.test.ts real-git tests fail in my sandbox only, because its git wrapper rejects the test's commit author. CI is the source of truth there.
  • I did not run craft prepare end to end, and the Release workflow was not triggered.

The bundle went in as three commits (part 1 to 3) because the sandbox's push proxy rejects large packs.

via @BYK.

--

View Session [Sentry]

Switch the Release workflow from action-prepare-release to getsentry/craft@v3
with the full bump set (auto, pre, patch, minor, major; default auto), an
optional exact version override, and force, matching getsentry/junior.

Craft reads the reachable vX.Y.Z-src tags as prereleases, so auto and bump
types would promote 0.52.0-src to 0.52.0. Map the source tags back to vX.Y.Z
in the job checkout before Craft runs. Set minVersion 3.9.0 so Craft allows
auto, bump types, and pre.

Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
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
@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
warden-prod Ready Ready Preview Nov 7, 2026 1:14am UTC

Request Review

A pre release publishes a GitHub Release, and update-major-tag.yml moved v0
to it, so @v0 users would run the prerelease. Move the bundle commit and tag
updates into bin/publish-action-bundle.sh and skip the major tag when the
version has a prerelease suffix.
Comment thread .github/workflows/release.yml Resolved
Craft could not read warden's releases because each vX.Y.Z tag pointed at
a detached commit holding dist/action, so main only reached vX.Y.Z-src.
Commit the ncc bundle to main instead and check its freshness in CI, so
Craft's github target tags a release commit that main reaches.

- Track dist/action bundle files, mark them linguist-generated
- CI fails when a rebuilt bundle differs from the committed one
- Remove the tag remap, -src tags and the detached bundle commit
- update-major-tag.yml only moves vX, and skips prereleases

Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
sentry-junior Bot and others added 3 commits November 6, 2026 13:18
Built with pnpm build:action from the current sources (unchanged from main
95d26a7). The files are byte-identical to the v0.52.0 bundle, and Node 22
and Node 24 builds match. Split in parts to fit the push size limit.

Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
Comment thread dist/action/786.index.js
model: model.id,
messages,
stream: true,
prompt_cache_key: (model.baseUrl.includes("api.openai.com") && cacheRetention !== "none") ||
Comment thread dist/action/786.index.js
const isTogether = provider === "together" || baseUrl.includes("api.together.ai") || baseUrl.includes("api.together.xyz");
const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
Comment thread dist/action/786.index.js
const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
Comment thread dist/action/786.index.js
const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
Comment thread dist/action/786.index.js
const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
Comment thread dist/action/786.index.js
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai");
const isDeepSeek = provider === "deepseek" || baseUrl.toLowerCase().includes("deepseek.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 bin/update-major-tag.sh Resolved
git describe --tags prefers the annotated v0 over the lightweight vX.Y.Z
on the same commit, so Craft would read v0 as the previous release. Put
v0 on a same-tree child commit that main does not reach.
Comment thread bin/check-action-dist.sh Resolved
Comment thread bin/update-major-tag.sh Resolved
sentry-junior Bot added a commit to getsentry/vitest-evals that referenced this pull request Nov 6, 2026
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 PRs, rebuild dist/action and push it to the PR branch with a
release bot app token, so CI runs again on the new commit. The token is
created after the build. Fork PRs can't be pushed to, so the existing
freshness check stays as the gate there and on main and release branches.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Comment thread .github/workflows/action-dist.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 bin/commit-action-dist.sh Resolved
Build the bundle in a job with no secrets and pass it on as an artifact.
A second job creates the app token, commits the artifact and pushes it,
with no install, no build and git hooks off for both commit and push.
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>
Craft 3.11.1 moves floating tags on stable releases only and skips them
when it looks up the previous release. Set floatingTags: ['v{major}'] on
the github target, require Craft 3.11.1, and remove update-major-tag.yml
and bin/update-major-tag.sh.

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.

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 62844ca. Configure here.

Comment thread .craft.yml Resolved
Craft bumps from the latest version tag, prereleases included. On main
that is v0.52.0-src, so pre would publish 0.52.0-src.0 and major 1.0.0.
Without a version input, fail when that tag is not the package version,
and correct the transition notes in the release spec.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
The commit job ran on pull_request, so a writer could edit the workflow
and read SENTRY_RELEASE_BOT_PRIVATE_KEY. The pull_request build now only
uploads a stale bundle. commit-action-dist.yml runs on workflow_run from
the default branch, takes the PR identity from the payload, copies only
regular files from the artifact, runs no PR code, and mints the token
last before a fast-forward push.

Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
The committed ncc bundle in dist/action/ raised CodeQL alerts on
generated code. Scan the same languages as default setup (actions,
javascript-typescript, python) with a config that ignores dist/.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
A late action-dist run for an older commit cancelled the push for the
newer commit. The remaining push then failed the fast-forward check, so
the rebuilt bundle never landed.
@BYK
BYK merged commit ba6f685 into main Nov 7, 2026
22 of 26 checks passed
@BYK
BYK deleted the ci/release-craft-auto-versioning branch November 7, 2026 14:53
sentry-junior Bot added a commit that referenced this pull request Nov 7, 2026
The first Craft-managed release diffed from v0.46.0, so it repeated the
0.46.1 to 0.52.0 entries. Keep only the changes since 0.52.0 (#566, #567),
as specs/release-process.md asks for this transition release.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>

This branch was successfully deployed

2 active deployments
Preview – warden-prod — 07b22cf8 Deployed Nov 7, 2026 by vercel[bot]
Preview – warden — 07b22cf8 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.

2 participants