code-foundry 1.53.1 → 1.53.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -10,6 +10,11 @@ on:
|
|
|
10
10
|
required: false
|
|
11
11
|
type: boolean
|
|
12
12
|
default: false
|
|
13
|
+
recover-npm-tag:
|
|
14
|
+
description: Requalify and publish the exact archive for a current immutable release missing from npm.
|
|
15
|
+
required: false
|
|
16
|
+
type: string
|
|
17
|
+
default: ''
|
|
13
18
|
|
|
14
19
|
permissions:
|
|
15
20
|
contents: read
|
|
@@ -28,7 +33,7 @@ jobs:
|
|
|
28
33
|
# content they merge was already audited on its pull request, and the
|
|
29
34
|
# release merge re-qualifies the exact tree it publishes.
|
|
30
35
|
needs: [release, recovery]
|
|
31
|
-
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
36
|
+
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '') && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
32
37
|
uses: ./.github/workflows/consumer-qualification.yml
|
|
33
38
|
with:
|
|
34
39
|
billing-pause-bypass: ${{ github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true }}
|
|
@@ -38,7 +43,7 @@ jobs:
|
|
|
38
43
|
|
|
39
44
|
preflight:
|
|
40
45
|
name: Verify release prerequisites
|
|
41
|
-
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true))
|
|
46
|
+
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '')
|
|
42
47
|
runs-on: ubuntu-24.04
|
|
43
48
|
timeout-minutes: 5
|
|
44
49
|
steps:
|
|
@@ -76,7 +81,7 @@ jobs:
|
|
|
76
81
|
# it. Version pull requests keep flowing even when the candidate is broken;
|
|
77
82
|
# publication stays gated on qualification success in the stage job.
|
|
78
83
|
needs: [preflight]
|
|
79
|
-
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true))
|
|
84
|
+
if: github.ref == 'refs/heads/main' && (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '')
|
|
80
85
|
uses: ./.github/workflows/release.yml
|
|
81
86
|
with:
|
|
82
87
|
billing-pause-bypass: ${{ github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true }}
|
|
@@ -97,7 +102,7 @@ jobs:
|
|
|
97
102
|
recovery:
|
|
98
103
|
name: Recover qualified draft identity
|
|
99
104
|
needs: [release]
|
|
100
|
-
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && needs.release.result == 'success'
|
|
105
|
+
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '') && needs.release.result == 'success'
|
|
101
106
|
runs-on: ubuntu-24.04
|
|
102
107
|
timeout-minutes: 5
|
|
103
108
|
permissions:
|
|
@@ -170,7 +175,7 @@ jobs:
|
|
|
170
175
|
# Qualification only runs when this push created a release or recovery
|
|
171
176
|
# found a stuck one; staging additionally requires its success so an
|
|
172
177
|
# unqualified tree can never reach publication.
|
|
173
|
-
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && github.ref == 'refs/heads/main' && needs.qualification.result == 'success' && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
178
|
+
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && github.ref == 'refs/heads/main' && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '') && needs.qualification.result == 'success' && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
174
179
|
runs-on: ubuntu-24.04
|
|
175
180
|
timeout-minutes: 15
|
|
176
181
|
permissions:
|
|
@@ -244,7 +249,7 @@ jobs:
|
|
|
244
249
|
publish:
|
|
245
250
|
name: Publish verified package
|
|
246
251
|
needs: [qualification, release, recovery, stage]
|
|
247
|
-
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && github.ref == 'refs/heads/main' && needs.stage.result == 'success' && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
252
|
+
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)) && github.ref == 'refs/heads/main' && !(github.event_name == 'workflow_dispatch' && inputs['recover-npm-tag'] != '') && needs.stage.result == 'success' && (needs.release.outputs.release_created == 'true' || needs.recovery.outputs.found == 'true')
|
|
248
253
|
uses: ./.github/workflows/qualified-foundry-publish.yml
|
|
249
254
|
permissions:
|
|
250
255
|
actions: read
|
|
@@ -255,3 +260,52 @@ jobs:
|
|
|
255
260
|
tag: ${{ needs.release.outputs.tag_name || needs.recovery.outputs.tag }}
|
|
256
261
|
asset: ${{ needs.qualification.outputs.filename }}
|
|
257
262
|
billing-pause-bypass: ${{ github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true }}
|
|
263
|
+
|
|
264
|
+
npm_recovery_target:
|
|
265
|
+
name: Verify npm recovery target
|
|
266
|
+
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs['recover-npm-tag'] != '' && vars.CI_BILLING_PAUSED != 'true'
|
|
267
|
+
runs-on: ubuntu-24.04
|
|
268
|
+
timeout-minutes: 5
|
|
269
|
+
permissions:
|
|
270
|
+
contents: read
|
|
271
|
+
outputs:
|
|
272
|
+
tag: ${{ steps.target.outputs.tag }}
|
|
273
|
+
asset: ${{ steps.target.outputs.asset }}
|
|
274
|
+
source-sha: ${{ steps.target.outputs.source-sha }}
|
|
275
|
+
steps:
|
|
276
|
+
- name: Checkout trusted recovery verifier
|
|
277
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
278
|
+
with:
|
|
279
|
+
persist-credentials: false
|
|
280
|
+
fetch-depth: 0
|
|
281
|
+
ref: ${{ github.sha }}
|
|
282
|
+
- name: Setup Node
|
|
283
|
+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
284
|
+
with:
|
|
285
|
+
node-version: '24'
|
|
286
|
+
- name: Require exact immutable release and absent npm version
|
|
287
|
+
id: target
|
|
288
|
+
env:
|
|
289
|
+
GH_TOKEN: ${{ github.token }}
|
|
290
|
+
RELEASE_TAG: ${{ inputs['recover-npm-tag'] }}
|
|
291
|
+
CURRENT_SHA: ${{ github.sha }}
|
|
292
|
+
run: |
|
|
293
|
+
set -euo pipefail
|
|
294
|
+
node src/commands/release-recovery.mjs verify-target \
|
|
295
|
+
"$GITHUB_REPOSITORY" "$RELEASE_TAG" "$CURRENT_SHA" "$GITHUB_OUTPUT"
|
|
296
|
+
|
|
297
|
+
npm_recovery_publish:
|
|
298
|
+
name: Requalify and publish recovered archive
|
|
299
|
+
needs: npm_recovery_target
|
|
300
|
+
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && needs.npm_recovery_target.result == 'success' && vars.CI_BILLING_PAUSED != 'true'
|
|
301
|
+
uses: ./.github/workflows/qualified-foundry-publish.yml
|
|
302
|
+
permissions:
|
|
303
|
+
actions: read
|
|
304
|
+
attestations: read
|
|
305
|
+
contents: read
|
|
306
|
+
id-token: write
|
|
307
|
+
with:
|
|
308
|
+
tag: ${{ needs.npm_recovery_target.outputs.tag }}
|
|
309
|
+
asset: ${{ needs.npm_recovery_target.outputs.asset }}
|
|
310
|
+
source-sha: ${{ needs.npm_recovery_target.outputs['source-sha'] }}
|
|
311
|
+
billing-pause-bypass: false
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.53.2](https://github.com/0xPlayerOne/code-foundry/compare/v1.53.1...v1.53.2) (2026-10-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* support reviewed Playwright 1.64.1 UI receipts ([#817](https://github.com/0xPlayerOne/code-foundry/issues/817)) ([814bf68](https://github.com/0xPlayerOne/code-foundry/commit/814bf68818dcf2a80253e133895cbe3e539b5b7f))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Maintenance
|
|
12
|
+
|
|
13
|
+
* add verified npm publication recovery ([#815](https://github.com/0xPlayerOne/code-foundry/issues/815)) ([5876361](https://github.com/0xPlayerOne/code-foundry/commit/58763616b3dc38d127680914eeef6151b3375b37))
|
|
14
|
+
|
|
3
15
|
## [1.53.1](https://github.com/0xPlayerOne/code-foundry/compare/v1.53.0...v1.53.1) (2026-10-30)
|
|
4
16
|
|
|
5
17
|
|
|
@@ -138,16 +150,9 @@
|
|
|
138
150
|
|
|
139
151
|
* **release:** audit generated release content for stale snapshots ([#775](https://github.com/0xPlayerOne/code-foundry/issues/775)) ([f842c27](https://github.com/0xPlayerOne/code-foundry/commit/f842c271e6b270b63a6d9b839795a849237c7a7d))
|
|
140
152
|
|
|
141
|
-
## [1.48.5](https://github.com/0xPlayerOne/code-foundry/compare/v1.48.4...v1.48.5) (2026-10-22)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
### Bug Fixes
|
|
145
|
-
|
|
146
|
-
* **ci:** serialize billing receipt and report uploads ([#773](https://github.com/0xPlayerOne/code-foundry/issues/773)) ([6497225](https://github.com/0xPlayerOne/code-foundry/commit/6497225bf2d672380b6b5231378b424dffb8afbb))
|
|
147
|
-
|
|
148
153
|
<!-- code-foundry: packaged changelog -->
|
|
149
154
|
|
|
150
155
|
---
|
|
151
156
|
|
|
152
|
-
This packaged changelog lists the 20 most recent releases;
|
|
157
|
+
This packaged changelog lists the 20 most recent releases; 273 older releases are omitted to keep the package small.
|
|
153
158
|
See the [full changelog](https://github.com/0xPlayerOne/code-foundry/blob/main/CHANGELOG.md) for the complete history.
|
|
@@ -35,13 +35,11 @@ actual caller workflow filename, `release_self-ci.yml`, in repository
|
|
|
35
35
|
environment. Both the caller and reusable publisher grant `id-token: write`.
|
|
36
36
|
For generated consumer workflows, the caller filename is `release.yml` and the
|
|
37
37
|
auth mode remains configurable with `npm_publish_auth`.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
To recover a GitHub release missing from npm, the self-only dispatch requires the
|
|
39
|
+
current stable tag, immutable release, exact archive, npm 404, fresh Node 24/26
|
|
40
|
+
qualification, and OIDC publication. Existing npm versions are never overwritten.
|
|
41
41
|
|
|
42
|
-
The publisher never rebuilds
|
|
43
|
-
already-published version conflict as proof of success. It never accepts or
|
|
44
|
-
forwards `NPM_TOKEN`.
|
|
42
|
+
The publisher never rebuilds a package or accepts `NPM_TOKEN`.
|
|
45
43
|
|
|
46
44
|
Qualification and publication are gated on `main` push or an explicitly
|
|
47
45
|
requested `workflow_dispatch`. The shared billing pause blocks normal runs. A
|
|
@@ -123,6 +121,11 @@ state still match the qualified candidate. An already-published release is never
|
|
|
123
121
|
restaged or overwritten. Inspect the retained staging and publication identity
|
|
124
122
|
receipts when recovery is needed.
|
|
125
123
|
|
|
124
|
+
To recover a published GitHub release that is missing from npm, dispatch the
|
|
125
|
+
self-only `release_self-ci.yml` workflow on `main` with `recover-npm-tag`. It
|
|
126
|
+
requires the current stable tag, immutable release, exact archive, and exact npm
|
|
127
|
+
404, then requalifies that archive on Node 24/26 before OIDC publication.
|
|
128
|
+
|
|
126
129
|
## Publication prerequisites
|
|
127
130
|
|
|
128
131
|
Enable immutable releases and verify the setting with the actual
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-foundry",
|
|
3
|
-
"version": "1.53.
|
|
3
|
+
"version": "1.53.2",
|
|
4
4
|
"description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
|
|
5
5
|
"homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"src",
|
|
19
19
|
"!src/commands/qualification-receipt.mjs",
|
|
20
|
+
"!src/commands/release-recovery.mjs",
|
|
20
21
|
"!src/lib/qualification-receipt.mjs",
|
|
21
22
|
"!src/lib/release-package-contract.mjs",
|
|
22
23
|
"docs",
|
|
23
24
|
".github",
|
|
24
25
|
"!.github/actions/**",
|
|
26
|
+
"!.github/workflows/qualified-foundry-publish.yml",
|
|
25
27
|
".githooks",
|
|
26
28
|
".editorconfig",
|
|
27
29
|
".gitattributes",
|
package/src/commands/sync.mjs
CHANGED
|
@@ -1247,19 +1247,28 @@ function renderWorkflow(content, config, repository, ref, rustCodeql, file, self
|
|
|
1247
1247
|
// recovery, staging, and qualified publication. Consumer callers must
|
|
1248
1248
|
// retain the ordinary reusable Release Please path instead of inheriting
|
|
1249
1249
|
// self-only jobs whose outputs and environments do not exist for them.
|
|
1250
|
-
for (const job of [
|
|
1250
|
+
for (const job of [
|
|
1251
|
+
'qualification',
|
|
1252
|
+
'preflight',
|
|
1253
|
+
'recovery',
|
|
1254
|
+
'stage',
|
|
1255
|
+
'publish',
|
|
1256
|
+
'npm_recovery_target',
|
|
1257
|
+
'npm_recovery_publish',
|
|
1258
|
+
])
|
|
1251
1259
|
rendered = removeWorkflowBlock(rendered, job)
|
|
1260
|
+
rendered = removeWorkflowBlock(rendered, 'recover-npm-tag', ' ')
|
|
1252
1261
|
rendered = rendered.replace(/^ needs: \[preflight\]\n/m, '')
|
|
1253
1262
|
rendered = rendered.replace(/^ config-file: \.github\/release-please-foundry\.json\n/m, '')
|
|
1254
1263
|
if (config.release_defer_publication !== 'true') {
|
|
1255
1264
|
rendered = rendered.replace(/^ defer-publication: true\n/m, '')
|
|
1256
1265
|
}
|
|
1257
1266
|
rendered = rendered.replace(
|
|
1258
|
-
/^ if: github\.ref == 'refs\/heads\/main' && \(vars\.CI_BILLING_PAUSED != 'true' \|\| \(github\.event_name == 'workflow_dispatch' && inputs\['release-while-paused'\] == true\)\)\n/m,
|
|
1267
|
+
/^ if: github\.ref == 'refs\/heads\/main' && \(vars\.CI_BILLING_PAUSED != 'true' \|\| \(github\.event_name == 'workflow_dispatch' && inputs\['release-while-paused'\] == true\)\) && !\(github\.event_name == 'workflow_dispatch' && inputs\['recover-npm-tag'\] != ''\)\n/m,
|
|
1259
1268
|
" if: vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)\n"
|
|
1260
1269
|
)
|
|
1261
1270
|
rendered = rendered.replace(
|
|
1262
|
-
/^ if: github\.ref == 'refs\/heads\/main' && \(vars\.CI_BILLING_PAUSED != 'true' \|\| \(github\.event_name == 'workflow_dispatch' && inputs\['release-while-paused'\] == true\)\)\n/m,
|
|
1271
|
+
/^ if: github\.ref == 'refs\/heads\/main' && \(vars\.CI_BILLING_PAUSED != 'true' \|\| \(github\.event_name == 'workflow_dispatch' && inputs\['release-while-paused'\] == true\)\) && !\(github\.event_name == 'workflow_dispatch' && inputs\['recover-npm-tag'\] != ''\)\n/m,
|
|
1263
1272
|
" if: vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['release-while-paused'] == true)\n"
|
|
1264
1273
|
)
|
|
1265
1274
|
// Gate ordinary pushes while allowing the release squash and manual hotfixes.
|
|
@@ -1386,19 +1395,25 @@ function renderWorkflow(content, config, repository, ref, rustCodeql, file, self
|
|
|
1386
1395
|
}
|
|
1387
1396
|
|
|
1388
1397
|
/**
|
|
1389
|
-
* Remove
|
|
1390
|
-
* This is used for workflow jobs and triggers whose feature is
|
|
1391
|
-
* configuration.
|
|
1398
|
+
* Remove an indented YAML mapping block by id while preserving the surrounding
|
|
1399
|
+
* file. This is used for workflow jobs, inputs, and triggers whose feature is
|
|
1400
|
+
* disabled by configuration.
|
|
1392
1401
|
* @param {string} content
|
|
1393
1402
|
* @param {string} blockId
|
|
1403
|
+
* @param {string} [indentation]
|
|
1394
1404
|
* @returns {string}
|
|
1395
1405
|
*/
|
|
1396
|
-
function removeWorkflowBlock(content, blockId) {
|
|
1406
|
+
function removeWorkflowBlock(content, blockId, indentation = ' ') {
|
|
1397
1407
|
const lines = content.split('\n')
|
|
1398
|
-
const start = lines.findIndex((line) => line ===
|
|
1408
|
+
const start = lines.findIndex((line) => line === `${indentation}${blockId}:`)
|
|
1399
1409
|
if (start === -1) return content
|
|
1400
1410
|
let end = start + 1
|
|
1401
|
-
while (end < lines.length
|
|
1411
|
+
while (end < lines.length) {
|
|
1412
|
+
const line = lines[end]
|
|
1413
|
+
const level = line.match(/^ */)?.[0].length ?? 0
|
|
1414
|
+
if (line.trim() && level <= indentation.length) break
|
|
1415
|
+
end += 1
|
|
1416
|
+
}
|
|
1402
1417
|
lines.splice(start, end - start)
|
|
1403
1418
|
if (content.endsWith('\n') && lines.at(-1) !== '') lines.push('')
|
|
1404
1419
|
return lines.join('\n')
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
name: Qualified Foundry Publication
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_call:
|
|
5
|
-
inputs:
|
|
6
|
-
tag:
|
|
7
|
-
description: Published immutable release tag at the caller commit.
|
|
8
|
-
required: true
|
|
9
|
-
type: string
|
|
10
|
-
asset:
|
|
11
|
-
description: Exact pre-attached Code Foundry npm tarball name.
|
|
12
|
-
required: true
|
|
13
|
-
type: string
|
|
14
|
-
billing-pause-bypass:
|
|
15
|
-
description: Allow only an explicitly dispatched release while shared CI remains paused.
|
|
16
|
-
required: false
|
|
17
|
-
type: boolean
|
|
18
|
-
default: false
|
|
19
|
-
|
|
20
|
-
permissions:
|
|
21
|
-
attestations: read
|
|
22
|
-
contents: read
|
|
23
|
-
|
|
24
|
-
jobs:
|
|
25
|
-
qualify:
|
|
26
|
-
name: Qualify Node ${{ matrix.node }}
|
|
27
|
-
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['billing-pause-bypass'] == true)) && github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
|
28
|
-
runs-on: ubuntu-24.04
|
|
29
|
-
timeout-minutes: 15
|
|
30
|
-
strategy:
|
|
31
|
-
fail-fast: false
|
|
32
|
-
matrix:
|
|
33
|
-
node: ['24', '26']
|
|
34
|
-
steps:
|
|
35
|
-
- name: Checkout trusted qualification runtime
|
|
36
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
37
|
-
with:
|
|
38
|
-
persist-credentials: false
|
|
39
|
-
ref: ${{ github.sha }}
|
|
40
|
-
- name: Setup Node
|
|
41
|
-
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
42
|
-
with:
|
|
43
|
-
node-version: ${{ matrix.node }}
|
|
44
|
-
- name: Install pinned Actionlint
|
|
45
|
-
run: go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.12
|
|
46
|
-
- name: Download and cryptographically verify the release archive
|
|
47
|
-
env:
|
|
48
|
-
GH_TOKEN: ${{ github.token }}
|
|
49
|
-
RELEASE_TAG: ${{ inputs.tag }}
|
|
50
|
-
RELEASE_ASSET: ${{ inputs.asset }}
|
|
51
|
-
run: |
|
|
52
|
-
set -euo pipefail
|
|
53
|
-
node src/commands/qualified-publication.mjs download \
|
|
54
|
-
"$GITHUB_REPOSITORY" "$RELEASE_TAG" "$GITHUB_SHA" "$RELEASE_ASSET" \
|
|
55
|
-
"$RUNNER_TEMP/candidate" > "$RUNNER_TEMP/download.json"
|
|
56
|
-
- name: Qualify those exact bytes
|
|
57
|
-
env:
|
|
58
|
-
RELEASE_ASSET: ${{ inputs.asset }}
|
|
59
|
-
run: |
|
|
60
|
-
set -euo pipefail
|
|
61
|
-
node src/lib/consumer-qualification.mjs \
|
|
62
|
-
"$RUNNER_TEMP/candidate/$RELEASE_ASSET" "$GITHUB_SHA" \
|
|
63
|
-
"$RUNNER_TEMP/report.json" "$(go env GOPATH)/bin/actionlint"
|
|
64
|
-
- name: Retain this attempt's qualification report
|
|
65
|
-
if: always()
|
|
66
|
-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
67
|
-
with:
|
|
68
|
-
name: qualified-${{ github.run_attempt }}-node-${{ matrix.node }}
|
|
69
|
-
path: ${{ runner.temp }}/report.json
|
|
70
|
-
if-no-files-found: error
|
|
71
|
-
retention-days: 14
|
|
72
|
-
|
|
73
|
-
publish:
|
|
74
|
-
name: Publish qualified archive
|
|
75
|
-
needs: qualify
|
|
76
|
-
if: (vars.CI_BILLING_PAUSED != 'true' || (github.event_name == 'workflow_dispatch' && inputs['billing-pause-bypass'] == true)) && github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
|
77
|
-
runs-on: ubuntu-24.04
|
|
78
|
-
timeout-minutes: 15
|
|
79
|
-
concurrency:
|
|
80
|
-
group: qualified-foundry-npm-${{ github.repository }}-${{ inputs.tag }}
|
|
81
|
-
cancel-in-progress: false
|
|
82
|
-
permissions:
|
|
83
|
-
actions: read
|
|
84
|
-
attestations: read
|
|
85
|
-
contents: read
|
|
86
|
-
id-token: write
|
|
87
|
-
env:
|
|
88
|
-
RELEASE_TAG: ${{ inputs.tag }}
|
|
89
|
-
RELEASE_ASSET: ${{ inputs.asset }}
|
|
90
|
-
steps:
|
|
91
|
-
- name: Checkout trusted publication runtime
|
|
92
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
93
|
-
with:
|
|
94
|
-
persist-credentials: false
|
|
95
|
-
ref: ${{ github.sha }}
|
|
96
|
-
- name: Setup Node for trusted publishing
|
|
97
|
-
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
98
|
-
with:
|
|
99
|
-
node-version: '24'
|
|
100
|
-
- name: Retrieve only this run attempt's evidence
|
|
101
|
-
env:
|
|
102
|
-
GH_TOKEN: ${{ github.token }}
|
|
103
|
-
run: |
|
|
104
|
-
set -euo pipefail
|
|
105
|
-
for node in 24 26; do
|
|
106
|
-
gh run download "$GITHUB_RUN_ID" --repo "$GITHUB_REPOSITORY" \
|
|
107
|
-
--name "qualified-$GITHUB_RUN_ATTEMPT-node-$node" \
|
|
108
|
-
--dir "$RUNNER_TEMP/reports/$node"
|
|
109
|
-
done
|
|
110
|
-
node src/commands/qualified-publication.mjs download \
|
|
111
|
-
"$GITHUB_REPOSITORY" "$RELEASE_TAG" "$GITHUB_SHA" "$RELEASE_ASSET" \
|
|
112
|
-
"$RUNNER_TEMP/candidate" > "$RUNNER_TEMP/download.json"
|
|
113
|
-
- name: Reverify and publish the tested tarball without lifecycle hooks
|
|
114
|
-
env:
|
|
115
|
-
GH_TOKEN: ${{ github.token }}
|
|
116
|
-
run: |
|
|
117
|
-
set -euo pipefail
|
|
118
|
-
node src/commands/qualified-publication.mjs publish \
|
|
119
|
-
"$GITHUB_REPOSITORY" "$RELEASE_TAG" "$GITHUB_SHA" "$RELEASE_ASSET" \
|
|
120
|
-
"$RUNNER_TEMP/candidate" \
|
|
121
|
-
"$RUNNER_TEMP/reports/24/report.json" \
|
|
122
|
-
"$RUNNER_TEMP/reports/26/report.json" > "$RUNNER_TEMP/publication.json"
|
|
123
|
-
- name: Retain publication identity
|
|
124
|
-
if: always()
|
|
125
|
-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
126
|
-
with:
|
|
127
|
-
name: qualified-publication-${{ github.run_attempt }}
|
|
128
|
-
path: ${{ runner.temp }}/publication.json
|
|
129
|
-
if-no-files-found: warn
|
|
130
|
-
retention-days: 14
|