11name : Create Release
22
33on : # zizmor: ignore[concurrency-limits]
4- push :
5- tags :
6- - ' v*'
4+ workflow_dispatch :
5+ inputs :
6+ version :
7+ description : ' Release version, without the v prefix (e.g. 6.2.0)'
8+ required : true
9+ type : string
710
811permissions : {}
912
1013jobs :
11- build : # zizmor: ignore[anonymous-definition]
14+ release :
15+ name : Create Release
1216 runs-on : ubuntu-latest
13- permissions :
14- contents : write # create GitHub release and upload assets
17+ environment : Releases
18+ permissions : {} # all writes go through the App token; GITHUB_TOKEN needs no scopes
1519 steps :
16- - name : Checkout code
20+ - name : Resolve and validate version
21+ env :
22+ INPUT_VERSION : ${{ inputs.version }}
23+ BRANCH : ${{ github.ref_name }}
24+ run : |
25+ version="${INPUT_VERSION#v}"
26+
27+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$ ]]; then
28+ echo "::error::Version must look like 6.2.0 (got: $INPUT_VERSION)"
29+ exit 1
30+ fi
31+
32+ if [ "${version%%.*}" != "${BRANCH%%.*}" ]; then
33+ echo "::error::Version $version does not belong on the $BRANCH branch"
34+ exit 1
35+ fi
36+
37+ echo "TAG=v$version" >> "$GITHUB_ENV"
38+
39+ - name : Get release bot token
40+ id : app-token
41+ uses : actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
42+ with :
43+ client-id : ${{ secrets.RELEASE_APP_CLIENT_ID }}
44+ private-key : ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
45+ permission-contents : write
46+
47+ - name : Checkout
1748 uses : actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
1849 with :
19- persist-credentials : false
50+ token : ${{ steps.app-token.outputs.token }}
51+ persist-credentials : true # zizmor: ignore[artipacked] App token is needed to push the tag
52+
53+ - name : Assert tag does not already exist
54+ run : |
55+ existing="$(git ls-remote --tags origin "$TAG")"
56+ [ -z "$existing" ] || { echo "::error::Tag $TAG already exists on remote. Aborting."; exit 1; }
2057
2158 - name : Use Node.js 20.19.0
2259 uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -30,25 +67,48 @@ jobs:
3067 - name : Build release assets
3168 run : bash ./scripts/build-release.sh
3269
70+ - name : Create the build commit
71+ env :
72+ GH_TOKEN : ${{ steps.app-token.outputs.token }}
73+ APP_SLUG : ${{ steps.app-token.outputs.app-slug }}
74+ run : |
75+ USER_ID="$(gh api "/users/${APP_SLUG}[bot]" --jq .id)"
76+ git config user.name "${APP_SLUG}[bot]"
77+ git config user.email "${USER_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
78+ git add --force \
79+ resources/dist \
80+ resources/dist-dev \
81+ resources/dist-frontend \
82+ resources/dist-package
83+ git commit -m "Build assets for $TAG"
84+
85+ - name : Tag and push the build commit
86+ run : |
87+ git tag "$TAG"
88+ git push origin "$TAG"
89+
3390 - name : Get Changelog
3491 id : changelog
3592 uses : statamic/changelog-action@5d112d0d790cdeeb5adca3e584e37edc474ab51b # v1.0.2
3693 with :
37- version : ${{ github.ref }}
94+ version : ${{ env.TAG }}
3895
3996 - name : Create release
4097 env :
41- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
42- RELEASE_VERSION : ${{ steps.changelog.outputs.version }}
98+ GH_TOKEN : ${{ steps.app-token.outputs.token }}
4399 RELEASE_NOTES : ${{ steps.changelog.outputs.text }}
100+ IS_DEFAULT_BRANCH : ${{ github.ref_name == github.event.repository.default_branch }}
44101 run : |
45- gh release create "$RELEASE_VERSION" \
46- --title "$RELEASE_VERSION" \
102+ latest="$IS_DEFAULT_BRANCH"
103+ prerelease=false
104+ case "$TAG" in
105+ *-*) prerelease=true; latest=false ;;
106+ esac
107+ gh release create "$TAG" \
108+ --title "$TAG" \
47109 --notes "$RELEASE_NOTES" \
48- ./resources/dist.tar.gz \
49- ./resources/dist-dev.tar.gz \
50- ./resources/dist-frontend.tar.gz \
51- ./resources/dist-package.tar.gz
110+ --latest="$latest" \
111+ --prerelease="$prerelease"
52112
53113 - name : Deploy Storybook to Forge
54114 continue-on-error : true
0 commit comments