11name : Release
2+
23on :
3- release :
4- types : [published]
4+ push :
5+ tags :
6+ - ' *.*.*'
7+ workflow_dispatch :
8+ inputs :
9+ release_tag :
10+ description : ' Release tag to publish, for example 2026.05.09'
11+ required : true
12+ type : string
13+
14+ permissions :
15+ contents : read
16+
17+ concurrency :
18+ group : release-${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
19+ cancel-in-progress : false
20+
21+ env :
22+ RELEASE_TAG : ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
523
624jobs :
7- tag :
8- name : Add/update 'latest' tag
25+ validate :
26+ name : Validate package
927 runs-on : ubuntu-latest
1028 steps :
1129 - name : Checkout repository
12- uses : actions/checkout@v2
13- - name : Run latest-tag
14- uses : EndBug/latest-tag@v1
15- env :
16- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
30+ uses : actions/checkout@v6
31+
32+ - name : Set up Node.js
33+ uses : actions/setup-node@v6
34+ with :
35+ node-version : 22
36+ cache : npm
37+
38+ - name : Normalize release version
39+ run : node .github/scripts/normalize-release-version.js
40+
41+ - name : Install dependencies
42+ run : |
43+ if [ -f package-lock.json ]; then
44+ npm ci
45+ else
46+ npm install
47+ fi
48+
49+ - name : Run tests
50+ run : npm run test --if-present
51+
52+ - name : Run lint
53+ run : npm run lint --if-present
54+
55+ - name : Preview package contents
56+ run : npm pack --dry-run
1757
1858 publish-npm :
19- name : Publish on NPM
59+ name : Publish to npm
2060 runs-on : ubuntu-latest
21- needs : tag
61+ needs : validate
62+ permissions :
63+ contents : read
64+ id-token : write
2265 steps :
23- - uses : actions/checkout@v2
24- - name : Set up Node.js for NPM
25- uses : actions/setup-node@v1
66+ - name : Checkout repository
67+ uses : actions/checkout@v6
68+
69+ - name : Set up Node.js for npm
70+ uses : actions/setup-node@v6
2671 with :
72+ node-version : 24
2773 registry-url : ' https://registry.npmjs.org'
28- - run : npm install
29- - run : npm publish
30- env :
31- NODE_AUTH_TOKEN : ${{ secrets.NPM_AUTH_TOKEN }}
74+ package-manager-cache : false
75+
76+ - name : Normalize release version
77+ run : node .github/scripts/normalize-release-version.js
78+
79+ - name : Install dependencies
80+ run : |
81+ if [ -f package-lock.json ]; then
82+ npm ci
83+ else
84+ npm install
85+ fi
86+
87+ - name : Check npm package version
88+ id : npm-package
89+ run : |
90+ PACKAGE_NAME=$(node -p "require('./package.json').name")
91+ PACKAGE_VERSION=$(node -p "require('./package.json').version")
3292
33- publish-gpr :
34- name : Publish on GPR
93+ if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version --registry=https://registry.npmjs.org >/dev/null 2>&1; then
94+ echo "${PACKAGE_NAME}@${PACKAGE_VERSION} already exists on npm. Skipping publish."
95+ echo "exists=true" >> "${GITHUB_OUTPUT}"
96+ else
97+ echo "${PACKAGE_NAME}@${PACKAGE_VERSION} does not exist on npm. Publishing."
98+ echo "exists=false" >> "${GITHUB_OUTPUT}"
99+ fi
100+
101+ - name : Publish to npm
102+ if : steps.npm-package.outputs.exists != 'true'
103+ run : npm publish --access public
104+
105+ publish-github-packages :
106+ name : Publish to GitHub Packages
35107 runs-on : ubuntu-latest
36- needs : tag
108+ needs : validate
109+ permissions :
110+ contents : read
111+ packages : write
37112 steps :
38- - uses : actions/checkout@v2
39- - name : Set up Node.js for GPR
40- uses : actions/setup-node@v1
113+ - name : Checkout repository
114+ uses : actions/checkout@v6
115+
116+ - name : Set up Node.js for GitHub Packages
117+ uses : actions/setup-node@v6
41118 with :
119+ node-version : 22
42120 registry-url : ' https://npm.pkg.github.com/'
43121 scope : ' @markbattistella'
44- - run : npm install
45- - run : npm publish
122+ cache : npm
123+
124+ - name : Normalize release version
125+ run : node .github/scripts/normalize-release-version.js
126+
127+ - name : Install dependencies
128+ run : |
129+ if [ -f package-lock.json ]; then
130+ npm ci
131+ else
132+ npm install
133+ fi
134+
135+ - name : Check GitHub Packages version
136+ id : github-package
137+ run : |
138+ PACKAGE_NAME=$(node -p "require('./package.json').name")
139+ PACKAGE_VERSION=$(node -p "require('./package.json').version")
140+
141+ if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version --registry=https://npm.pkg.github.com/ >/dev/null 2>&1; then
142+ echo "${PACKAGE_NAME}@${PACKAGE_VERSION} already exists on GitHub Packages. Skipping publish."
143+ echo "exists=true" >> "${GITHUB_OUTPUT}"
144+ else
145+ echo "${PACKAGE_NAME}@${PACKAGE_VERSION} does not exist on GitHub Packages. Publishing."
146+ echo "exists=false" >> "${GITHUB_OUTPUT}"
147+ fi
148+ env :
149+ NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
150+
151+ - name : Publish to GitHub Packages
152+ if : steps.github-package.outputs.exists != 'true'
153+ run : npm publish
46154 env :
47- NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
155+ NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments