code-foundry 1.0.6 → 1.1.1
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/code-foundry.yml +1 -1
- package/.github/workflows/codeql.yml +73 -182
- package/.github/workflows/security.yml +96 -129
- package/CHANGELOG.md +14 -0
- package/docs/WORKFLOWS.md +14 -5
- package/package.json +1 -1
package/.github/code-foundry.yml
CHANGED
|
@@ -39,7 +39,9 @@ permissions:
|
|
|
39
39
|
packages: read
|
|
40
40
|
security-events: write
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# Analyzers run only for detected languages: the analysis matrix is built from
|
|
43
|
+
# detection, so repositories never see skipped checks for languages they do
|
|
44
|
+
# not use. An empty matrix while analysis is enabled fails the build closed.
|
|
43
45
|
env:
|
|
44
46
|
REPO_FOUNDRY_PROFILE: ${{ vars.REPO_FOUNDRY_PROFILE }}
|
|
45
47
|
REPO_FOUNDRY_LANGUAGES: ${{ vars.REPO_FOUNDRY_LANGUAGES }}
|
|
@@ -58,6 +60,8 @@ jobs:
|
|
|
58
60
|
outputs:
|
|
59
61
|
languages: ${{ steps.languages.outputs.languages }}
|
|
60
62
|
enabled: ${{ steps.languages.outputs.enabled }}
|
|
63
|
+
matrix: ${{ steps.matrix.outputs.matrix }}
|
|
64
|
+
rust_matrix: ${{ steps.matrix.outputs.rust_matrix }}
|
|
61
65
|
code_security: ${{ steps.security.outputs.status }}
|
|
62
66
|
actions_available: ${{ steps.languages.outputs.actions_available }}
|
|
63
67
|
actions_changed: ${{ steps.languages.outputs.actions_changed }}
|
|
@@ -126,148 +130,65 @@ jobs:
|
|
|
126
130
|
REPO_FOUNDRY_PRIVATE: ${{ github.event.repository.private }}
|
|
127
131
|
REPO_FOUNDRY_VISIBILITY: ${{ github.event.repository.visibility }}
|
|
128
132
|
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs codeql
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
136
|
-
needs.detect.outputs.actions_available == 'true'
|
|
137
|
-
runs-on: ${{ inputs.runner }}
|
|
138
|
-
timeout-minutes: 30
|
|
139
|
-
steps:
|
|
140
|
-
- name: Checkout
|
|
141
|
-
if: >-
|
|
142
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
143
|
-
needs.detect.outputs.actions_available == 'true' &&
|
|
144
|
-
needs.detect.outputs.actions_changed == 'true'
|
|
145
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
146
|
-
with:
|
|
147
|
-
persist-credentials: false
|
|
148
|
-
- name: Runtime
|
|
149
|
-
if: >-
|
|
150
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
151
|
-
needs.detect.outputs.actions_available == 'true' &&
|
|
152
|
-
needs.detect.outputs.actions_changed == 'true'
|
|
153
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
154
|
-
with:
|
|
155
|
-
persist-credentials: false
|
|
156
|
-
repository: ${{ inputs.runtime-repository }}
|
|
157
|
-
ref: ${{ inputs.runtime-ref }}
|
|
158
|
-
path: .github/.code-foundry
|
|
159
|
-
sparse-checkout: |
|
|
160
|
-
.github/actions
|
|
161
|
-
src/lib
|
|
162
|
-
src/runtime.mjs
|
|
163
|
-
- name: Install runtime
|
|
164
|
-
if: >-
|
|
165
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
166
|
-
needs.detect.outputs.actions_available == 'true' &&
|
|
167
|
-
needs.detect.outputs.actions_changed == 'true'
|
|
168
|
-
run: |
|
|
169
|
-
mkdir -p .github/actions
|
|
170
|
-
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
171
|
-
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
172
|
-
- name: Analyze
|
|
173
|
-
if: >-
|
|
174
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
175
|
-
needs.detect.outputs.actions_available == 'true' &&
|
|
176
|
-
needs.detect.outputs.actions_changed == 'true'
|
|
177
|
-
uses: ./.github/actions/codeql
|
|
178
|
-
with:
|
|
179
|
-
language: actions
|
|
180
|
-
build-mode: ${{ needs.detect.outputs.actions_build_mode }}
|
|
181
|
-
category: /language:actions
|
|
182
|
-
- name: Not applicable
|
|
183
|
-
if: >-
|
|
184
|
-
needs.detect.outputs.enabled != 'true' ||
|
|
185
|
-
needs.detect.outputs.actions_available != 'true' ||
|
|
186
|
-
needs.detect.outputs.actions_changed != 'true'
|
|
187
|
-
run: echo "CodeQL Actions analysis is not applicable to this change."
|
|
188
|
-
|
|
189
|
-
analyze-typescript:
|
|
190
|
-
name: Analyze (TypeScript)
|
|
191
|
-
needs: detect
|
|
192
|
-
if: >-
|
|
193
|
-
vars.CI_BILLING_PAUSED != 'true' &&
|
|
194
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
195
|
-
needs.detect.outputs.javascript_available == 'true'
|
|
196
|
-
runs-on: ${{ inputs.runner }}
|
|
197
|
-
timeout-minutes: 30
|
|
198
|
-
steps:
|
|
199
|
-
- name: Checkout
|
|
200
|
-
if: >-
|
|
201
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
202
|
-
needs.detect.outputs.javascript_available == 'true' &&
|
|
203
|
-
needs.detect.outputs.javascript_changed == 'true'
|
|
204
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
205
|
-
with:
|
|
206
|
-
persist-credentials: false
|
|
207
|
-
- name: Runtime
|
|
208
|
-
if: >-
|
|
209
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
210
|
-
needs.detect.outputs.javascript_available == 'true' &&
|
|
211
|
-
needs.detect.outputs.javascript_changed == 'true'
|
|
212
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
213
|
-
with:
|
|
214
|
-
persist-credentials: false
|
|
215
|
-
repository: ${{ inputs.runtime-repository }}
|
|
216
|
-
ref: ${{ inputs.runtime-ref }}
|
|
217
|
-
path: .github/.code-foundry
|
|
218
|
-
sparse-checkout: |
|
|
219
|
-
.github/actions
|
|
220
|
-
src/lib
|
|
221
|
-
src/runtime.mjs
|
|
222
|
-
- name: Install runtime
|
|
223
|
-
if: >-
|
|
224
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
225
|
-
needs.detect.outputs.javascript_available == 'true' &&
|
|
226
|
-
needs.detect.outputs.javascript_changed == 'true'
|
|
133
|
+
- id: matrix
|
|
134
|
+
name: Build analysis matrix
|
|
135
|
+
env:
|
|
136
|
+
MATRIX_ENABLED: ${{ steps.languages.outputs.enabled }}
|
|
137
|
+
MATRIX_LANGUAGES: ${{ steps.languages.outputs.languages }}
|
|
138
|
+
MATRIX_SHARDS: ${{ inputs.rust-shards }}
|
|
227
139
|
run: |
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
140
|
+
node -e '
|
|
141
|
+
const fs = require("node:fs");
|
|
142
|
+
const out = process.env.GITHUB_OUTPUT;
|
|
143
|
+
function append(name, value) { fs.appendFileSync(out, name + "=" + value + "\n"); }
|
|
144
|
+
const enabled = process.env.MATRIX_ENABLED === "true";
|
|
145
|
+
if (!enabled) {
|
|
146
|
+
append("matrix", "[]");
|
|
147
|
+
append("rust_matrix", "[]");
|
|
148
|
+
} else {
|
|
149
|
+
const languages = JSON.parse(process.env.MATRIX_LANGUAGES || "[]");
|
|
150
|
+
const shards = JSON.parse(process.env.MATRIX_SHARDS || "[\"all\"]");
|
|
151
|
+
const display = { actions: "Actions", "javascript-typescript": "TypeScript", python: "Python" };
|
|
152
|
+
const matrix = languages
|
|
153
|
+
.filter((entry) => entry.language !== "rust")
|
|
154
|
+
.map((entry) => ({
|
|
155
|
+
display: display[entry.language] || entry.language,
|
|
156
|
+
language: entry.language,
|
|
157
|
+
category: "/language/" + entry.language,
|
|
158
|
+
build_mode: entry["build-mode"] || "none",
|
|
159
|
+
changed: entry.changed === true,
|
|
160
|
+
}));
|
|
161
|
+
const rust = languages.find((entry) => entry.language === "rust");
|
|
162
|
+
const rustMatrix = rust
|
|
163
|
+
? shards.map((shard) => ({ display: "Rust (" + shard + ")", shard: String(shard), changed: rust.changed === true }))
|
|
164
|
+
: [];
|
|
165
|
+
if (!matrix.length && !rustMatrix.length) {
|
|
166
|
+
console.error("CodeQL analysis matrix is empty while analysis is enabled.");
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
append("matrix", JSON.stringify(matrix));
|
|
170
|
+
append("rust_matrix", JSON.stringify(rustMatrix));
|
|
171
|
+
}
|
|
172
|
+
'
|
|
247
173
|
|
|
248
|
-
analyze
|
|
249
|
-
name: Analyze (
|
|
174
|
+
analyze:
|
|
175
|
+
name: Analyze (${{ matrix.entry.display }})
|
|
250
176
|
needs: detect
|
|
251
|
-
if:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
177
|
+
if: vars.CI_BILLING_PAUSED != 'true' && needs.detect.outputs.enabled == 'true'
|
|
178
|
+
strategy:
|
|
179
|
+
fail-fast: false
|
|
180
|
+
matrix:
|
|
181
|
+
entry: ${{ fromJson(needs.detect.outputs.matrix || '[]') }}
|
|
255
182
|
runs-on: ${{ inputs.runner }}
|
|
256
183
|
timeout-minutes: 30
|
|
257
184
|
steps:
|
|
258
185
|
- name: Checkout
|
|
259
|
-
if:
|
|
260
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
261
|
-
needs.detect.outputs.python_available == 'true' &&
|
|
262
|
-
needs.detect.outputs.python_changed == 'true'
|
|
186
|
+
if: ${{ matrix.entry.changed == true }}
|
|
263
187
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
264
188
|
with:
|
|
265
189
|
persist-credentials: false
|
|
266
190
|
- name: Runtime
|
|
267
|
-
if:
|
|
268
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
269
|
-
needs.detect.outputs.python_available == 'true' &&
|
|
270
|
-
needs.detect.outputs.python_changed == 'true'
|
|
191
|
+
if: ${{ matrix.entry.changed == true }}
|
|
271
192
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
272
193
|
with:
|
|
273
194
|
persist-credentials: false
|
|
@@ -279,59 +200,44 @@ jobs:
|
|
|
279
200
|
src/lib
|
|
280
201
|
src/runtime.mjs
|
|
281
202
|
- name: Install runtime
|
|
282
|
-
if:
|
|
283
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
284
|
-
needs.detect.outputs.python_available == 'true' &&
|
|
285
|
-
needs.detect.outputs.python_changed == 'true'
|
|
203
|
+
if: ${{ matrix.entry.changed == true }}
|
|
286
204
|
run: |
|
|
287
205
|
mkdir -p .github/actions
|
|
288
206
|
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
289
207
|
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
290
208
|
- name: Analyze
|
|
291
|
-
if:
|
|
292
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
293
|
-
needs.detect.outputs.python_available == 'true' &&
|
|
294
|
-
needs.detect.outputs.python_changed == 'true'
|
|
209
|
+
if: ${{ matrix.entry.changed == true }}
|
|
295
210
|
uses: ./.github/actions/codeql
|
|
296
211
|
with:
|
|
297
|
-
language:
|
|
298
|
-
build-mode: ${{
|
|
299
|
-
category:
|
|
212
|
+
language: ${{ matrix.entry.language }}
|
|
213
|
+
build-mode: ${{ matrix.entry.build_mode }}
|
|
214
|
+
category: ${{ matrix.entry.category }}
|
|
300
215
|
- name: Not applicable
|
|
301
|
-
if:
|
|
302
|
-
|
|
303
|
-
needs.detect.outputs.python_available != 'true' ||
|
|
304
|
-
needs.detect.outputs.python_changed != 'true'
|
|
305
|
-
run: echo "CodeQL Python analysis is not applicable to this change."
|
|
216
|
+
if: ${{ matrix.entry.changed != true }}
|
|
217
|
+
run: echo "CodeQL ${{ matrix.entry.display }} analysis is not applicable to this change."
|
|
306
218
|
|
|
219
|
+
# Rust keeps its own job so shard fan-out stays behind the
|
|
220
|
+
# rust-max-parallel throttle. The static name matches the pre-matrix check
|
|
221
|
+
# name; per-shard detail stays in the SARIF category and step logs.
|
|
307
222
|
analyze-rust:
|
|
308
223
|
name: Analyze (Rust)
|
|
309
224
|
needs: detect
|
|
310
|
-
if:
|
|
311
|
-
vars.CI_BILLING_PAUSED != 'true' &&
|
|
312
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
313
|
-
needs.detect.outputs.rust_available == 'true'
|
|
225
|
+
if: vars.CI_BILLING_PAUSED != 'true' && needs.detect.outputs.enabled == 'true' && needs.detect.outputs.rust_available == 'true'
|
|
314
226
|
strategy:
|
|
315
227
|
fail-fast: false
|
|
316
228
|
max-parallel: ${{ inputs.rust-max-parallel }}
|
|
317
229
|
matrix:
|
|
318
|
-
|
|
230
|
+
entry: ${{ fromJson(needs.detect.outputs.rust_matrix || '[]') }}
|
|
319
231
|
runs-on: ${{ inputs.runner }}
|
|
320
232
|
timeout-minutes: 30
|
|
321
233
|
steps:
|
|
322
234
|
- name: Checkout
|
|
323
|
-
if:
|
|
324
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
325
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
326
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
235
|
+
if: ${{ matrix.entry.changed == true }}
|
|
327
236
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
328
237
|
with:
|
|
329
238
|
persist-credentials: false
|
|
330
239
|
- name: Runtime
|
|
331
|
-
if:
|
|
332
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
333
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
334
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
240
|
+
if: ${{ matrix.entry.changed == true }}
|
|
335
241
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
336
242
|
with:
|
|
337
243
|
persist-credentials: false
|
|
@@ -343,22 +249,16 @@ jobs:
|
|
|
343
249
|
src/lib
|
|
344
250
|
src/runtime.mjs
|
|
345
251
|
- name: Install runtime
|
|
346
|
-
if:
|
|
347
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
348
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
349
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
252
|
+
if: ${{ matrix.entry.changed == true }}
|
|
350
253
|
run: |
|
|
351
254
|
mkdir -p .github/actions
|
|
352
255
|
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
353
256
|
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
354
257
|
- name: Configure Rust scope
|
|
355
|
-
if:
|
|
356
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
357
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
358
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
258
|
+
if: ${{ matrix.entry.changed == true }}
|
|
359
259
|
id: scope
|
|
360
260
|
env:
|
|
361
|
-
RUST_SCOPE: ${{ matrix.shard }}
|
|
261
|
+
RUST_SCOPE: ${{ matrix.entry.shard }}
|
|
362
262
|
run: |
|
|
363
263
|
set -euo pipefail
|
|
364
264
|
scope="$RUST_SCOPE"
|
|
@@ -403,10 +303,7 @@ jobs:
|
|
|
403
303
|
echo "config_file=$config_file" >> "$GITHUB_OUTPUT"
|
|
404
304
|
echo "scope_id=$scope_id" >> "$GITHUB_OUTPUT"
|
|
405
305
|
- name: Initialize
|
|
406
|
-
if:
|
|
407
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
408
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
409
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
306
|
+
if: ${{ matrix.entry.changed == true }}
|
|
410
307
|
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
|
|
411
308
|
with:
|
|
412
309
|
languages: rust
|
|
@@ -414,18 +311,12 @@ jobs:
|
|
|
414
311
|
config-file: ${{ steps.scope.outputs.config_file }}
|
|
415
312
|
threads: ${{ inputs.rust-threads }}
|
|
416
313
|
- name: Analyze
|
|
417
|
-
if:
|
|
418
|
-
needs.detect.outputs.enabled == 'true' &&
|
|
419
|
-
needs.detect.outputs.rust_available == 'true' &&
|
|
420
|
-
needs.detect.outputs.rust_changed == 'true'
|
|
314
|
+
if: ${{ matrix.entry.changed == true }}
|
|
421
315
|
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
|
|
422
316
|
with:
|
|
423
317
|
category: /language:rust/${{ steps.scope.outputs.scope_id }}
|
|
424
318
|
upload-database: false
|
|
425
319
|
wait-for-processing: false
|
|
426
320
|
- name: Not applicable
|
|
427
|
-
if:
|
|
428
|
-
needs.detect.outputs.enabled != 'true' ||
|
|
429
|
-
needs.detect.outputs.rust_available != 'true' ||
|
|
430
|
-
needs.detect.outputs.rust_changed != 'true'
|
|
321
|
+
if: ${{ matrix.entry.changed != true }}
|
|
431
322
|
run: echo "CodeQL Rust analysis is not applicable to this change."
|
|
@@ -45,6 +45,7 @@ jobs:
|
|
|
45
45
|
python: ${{ steps.profile.outputs.python }}
|
|
46
46
|
python_requirements: ${{ steps.profile.outputs.python_requirements }}
|
|
47
47
|
dependency_review: ${{ steps.profile.outputs.dependency_review }}
|
|
48
|
+
audit_matrix: ${{ steps.matrix.outputs.audit_matrix }}
|
|
48
49
|
steps:
|
|
49
50
|
- name: Checkout
|
|
50
51
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
@@ -99,15 +100,49 @@ jobs:
|
|
|
99
100
|
REPO_FOUNDRY_PRIVATE: ${{ github.event.repository.private }}
|
|
100
101
|
REPO_FOUNDRY_VISIBILITY: ${{ github.event.repository.visibility }}
|
|
101
102
|
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security profile >> "$GITHUB_OUTPUT"
|
|
103
|
+
- id: matrix
|
|
104
|
+
name: Build audit matrix
|
|
105
|
+
env:
|
|
106
|
+
MATRIX_JAVASCRIPT: ${{ steps.profile.outputs.javascript }}
|
|
107
|
+
MATRIX_RUST: ${{ steps.profile.outputs.rust }}
|
|
108
|
+
MATRIX_PYTHON: ${{ steps.profile.outputs.python }}
|
|
109
|
+
MATRIX_REQUIREMENTS: ${{ steps.profile.outputs.python_requirements }}
|
|
110
|
+
run: |
|
|
111
|
+
node -e '
|
|
112
|
+
const fs = require("node:fs");
|
|
113
|
+
const env = process.env;
|
|
114
|
+
const entries = [];
|
|
115
|
+
if (env.MATRIX_JAVASCRIPT === "true") entries.push({ display: "JavaScript", language: "javascript" });
|
|
116
|
+
if (env.MATRIX_RUST === "true") entries.push({ display: "Rust", language: "rust" });
|
|
117
|
+
if (env.MATRIX_PYTHON === "true") {
|
|
118
|
+
let requirements = [];
|
|
119
|
+
try { requirements = JSON.parse(env.MATRIX_REQUIREMENTS || "[]"); } catch (error) { requirements = []; }
|
|
120
|
+
for (const requirement of requirements.filter((item) => item && item !== "none")) {
|
|
121
|
+
entries.push({ display: "Python / " + requirement, language: "python", requirement: requirement });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
fs.appendFileSync(env.GITHUB_OUTPUT, "audit_matrix=" + JSON.stringify(entries) + "\n");
|
|
125
|
+
'
|
|
102
126
|
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
# Audits run only for detected languages: the audit matrix is built from the
|
|
128
|
+
# profile, so repositories never see skipped checks for ecosystems they do
|
|
129
|
+
# not use. An empty matrix skips this job with no per-language rows.
|
|
130
|
+
dependency-audit:
|
|
131
|
+
name: Dependency Audit (${{ matrix.entry.display }})
|
|
105
132
|
needs: profile
|
|
106
|
-
if:
|
|
133
|
+
if: vars.CI_BILLING_PAUSED != 'true' && needs.profile.result == 'success'
|
|
134
|
+
strategy:
|
|
135
|
+
fail-fast: false
|
|
136
|
+
max-parallel: 8
|
|
137
|
+
matrix:
|
|
138
|
+
entry: ${{ fromJson(needs.profile.outputs.audit_matrix || '[]') }}
|
|
107
139
|
runs-on: ${{ inputs.runner }}
|
|
108
140
|
timeout-minutes: 20
|
|
141
|
+
env:
|
|
142
|
+
REPO_FOUNDRY_PYTHON_REQUIREMENT: ${{ matrix.entry.requirement }}
|
|
109
143
|
steps:
|
|
110
|
-
- name: Checkout
|
|
144
|
+
- name: Checkout JavaScript
|
|
145
|
+
if: matrix.entry.language == 'javascript'
|
|
111
146
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
112
147
|
with:
|
|
113
148
|
persist-credentials: false
|
|
@@ -126,43 +161,22 @@ jobs:
|
|
|
126
161
|
**/yarn.lock
|
|
127
162
|
**/package-lock.json
|
|
128
163
|
sparse-checkout-cone-mode: false
|
|
129
|
-
- name:
|
|
164
|
+
- name: Checkout Rust
|
|
165
|
+
if: matrix.entry.language == 'rust'
|
|
130
166
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
131
167
|
with:
|
|
132
168
|
persist-credentials: false
|
|
133
|
-
|
|
134
|
-
ref: ${{ inputs.runtime-ref }}
|
|
135
|
-
path: .github/.code-foundry
|
|
169
|
+
filter: blob:none
|
|
136
170
|
sparse-checkout: |
|
|
137
|
-
.github
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
id: applicability
|
|
147
|
-
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security should_run javascript >> "$GITHUB_OUTPUT"
|
|
148
|
-
- name: Setup
|
|
149
|
-
if: steps.applicability.outputs.applicable == 'true'
|
|
150
|
-
uses: ./.github/actions/setup
|
|
151
|
-
with:
|
|
152
|
-
mise-scope: javascript
|
|
153
|
-
cache-save: ${{ github.event_name == 'push' }}
|
|
154
|
-
- name: Audit dependencies
|
|
155
|
-
if: steps.applicability.outputs.applicable == 'true'
|
|
156
|
-
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security audit javascript
|
|
157
|
-
|
|
158
|
-
dependency-audit-rust:
|
|
159
|
-
name: Dependency Audit (Rust)
|
|
160
|
-
needs: profile
|
|
161
|
-
if: ${{ vars.CI_BILLING_PAUSED != 'true' && needs.profile.result == 'success' && needs.profile.outputs.rust == 'true' }}
|
|
162
|
-
runs-on: ${{ inputs.runner }}
|
|
163
|
-
timeout-minutes: 20
|
|
164
|
-
steps:
|
|
165
|
-
- name: Checkout
|
|
171
|
+
.github
|
|
172
|
+
.mise.toml
|
|
173
|
+
mise.lock
|
|
174
|
+
**/Cargo.toml
|
|
175
|
+
**/Cargo.lock
|
|
176
|
+
**/.cargo/**
|
|
177
|
+
sparse-checkout-cone-mode: false
|
|
178
|
+
- name: Checkout Python
|
|
179
|
+
if: matrix.entry.language == 'python'
|
|
166
180
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
167
181
|
with:
|
|
168
182
|
persist-credentials: false
|
|
@@ -171,9 +185,14 @@ jobs:
|
|
|
171
185
|
.github
|
|
172
186
|
.mise.toml
|
|
173
187
|
mise.lock
|
|
174
|
-
**/
|
|
175
|
-
**/
|
|
176
|
-
|
|
188
|
+
**/pyproject.toml
|
|
189
|
+
**/requirements*.txt
|
|
190
|
+
**/setup.py
|
|
191
|
+
**/setup.cfg
|
|
192
|
+
**/Pipfile
|
|
193
|
+
**/Pipfile.lock
|
|
194
|
+
**/poetry.lock
|
|
195
|
+
**/uv.lock
|
|
177
196
|
sparse-checkout-cone-mode: false
|
|
178
197
|
- name: Runtime
|
|
179
198
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
@@ -191,12 +210,32 @@ jobs:
|
|
|
191
210
|
mkdir -p .github/actions
|
|
192
211
|
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
193
212
|
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
194
|
-
- name: Detect
|
|
195
|
-
id: applicability
|
|
213
|
+
- name: Detect JavaScript
|
|
214
|
+
id: applicability-javascript
|
|
215
|
+
if: matrix.entry.language == 'javascript'
|
|
216
|
+
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security should_run javascript >> "$GITHUB_OUTPUT"
|
|
217
|
+
- name: Detect Rust
|
|
218
|
+
id: applicability-rust
|
|
219
|
+
if: matrix.entry.language == 'rust'
|
|
196
220
|
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security should_run rust >> "$GITHUB_OUTPUT"
|
|
221
|
+
- name: Setup JavaScript
|
|
222
|
+
if: >-
|
|
223
|
+
matrix.entry.language == 'javascript' &&
|
|
224
|
+
steps.applicability-javascript.outputs.applicable == 'true'
|
|
225
|
+
uses: ./.github/actions/setup
|
|
226
|
+
with:
|
|
227
|
+
mise-scope: javascript
|
|
228
|
+
cache-save: ${{ github.event_name == 'push' }}
|
|
229
|
+
- name: Audit JavaScript dependencies
|
|
230
|
+
if: >-
|
|
231
|
+
matrix.entry.language == 'javascript' &&
|
|
232
|
+
steps.applicability-javascript.outputs.applicable == 'true'
|
|
233
|
+
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security audit javascript
|
|
197
234
|
- name: Check Rust
|
|
198
235
|
id: system-rust
|
|
199
|
-
if:
|
|
236
|
+
if: >-
|
|
237
|
+
matrix.entry.language == 'rust' &&
|
|
238
|
+
steps.applicability-rust.outputs.applicable == 'true'
|
|
200
239
|
shell: bash
|
|
201
240
|
run: |
|
|
202
241
|
if command -v cargo >/dev/null 2>&1 && command -v rustc >/dev/null 2>&1; then
|
|
@@ -206,109 +245,37 @@ jobs:
|
|
|
206
245
|
else
|
|
207
246
|
echo 'available=false' >> "$GITHUB_OUTPUT"
|
|
208
247
|
fi
|
|
209
|
-
- name: Setup
|
|
248
|
+
- name: Setup Rust
|
|
210
249
|
if: >-
|
|
211
|
-
|
|
250
|
+
matrix.entry.language == 'rust' &&
|
|
251
|
+
steps.applicability-rust.outputs.applicable == 'true' &&
|
|
212
252
|
steps.system-rust.outputs.available != 'true'
|
|
213
253
|
uses: ./.github/actions/setup
|
|
214
254
|
with:
|
|
215
255
|
mise-scope: rust
|
|
216
256
|
cache-save: ${{ github.event_name == 'push' }}
|
|
217
257
|
- name: Install cargo-audit
|
|
218
|
-
if:
|
|
258
|
+
if: >-
|
|
259
|
+
matrix.entry.language == 'rust' &&
|
|
260
|
+
steps.applicability-rust.outputs.applicable == 'true'
|
|
219
261
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2
|
|
220
262
|
with:
|
|
221
263
|
tool: cargo-audit
|
|
222
|
-
- name: Audit dependencies
|
|
223
|
-
if:
|
|
264
|
+
- name: Audit Rust dependencies
|
|
265
|
+
if: >-
|
|
266
|
+
matrix.entry.language == 'rust' &&
|
|
267
|
+
steps.applicability-rust.outputs.applicable == 'true'
|
|
224
268
|
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security audit rust
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
name: Dependency Audit (Python) / ${{ matrix.requirement }}
|
|
228
|
-
needs: profile
|
|
229
|
-
if: >-
|
|
230
|
-
${{ vars.CI_BILLING_PAUSED != 'true' &&
|
|
231
|
-
needs.profile.result == 'success' &&
|
|
232
|
-
needs.profile.outputs.python == 'true' &&
|
|
233
|
-
needs.profile.outputs.python_requirements != '["none"]' }}
|
|
234
|
-
strategy:
|
|
235
|
-
fail-fast: false
|
|
236
|
-
max-parallel: 8
|
|
237
|
-
matrix:
|
|
238
|
-
requirement: ${{ fromJSON(needs.profile.outputs.python_requirements) }}
|
|
239
|
-
runs-on: ${{ inputs.runner }}
|
|
240
|
-
timeout-minutes: 20
|
|
241
|
-
env:
|
|
242
|
-
REPO_FOUNDRY_PYTHON_REQUIREMENT: ${{ matrix.requirement }}
|
|
243
|
-
steps:
|
|
244
|
-
- name: Checkout
|
|
245
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
246
|
-
with:
|
|
247
|
-
persist-credentials: false
|
|
248
|
-
filter: blob:none
|
|
249
|
-
sparse-checkout: |
|
|
250
|
-
.github
|
|
251
|
-
.mise.toml
|
|
252
|
-
mise.lock
|
|
253
|
-
**/pyproject.toml
|
|
254
|
-
**/requirements*.txt
|
|
255
|
-
**/setup.py
|
|
256
|
-
**/setup.cfg
|
|
257
|
-
**/Pipfile
|
|
258
|
-
**/Pipfile.lock
|
|
259
|
-
**/poetry.lock
|
|
260
|
-
**/uv.lock
|
|
261
|
-
sparse-checkout-cone-mode: false
|
|
262
|
-
- name: Runtime
|
|
263
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
264
|
-
with:
|
|
265
|
-
persist-credentials: false
|
|
266
|
-
repository: ${{ inputs.runtime-repository }}
|
|
267
|
-
ref: ${{ inputs.runtime-ref }}
|
|
268
|
-
path: .github/.code-foundry
|
|
269
|
-
sparse-checkout: |
|
|
270
|
-
.github/actions
|
|
271
|
-
src/lib
|
|
272
|
-
src/runtime.mjs
|
|
273
|
-
- name: Install runtime
|
|
274
|
-
run: |
|
|
275
|
-
mkdir -p .github/actions
|
|
276
|
-
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
277
|
-
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
278
|
-
- name: Setup
|
|
269
|
+
- name: Setup Python
|
|
270
|
+
if: matrix.entry.language == 'python'
|
|
279
271
|
uses: ./.github/actions/setup
|
|
280
272
|
with:
|
|
281
273
|
mise-scope: python
|
|
282
274
|
cache-save: ${{ github.event_name == 'push' }}
|
|
283
|
-
- name: Audit dependencies
|
|
275
|
+
- name: Audit Python dependencies
|
|
276
|
+
if: matrix.entry.language == 'python'
|
|
284
277
|
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs security audit python
|
|
285
278
|
|
|
286
|
-
dependency-audit-python-gate:
|
|
287
|
-
name: Dependency Audit (Python)
|
|
288
|
-
needs: [profile, dependency-audit-python]
|
|
289
|
-
if: >-
|
|
290
|
-
${{ vars.CI_BILLING_PAUSED != 'true' &&
|
|
291
|
-
always() &&
|
|
292
|
-
needs.profile.result == 'success' &&
|
|
293
|
-
needs.profile.outputs.python == 'true' &&
|
|
294
|
-
needs.profile.outputs.python_requirements != '["none"]' }}
|
|
295
|
-
runs-on: ${{ inputs.runner }}
|
|
296
|
-
timeout-minutes: 5
|
|
297
|
-
steps:
|
|
298
|
-
- name: Gate
|
|
299
|
-
env:
|
|
300
|
-
PROFILE_RESULT: ${{ needs.profile.result }}
|
|
301
|
-
AUDIT_RESULT: ${{ needs.dependency-audit-python.result }}
|
|
302
|
-
run: |
|
|
303
|
-
if [ "$PROFILE_RESULT" != success ]; then
|
|
304
|
-
echo "Python audit profile failed: $PROFILE_RESULT" >&2
|
|
305
|
-
exit 1
|
|
306
|
-
fi
|
|
307
|
-
case "$AUDIT_RESULT" in
|
|
308
|
-
success|skipped) exit 0 ;;
|
|
309
|
-
*) echo "Python dependency audit failed: $AUDIT_RESULT" >&2; exit 1 ;;
|
|
310
|
-
esac
|
|
311
|
-
|
|
312
279
|
dependency-review:
|
|
313
280
|
name: Dependency Review
|
|
314
281
|
needs: profile
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.1](https://github.com/0xPlayerOne/code-foundry/compare/v1.1.0...v1.1.1) (2026-09-06)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* keep a static check name for the Rust CodeQL job ([#462](https://github.com/0xPlayerOne/code-foundry/issues/462)) ([c8c4a36](https://github.com/0xPlayerOne/code-foundry/commit/c8c4a364a7f77e404159fbe7c08ee695f78c8b61))
|
|
9
|
+
|
|
10
|
+
## [1.1.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.0.6...v1.1.0) (2026-09-06)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* scope per-language checks to detected languages via matrix ([#459](https://github.com/0xPlayerOne/code-foundry/issues/459)) ([71f8985](https://github.com/0xPlayerOne/code-foundry/commit/71f8985b9732d39b7b68df40a4c8cbe5a90175fe))
|
|
16
|
+
|
|
3
17
|
## [1.0.6](https://github.com/0xPlayerOne/code-foundry/compare/v1.0.5...v1.0.6) (2026-09-06)
|
|
4
18
|
|
|
5
19
|
|
package/docs/WORKFLOWS.md
CHANGED
|
@@ -82,8 +82,13 @@ honor the shared billing pause.
|
|
|
82
82
|
| Release | Release Please, GitHub release, and optional npm publication |
|
|
83
83
|
|
|
84
84
|
Use concise job names such as `CI / Format`, `Test / Unit`, and
|
|
85
|
-
`CodeQL / Analyze (Python)`.
|
|
86
|
-
|
|
85
|
+
`CodeQL / Analyze (Python)`. Per-language CodeQL analyzers and security
|
|
86
|
+
audits run through a detection-built matrix, so a repository only ever shows
|
|
87
|
+
checks for languages it actually uses; inapplicable languages produce no
|
|
88
|
+
checks instead of skipped rows. Required checks should match the jobs
|
|
89
|
+
actually enabled for the repository profile — in practice, require only the
|
|
90
|
+
aggregate `Validation / Gate`, which fails closed unless every generated
|
|
91
|
+
check succeeds.
|
|
87
92
|
|
|
88
93
|
## Merge methods
|
|
89
94
|
|
|
@@ -178,9 +183,13 @@ validation gate. Land changes through the standard `direct` or
|
|
|
178
183
|
- Solidity: preserve the repository's native Hardhat, Foundry, or specialized
|
|
179
184
|
test/security workflows.
|
|
180
185
|
|
|
181
|
-
Jobs detect applicability before installing tools.
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
Jobs detect applicability before installing tools. Per-language CodeQL and
|
|
187
|
+
security-audit jobs are generated from detection, so empty language surfaces
|
|
188
|
+
produce no checks at all instead of skipped rows; the aggregate
|
|
189
|
+
`Validation / Gate` keeps branch protection unambiguous for mixed-language
|
|
190
|
+
repositories by failing closed unless every generated check succeeds. An
|
|
191
|
+
empty analysis matrix while analysis is enabled fails the build instead of
|
|
192
|
+
silently skipping every analyzer.
|
|
184
193
|
|
|
185
194
|
## Security behavior
|
|
186
195
|
|
package/package.json
CHANGED