Skip to content

Commit cc8ffd3

Browse files
authored
feat: auto release snapshot version now (#556)
1 parent 406c459 commit cc8ffd3

3 files changed

Lines changed: 267 additions & 7 deletions

File tree

.github/workflows/main.yml

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,104 @@ jobs:
2828
flags: node-${{ matrix.node-version }}
2929
fail_ci_if_error: false
3030

31-
semantic-release:
31+
prepare_snapshot_version:
32+
name: Prepare Snapshot Version
3233
needs: [test]
34+
if: >-
35+
${{
36+
github.repository == 'apache/casbin-node-casbin' &&
37+
github.event_name == 'push' &&
38+
github.ref == 'refs/heads/master'
39+
}}
3340
runs-on: ubuntu-latest
41+
outputs:
42+
version: ${{ steps.snapshot.outputs.version }}
43+
npm_version: ${{ steps.snapshot.outputs.npm_version }}
44+
basename: ${{ steps.snapshot.outputs.basename }}
45+
previous_tag: ${{ steps.snapshot.outputs.previous_tag }}
3446
steps:
3547
- uses: actions/checkout@v4
48+
with:
49+
fetch-depth: 0
50+
ref: ${{ github.sha }}
51+
52+
- name: Compute snapshot version
53+
id: snapshot
54+
run: |
55+
LATEST_RELEASE_TAG="$(
56+
git tag --list 'v*' |
57+
grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' |
58+
sort -V |
59+
tail -n 1
60+
)"
61+
62+
if [ -z "${LATEST_RELEASE_TAG}" ]; then
63+
BASE_VERSION="0.1.0"
64+
else
65+
RELEASE_VERSION="${LATEST_RELEASE_TAG#v}"
66+
MAJOR="${RELEASE_VERSION%%.*}"
67+
REST="${RELEASE_VERSION#*.}"
68+
MINOR="${REST%%.*}"
69+
NEXT_MINOR="$((MINOR + 1))"
70+
BASE_VERSION="${MAJOR}.${NEXT_MINOR}.0"
71+
fi
72+
73+
ESCAPED_BASE_VERSION="${BASE_VERSION//./\\.}"
74+
LAST_SNAPSHOT_NUMBER="$(
75+
git tag --list "v${BASE_VERSION}-snapshot.*" |
76+
sed -nE "s/^v${ESCAPED_BASE_VERSION}-snapshot\.([0-9]+)$/\1/p" |
77+
sort -n |
78+
tail -n 1
79+
)"
80+
LAST_SNAPSHOT_NUMBER="${LAST_SNAPSHOT_NUMBER:-0}"
81+
NEXT_SNAPSHOT_NUMBER="$((LAST_SNAPSHOT_NUMBER + 1))"
82+
SNAPSHOT_VERSION="v${BASE_VERSION}-snapshot.${NEXT_SNAPSHOT_NUMBER}"
83+
NPM_VERSION="${SNAPSHOT_VERSION#v}"
84+
BASENAME="casbin-${NPM_VERSION}-src"
85+
86+
echo "version=${SNAPSHOT_VERSION}" >> "${GITHUB_OUTPUT}"
87+
echo "npm_version=${NPM_VERSION}" >> "${GITHUB_OUTPUT}"
88+
echo "basename=${BASENAME}" >> "${GITHUB_OUTPUT}"
89+
if [ "${LAST_SNAPSHOT_NUMBER}" -gt 0 ]; then
90+
echo "previous_tag=v${BASE_VERSION}-snapshot.${LAST_SNAPSHOT_NUMBER}" >> "${GITHUB_OUTPUT}"
91+
else
92+
echo "previous_tag=${LATEST_RELEASE_TAG}" >> "${GITHUB_OUTPUT}"
93+
fi
94+
95+
echo "Computed snapshot version: ${SNAPSHOT_VERSION}"
96+
echo "Computed npm version: ${NPM_VERSION}"
97+
98+
publish-npm:
99+
name: Publish NPM
100+
needs: prepare_snapshot_version
101+
if: >-
102+
${{
103+
github.repository == 'apache/casbin-node-casbin' &&
104+
github.event_name == 'push' &&
105+
github.ref == 'refs/heads/master'
106+
}}
107+
uses: ./.github/workflows/npm-snapshot.yml
108+
with:
109+
npm_version: ${{ needs.prepare_snapshot_version.outputs.npm_version }}
110+
ref: ${{ github.sha }}
111+
secrets: inherit
36112

37-
- name: Run semantic-release
38-
if: github.repository == 'apache/casbin-node-casbin' && github.event_name == 'push'
39-
run: yarn install && yarn semantic-release
40-
env:
41-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
113+
semantic-relese:
114+
name: semantic-relese
115+
needs:
116+
- prepare_snapshot_version
117+
- publish-npm
118+
if: >-
119+
${{
120+
github.repository == 'apache/casbin-node-casbin' &&
121+
github.event_name == 'push' &&
122+
github.ref == 'refs/heads/master'
123+
}}
124+
permissions:
125+
contents: write
126+
uses: ./.github/workflows/semantic-relese.yml
127+
with:
128+
version: ${{ needs.prepare_snapshot_version.outputs.version }}
129+
basename: ${{ needs.prepare_snapshot_version.outputs.basename }}
130+
previous_tag: ${{ needs.prepare_snapshot_version.outputs.previous_tag }}
131+
ref: ${{ github.sha }}

.github/workflows/npm-snapshot.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Publish NPM
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
npm_version:
7+
required: true
8+
type: string
9+
ref:
10+
required: true
11+
type: string
12+
workflow_dispatch:
13+
inputs:
14+
npm_version:
15+
description: NPM snapshot version to publish, for example 1.2.3-snapshot.1
16+
required: true
17+
type: string
18+
ref:
19+
description: Git ref or commit SHA to publish
20+
required: true
21+
type: string
22+
23+
permissions:
24+
contents: read
25+
26+
jobs:
27+
publish-npm:
28+
name: Publish NPM
29+
if: ${{ github.repository == 'apache/casbin-node-casbin' }}
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
ref: ${{ inputs.ref }}
37+
38+
- name: Set up Node.js
39+
uses: actions/setup-node@v4
40+
with:
41+
node-version: 22
42+
registry-url: https://registry.npmjs.org
43+
44+
- name: Publish snapshot package
45+
run: |
46+
yarn install --frozen-lockfile
47+
npm version "${{ inputs.npm_version }}" --no-git-tag-version
48+
npm publish --tag snapshot
49+
env:
50+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: semantic-relese
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
version:
7+
required: true
8+
type: string
9+
basename:
10+
required: true
11+
type: string
12+
previous_tag:
13+
required: false
14+
type: string
15+
default: ""
16+
ref:
17+
required: true
18+
type: string
19+
workflow_dispatch:
20+
inputs:
21+
version:
22+
description: GitHub release tag, for example v1.2.3-snapshot.1
23+
required: true
24+
type: string
25+
basename:
26+
description: Source archive basename, for example casbin-1.2.3-snapshot.1-src
27+
required: true
28+
type: string
29+
previous_tag:
30+
description: Previous tag for release notes
31+
required: false
32+
type: string
33+
ref:
34+
description: Git ref or commit SHA for the snapshot
35+
required: true
36+
type: string
37+
38+
permissions:
39+
contents: write
40+
41+
jobs:
42+
semantic-relese:
43+
name: semantic-relese
44+
if: ${{ github.repository == 'apache/casbin-node-casbin' }}
45+
runs-on: ubuntu-latest
46+
steps:
47+
- name: Checkout
48+
uses: actions/checkout@v4
49+
with:
50+
fetch-depth: 0
51+
ref: ${{ inputs.ref }}
52+
53+
- name: Generate snapshot release notes
54+
run: |
55+
PREVIOUS_TAG="${{ inputs.previous_tag }}"
56+
CURRENT_TAG="${{ inputs.version }}"
57+
CURRENT_VERSION="${CURRENT_TAG#v}"
58+
RELEASE_DATE="$(date -u +%F)"
59+
RANGE="HEAD"
60+
61+
if [ -n "${PREVIOUS_TAG}" ]; then
62+
RANGE="${PREVIOUS_TAG}..HEAD"
63+
fi
64+
65+
FEATURES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(feat)(\(.+\))?: ' || true)"
66+
FIXES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(fix)(\(.+\))?: ' || true)"
67+
DOCS="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(docs?|doc)(\(.+\))?: ' || true)"
68+
69+
{
70+
if [ -n "${PREVIOUS_TAG}" ]; then
71+
echo "# [${CURRENT_VERSION}](https://github.com/${GITHUB_REPOSITORY}/compare/${PREVIOUS_TAG}...${CURRENT_TAG}) (${RELEASE_DATE})"
72+
else
73+
echo "# ${CURRENT_VERSION} (${RELEASE_DATE})"
74+
fi
75+
echo
76+
if [ -n "${FEATURES}" ]; then
77+
echo "## Features"
78+
echo
79+
printf '%s\n' "${FEATURES}" | sed 's/^/- /'
80+
echo
81+
fi
82+
83+
if [ -n "${FIXES}" ]; then
84+
echo "## Fixes"
85+
echo
86+
printf '%s\n' "${FIXES}" | sed 's/^/- /'
87+
echo
88+
fi
89+
90+
if [ -n "${DOCS}" ]; then
91+
echo "## Docs"
92+
echo
93+
printf '%s\n' "${DOCS}" | sed 's/^/- /'
94+
echo
95+
fi
96+
97+
if [ -z "${FEATURES}${FIXES}${DOCS}" ]; then
98+
echo "## Notes"
99+
echo
100+
echo "- No feat/fix/doc commits were found in this snapshot range."
101+
fi
102+
} > SNAPSHOT_RELEASE_NOTES.md
103+
104+
- name: Create source archives
105+
run: |
106+
mkdir -p dist
107+
git archive --format=tar.gz --prefix="${{ inputs.basename }}/" -o "dist/${{ inputs.basename }}.tar.gz" HEAD
108+
git archive --format=zip --prefix="${{ inputs.basename }}/" -o "dist/${{ inputs.basename }}.zip" HEAD
109+
110+
- name: Create source snapshot release
111+
uses: softprops/action-gh-release@v2
112+
with:
113+
tag_name: ${{ inputs.version }}
114+
target_commitish: ${{ inputs.ref }}
115+
name: ${{ inputs.version }}
116+
body_path: SNAPSHOT_RELEASE_NOTES.md
117+
draft: false
118+
prerelease: false
119+
files: |
120+
dist/${{ inputs.basename }}.tar.gz
121+
dist/${{ inputs.basename }}.zip

0 commit comments

Comments
 (0)