Skip to content

Commit c3a2619

Browse files
committed
Adjust release process
Rulesets prohibit pushing commits on `main` without a PR. This means that running `npm version` within `main` actually creates more work. Further, the release workflow requires CI to have passed on the tagged commit, but it's triggered when the tag is pushed. Simplify by triggering on pushes to `main`, when that commit has a release tag. We can then create a PR for a release branch, push the tag commit, and trigger the release when merging the commit into `main`. This still has to happen locally since we must include the tagged commit.
1 parent b99b703 commit c3a2619

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

.github/workflows/release.yml

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: Release
22
on:
33
push:
4-
tags:
5-
- 'v*'
4+
branches:
5+
- 'main'
66
workflow_dispatch:
77
inputs:
88
tag:
@@ -31,7 +31,41 @@ jobs:
3131
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}
3232
fetch-depth: 0
3333

34+
- name: Check if release tag exists for this commit
35+
id: check_tag
36+
run: |
37+
# For manual dispatch, we already know we should proceed
38+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
39+
echo "proceed=true" >> $GITHUB_OUTPUT
40+
echo "release_tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT
41+
exit 0
42+
fi
43+
44+
# For push to main branch, check if a release tag points to this commit
45+
TAGS=$(git tag --points-at ${{ github.sha }} | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$' || true)
46+
47+
if [[ -z "$TAGS" ]]; then
48+
echo "No release tag found for commit ${{ github.sha }} on main branch"
49+
echo "proceed=false" >> $GITHUB_OUTPUT
50+
exit 0
51+
fi
52+
53+
# Check for multiple tags and fail if found
54+
TAG_COUNT=$(echo "$TAGS" | wc -l)
55+
if [[ $TAG_COUNT -gt 1 ]]; then
56+
echo "Multiple release tags found for this commit:"
57+
echo "$TAGS"
58+
echo "Please use workflow dispatch to specify which tag to release"
59+
exit 1
60+
fi
61+
62+
RELEASE_TAG="$TAGS"
63+
echo "Found release tag: $RELEASE_TAG"
64+
echo "proceed=true" >> $GITHUB_OUTPUT
65+
echo "release_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
66+
3467
- name: Verify tag matches package.json version
68+
if: steps.check_tag.outputs.proceed == 'true'
3569
run: |
3670
jq --raw-output --exit-status --arg tag "$RELEASE_TAG" '
3771
if (.version == ($tag | ltrimstr("v"))) then
@@ -40,21 +74,10 @@ jobs:
4074
"Package version (\(.version)) does not match tag version (\($tag | ltrimstr("v")))" | halt_error(1)
4175
end' package.json
4276
env:
43-
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
44-
45-
- name: Verify commit is in main branch
46-
run: |
47-
# Check if the tagged commit is included in the main branch
48-
if git merge-base --is-ancestor ${{ github.sha }} origin/main; then
49-
echo "Tagged commit is properly included in main branch"
50-
else
51-
echo "Tagged commit is not included in the main branch"
52-
echo "Please push the commit to main before releasing"
53-
exit 1
54-
fi
77+
RELEASE_TAG: ${{ steps.check_tag.outputs.release_tag }}
5578

5679
- name: Check CI status
57-
if: ${{ !inputs.skip_ci_check }}
80+
if: ${{ steps.check_tag.outputs.proceed == 'true' && !inputs.skip_ci_check }}
5881
run: |
5982
# Check if CI has completed successfully for this commit
6083
gh run list --commit ${{ github.sha }} --status success --json workflowName | jq --raw-output --exit-status '
@@ -67,23 +90,26 @@ jobs:
6790
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6891

6992
- name: Setup Node.js
93+
if: steps.check_tag.outputs.proceed == 'true'
7094
uses: actions/setup-node@v4
7195
with:
7296
node-version-file: package.json
7397
cache: npm
7498
registry-url: https://registry.npmjs.org
7599

76100
- name: Publish to npm with provenance
101+
if: steps.check_tag.outputs.proceed == 'true'
77102
run: npm publish --provenance
78103
env:
79104
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
80105

81106
- name: Create GitHub Release
107+
if: steps.check_tag.outputs.proceed == 'true'
82108
run: |
83109
gh release create "$RELEASE_TAG" \
84110
--title "$RELEASE_TAG" \
85111
--draft \
86112
--generate-notes
87113
env:
88-
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
114+
RELEASE_TAG: ${{ steps.check_tag.outputs.release_tag }}
89115
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

maintaining.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,22 @@ Speaking of, using newer TypeScript features could be considered a breaking chan
4343

4444
## Release process
4545

46-
1. In the `main` branch, use `npm version` with the correct increment.
47-
1. Push the resulting tag (`git push --tags`).
48-
1. Wait for minimal CI checks to pass and push the `main` branch.
49-
1. Wait for full CI run to complete on the tag.
50-
1. The *Release* workflow will automatically run and publish to npm with provenance. It will also create a draft GitHub release.
46+
1. Create a release branch, then use `npm version` with the correct increment.
47+
1. Push the resulting tag (`git push --tags`) and create a pull request from the branch.
48+
1. Wait for full CI checks to pass on the pull request.
49+
1. Locally, merge the release branch into `main` using `git merge --ff-only`.
50+
1. Push `main`.
51+
1. The *Release* workflow will automatically run when the tagged commit is pushed to `main` and publish to npm with provenance. It will also create a draft GitHub release.
5152
1. Review and publish the [draft GitHub release](https://github.com/avajs/ava/releases).
5253

5354
The *Release* workflow includes several safety checks:
5455

5556
- Validates the tag version matches `package.json`
56-
- Verifies the tagged commit is included in the `main` branch
5757
- Confirms CI has passed for the commit
5858

5959
### Manual Release
6060

61-
If CI fails for the tag and you're confident this is not due to a fault in the release, you can manually trigger the *Release* workflow:
61+
If CI fails and you're confident this is not due to a fault in the release, or if there are multiple tags pointing to the same commit, you can manually trigger the *Release* workflow:
6262

6363
1. Go to the [*Release* workflow](https://github.com/avajs/ava/actions/workflows/release.yml)
6464
1. Click "Run workflow"

0 commit comments

Comments
 (0)