code-foundry 1.48.7 → 1.50.0
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.
- package/.github/CONTRIBUTING.md +8 -8
- package/.github/code-foundry.schema.json +10 -0
- package/.github/code-foundry.yml +2 -0
- package/.github/workflows/ci.yml +41 -5
- package/.github/workflows/draft-enforcement_self-ci.yml +12 -8
- package/.github/workflows/qualification-receipt.yml +201 -0
- package/.github/workflows/qualified-foundry-publish.yml +0 -12
- package/.github/workflows/release.yml +155 -107
- package/.github/workflows/release_self-ci.yml +0 -2
- package/.github/workflows/security.yml +3 -1
- package/.github/workflows/test.yml +90 -1
- package/.github/workflows/validation-billing.yml +160 -24
- package/.github/workflows/validation-no-codeql.yml +92 -16
- package/.github/workflows/validation.yml +97 -16
- package/.github/workflows/validation_self-ci.yml +7 -4
- package/CHANGELOG.md +50 -50
- package/docs/CONFIGURATION.md +11 -0
- package/docs/PUBLISHING.md +13 -5
- package/docs/WORKFLOWS.md +25 -12
- package/docs/qualified-publication.md +22 -14
- package/package.json +4 -1
- package/src/commands/qualified-publication.mjs +27 -0
- package/src/commands/sync.mjs +50 -4
- package/src/lib/github-doctor.mjs +23 -2
- package/src/lib/node-package-performance.mjs +57 -2
- package/src/lib/product-quality.mjs +11 -11
- package/src/lib/validation-policy.mjs +11 -11
- package/src/runtime-core.mjs +24 -0
package/.github/CONTRIBUTING.md
CHANGED
|
@@ -220,14 +220,14 @@ Keep pull requests focused and reviewable. Include screenshots or recordings for
|
|
|
220
220
|
|
|
221
221
|
## Workflow and check behavior
|
|
222
222
|
|
|
223
|
-
| Event
|
|
224
|
-
|
|
|
225
|
-
| Draft pull request targeting `main`
|
|
226
|
-
| Ready pull request targeting `main`
|
|
227
|
-
| Exact Release Please
|
|
228
|
-
| Scheduled or manual validation
|
|
229
|
-
| Push to a working branch
|
|
230
|
-
| Push to `main`
|
|
223
|
+
| Event | Expected automation |
|
|
224
|
+
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
225
|
+
| Draft pull request targeting `main` | No runner-heavy validation; run local checks before requesting review |
|
|
226
|
+
| Ready pull request targeting `main` | Audit validation: CI, full tests, Security, and CodeQL, ending in `Validation / Gate` |
|
|
227
|
+
| Exact Release Please PR targeting `main` | Release diff, configured CodeQL, build/package check, and either a verified receipt or full CI/tests |
|
|
228
|
+
| Scheduled or manual validation | Full audit tier |
|
|
229
|
+
| Push to a working branch | Draft PR workflow |
|
|
230
|
+
| Push to `main` | Release workflow; CodeQL skips release-only merges (audit covers drift) |
|
|
231
231
|
|
|
232
232
|
Draft pull requests do not start validation unless `draft_protection: false` is configured. The lightweight Draft Guard converts ordinary pull requests opened or reopened while ready back to draft; it never checks out pull-request code and it excludes Release Please version heads, whose release workflow owns their state. Marking a pull request ready for review starts the applicable validation tier, and each new commit on a ready pull request reruns that tier for the current head. Draft updates allocate no validation runner while protection is enabled. Converting a pull request to draft runs only the lightweight cancellation control.
|
|
233
233
|
|
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
"description": "Explicit JavaScript formatter. Omit to preserve repository scripts and the Oxfmt fallback.",
|
|
8
8
|
"type": "string",
|
|
9
9
|
"enum": ["oxfmt", "prettier", "bun"]
|
|
10
|
+
},
|
|
11
|
+
"release_qualification_receipts": {
|
|
12
|
+
"description": "Opt in to seven-day exact-tree qualification receipts for Release Please validation.",
|
|
13
|
+
"type": "string",
|
|
14
|
+
"enum": ["true", "false"]
|
|
15
|
+
},
|
|
16
|
+
"npm_publish_auth": {
|
|
17
|
+
"description": "npm publisher authentication: auto preserves token users and uses OIDC when no publish token is present; oidc forces trusted publishing; token requires NPM_TOKEN.",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["auto", "oidc", "token"]
|
|
10
20
|
}
|
|
11
21
|
},
|
|
12
22
|
"additionalProperties": true
|
package/.github/code-foundry.yml
CHANGED
|
@@ -5,6 +5,7 @@ languages: typescript
|
|
|
5
5
|
features: all
|
|
6
6
|
draft_protection: true
|
|
7
7
|
codeql: auto
|
|
8
|
+
release_qualification_receipts: false
|
|
8
9
|
codeql_rust_shards: '["all"]'
|
|
9
10
|
codeql_rust_threads: 1
|
|
10
11
|
codeql_rust_max_parallel: 1
|
|
@@ -15,6 +16,7 @@ runtime_repository: 0xPlayerOne/code-foundry
|
|
|
15
16
|
runtime_ref: v1.30.0
|
|
16
17
|
release_type: node
|
|
17
18
|
npm_publish: true
|
|
19
|
+
npm_publish_auth: oidc
|
|
18
20
|
license: agpl-3.0-or-later
|
|
19
21
|
git_workflow: direct
|
|
20
22
|
merge_strategy: squash
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -23,6 +23,16 @@ on:
|
|
|
23
23
|
required: false
|
|
24
24
|
type: string
|
|
25
25
|
default: task-result
|
|
26
|
+
release-build-only:
|
|
27
|
+
description: Run only the build lane after an exact successful source qualification receipt.
|
|
28
|
+
required: false
|
|
29
|
+
type: boolean
|
|
30
|
+
default: false
|
|
31
|
+
release-package-check:
|
|
32
|
+
description: Inspect the versioned npm package contents on release pull requests.
|
|
33
|
+
required: false
|
|
34
|
+
type: boolean
|
|
35
|
+
default: false
|
|
26
36
|
secrets:
|
|
27
37
|
TURBO_TOKEN:
|
|
28
38
|
required: false
|
|
@@ -55,7 +65,7 @@ concurrency:
|
|
|
55
65
|
jobs:
|
|
56
66
|
format:
|
|
57
67
|
name: Format
|
|
58
|
-
if: vars.CI_BILLING_PAUSED != 'true'
|
|
68
|
+
if: vars.CI_BILLING_PAUSED != 'true' && inputs.release-build-only != true
|
|
59
69
|
runs-on: ${{ inputs.runner }}
|
|
60
70
|
timeout-minutes: 30
|
|
61
71
|
steps:
|
|
@@ -124,7 +134,7 @@ jobs:
|
|
|
124
134
|
|
|
125
135
|
lint:
|
|
126
136
|
name: Lint
|
|
127
|
-
if: vars.CI_BILLING_PAUSED != 'true'
|
|
137
|
+
if: vars.CI_BILLING_PAUSED != 'true' && inputs.release-build-only != true
|
|
128
138
|
runs-on: ${{ inputs.runner }}
|
|
129
139
|
timeout-minutes: 30
|
|
130
140
|
steps:
|
|
@@ -188,7 +198,7 @@ jobs:
|
|
|
188
198
|
|
|
189
199
|
type-check:
|
|
190
200
|
name: Type-Check
|
|
191
|
-
if: vars.CI_BILLING_PAUSED != 'true'
|
|
201
|
+
if: vars.CI_BILLING_PAUSED != 'true' && inputs.release-build-only != true
|
|
192
202
|
permissions:
|
|
193
203
|
contents: read
|
|
194
204
|
issues: read
|
|
@@ -279,6 +289,7 @@ jobs:
|
|
|
279
289
|
path: .github/.code-foundry
|
|
280
290
|
sparse-checkout: |
|
|
281
291
|
.github/actions
|
|
292
|
+
src/commands/qualification-receipt.mjs
|
|
282
293
|
src/lib
|
|
283
294
|
src/runtime-core.mjs
|
|
284
295
|
src/runtime.mjs
|
|
@@ -287,6 +298,11 @@ jobs:
|
|
|
287
298
|
mkdir -p .github/actions
|
|
288
299
|
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
289
300
|
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
301
|
+
- name: Set up Node.js 24.18.0 for package inspection
|
|
302
|
+
if: inputs.release-package-check == true
|
|
303
|
+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
304
|
+
with:
|
|
305
|
+
node-version: 24.18.0
|
|
290
306
|
- name: Detect
|
|
291
307
|
id: applicability
|
|
292
308
|
env:
|
|
@@ -296,8 +312,13 @@ jobs:
|
|
|
296
312
|
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
297
313
|
BEFORE_SHA: ${{ github.event.before }}
|
|
298
314
|
run: node "$RUNNER_TEMP/code-foundry/src/runtime.mjs" ci should_run build >> "$GITHUB_OUTPUT"
|
|
315
|
+
- name: Verify versioned package build contract
|
|
316
|
+
if: inputs.release-package-check == true
|
|
317
|
+
env:
|
|
318
|
+
FOUNDRY_BUILD_TASK_APPLICABLE: ${{ steps.applicability.outputs.applicable }}
|
|
319
|
+
run: node "$RUNNER_TEMP/code-foundry/src/commands/qualification-receipt.mjs" package-contract
|
|
299
320
|
- name: Setup
|
|
300
|
-
if: steps.applicability.outputs.applicable == 'true' && steps.applicability.outputs.affected != 'false'
|
|
321
|
+
if: steps.applicability.outputs.applicable == 'true' && (inputs.release-build-only == true || steps.applicability.outputs.affected != 'false')
|
|
301
322
|
uses: ./.github/actions/setup
|
|
302
323
|
with:
|
|
303
324
|
install: 'true'
|
|
@@ -305,8 +326,23 @@ jobs:
|
|
|
305
326
|
task: build
|
|
306
327
|
- name: Build
|
|
307
328
|
id: execute
|
|
308
|
-
if: steps.applicability.outputs.applicable == 'true' && steps.applicability.outputs.affected != 'false'
|
|
329
|
+
if: steps.applicability.outputs.applicable == 'true' && (inputs.release-build-only == true || steps.applicability.outputs.affected != 'false')
|
|
309
330
|
run: node "$RUNNER_TEMP/code-foundry/src/runtime.mjs" ci build
|
|
331
|
+
- name: Inspect versioned npm package contents
|
|
332
|
+
if: inputs.release-package-check == true && hashFiles('package.json') != ''
|
|
333
|
+
run: |
|
|
334
|
+
npm pack --dry-run --ignore-scripts --json > "$RUNNER_TEMP/foundry-package-inspection.json"
|
|
335
|
+
node --input-type=module -e '
|
|
336
|
+
import { readFileSync } from "node:fs";
|
|
337
|
+
import { join } from "node:path";
|
|
338
|
+
import { pathToFileURL } from "node:url";
|
|
339
|
+
|
|
340
|
+
const runtime = join(process.env.RUNNER_TEMP, "code-foundry", "src/lib/node-package-performance.mjs");
|
|
341
|
+
const { verifyNpmPackPackage } = await import(pathToFileURL(runtime).href);
|
|
342
|
+
const manifest = JSON.parse(readFileSync("package.json", "utf8"));
|
|
343
|
+
const report = JSON.parse(readFileSync(process.argv[1], "utf8"));
|
|
344
|
+
verifyNpmPackPackage(report, manifest);
|
|
345
|
+
' "$RUNNER_TEMP/foundry-package-inspection.json"
|
|
310
346
|
- name: Retain task receipt
|
|
311
347
|
if: >-
|
|
312
348
|
always() &&
|
|
@@ -36,11 +36,11 @@ jobs:
|
|
|
36
36
|
exit 1
|
|
37
37
|
fi
|
|
38
38
|
|
|
39
|
-
read -r draft head_ref head_sha updated_at < <(
|
|
39
|
+
read -r draft head_ref head_sha updated_at node_id < <(
|
|
40
40
|
gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \
|
|
41
|
-
--jq '[.draft, .head.ref, .head.sha, .updated_at] | @tsv'
|
|
41
|
+
--jq '[.draft, .head.ref, .head.sha, .updated_at, .node_id] | @tsv'
|
|
42
42
|
)
|
|
43
|
-
if [ -z "$draft" ] || [ -z "$head_ref" ] || [ -z "$head_sha" ] || [ -z "$updated_at" ]; then
|
|
43
|
+
if [ -z "$draft" ] || [ -z "$head_ref" ] || [ -z "$head_sha" ] || [ -z "$updated_at" ] || [ -z "$node_id" ]; then
|
|
44
44
|
echo '::error title=Draft guard cannot verify current state::The GitHub API response did not include the required pull-request metadata.'
|
|
45
45
|
exit 1
|
|
46
46
|
fi
|
|
@@ -70,9 +70,13 @@ jobs:
|
|
|
70
70
|
exit 1
|
|
71
71
|
fi
|
|
72
72
|
|
|
73
|
-
gh api \
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
result=$(gh api graphql \
|
|
74
|
+
-f query='mutation($pullRequestId: ID!) { convertPullRequestToDraft(input: {pullRequestId: $pullRequestId}) { pullRequest { id isDraft } } }' \
|
|
75
|
+
-f pullRequestId="$node_id" \
|
|
76
|
+
--jq '.data.convertPullRequestToDraft.pullRequest | [.id, .isDraft] | @tsv')
|
|
77
|
+
read -r returned_id is_draft <<< "$result"
|
|
78
|
+
if [ "$returned_id" != "$node_id" ] || [ "$is_draft" != true ]; then
|
|
79
|
+
echo '::error title=Draft guard conversion failed::GraphQL did not confirm the expected pull request is a draft.'
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
78
82
|
echo "Converted ordinary pull request #$PR_NUMBER to draft; validation waits for ready_for_review."
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
name: Code Foundry Qualification Receipt
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
phase:
|
|
7
|
+
description: Produce evidence after a full audit or verify it for a release PR.
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
mode:
|
|
11
|
+
description: Validation tier associated with this receipt operation.
|
|
12
|
+
required: true
|
|
13
|
+
type: string
|
|
14
|
+
enabled:
|
|
15
|
+
description: Consumer opt-in for qualification receipt reuse.
|
|
16
|
+
required: false
|
|
17
|
+
type: boolean
|
|
18
|
+
default: false
|
|
19
|
+
codeql-enabled:
|
|
20
|
+
description: Whether the consumer requires CodeQL in its audit and release lanes.
|
|
21
|
+
required: false
|
|
22
|
+
type: boolean
|
|
23
|
+
default: true
|
|
24
|
+
runtime-repository:
|
|
25
|
+
description: Repository containing the Code Foundry runtime.
|
|
26
|
+
required: true
|
|
27
|
+
type: string
|
|
28
|
+
runtime-ref:
|
|
29
|
+
description: Runtime commit, tag, or ref used by source validation.
|
|
30
|
+
required: true
|
|
31
|
+
type: string
|
|
32
|
+
job-results-json:
|
|
33
|
+
description: Normalized component results for the successful full audit.
|
|
34
|
+
required: false
|
|
35
|
+
type: string
|
|
36
|
+
default: '{}'
|
|
37
|
+
required-job-names-json:
|
|
38
|
+
description: Exact aggregate gate job names to verify from the source run's complete attempt-job listing.
|
|
39
|
+
required: false
|
|
40
|
+
type: string
|
|
41
|
+
default: '[]'
|
|
42
|
+
outputs:
|
|
43
|
+
reuse:
|
|
44
|
+
description: True only when a matching recent source receipt was verified.
|
|
45
|
+
value: ${{ jobs.verify.outputs.reuse }}
|
|
46
|
+
|
|
47
|
+
permissions:
|
|
48
|
+
actions: read
|
|
49
|
+
contents: read
|
|
50
|
+
pull-requests: read
|
|
51
|
+
|
|
52
|
+
jobs:
|
|
53
|
+
verify:
|
|
54
|
+
name: Verify source receipt
|
|
55
|
+
if: >-
|
|
56
|
+
vars.CI_BILLING_PAUSED != 'true' && inputs.enabled == true &&
|
|
57
|
+
inputs.phase == 'verify' && inputs.mode == 'release'
|
|
58
|
+
runs-on: ubuntu-slim
|
|
59
|
+
timeout-minutes: 15
|
|
60
|
+
outputs:
|
|
61
|
+
reuse: ${{ steps.verify.outputs.reuse }}
|
|
62
|
+
steps:
|
|
63
|
+
- name: Checkout release PR source
|
|
64
|
+
id: source
|
|
65
|
+
continue-on-error: true
|
|
66
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
67
|
+
with:
|
|
68
|
+
persist-credentials: false
|
|
69
|
+
fetch-depth: 0
|
|
70
|
+
- name: Checkout runtime
|
|
71
|
+
id: runtime
|
|
72
|
+
if: steps.source.outcome == 'success'
|
|
73
|
+
continue-on-error: true
|
|
74
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
75
|
+
with:
|
|
76
|
+
persist-credentials: false
|
|
77
|
+
repository: ${{ inputs.runtime-repository }}
|
|
78
|
+
ref: ${{ inputs.runtime-ref }}
|
|
79
|
+
path: .github/.code-foundry
|
|
80
|
+
sparse-checkout: |
|
|
81
|
+
src/commands/qualification-receipt.mjs
|
|
82
|
+
src/lib
|
|
83
|
+
src/runtime-core.mjs
|
|
84
|
+
src/runtime.mjs
|
|
85
|
+
- name: Install runtime
|
|
86
|
+
id: install
|
|
87
|
+
if: steps.runtime.outcome == 'success'
|
|
88
|
+
continue-on-error: true
|
|
89
|
+
run: mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
90
|
+
- name: Set up Node.js 24.18.0
|
|
91
|
+
id: node
|
|
92
|
+
if: steps.install.outcome == 'success'
|
|
93
|
+
continue-on-error: true
|
|
94
|
+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
95
|
+
with:
|
|
96
|
+
node-version: 24.18.0
|
|
97
|
+
- name: Check version-only release diff
|
|
98
|
+
id: release-policy
|
|
99
|
+
if: steps.node.outcome == 'success'
|
|
100
|
+
continue-on-error: true
|
|
101
|
+
env:
|
|
102
|
+
FOUNDRY_BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
103
|
+
FOUNDRY_HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
|
104
|
+
FOUNDRY_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
|
105
|
+
FOUNDRY_REPOSITORY: ${{ github.repository }}
|
|
106
|
+
RUNTIME_PATH: ${{ runner.temp }}/code-foundry
|
|
107
|
+
run: node "$RUNTIME_PATH/src/runtime.mjs" validation release_diff
|
|
108
|
+
- name: Verify source qualification receipt
|
|
109
|
+
id: verify
|
|
110
|
+
if: always()
|
|
111
|
+
continue-on-error: true
|
|
112
|
+
env:
|
|
113
|
+
SOURCE_READY: ${{ steps.source.outcome }}
|
|
114
|
+
RUNTIME_READY: ${{ steps.install.outcome }}
|
|
115
|
+
NODE_READY: ${{ steps.node.outcome }}
|
|
116
|
+
POLICY_READY: ${{ steps.release-policy.outcome }}
|
|
117
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
118
|
+
RUNTIME_PATH: ${{ runner.temp }}/code-foundry
|
|
119
|
+
RUNTIME_REPOSITORY: ${{ inputs.runtime-repository }}
|
|
120
|
+
FOUNDRY_MODE: ${{ inputs.mode }}
|
|
121
|
+
FOUNDRY_CODEQL_ENABLED: ${{ inputs.codeql-enabled }}
|
|
122
|
+
FOUNDRY_REQUIRED_JOB_NAMES_JSON: ${{ inputs.required-job-names-json }}
|
|
123
|
+
run: |
|
|
124
|
+
if [ "$SOURCE_READY" = success ] && [ "$RUNTIME_READY" = success ] && [ "$NODE_READY" = success ] && [ "$POLICY_READY" = success ] && [ -f "$RUNTIME_PATH/src/commands/qualification-receipt.mjs" ]; then
|
|
125
|
+
node "$RUNTIME_PATH/src/commands/qualification-receipt.mjs" verify >> "$GITHUB_OUTPUT"
|
|
126
|
+
else
|
|
127
|
+
echo 'reuse=false' >> "$GITHUB_OUTPUT"
|
|
128
|
+
echo 'reason=qualification or version-only release policy unavailable; using full validation' >> "$GITHUB_OUTPUT"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
produce:
|
|
132
|
+
name: Produce source receipt
|
|
133
|
+
if: >-
|
|
134
|
+
vars.CI_BILLING_PAUSED != 'true' && inputs.enabled == true &&
|
|
135
|
+
inputs.phase == 'produce' && inputs.mode == 'audit'
|
|
136
|
+
runs-on: ubuntu-slim
|
|
137
|
+
timeout-minutes: 10
|
|
138
|
+
steps:
|
|
139
|
+
- name: Checkout tested source tree
|
|
140
|
+
id: source
|
|
141
|
+
continue-on-error: true
|
|
142
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
143
|
+
with:
|
|
144
|
+
persist-credentials: false
|
|
145
|
+
ref: ${{ github.sha }}
|
|
146
|
+
fetch-depth: 2
|
|
147
|
+
- name: Checkout runtime
|
|
148
|
+
id: runtime
|
|
149
|
+
if: steps.source.outcome == 'success'
|
|
150
|
+
continue-on-error: true
|
|
151
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
152
|
+
with:
|
|
153
|
+
persist-credentials: false
|
|
154
|
+
repository: ${{ inputs.runtime-repository }}
|
|
155
|
+
ref: ${{ inputs.runtime-ref }}
|
|
156
|
+
path: .github/.code-foundry
|
|
157
|
+
sparse-checkout: |
|
|
158
|
+
src/commands/qualification-receipt.mjs
|
|
159
|
+
src/lib
|
|
160
|
+
- name: Install runtime
|
|
161
|
+
id: install
|
|
162
|
+
if: steps.runtime.outcome == 'success'
|
|
163
|
+
continue-on-error: true
|
|
164
|
+
run: mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
165
|
+
- name: Set up Node.js 24.18.0
|
|
166
|
+
id: node
|
|
167
|
+
if: steps.install.outcome == 'success'
|
|
168
|
+
continue-on-error: true
|
|
169
|
+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
170
|
+
with:
|
|
171
|
+
node-version: 24.18.0
|
|
172
|
+
- name: Create qualification receipt
|
|
173
|
+
id: produce
|
|
174
|
+
if: always()
|
|
175
|
+
continue-on-error: true
|
|
176
|
+
env:
|
|
177
|
+
SOURCE_READY: ${{ steps.source.outcome }}
|
|
178
|
+
RUNTIME_READY: ${{ steps.install.outcome }}
|
|
179
|
+
NODE_READY: ${{ steps.node.outcome }}
|
|
180
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
181
|
+
RUNTIME_PATH: ${{ runner.temp }}/code-foundry
|
|
182
|
+
RUNTIME_REPOSITORY: ${{ inputs.runtime-repository }}
|
|
183
|
+
FOUNDRY_MODE: ${{ inputs.mode }}
|
|
184
|
+
FOUNDRY_JOB_RESULTS_JSON: ${{ inputs.job-results-json }}
|
|
185
|
+
FOUNDRY_REQUIRED_JOB_NAMES_JSON: ${{ inputs.required-job-names-json }}
|
|
186
|
+
run: |
|
|
187
|
+
if [ "$SOURCE_READY" = success ] && [ "$RUNTIME_READY" = success ] && [ "$NODE_READY" = success ] && [ -f "$RUNTIME_PATH/src/commands/qualification-receipt.mjs" ]; then
|
|
188
|
+
node "$RUNTIME_PATH/src/commands/qualification-receipt.mjs" produce >> "$GITHUB_OUTPUT"
|
|
189
|
+
else
|
|
190
|
+
echo 'reuse=false' >> "$GITHUB_OUTPUT"
|
|
191
|
+
echo 'reason=receipt setup unavailable' >> "$GITHUB_OUTPUT"
|
|
192
|
+
fi
|
|
193
|
+
- name: Upload qualification receipt
|
|
194
|
+
if: steps.produce.outputs.reuse == 'true'
|
|
195
|
+
continue-on-error: true
|
|
196
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
197
|
+
with:
|
|
198
|
+
name: code-foundry-qualification-v2-${{ github.run_id }}-${{ github.run_attempt }}
|
|
199
|
+
path: qualification-receipt.json
|
|
200
|
+
if-no-files-found: error
|
|
201
|
+
retention-days: 7
|
|
@@ -16,9 +16,6 @@ on:
|
|
|
16
16
|
required: false
|
|
17
17
|
type: boolean
|
|
18
18
|
default: false
|
|
19
|
-
secrets:
|
|
20
|
-
NPM_TOKEN:
|
|
21
|
-
required: false
|
|
22
19
|
|
|
23
20
|
permissions:
|
|
24
21
|
attestations: read
|
|
@@ -88,7 +85,6 @@ jobs:
|
|
|
88
85
|
contents: read
|
|
89
86
|
id-token: write
|
|
90
87
|
env:
|
|
91
|
-
HAS_NPM_TOKEN: ${{ secrets.NPM_TOKEN != '' }}
|
|
92
88
|
RELEASE_TAG: ${{ inputs.tag }}
|
|
93
89
|
RELEASE_ASSET: ${{ inputs.asset }}
|
|
94
90
|
steps:
|
|
@@ -98,16 +94,9 @@ jobs:
|
|
|
98
94
|
persist-credentials: false
|
|
99
95
|
ref: ${{ github.sha }}
|
|
100
96
|
- name: Setup Node for trusted publishing
|
|
101
|
-
if: env.HAS_NPM_TOKEN != 'true'
|
|
102
|
-
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
103
|
-
with:
|
|
104
|
-
node-version: '24'
|
|
105
|
-
- name: Setup Node for token publishing
|
|
106
|
-
if: env.HAS_NPM_TOKEN == 'true'
|
|
107
97
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
108
98
|
with:
|
|
109
99
|
node-version: '24'
|
|
110
|
-
registry-url: https://registry.npmjs.org
|
|
111
100
|
- name: Retrieve only this run attempt's evidence
|
|
112
101
|
env:
|
|
113
102
|
GH_TOKEN: ${{ github.token }}
|
|
@@ -124,7 +113,6 @@ jobs:
|
|
|
124
113
|
- name: Reverify and publish the tested tarball without lifecycle hooks
|
|
125
114
|
env:
|
|
126
115
|
GH_TOKEN: ${{ github.token }}
|
|
127
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
128
116
|
run: |
|
|
129
117
|
set -euo pipefail
|
|
130
118
|
node src/commands/qualified-publication.mjs publish \
|