Repository navigation
Merge pull request #767 from Pinstack/codex/fix-cursor-session-attrib… #345
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Auto-publish on merge: when a version bump lands on `main` or a `release/*` | |
| # maintenance branch, create the matching `vX.Y.Z` tag and GitHub release with | |
| # notes from CHANGELOG.md. Idempotent — `release.py publish` is a no-op when the | |
| # tag and its GitHub release already exist, so merges that don't bump the version | |
| # do nothing, and whichever branch carries a given version first wins the tag. An | |
| # existing tag is verified, not trusted: the commit it points to on origin must | |
| # carry the version (or, on a lost `gh release create` race, be exactly the commit | |
| # this run targeted), and a mismatch, a local-only tag or a failed `git ls-remote` | |
| # read of origin fails the publish. A verified tag with no release gets its | |
| # release created on that tag. After a fresh create the tag is re-read on origin | |
| # and must point at the commit this run targeted (`gh` ignores `--target` for a | |
| # pre-existing tag); otherwise the publish fails and the operator cleans up. | |
| on: | |
| push: | |
| branches: [main, release/*] | |
| concurrency: | |
| # Deliberately ref-independent: `main` and a `release/*` branch can carry the | |
| # same version, and keying on `github.ref` would put them in separate groups and | |
| # let both publish runs proceed at once. One group repo-wide serializes them, so | |
| # the second run checks out *after* the first pushed the tag, finds the verified | |
| # tag and its release, and no-ops. Never cancel-in-progress — a cancelled publish | |
| # leaves the tag unmade. | |
| group: release-publish | |
| cancel-in-progress: false | |
| # `queue: max` because the default single-slot queue cancels an older *pending* | |
| # publish when a newer run enters the group — an evicted publish is a silently | |
| # unmade tag, the same failure the no-cancel rule above exists to prevent. | |
| # The key shipped 2026-05-07; actionlint 1.7.12 (pinned, and upstream's latest, | |
| # 2026-03-30) predates it and rejects it as unknown, so the check is suppressed | |
| # here rather than repo-wide. Drop this once actionlint learns the key. | |
| # trunk-ignore(actionlint/syntax-check) | |
| queue: max | |
| permissions: | |
| contents: write # create tags + releases | |
| jobs: | |
| publish: | |
| name: publish | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 # need all tags to detect whether vX.Y.Z already exists | |
| # Nothing here runs an authenticated git op: the tag check's | |
| # `git ls-remote origin` is an unauthenticated read of the public repo, | |
| # and the tag itself is created by `gh`, which uses GH_TOKEN. | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v10.0.1 | |
| with: | |
| # This is the one job that writes outside the run (it pushes a tag and | |
| # cuts a release), so it does not restore a cache another workflow could | |
| # have poisoned. `release.py publish` runs under `--no-project` and | |
| # installs nothing, so there is no cache worth keeping here anyway. | |
| enable-cache: false | |
| - name: Create tag + GitHub release (idempotent) | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: uv run --no-project python scripts/release.py publish |