Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,41 @@ jobs:
- uses: release-drafter/release-drafter@4d75298e00d9e34c483e5ff8c68d0ea1c1940c1e # v7.5.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6

# The Releases page must tell the truth before Publish is clicked: when
# the manifest version is already released, the draft carries a warning
# banner; once the manifests are bumped, the banner clears and the
# draft's tag/title default to the guard-passing v<version>.
- name: Sync the draft with the manifest version
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
VERSION="$(jq -r .version cli/deno.json)"
DRAFT_ID="$(gh api "repos/${{ github.repository }}/releases?per_page=10" --jq '[.[] | select(.draft)][0].id // empty')"
if [ -z "$DRAFT_ID" ]; then
echo "no draft release found"
exit 0
fi
gh api "repos/${{ github.repository }}/releases/$DRAFT_ID" --jq .body > /tmp/body.md
sed '/<!-- version-banner -->/,/<!-- \/version-banner -->/d' /tmp/body.md > /tmp/clean.md
if git ls-remote --exit-code origin "refs/tags/v$VERSION" >/dev/null 2>&1; then
{
echo "<!-- version-banner -->"
echo "> [!WARNING]"
echo "> The manifests still declare \`$VERSION\`, which is already released."
echo "> Bump every manifest before publishing this draft (release spec §2)."
echo "<!-- /version-banner -->"
echo
cat /tmp/clean.md
} > /tmp/new.md
gh api -X PATCH "repos/${{ github.repository }}/releases/$DRAFT_ID" \
-F body=@/tmp/new.md >/dev/null
echo "draft flagged: manifests still at already-released $VERSION"
else
gh api -X PATCH "repos/${{ github.repository }}/releases/$DRAFT_ID" \
-f tag_name="v$VERSION" -f name="v$VERSION" -F body=@/tmp/clean.md >/dev/null
echo "draft synced to v$VERSION"
fi
49 changes: 38 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,46 @@ permissions:
contents: write

jobs:
# Refuse a tag the manifests do not declare (spec §2) — the binary's
# --version comes from cli/deno.json. On failure, the mistake is made
# visible on the release itself, not just in this log.
preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6

- name: Tag matches the manifest version
run: |
TAG="${{ github.ref_name }}"
declared="$(jq -r .version cli/deno.json)"
if [ "v$declared" != "$TAG" ]; then
echo "::error::cli/deno.json declares $declared but the tag is $TAG — bump the manifests first"
exit 1
fi

- name: Flag the release when the tag cannot build
if: failure()
env:
GH_TOKEN: ${{ github.token }}
run: |
set -u
TAG="${{ github.ref_name }}"
gh release view "$TAG" --json body --jq .body > /tmp/body.md 2>/dev/null || exit 0
{
echo "> [!CAUTION]"
echo "> This release did not build: the manifests do not declare \`${TAG#v}\`."
echo "> Delete this release and its tag, bump every manifest, and release again"
echo "> (release spec §2)."
echo
cat /tmp/body.md
} > /tmp/new.md
gh release edit "$TAG" --prerelease \
--title "$TAG — failed: manifests not bumped" \
--notes-file /tmp/new.md || true

build:
name: Compile ${{ matrix.target }}
needs: preflight
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -28,17 +66,6 @@ jobs:
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6

# Refuse a tag the manifests do not declare (spec §2) — the binary's
# --version comes from cli/deno.json.
- name: Tag matches the manifest version
run: |
TAG="${{ github.ref_name }}"
declared="$(jq -r .version cli/deno.json)"
if [ "v$declared" != "$TAG" ]; then
echo "::error::cli/deno.json declares $declared but the tag is $TAG — bump the manifests first"
exit 1
fi

- uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
with:
deno-version: v2.9.1
Expand Down
19 changes: 12 additions & 7 deletions specs/release-process-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,18 @@ create the `vX.Y.Z` tag.

- **`draft-release.yml`** (`push: main`): maintains the rolling draft release
with release-drafter (config: `.github/release-drafter.yml`). Each merged PR
appends a changelog line; publishing the draft cuts the release. Before
publishing, set the tag to the version the manifests declare — the guards
below refuse a mismatched tag.
- **`release.yml`** (`push: tags v*`): validates the tag against
`cli/deno.json`, compiles `xmd` per target with
`--include packages/code-review-agent`, and attaches the binaries and sha256
checksums to the tag's GitHub Release.
appends a changelog line; publishing the draft cuts the release. After every
merge the workflow syncs the draft with the manifests: when the manifest
version is already released, the draft's notes carry a warning banner saying
the manifests need bumping; once bumped, the banner clears and the draft's
tag and title default to the guard-passing `v<version>`.
- **`release.yml`** (`push: tags v*`): a preflight job validates the tag
against `cli/deno.json`; on mismatch it flags the just-published release on
the Releases page — caution note in the notes, a failed title, and the
prerelease marker — so a forgotten bump is visible where the release was
made, then refuses to build. On a valid tag it compiles `xmd` per target
with `--include packages/code-review-agent` and attaches the binaries and
sha256 checksums to the tag's GitHub Release.
- **`publish-packages.yml`** (`push: tags v*`): GENERATED by
`scripts/gen-publish-workflow.md` — an executable markdown document that
derives the jobs from the workspace manifests — never edited by hand. Run
Expand Down
Loading