6060 id : deployment
6161 uses : actions/deploy-pages@v4
6262
63- # Semantic release job
63+ # CalVer release job
6464 release-on-push :
6565 permissions :
6666 contents : write
@@ -71,13 +71,68 @@ jobs:
7171 uses : actions/checkout@v5
7272 with :
7373 fetch-depth : 0
74- persist-credentials : false
75- - name : Semantic Release
76- uses : cycjimmy/semantic-release-action@v4
77- with :
78- branches : main
79- extra_plugins : |
80- conventional-changelog-conventionalcommits@8.0.0
81- @semantic-release/commit-analyzer@10.0.1
74+ - name : Create CalVer tag
75+ id : calver
76+ shell : bash
77+ run : |
78+ set -euo pipefail
79+
80+ git fetch --tags
81+
82+ existing_tag="$(git tag --points-at HEAD | grep -E '^[0-9]{2}\.[0-9]{2}\.[0-9]+$' | head -n 1 || true)"
83+ if [[ -n "${existing_tag}" ]]; then
84+ echo "tag=${existing_tag}" >> "$GITHUB_OUTPUT"
85+ echo "created=false" >> "$GITHUB_OUTPUT"
86+ exit 0
87+ fi
88+
89+ base="$(TZ=UTC date +%y.%m)"
90+ latest_for_month="$(git tag -l "${base}.*" | grep -E "^${base//./\\.}\.[0-9]+$" | sort -V | tail -n 1 || true)"
91+
92+ if [[ -z "${latest_for_month}" ]]; then
93+ tag="${base}.0"
94+ else
95+ sequence="${latest_for_month##*.}"
96+ tag="${base}.$((sequence + 1))"
97+ fi
98+
99+ git config user.name "github-actions[bot]"
100+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
101+ git tag -a "${tag}" -m "Release ${tag}"
102+ git push origin "${tag}"
103+
104+ echo "tag=${tag}" >> "$GITHUB_OUTPUT"
105+ echo "created=true" >> "$GITHUB_OUTPUT"
106+ - name : Publish GitHub release
107+ uses : actions/github-script@v8
82108 env :
83- GITHUB_TOKEN : ${{ secrets.RELEASE_TOKEN }}
109+ GITHUB_TOKEN : ${{ secrets.RELEASE_TOKEN || github.token }}
110+ RELEASE_TAG : ${{ steps.calver.outputs.tag }}
111+ with :
112+ script : |
113+ const tag = process.env.RELEASE_TAG;
114+ const { owner, repo } = context.repo;
115+
116+ try {
117+ const existing = await github.rest.repos.getReleaseByTag({
118+ owner,
119+ repo,
120+ tag,
121+ });
122+ core.info(`Release already exists for ${tag}: ${existing.data.html_url}`);
123+ return;
124+ } catch (error) {
125+ if (error.status !== 404) {
126+ throw error;
127+ }
128+ }
129+
130+ const release = await github.rest.repos.createRelease({
131+ owner,
132+ repo,
133+ tag_name: tag,
134+ name: `Release ${tag}`,
135+ generate_release_notes: true,
136+ });
137+
138+ core.info(`Created release ${release.data.html_url}`);
0 commit comments