Skip to content

Commit 87cdf1f

Browse files
committed
feat(ci): add manual release workflow with tag management
Switch the release workflow from tag-triggered pushes to manual dispatch and automate release preparation from main. This validates the version, builds and commits the release artifact on a release branch, creates versioned major/minor tags, and publishes the GitHub release to make releases safer and more repeatable.feat(ci): add manual release workflow with tag management Switch the release workflow from tag-triggered pushes to manual dispatch and automate release preparation from main. This validates the version, builds and commits the release artifact on a release branch, creates versioned major/minor tags, and publishes the GitHub release to make releases safer and more repeatable.
1 parent 349ba36 commit 87cdf1f

5 files changed

Lines changed: 105 additions & 26189 deletions

File tree

.github/workflows/release.yml

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
name: release
22

33
on:
4-
push:
5-
tags:
6-
- 'v*'
4+
workflow_dispatch:
5+
inputs:
6+
update_minor_tag:
7+
description: Also move the vX.Y tag to this release
8+
required: false
9+
default: true
10+
type: boolean
711

812
permissions: {}
913

@@ -18,19 +22,86 @@ jobs:
1822
with:
1923
persist-credentials: false
2024
- uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0
25+
fetch-depth: 0
2126
with:
2227
version: 8.15.4
2328
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
2429
with:
2530
node-version: 20
2631
cache: pnpm
27-
- run: pnpm install --frozen-lockfile
28-
- run: pnpm run lint
29-
- run: pnpm run typecheck
30-
- run: pnpm run coverage
31-
- run: pnpm run validate
32-
- run: pnpm run build
33-
- run: test -f action.yml
34-
- uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
32+
33+
- name: Configure git
34+
run: |
35+
git config user.name "github-actions[bot]"
36+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
37+
38+
- name: Ensure branch is main
39+
run: |
40+
if [ "${GITHUB_REF_NAME}" != "main" ]; then
41+
echo "Release workflow must run from main. Current ref: ${GITHUB_REF_NAME}"
42+
exit 1
43+
fi
44+
45+
- name: Read version from package.json
46+
id: meta
47+
run: |
48+
VERSION="$(node -p "require('./package.json').version")"
49+
if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
50+
echo "package.json version must be full semver like 1.2.3"
51+
exit 1
52+
fi
53+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
54+
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
55+
echo "major_tag=v${VERSION%%.*}" >> "$GITHUB_OUTPUT"
56+
echo "minor_tag=v$(printf '%s' "$VERSION" | cut -d. -f1,2)" >> "$GITHUB_OUTPUT"
57+
echo "release_branch=release" >> "$GITHUB_OUTPUT"
58+
59+
- name: Ensure version tag does not already exist
60+
run: |
61+
if git ls-remote --exit-code --tags origin "refs/tags/${{ steps.meta.outputs.tag }}" >/dev/null 2>&1; then
62+
echo "Tag ${{ steps.meta.outputs.tag }} already exists on origin"
63+
exit 1
64+
fi
65+
66+
- name: Install dependencies
67+
run: pnpm install --frozen-lockfile
68+
69+
- name: Validate source branch
70+
run: pnpm run check
71+
72+
- name: Create release branch from main
73+
run: |
74+
git switch --create "${{ steps.meta.outputs.release_branch }}" || git switch "${{ steps.meta.outputs.release_branch }}"
75+
git reset --hard "origin/main"
76+
77+
- name: Build release artifact
78+
run: pnpm run build
79+
80+
- name: Commit release artifact
81+
run: |
82+
git add -f dist/index.js
83+
git commit -m "chore(release): publish ${{ steps.meta.outputs.tag }}" \
84+
-m "Build the GitHub Action artifact from package.json version ${{ steps.meta.outputs.version }}."
85+
86+
- name: Create release tags
87+
run: |
88+
git tag -a "${{ steps.meta.outputs.tag }}" -m "Release ${{ steps.meta.outputs.tag }}"
89+
git tag -fa "${{ steps.meta.outputs.major_tag }}" -m "Release ${{ steps.meta.outputs.major_tag }} -> ${{ steps.meta.outputs.tag }}"
90+
if [ "${{ inputs.update_minor_tag }}" = "true" ]; then
91+
git tag -fa "${{ steps.meta.outputs.minor_tag }}" -m "Release ${{ steps.meta.outputs.minor_tag }} -> ${{ steps.meta.outputs.tag }}"
92+
fi
93+
94+
- name: Push release branch and tags
95+
run: |
96+
git push origin HEAD:${{ steps.meta.outputs.release_branch }} --force-with-lease
97+
git push origin "${{ steps.meta.outputs.tag }}"
98+
git push origin "${{ steps.meta.outputs.major_tag }}" --force
99+
if [ "${{ inputs.update_minor_tag }}" = "true" ]; then
100+
git push origin "${{ steps.meta.outputs.minor_tag }}" --force
101+
fi
102+
103+
- name: Publish GitHub Release
104+
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
35105
with:
106+
tag_name: ${{ steps.meta.outputs.tag }}
36107
generate_release_notes: true

.github/workflows/self-test.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ jobs:
1616
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
1717
with:
1818
persist-credentials: false
19+
- uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0
20+
with:
21+
version: 8.15.4
22+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
23+
with:
24+
node-version: 20
25+
cache: pnpm
26+
- run: pnpm install --frozen-lockfile
27+
- run: pnpm run build
1928
- uses: ./
2029
with:
2130
github-token: ${{ github.token }}
@@ -31,6 +40,15 @@ jobs:
3140
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3241
with:
3342
persist-credentials: false
43+
- uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0
44+
with:
45+
version: 8.15.4
46+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
47+
with:
48+
node-version: 20
49+
cache: pnpm
50+
- run: pnpm install --frozen-lockfile
51+
- run: pnpm run build
3452
- id: policy-gate
3553
continue-on-error: true
3654
uses: ./

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ make build
6969

7070
## Release
7171

72-
Tag a version like `v1.0.0` to run the release workflow. The repository uses PolyForm Noncommercial 1.0.0.
72+
Keep `main` source-only. To publish, run the `release` workflow manually from `main`. The workflow reads the version from `package.json`, validates the repo, creates a release commit on the dedicated `release` branch with `dist/index.js`, tags `vX.Y.Z`, and moves `vX` so consumers can keep using `uses: failuresmith/github-policy-gate@v1`. The repository uses PolyForm Noncommercial 1.0.0.

0 commit comments

Comments
 (0)