@@ -11,10 +11,50 @@ permissions:
1111
1212jobs :
1313 # ==========================================
14- # Job 1: Publish to NPM
14+ # Job 1: Security Audit (gates all other jobs)
15+ # ==========================================
16+ security-audit :
17+ name : Security Audit
18+ runs-on : ubuntu-latest
19+ permissions :
20+ contents : read
21+
22+ steps :
23+ - name : Checkout code
24+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
25+ with :
26+ fetch-depth : 0
27+
28+ - name : Verify tag is on main
29+ run : |
30+ git fetch origin main
31+ if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
32+ echo "::error::Tagged commit is not on main branch — aborting release"
33+ exit 1
34+ fi
35+
36+ - name : Setup Node.js
37+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
38+ with :
39+ node-version : " 22"
40+
41+ - name : Install pnpm
42+ uses : pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
43+ with :
44+ version : 10.12.2
45+
46+ - name : Install dependencies
47+ run : pnpm install --frozen-lockfile
48+
49+ - name : Security audit
50+ run : pnpm audit --audit-level=critical
51+
52+ # ==========================================
53+ # Job 2: Publish to NPM
1554 # ==========================================
1655 publish :
1756 name : Publish to NPM
57+ needs : security-audit
1858 runs-on : ubuntu-latest
1959 environment : production
2060 permissions :
@@ -23,18 +63,26 @@ jobs:
2363
2464 steps :
2565 - name : Checkout code
26- uses : actions/checkout@v4
66+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
2767 with :
28- ref : main
68+ fetch-depth : 0
69+
70+ - name : Verify tag is on main
71+ run : |
72+ git fetch origin main
73+ if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
74+ echo "::error::Tagged commit is not on main branch — aborting publish"
75+ exit 1
76+ fi
2977
3078 - name : Setup Node.js
31- uses : actions/setup-node@v4
79+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
3280 with :
3381 node-version : " 22"
3482 registry-url : " https://registry.npmjs.org"
3583
3684 - name : Install pnpm
37- uses : pnpm/action-setup@v2
85+ uses : pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
3886 with :
3987 version : 10.12.2
4088
@@ -55,16 +103,16 @@ jobs:
55103 run : pnpm publish --access public --no-git-checks
56104
57105 # ==========================================
58- # Job 2 : Build binaries for all platforms
106+ # Job 3 : Build binaries for all platforms
59107 # ==========================================
60108 build-binaries :
61109 name : Build Binary (${{ matrix.platform }}-${{ matrix.arch }})
110+ needs : security-audit
62111 runs-on : ${{ matrix.os }}
63- # SECURITY: Only grant write permission where needed
64112 permissions :
65113 contents : read
66- attestations : write # SECURITY: For artifact attestation
67- id-token : write # SECURITY: For OIDC signing
114+ attestations : write
115+ id-token : write
68116
69117 strategy :
70118 matrix :
@@ -85,23 +133,33 @@ jobs:
85133
86134 steps :
87135 - name : Checkout code
88- uses : actions/checkout@v4
136+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
137+ with :
138+ fetch-depth : 0
139+
140+ - name : Verify tag is on main
141+ run : |
142+ git fetch origin main
143+ if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
144+ echo "::error::Tagged commit is not on main branch — aborting build"
145+ exit 1
146+ fi
89147
90148 - name : Setup Node.js
91149 if : ${{ !matrix.node_arch }}
92- uses : actions/setup-node@v4
150+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
93151 with :
94152 node-version : " 22"
95153
96154 - name : Setup Node.js (x64 via Rosetta)
97155 if : ${{ matrix.node_arch }}
98- uses : actions/setup-node@v4
156+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
99157 with :
100158 node-version : " 22"
101159 architecture : ${{ matrix.node_arch }}
102160
103161 - name : Install pnpm
104- uses : pnpm/action-setup@v2
162+ uses : pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
105163 with :
106164 version : 10.12.2
107165
@@ -111,7 +169,7 @@ jobs:
111169 echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
112170
113171 - name : Setup pnpm cache
114- uses : actions/cache@v3
172+ uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
115173 with :
116174 path : ${{ env.STORE_PATH }}
117175 key : ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -121,11 +179,6 @@ jobs:
121179 - name : Install dependencies
122180 run : pnpm install --frozen-lockfile
123181
124- # SECURITY: Run audit before building
125- - name : Security audit
126- run : pnpm audit --audit-level=high
127- continue-on-error : true
128-
129182 - name : Build TypeScript
130183 run : pnpm build
131184
@@ -143,7 +196,6 @@ jobs:
143196 shell : bash
144197 run : mv shield.exe shield-windows-${{ matrix.arch }}.exe
145198
146- # SECURITY: Generate SHA256 checksum for integrity verification
147199 - name : Generate checksum (Unix)
148200 if : matrix.platform != 'win32'
149201 run : |
@@ -158,22 +210,21 @@ jobs:
158210 "$($hash.Hash.ToLower()) shield-windows-${{ matrix.arch }}.exe" | Out-File -Encoding utf8 shield-windows-${{ matrix.arch }}.exe.sha256
159211 Get-Content shield-windows-${{ matrix.arch }}.exe.sha256
160212
161- # SECURITY: Generate artifact attestation (proves binary was built by this workflow)
162213 - name : Generate artifact attestation
163- uses : actions/attest-build-provenance@v2
214+ uses : actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be
164215 with :
165216 subject-path : " shield-*"
166217
167218 - name : Upload artifacts
168- uses : actions/upload-artifact@v4
219+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
169220 with :
170221 name : binary-${{ matrix.platform }}-${{ matrix.arch }}
171222 path : |
172223 shield-${{ matrix.platform == 'win32' && 'windows' || matrix.platform }}-${{ matrix.arch }}${{ matrix.platform == 'win32' && '.exe' || '' }}
173224 shield-${{ matrix.platform == 'win32' && 'windows' || matrix.platform }}-${{ matrix.arch }}${{ matrix.platform == 'win32' && '.exe' || '' }}.sha256
174225
175226 # ==========================================
176- # Job 3 : Create GitHub Release with all binaries
227+ # Job 4 : Create GitHub Release with all binaries
177228 # ==========================================
178229 create-release :
179230 name : Create GitHub Release
@@ -184,7 +235,7 @@ jobs:
184235
185236 steps :
186237 - name : Download all artifacts
187- uses : actions/download-artifact@v4
238+ uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
188239 with :
189240 pattern : binary-*
190241 merge-multiple : true
@@ -193,7 +244,7 @@ jobs:
193244 run : ls -la shield-*
194245
195246 - name : Create Release
196- uses : softprops/action-gh-release@v2
247+ uses : softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
197248 with :
198249 files : shield-*
199250 env :
0 commit comments