code-foundry 0.1.4
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/.editorconfig +18 -0
- package/.env.example +3 -0
- package/.gitattributes +9 -0
- package/.githooks/pre-commit +67 -0
- package/.github/CODEOWNERS +4 -0
- package/.github/CODE_OF_CONDUCT.md +41 -0
- package/.github/CONTRIBUTING.md +198 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +56 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +29 -0
- package/.github/SECURITY.md +23 -0
- package/.github/actions/cache/action.yml +43 -0
- package/.github/actions/codeql/action.yml +29 -0
- package/.github/actions/setup/action.yml +776 -0
- package/.github/dependabot.yml +42 -0
- package/.github/scripts/bootstrap.sh +20 -0
- package/.github/scripts/changed-files.sh +96 -0
- package/.github/scripts/ci.sh +636 -0
- package/.github/scripts/codeql-languages.sh +86 -0
- package/.github/scripts/doctor.sh +103 -0
- package/.github/scripts/format-fast-path.sh +80 -0
- package/.github/scripts/init-repo.sh +134 -0
- package/.github/scripts/security.sh +209 -0
- package/.github/scripts/sitecustomize.py +17 -0
- package/.github/scripts/sync-codeowners.sh +76 -0
- package/.github/scripts/sync-protection.sh +137 -0
- package/.github/scripts/sync-template.sh +432 -0
- package/.github/scripts/turbo-cache-probe.sh +102 -0
- package/.github/template.yml +7 -0
- package/.github/template.yml.example +8 -0
- package/.github/workflows/ci.yml +166 -0
- package/.github/workflows/codeql.yml +160 -0
- package/.github/workflows/draft-pr.yml +59 -0
- package/.github/workflows/release-pr.yml +66 -0
- package/.github/workflows/release.yml +103 -0
- package/.github/workflows/security.yml +228 -0
- package/.github/workflows/test.yml +175 -0
- package/.gitignore +77 -0
- package/.mise.toml +6 -0
- package/.prettierrc +6 -0
- package/AGENTS.md +155 -0
- package/CHANGELOG.md +3 -0
- package/LICENSE +616 -0
- package/NOTICE +7 -0
- package/README.md +172 -0
- package/package.json +44 -0
- package/release-please-config.json +16 -0
- package/ruff.toml +6 -0
- package/src/cli.mjs +137 -0
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
name: Repository Setup
|
|
2
|
+
description: Install the pinned mise toolchain and optionally project dependencies.
|
|
3
|
+
|
|
4
|
+
inputs:
|
|
5
|
+
install:
|
|
6
|
+
description: Install dependencies for the detected project ecosystems.
|
|
7
|
+
required: false
|
|
8
|
+
default: 'false'
|
|
9
|
+
install-javascript:
|
|
10
|
+
description: Install JavaScript/TypeScript package dependencies when install is enabled.
|
|
11
|
+
required: false
|
|
12
|
+
default: 'true'
|
|
13
|
+
install-python:
|
|
14
|
+
description: Install Python project dependencies when install is enabled.
|
|
15
|
+
required: false
|
|
16
|
+
default: 'true'
|
|
17
|
+
install-rust:
|
|
18
|
+
description: Fetch Rust project dependencies when install is enabled.
|
|
19
|
+
required: false
|
|
20
|
+
default: 'true'
|
|
21
|
+
mise-scope:
|
|
22
|
+
description: Limit mise installation and language package caches to auto, all, javascript, python, or rust.
|
|
23
|
+
required: false
|
|
24
|
+
default: auto
|
|
25
|
+
cache-build:
|
|
26
|
+
description: Restore JavaScript framework, Rust dependency, and incremental compiler caches.
|
|
27
|
+
required: false
|
|
28
|
+
default: 'true'
|
|
29
|
+
cache-environment:
|
|
30
|
+
description: Restore materialized Python virtual environments; disable for parallel test jobs with large environments.
|
|
31
|
+
required: false
|
|
32
|
+
default: 'true'
|
|
33
|
+
cache-installed:
|
|
34
|
+
description: Cache materialized JavaScript dependencies; auto skips large Bun node_modules trees and keeps compact link-based installs.
|
|
35
|
+
required: false
|
|
36
|
+
default: auto
|
|
37
|
+
cache-save:
|
|
38
|
+
description: Save restored caches after the job completes; disable to avoid post-job archive work in parallel jobs.
|
|
39
|
+
required: false
|
|
40
|
+
default: 'true'
|
|
41
|
+
cache-packages:
|
|
42
|
+
description: Restore JavaScript package-manager caches; auto skips large Bun lockfiles, or use true/false to override.
|
|
43
|
+
required: false
|
|
44
|
+
default: auto
|
|
45
|
+
cache-lint:
|
|
46
|
+
description: Restore the JavaScript/TypeScript lint cache.
|
|
47
|
+
required: false
|
|
48
|
+
default: 'false'
|
|
49
|
+
cache-format:
|
|
50
|
+
description: Restore the Prettier format cache.
|
|
51
|
+
required: false
|
|
52
|
+
default: 'false'
|
|
53
|
+
cache-turbo:
|
|
54
|
+
description: Cache local Turborepo artifacts; auto skips duplicate archives when TURBO_TOKEN enables remote caching.
|
|
55
|
+
required: false
|
|
56
|
+
default: auto
|
|
57
|
+
task:
|
|
58
|
+
description: Optional CI task used to scope test dependency installation.
|
|
59
|
+
required: false
|
|
60
|
+
default: ''
|
|
61
|
+
task-javascript:
|
|
62
|
+
description: Whether the selected task has a JavaScript suite; auto preserves default detection.
|
|
63
|
+
required: false
|
|
64
|
+
default: auto
|
|
65
|
+
task-python:
|
|
66
|
+
description: Whether the selected task has a Python suite; auto preserves default detection.
|
|
67
|
+
required: false
|
|
68
|
+
default: auto
|
|
69
|
+
task-rust:
|
|
70
|
+
description: Whether the selected task has a Rust suite; auto preserves default detection.
|
|
71
|
+
required: false
|
|
72
|
+
default: auto
|
|
73
|
+
|
|
74
|
+
runs:
|
|
75
|
+
using: composite
|
|
76
|
+
steps:
|
|
77
|
+
- name: Disable framework telemetry
|
|
78
|
+
shell: bash
|
|
79
|
+
run: |
|
|
80
|
+
echo 'TURBO_TELEMETRY_DISABLED=1' >> "$GITHUB_ENV"
|
|
81
|
+
echo 'NEXT_TELEMETRY_DISABLED=1' >> "$GITHUB_ENV"
|
|
82
|
+
- name: Detect project profile
|
|
83
|
+
id: profile
|
|
84
|
+
shell: bash
|
|
85
|
+
run: |
|
|
86
|
+
tracked_files="$(git ls-files)"
|
|
87
|
+
|
|
88
|
+
has_tracked_regex() {
|
|
89
|
+
printf '%s\n' "$tracked_files" | grep -Eq "$1"
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
has_python_source() {
|
|
93
|
+
awk '!/^\.github\// && /(^|\/)[^\/]+\.py$/ { found=1; exit } END { exit !found }' <<< "$tracked_files"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
has_package_script() {
|
|
97
|
+
[ -f package.json ] || return 1
|
|
98
|
+
node - "$1" <<'NODE'
|
|
99
|
+
const fs = require('node:fs');
|
|
100
|
+
const script = process.argv[2];
|
|
101
|
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
102
|
+
process.exit(packageJson.scripts?.[script] ? 0 : 1);
|
|
103
|
+
NODE
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
script_uses_turbo() {
|
|
107
|
+
[ -f package.json ] || return 1
|
|
108
|
+
REPO_FOUNDRY_TURBO_TASK="$REPO_FOUNDRY_TASK" node <<'NODE'
|
|
109
|
+
const fs = require('node:fs');
|
|
110
|
+
const task = process.env.REPO_FOUNDRY_TURBO_TASK || '';
|
|
111
|
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
112
|
+
const scripts = packageJson.scripts || {};
|
|
113
|
+
const candidates = {
|
|
114
|
+
format: ['format:check', 'format', 'fmt'],
|
|
115
|
+
lint: ['lint'],
|
|
116
|
+
type_check: ['type-check', 'typecheck', 'type:check'],
|
|
117
|
+
build: ['build'],
|
|
118
|
+
unit: ['test:unit', 'test:coverage', 'test'],
|
|
119
|
+
integration: ['test:integration'],
|
|
120
|
+
e2e: ['test:e2e', 'e2e'],
|
|
121
|
+
smoke: ['test:smoke', 'smoke'],
|
|
122
|
+
}[task] || [];
|
|
123
|
+
const selected = candidates.find((name) => scripts[name]);
|
|
124
|
+
const usesTurbo = Boolean(selected && /\bturbo(?:\s|$)/.test(scripts[selected]));
|
|
125
|
+
process.exit(usesTurbo ? 0 : 1);
|
|
126
|
+
NODE
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
uses_prettier() {
|
|
130
|
+
[ -f package.json ] || return 0
|
|
131
|
+
node <<'NODE'
|
|
132
|
+
const fs = require('node:fs');
|
|
133
|
+
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
134
|
+
const scripts = p.scripts || {};
|
|
135
|
+
const dependencies = {
|
|
136
|
+
...p.dependencies,
|
|
137
|
+
...p.devDependencies,
|
|
138
|
+
...p.optionalDependencies,
|
|
139
|
+
...p.peerDependencies,
|
|
140
|
+
};
|
|
141
|
+
const usesPrettier = Boolean(dependencies.prettier) || Object.values(scripts).some((value) => /\bprettier\b/.test(value));
|
|
142
|
+
const hasFormatScript = Boolean(scripts['format:check'] || scripts.format || scripts.fmt);
|
|
143
|
+
process.exit(usesPrettier || !hasFormatScript ? 0 : 1);
|
|
144
|
+
NODE
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
uses_eslint() {
|
|
148
|
+
[ -f package.json ] || return 1
|
|
149
|
+
node <<'NODE'
|
|
150
|
+
const fs = require('node:fs');
|
|
151
|
+
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
152
|
+
const scripts = p.scripts || {};
|
|
153
|
+
const dependencies = {
|
|
154
|
+
...p.dependencies,
|
|
155
|
+
...p.devDependencies,
|
|
156
|
+
...p.optionalDependencies,
|
|
157
|
+
...p.peerDependencies,
|
|
158
|
+
};
|
|
159
|
+
const usesEslint = Boolean(dependencies.eslint) || Object.values(scripts).some((value) => /\beslint\b/.test(value));
|
|
160
|
+
process.exit(usesEslint ? 0 : 1);
|
|
161
|
+
NODE
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
javascript=false
|
|
165
|
+
if [ -f package.json ] || [ -f bun.lock ] || [ -f bun.lockb ] ||
|
|
166
|
+
[ -f pnpm-lock.yaml ] || [ -f yarn.lock ] || [ -f package-lock.json ] ||
|
|
167
|
+
has_tracked_regex '(^|/)[^/]+\.(js|jsx|mjs|cjs|ts|tsx|mts|cts)$'; then
|
|
168
|
+
javascript=true
|
|
169
|
+
echo 'javascript=true' >> "$GITHUB_OUTPUT"
|
|
170
|
+
else
|
|
171
|
+
echo 'javascript=false' >> "$GITHUB_OUTPUT"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if [ -f bun.lock ] || [ -f bun.lockb ] || [ -f pnpm-lock.yaml ] ||
|
|
175
|
+
[ -f yarn.lock ] || [ -f package-lock.json ]; then
|
|
176
|
+
javascript_dependencies=true
|
|
177
|
+
echo 'javascript_dependencies=true' >> "$GITHUB_OUTPUT"
|
|
178
|
+
elif [ -f package.json ] && REPO_FOUNDRY_PACKAGE_FILES="$tracked_files" node <<'NODE'
|
|
179
|
+
const fs = require('node:fs');
|
|
180
|
+
|
|
181
|
+
const files = (process.env.REPO_FOUNDRY_PACKAGE_FILES || '')
|
|
182
|
+
.trim()
|
|
183
|
+
.split('\n')
|
|
184
|
+
.filter((file) => /(^|\/)package\.json$/.test(file));
|
|
185
|
+
const groups = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
|
|
186
|
+
const hasDependencies = files.some((file) => {
|
|
187
|
+
try {
|
|
188
|
+
const packageJson = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
189
|
+
return groups.some((group) => packageJson[group] && Object.keys(packageJson[group]).length > 0) ||
|
|
190
|
+
Array.isArray(packageJson.workspaces) ||
|
|
191
|
+
(packageJson.workspaces && typeof packageJson.workspaces === 'object');
|
|
192
|
+
} catch {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
process.exit(hasDependencies ? 0 : 1);
|
|
197
|
+
NODE
|
|
198
|
+
then
|
|
199
|
+
javascript_dependencies=true
|
|
200
|
+
echo 'javascript_dependencies=true' >> "$GITHUB_OUTPUT"
|
|
201
|
+
else
|
|
202
|
+
javascript_dependencies=false
|
|
203
|
+
echo 'javascript_dependencies=false' >> "$GITHUB_OUTPUT"
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
javascript_package_manager=none
|
|
207
|
+
configured_package_manager=""
|
|
208
|
+
if [ -f .github/template.yml ]; then
|
|
209
|
+
configured_package_manager="$(awk -F': ' '/^package_manager:/ {print $2; exit}' .github/template.yml)"
|
|
210
|
+
fi
|
|
211
|
+
case "$configured_package_manager" in
|
|
212
|
+
bun|pnpm|yarn|npm) javascript_package_manager="$configured_package_manager" ;;
|
|
213
|
+
*)
|
|
214
|
+
if [ -f bun.lock ] || [ -f bun.lockb ]; then javascript_package_manager=bun
|
|
215
|
+
elif [ -f pnpm-lock.yaml ]; then javascript_package_manager=pnpm
|
|
216
|
+
elif [ -f yarn.lock ]; then javascript_package_manager=yarn
|
|
217
|
+
elif [ -f package-lock.json ]; then javascript_package_manager=npm
|
|
218
|
+
elif [ "$javascript_dependencies" = true ]; then javascript_package_manager=bun
|
|
219
|
+
fi
|
|
220
|
+
;;
|
|
221
|
+
esac
|
|
222
|
+
printf 'javascript_package_manager=%s\n' "$javascript_package_manager" >> "$GITHUB_OUTPUT"
|
|
223
|
+
|
|
224
|
+
javascript_packages_cache=true
|
|
225
|
+
case "$REPO_FOUNDRY_CACHE_PACKAGES" in
|
|
226
|
+
false) javascript_packages_cache=false ;;
|
|
227
|
+
true) : ;;
|
|
228
|
+
auto)
|
|
229
|
+
# Large Bun stores can take longer to transfer and extract than a
|
|
230
|
+
# clean registry install. Keep normal projects cached, but avoid
|
|
231
|
+
# the expensive archive for workspace graphs and once the tracked
|
|
232
|
+
# Bun lockfiles exceed 512 KiB in total. Workspace installs often
|
|
233
|
+
# resolve quickly from the registry, while their shared Bun store
|
|
234
|
+
# is expensive to archive. Set REPO_FOUNDRY_CACHE_PACKAGES=true
|
|
235
|
+
# when a repository has measured a cache win.
|
|
236
|
+
if [ "$javascript_package_manager" = bun ]; then
|
|
237
|
+
bun_workspace=false
|
|
238
|
+
if [ -f package.json ] && node -e '
|
|
239
|
+
const p = require("./package.json");
|
|
240
|
+
const workspaces = p.workspaces;
|
|
241
|
+
process.exit(
|
|
242
|
+
Array.isArray(workspaces) ||
|
|
243
|
+
Boolean(workspaces && typeof workspaces === "object") ? 0 : 1,
|
|
244
|
+
);
|
|
245
|
+
' 2>/dev/null; then
|
|
246
|
+
bun_workspace=true
|
|
247
|
+
fi
|
|
248
|
+
bun_lock_bytes=0
|
|
249
|
+
while IFS= read -r lockfile; do
|
|
250
|
+
[ -f "$lockfile" ] || continue
|
|
251
|
+
lock_bytes="$(wc -c < "$lockfile")"
|
|
252
|
+
bun_lock_bytes=$((bun_lock_bytes + lock_bytes))
|
|
253
|
+
done < <(printf '%s\n' "$tracked_files" | awk '/(^|\/)bun\.lock(b)?$/')
|
|
254
|
+
if [ "$bun_workspace" = true ] || [ "$bun_lock_bytes" -gt 524288 ]; then
|
|
255
|
+
javascript_packages_cache=false
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
;;
|
|
259
|
+
*) echo "Unsupported cache-packages value: $REPO_FOUNDRY_CACHE_PACKAGES" >&2; exit 2 ;;
|
|
260
|
+
esac
|
|
261
|
+
printf 'javascript_packages_cache=%s\n' "$javascript_packages_cache" >> "$GITHUB_OUTPUT"
|
|
262
|
+
|
|
263
|
+
python=false
|
|
264
|
+
if has_python_source || [ -f pyproject.toml ] ||
|
|
265
|
+
[ -f requirements.txt ] || [ -f requirements-dev.txt ]; then
|
|
266
|
+
python=true
|
|
267
|
+
echo 'python=true' >> "$GITHUB_OUTPUT"
|
|
268
|
+
else
|
|
269
|
+
echo 'python=false' >> "$GITHUB_OUTPUT"
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
rust=false
|
|
273
|
+
if [ -f Cargo.toml ] || [ -f Cargo.lock ]; then
|
|
274
|
+
rust=true
|
|
275
|
+
echo 'rust=true' >> "$GITHUB_OUTPUT"
|
|
276
|
+
else
|
|
277
|
+
echo 'rust=false' >> "$GITHUB_OUTPUT"
|
|
278
|
+
fi
|
|
279
|
+
|
|
280
|
+
turbo=false
|
|
281
|
+
if [ -f turbo.json ] || [ -f turbo.jsonc ] || has_tracked_regex '(^|/)turbo\.jsonc?$'; then
|
|
282
|
+
turbo=true
|
|
283
|
+
echo 'turbo=true' >> "$GITHUB_OUTPUT"
|
|
284
|
+
else
|
|
285
|
+
echo 'turbo=false' >> "$GITHUB_OUTPUT"
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
eslint=false
|
|
289
|
+
if [ -f .eslintrc ] || [ -f .eslintrc.js ] || [ -f .eslintrc.cjs ] ||
|
|
290
|
+
[ -f .eslintrc.json ] || has_tracked_regex '(^|/)(\.eslintrc[^/]*|eslint\.config\.[^/]*)$' ||
|
|
291
|
+
uses_eslint; then
|
|
292
|
+
eslint=true
|
|
293
|
+
echo 'eslint=true' >> "$GITHUB_OUTPUT"
|
|
294
|
+
else
|
|
295
|
+
echo 'eslint=false' >> "$GITHUB_OUTPUT"
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
prettier=false
|
|
299
|
+
if [ "$javascript" = true ]; then
|
|
300
|
+
# Cache the fallback formatter for projects without a dedicated
|
|
301
|
+
# config, but avoid probing an empty cache when a repository-owned
|
|
302
|
+
# format script does not use Prettier.
|
|
303
|
+
if uses_prettier; then
|
|
304
|
+
prettier=true
|
|
305
|
+
fi
|
|
306
|
+
fi
|
|
307
|
+
printf 'prettier=%s\n' "$prettier" >> "$GITHUB_OUTPUT"
|
|
308
|
+
|
|
309
|
+
# Repository-owned format/lint scripts are authoritative and commonly
|
|
310
|
+
# do not create the generic tool caches. Avoid recursive cache-path
|
|
311
|
+
# scans and post-job archive work unless the fallback runner is used.
|
|
312
|
+
prettier_fallback=false
|
|
313
|
+
if [ "$prettier" = true ] && ! has_package_script format:check; then
|
|
314
|
+
prettier_fallback=true
|
|
315
|
+
fi
|
|
316
|
+
eslint_fallback=false
|
|
317
|
+
if [ "$eslint" = true ] && ! has_package_script lint; then
|
|
318
|
+
eslint_fallback=true
|
|
319
|
+
fi
|
|
320
|
+
printf 'prettier_fallback=%s\n' "$prettier_fallback" >> "$GITHUB_OUTPUT"
|
|
321
|
+
printf 'eslint_fallback=%s\n' "$eslint_fallback" >> "$GITHUB_OUTPUT"
|
|
322
|
+
|
|
323
|
+
turbo_task=false
|
|
324
|
+
if [ -z "$REPO_FOUNDRY_TASK" ] || script_uses_turbo; then
|
|
325
|
+
turbo_task=true
|
|
326
|
+
fi
|
|
327
|
+
printf 'turbo_task=%s\n' "$turbo_task" >> "$GITHUB_OUTPUT"
|
|
328
|
+
|
|
329
|
+
build=false
|
|
330
|
+
if has_tracked_regex '(^|/)(next\.config\.[^/]*|vite\.config\.[^/]*|tsconfig[^/]*\.json)$'; then
|
|
331
|
+
build=true
|
|
332
|
+
echo 'build=true' >> "$GITHUB_OUTPUT"
|
|
333
|
+
else
|
|
334
|
+
echo 'build=false' >> "$GITHUB_OUTPUT"
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
python_dependencies=false
|
|
338
|
+
if [ -f pyproject.toml ] || [ -f uv.lock ] ||
|
|
339
|
+
has_tracked_regex '(^|/)requirements[^/]*\.txt$' ||
|
|
340
|
+
[ -f Pipfile.lock ] || [ -f poetry.lock ]; then
|
|
341
|
+
python_dependencies=true
|
|
342
|
+
echo 'python_dependencies=true' >> "$GITHUB_OUTPUT"
|
|
343
|
+
else
|
|
344
|
+
echo 'python_dependencies=false' >> "$GITHUB_OUTPUT"
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
configured_tool() {
|
|
348
|
+
[ -f .mise.toml ] && grep -Eq "^$1[[:space:]]*=" .mise.toml
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
ruff=false
|
|
352
|
+
if [ "$python" = true ] &&
|
|
353
|
+
{ [ -f ruff.toml ] || configured_tool ruff ||
|
|
354
|
+
{ [ -f pyproject.toml ] && grep -Eiq 'ruff|\[tool\.ruff' pyproject.toml; } ||
|
|
355
|
+
{ [ -f requirements.txt ] && grep -Eiq '(^|[-_.])ruff([<>=[:space:]]|$)' requirements.txt; } ||
|
|
356
|
+
{ [ -f requirements-dev.txt ] && grep -Eiq '(^|[-_.])ruff([<>=[:space:]]|$)' requirements-dev.txt; }; }; then
|
|
357
|
+
ruff=true
|
|
358
|
+
fi
|
|
359
|
+
printf 'ruff=%s\n' "$ruff" >> "$GITHUB_OUTPUT"
|
|
360
|
+
|
|
361
|
+
mise_tools=()
|
|
362
|
+
add_configured_tool() {
|
|
363
|
+
# Optional tools are expected to be absent in single-language repos.
|
|
364
|
+
# Keep that a successful probe so Bash strict mode does not abort
|
|
365
|
+
# profile detection before the actual setup step runs.
|
|
366
|
+
if configured_tool "$1"; then
|
|
367
|
+
mise_tools+=("$1")
|
|
368
|
+
fi
|
|
369
|
+
return 0
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
case "$REPO_FOUNDRY_MISE_SCOPE" in
|
|
373
|
+
all)
|
|
374
|
+
for tool in node bun python uv ruff rust; do add_configured_tool "$tool"; done
|
|
375
|
+
;;
|
|
376
|
+
auto)
|
|
377
|
+
task_language_needed() {
|
|
378
|
+
local language="$1" flag
|
|
379
|
+
case "$language" in
|
|
380
|
+
javascript) flag="$REPO_FOUNDRY_TASK_JAVASCRIPT" ;;
|
|
381
|
+
python) flag="$REPO_FOUNDRY_TASK_PYTHON" ;;
|
|
382
|
+
rust) flag="$REPO_FOUNDRY_TASK_RUST" ;;
|
|
383
|
+
*) return 0 ;;
|
|
384
|
+
esac
|
|
385
|
+
[ -z "$REPO_FOUNDRY_TASK" ] || [ "$flag" = auto ] || [ "$flag" = true ]
|
|
386
|
+
}
|
|
387
|
+
if [ "$javascript" = true ] && task_language_needed javascript; then
|
|
388
|
+
add_configured_tool node
|
|
389
|
+
if { [ -f bun.lock ] || [ -f bun.lockb ] ||
|
|
390
|
+
awk -F': ' '/^package_manager:/ {print $2; exit}' .github/template.yml 2>/dev/null | grep -qx bun; }; then
|
|
391
|
+
add_configured_tool bun
|
|
392
|
+
fi
|
|
393
|
+
fi
|
|
394
|
+
if [ "$python" = true ] && task_language_needed python; then
|
|
395
|
+
add_configured_tool python
|
|
396
|
+
add_configured_tool uv
|
|
397
|
+
add_configured_tool ruff
|
|
398
|
+
fi
|
|
399
|
+
if [ "$rust" = true ] && task_language_needed rust; then add_configured_tool rust; fi
|
|
400
|
+
;;
|
|
401
|
+
javascript)
|
|
402
|
+
configured_tool node && mise_tools+=(node)
|
|
403
|
+
if { [ -f bun.lock ] || [ -f bun.lockb ] ||
|
|
404
|
+
awk -F': ' '/^package_manager:/ {print $2; exit}' .github/template.yml 2>/dev/null | grep -qx bun; } && configured_tool bun; then
|
|
405
|
+
mise_tools+=(bun)
|
|
406
|
+
fi
|
|
407
|
+
;;
|
|
408
|
+
python)
|
|
409
|
+
configured_tool python && mise_tools+=(python)
|
|
410
|
+
configured_tool uv && mise_tools+=(uv)
|
|
411
|
+
configured_tool ruff && mise_tools+=(ruff)
|
|
412
|
+
;;
|
|
413
|
+
rust) configured_tool rust && mise_tools+=(rust) ;;
|
|
414
|
+
*) echo "Unsupported mise-scope: $REPO_FOUNDRY_MISE_SCOPE" >&2; exit 2 ;;
|
|
415
|
+
esac
|
|
416
|
+
printf 'mise_tools=%s\n' "${mise_tools[*]}" >> "$GITHUB_OUTPUT"
|
|
417
|
+
if [ "${#mise_tools[@]}" -gt 0 ]; then
|
|
418
|
+
printf 'mise_required=true\n' >> "$GITHUB_OUTPUT"
|
|
419
|
+
else
|
|
420
|
+
printf 'mise_required=false\n' >> "$GITHUB_OUTPUT"
|
|
421
|
+
fi
|
|
422
|
+
env:
|
|
423
|
+
REPO_FOUNDRY_MISE_SCOPE: ${{ inputs.mise-scope }}
|
|
424
|
+
REPO_FOUNDRY_TASK: ${{ inputs.task }}
|
|
425
|
+
REPO_FOUNDRY_TASK_JAVASCRIPT: ${{ inputs.task-javascript }}
|
|
426
|
+
REPO_FOUNDRY_TASK_PYTHON: ${{ inputs.task-python }}
|
|
427
|
+
REPO_FOUNDRY_TASK_RUST: ${{ inputs.task-rust }}
|
|
428
|
+
REPO_FOUNDRY_CACHE_PACKAGES: ${{ inputs.cache-packages }}
|
|
429
|
+
|
|
430
|
+
- name: Setup uv
|
|
431
|
+
if: >-
|
|
432
|
+
steps.profile.outputs.python == 'true' &&
|
|
433
|
+
(inputs.mise-scope == 'python' ||
|
|
434
|
+
(inputs.install == 'true' && inputs.install-python == 'true')) &&
|
|
435
|
+
!contains(steps.profile.outputs.mise_tools, 'uv')
|
|
436
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
437
|
+
with:
|
|
438
|
+
version: 0.11.32
|
|
439
|
+
enable-cache: false
|
|
440
|
+
|
|
441
|
+
- name: Cache installed JavaScript dependencies
|
|
442
|
+
id: javascript-dependencies
|
|
443
|
+
if: >-
|
|
444
|
+
inputs.install == 'true' &&
|
|
445
|
+
inputs.install-javascript == 'true' &&
|
|
446
|
+
inputs.cache-installed != 'false' &&
|
|
447
|
+
steps.profile.outputs.javascript_dependencies == 'true' &&
|
|
448
|
+
steps.profile.outputs.javascript_package_manager != 'npm' &&
|
|
449
|
+
(inputs.cache-installed == 'true' ||
|
|
450
|
+
steps.profile.outputs.javascript_package_manager == 'pnpm' ||
|
|
451
|
+
steps.profile.outputs.javascript_package_manager == 'yarn') &&
|
|
452
|
+
hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.npmrc', '**/.yarnrc*', '**/.pnpmfile.cjs', '.github/template.yml', '.mise.toml', 'mise.lock') != ''
|
|
453
|
+
uses: actions/cache/restore@v5
|
|
454
|
+
with:
|
|
455
|
+
path: |
|
|
456
|
+
**/node_modules
|
|
457
|
+
key: ${{ runner.os }}-javascript-installed-v3-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.npmrc', '**/.yarnrc*', '**/.pnpmfile.cjs', '.github/template.yml', '.mise.toml', 'mise.lock') }}
|
|
458
|
+
- name: Restore Bun dependencies
|
|
459
|
+
id: javascript-bun-cache-restore
|
|
460
|
+
if: >-
|
|
461
|
+
inputs.install == 'true' &&
|
|
462
|
+
inputs.install-javascript == 'true' &&
|
|
463
|
+
inputs.cache-installed != 'false' &&
|
|
464
|
+
steps.profile.outputs.javascript_dependencies == 'true' &&
|
|
465
|
+
steps.profile.outputs.javascript_package_manager == 'bun' &&
|
|
466
|
+
hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/.npmrc', '.github/template.yml', '.mise.toml', 'mise.lock') != ''
|
|
467
|
+
uses: actions/cache/restore@v5
|
|
468
|
+
with:
|
|
469
|
+
path: |
|
|
470
|
+
**/node_modules
|
|
471
|
+
key: ${{ runner.os }}-javascript-installed-v4-bun-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/.npmrc', '.github/template.yml', '.mise.toml', 'mise.lock') }}
|
|
472
|
+
- name: Detect Bun dependencies
|
|
473
|
+
id: javascript-bun-dependencies
|
|
474
|
+
if: >-
|
|
475
|
+
inputs.install == 'true' &&
|
|
476
|
+
inputs.install-javascript == 'true' &&
|
|
477
|
+
inputs.cache-installed != 'false' &&
|
|
478
|
+
steps.profile.outputs.javascript_dependencies == 'true' &&
|
|
479
|
+
steps.profile.outputs.javascript_package_manager == 'bun'
|
|
480
|
+
shell: bash
|
|
481
|
+
run: |
|
|
482
|
+
if find . -path './.git' -prune -o -type d -name node_modules -print -quit | grep -q .; then
|
|
483
|
+
echo 'restored=true' >> "$GITHUB_OUTPUT"
|
|
484
|
+
else
|
|
485
|
+
echo 'restored=false' >> "$GITHUB_OUTPUT"
|
|
486
|
+
fi
|
|
487
|
+
- name: Cache Corepack managers
|
|
488
|
+
if: (inputs.mise-scope == 'javascript' || steps.javascript-dependencies.outputs.cache-hit == 'true') && inputs.install-javascript == 'true' && steps.profile.outputs.javascript == 'true' && hashFiles('**/pnpm-lock.yaml', '**/yarn.lock') != ''
|
|
489
|
+
uses: ./.github/actions/cache
|
|
490
|
+
with:
|
|
491
|
+
save: ${{ inputs.cache-save }}
|
|
492
|
+
path: ~/.cache/node/corepack
|
|
493
|
+
# Corepack shims are independent of the project toolchain; keep this
|
|
494
|
+
# cache warm when Node, Bun, or other mise-managed tools change.
|
|
495
|
+
key: ${{ runner.os }}-corepack-${{ hashFiles('**/package.json', '**/pnpm-lock.yaml', '**/yarn.lock') }}
|
|
496
|
+
restore-keys: |
|
|
497
|
+
${{ runner.os }}-corepack-
|
|
498
|
+
- name: Cache JavaScript packages
|
|
499
|
+
id: javascript-packages
|
|
500
|
+
if: inputs.install == 'true' && inputs.install-javascript == 'true' && steps.profile.outputs.javascript_packages_cache == 'true' && steps.profile.outputs.javascript == 'true' && hashFiles('**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json') != '' && steps.javascript-dependencies.outputs.cache-hit != 'true' && steps.javascript-bun-dependencies.outputs.restored != 'true'
|
|
501
|
+
uses: actions/cache/restore@v5
|
|
502
|
+
with:
|
|
503
|
+
path: |
|
|
504
|
+
~/.bun/install/cache
|
|
505
|
+
~/.cache/node/corepack
|
|
506
|
+
~/.npm
|
|
507
|
+
~/.cache/yarn
|
|
508
|
+
~/.local/share/pnpm/store
|
|
509
|
+
key: ${{ runner.os }}-javascript-${{ hashFiles('**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json') }}
|
|
510
|
+
restore-keys: |
|
|
511
|
+
${{ runner.os }}-javascript-
|
|
512
|
+
- name: Cache JavaScript lint state
|
|
513
|
+
# Fallback ESLint mode is valid without a dedicated config file; use the
|
|
514
|
+
# manifest/lockfile as the cache identity in that case as well.
|
|
515
|
+
if: inputs.install == 'true' && inputs.cache-lint == 'true' && steps.profile.outputs.eslint_fallback == 'true' && hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.eslintrc*', '**/eslint.config.*') != ''
|
|
516
|
+
uses: ./.github/actions/cache
|
|
517
|
+
with:
|
|
518
|
+
save: ${{ inputs.cache-save }}
|
|
519
|
+
path: |
|
|
520
|
+
**/.eslintcache
|
|
521
|
+
key: ${{ runner.os }}-javascript-lint-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.eslintrc*', '**/eslint.config.*') }}
|
|
522
|
+
restore-keys: |
|
|
523
|
+
${{ runner.os }}-javascript-lint-${{ github.workflow }}-${{ github.job }}-
|
|
524
|
+
- name: Cache JavaScript format state
|
|
525
|
+
if: inputs.install == 'true' && inputs.cache-format == 'true' && steps.profile.outputs.prettier_fallback == 'true' && hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.prettierrc*', '**/prettier.config.*') != ''
|
|
526
|
+
uses: ./.github/actions/cache
|
|
527
|
+
with:
|
|
528
|
+
save: ${{ inputs.cache-save }}
|
|
529
|
+
path: |
|
|
530
|
+
**/node_modules/.cache/prettier
|
|
531
|
+
key: ${{ runner.os }}-javascript-format-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.prettierrc*', '**/prettier.config.*') }}
|
|
532
|
+
# Keep primary saves isolated so parallel jobs cannot race. A cache
|
|
533
|
+
# from another workflow job is still a valid warm fallback.
|
|
534
|
+
restore-keys: |
|
|
535
|
+
${{ runner.os }}-javascript-format-
|
|
536
|
+
- name: Cache JavaScript build state
|
|
537
|
+
if: >-
|
|
538
|
+
inputs.install == 'true' &&
|
|
539
|
+
inputs.cache-build == 'true' &&
|
|
540
|
+
(steps.profile.outputs.build == 'true' || inputs.task == 'build') &&
|
|
541
|
+
(inputs.task != 'type_check' ||
|
|
542
|
+
steps.profile.outputs.turbo != 'true' ||
|
|
543
|
+
steps.profile.outputs.turbo_task != 'true') &&
|
|
544
|
+
(env.TURBO_TOKEN == '' ||
|
|
545
|
+
env.TURBO_TEAM == '' ||
|
|
546
|
+
steps.profile.outputs.turbo != 'true' ||
|
|
547
|
+
steps.profile.outputs.turbo_task != 'true')
|
|
548
|
+
uses: ./.github/actions/cache
|
|
549
|
+
with:
|
|
550
|
+
save: ${{ inputs.cache-save }}
|
|
551
|
+
# Remote Turbo already stores task outputs for Turbo-backed builds.
|
|
552
|
+
# Avoid a second, often-empty framework cache archive in that mode;
|
|
553
|
+
# Turbo Type-Check tasks do not need framework build state either.
|
|
554
|
+
path: |
|
|
555
|
+
**/.next/cache
|
|
556
|
+
**/node_modules/.vite
|
|
557
|
+
**/*.tsbuildinfo
|
|
558
|
+
key: ${{ runner.os }}-javascript-build-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/next.config.*', '**/vite.config.*', '**/tsconfig*.json', '.mise.toml', 'mise.lock') }}
|
|
559
|
+
# Keep primary saves isolated so parallel jobs cannot race. A cache
|
|
560
|
+
# from another workflow job is still a valid warm fallback.
|
|
561
|
+
restore-keys: |
|
|
562
|
+
${{ runner.os }}-javascript-build-
|
|
563
|
+
- name: Cache Python environment
|
|
564
|
+
id: python-environment
|
|
565
|
+
if: inputs.install == 'true' && inputs.install-python == 'true' && inputs.cache-environment == 'true' && steps.profile.outputs.python == 'true' && hashFiles('**/pyproject.toml', '**/uv.lock', '**/requirements*.txt', '**/Pipfile.lock', '**/poetry.lock', '.mise.toml', 'mise.lock') != ''
|
|
566
|
+
uses: ./.github/actions/cache
|
|
567
|
+
with:
|
|
568
|
+
save: ${{ inputs.cache-save }}
|
|
569
|
+
path: |
|
|
570
|
+
.venv
|
|
571
|
+
**/.venv
|
|
572
|
+
key: ${{ runner.os }}-python-environment-${{ hashFiles('**/pyproject.toml', '**/uv.lock', '**/requirements*.txt', '**/Pipfile.lock', '**/poetry.lock', '.mise.toml', 'mise.lock') }}
|
|
573
|
+
- name: Cache Python packages
|
|
574
|
+
if: inputs.install == 'true' && (inputs.mise-scope == 'auto' || inputs.mise-scope == 'all' || inputs.mise-scope == 'python') && inputs.install-python == 'true' && steps.profile.outputs.python_dependencies == 'true' && hashFiles('**/pyproject.toml', '**/uv.lock', '**/requirements*.txt', '**/Pipfile.lock', '**/poetry.lock') != '' && steps.python-environment.outputs.cache-hit != 'true'
|
|
575
|
+
uses: ./.github/actions/cache
|
|
576
|
+
with:
|
|
577
|
+
save: ${{ inputs.cache-save }}
|
|
578
|
+
path: |
|
|
579
|
+
~/.cache/pip
|
|
580
|
+
~/.cache/uv
|
|
581
|
+
key: ${{ runner.os }}-python-${{ hashFiles('**/pyproject.toml', '**/uv.lock', '**/requirements*.txt', '**/Pipfile.lock', '**/poetry.lock') }}
|
|
582
|
+
restore-keys: |
|
|
583
|
+
${{ runner.os }}-python-
|
|
584
|
+
- name: Cache Python audit tools
|
|
585
|
+
id: python-audit-tools
|
|
586
|
+
if: inputs.install == 'false' && (inputs.mise-scope == 'auto' || inputs.mise-scope == 'all' || inputs.mise-scope == 'python') && inputs.install-python == 'true' && steps.profile.outputs.python_dependencies == 'true' && hashFiles('**/pyproject.toml', '**/uv.lock', '**/requirements*.txt', '**/Pipfile.lock', '**/poetry.lock') != ''
|
|
587
|
+
uses: ./.github/actions/cache
|
|
588
|
+
with:
|
|
589
|
+
save: ${{ inputs.cache-save }}
|
|
590
|
+
path: ~/.cache/uv-audit
|
|
591
|
+
# Keep scanner wheels and metadata warm across application and script
|
|
592
|
+
# changes. Bump v2 only when the pinned scanner version changes.
|
|
593
|
+
key: ${{ runner.os }}-python-audit-v2
|
|
594
|
+
restore-keys: |
|
|
595
|
+
${{ runner.os }}-python-audit-
|
|
596
|
+
- name: Enable offline Python audit
|
|
597
|
+
if: steps.python-audit-tools.outputs.cache-hit == 'true'
|
|
598
|
+
shell: bash
|
|
599
|
+
run: echo 'REPO_FOUNDRY_UV_AUDIT_OFFLINE=true' >> "$GITHUB_ENV"
|
|
600
|
+
- name: Cache Python lint state
|
|
601
|
+
if: inputs.install == 'true' && inputs.cache-lint == 'true' && steps.profile.outputs.ruff == 'true' && hashFiles('**/pyproject.toml', '**/ruff.toml', '.mise.toml', 'mise.lock') != ''
|
|
602
|
+
uses: ./.github/actions/cache
|
|
603
|
+
with:
|
|
604
|
+
save: ${{ inputs.cache-save }}
|
|
605
|
+
path: |
|
|
606
|
+
**/.ruff_cache
|
|
607
|
+
key: ${{ runner.os }}-python-lint-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/pyproject.toml', '**/ruff.toml', '.mise.toml', 'mise.lock') }}
|
|
608
|
+
# Primary saves remain job-specific; another job's Ruff cache is a
|
|
609
|
+
# useful warm fallback because Ruff validates entries by file state.
|
|
610
|
+
restore-keys: |
|
|
611
|
+
${{ runner.os }}-python-lint-${{ github.workflow }}-
|
|
612
|
+
- name: Cache Turborepo
|
|
613
|
+
if: >-
|
|
614
|
+
inputs.install == 'true' &&
|
|
615
|
+
inputs.install-javascript == 'true' &&
|
|
616
|
+
inputs.cache-turbo != 'false' &&
|
|
617
|
+
steps.profile.outputs.turbo == 'true' &&
|
|
618
|
+
steps.profile.outputs.turbo_task == 'true' &&
|
|
619
|
+
hashFiles('**/turbo.json', '**/turbo.jsonc') != '' &&
|
|
620
|
+
(inputs.cache-turbo == 'true' || env.TURBO_TOKEN == '' || env.TURBO_TEAM == '')
|
|
621
|
+
uses: ./.github/actions/cache
|
|
622
|
+
with:
|
|
623
|
+
save: ${{ inputs.cache-save }}
|
|
624
|
+
path: |
|
|
625
|
+
.turbo/cache
|
|
626
|
+
**/.turbo/cache
|
|
627
|
+
key: ${{ runner.os }}-turbo-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/turbo.json', '**/turbo.jsonc', '.mise.toml', 'mise.lock') }}
|
|
628
|
+
restore-keys: |
|
|
629
|
+
${{ runner.os }}-turbo-
|
|
630
|
+
- name: Configure remote Turbo
|
|
631
|
+
if: >-
|
|
632
|
+
inputs.install == 'true' &&
|
|
633
|
+
inputs.cache-turbo != 'true' &&
|
|
634
|
+
env.TURBO_TOKEN != '' &&
|
|
635
|
+
env.TURBO_TEAM != '' &&
|
|
636
|
+
steps.profile.outputs.turbo_task == 'true' &&
|
|
637
|
+
steps.profile.outputs.turbo == 'true'
|
|
638
|
+
shell: bash
|
|
639
|
+
run: echo 'REPO_FOUNDRY_TURBO_REMOTE_ONLY=true' >> "$GITHUB_ENV"
|
|
640
|
+
- name: Cache Rust packages
|
|
641
|
+
id: rust-packages
|
|
642
|
+
if: (inputs.mise-scope == 'auto' || inputs.mise-scope == 'all' || inputs.mise-scope == 'rust') && inputs.install-rust == 'true' && steps.profile.outputs.rust == 'true' && hashFiles('**/Cargo.toml', '**/Cargo.lock') != ''
|
|
643
|
+
uses: ./.github/actions/cache
|
|
644
|
+
with:
|
|
645
|
+
save: ${{ inputs.cache-save }}
|
|
646
|
+
path: |
|
|
647
|
+
~/.cargo/registry
|
|
648
|
+
~/.cargo/git
|
|
649
|
+
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
|
|
650
|
+
restore-keys: |
|
|
651
|
+
${{ runner.os }}-rust-
|
|
652
|
+
- name: Cache Rust advisory database
|
|
653
|
+
if: inputs.install == 'false' && (inputs.mise-scope == 'auto' || inputs.mise-scope == 'all' || inputs.mise-scope == 'rust') && inputs.install-rust == 'true' && steps.profile.outputs.rust == 'true' && hashFiles('**/Cargo.toml', '**/Cargo.lock') != ''
|
|
654
|
+
uses: ./.github/actions/cache
|
|
655
|
+
with:
|
|
656
|
+
save: ${{ inputs.cache-save }}
|
|
657
|
+
path: ~/.cargo/advisory-db
|
|
658
|
+
# The advisory database is independent of project dependencies. Keep
|
|
659
|
+
# it warm for Security without invalidating it on every lockfile edit.
|
|
660
|
+
key: ${{ runner.os }}-rust-advisory-${{ hashFiles('.github/scripts/security.sh') }}
|
|
661
|
+
restore-keys: |
|
|
662
|
+
${{ runner.os }}-rust-advisory-
|
|
663
|
+
- name: Cache Rust builds
|
|
664
|
+
if: inputs.install == 'true' && inputs.install-rust == 'true' && inputs.cache-build == 'true' && steps.profile.outputs.rust == 'true' && hashFiles('**/Cargo.toml', '**/Cargo.lock') != ''
|
|
665
|
+
uses: ./.github/actions/cache
|
|
666
|
+
with:
|
|
667
|
+
save: ${{ inputs.cache-save }}
|
|
668
|
+
# Keep reusable dependency/build-script artifacts for the Build job;
|
|
669
|
+
# exclude target/incremental and release output, which are large and
|
|
670
|
+
# provide little value on a fresh hosted runner.
|
|
671
|
+
path: |
|
|
672
|
+
target/.rustc_info.json
|
|
673
|
+
target/debug/deps
|
|
674
|
+
target/debug/build
|
|
675
|
+
target/debug/.fingerprint
|
|
676
|
+
target/debug/*.d
|
|
677
|
+
key: ${{ runner.os }}-rust-build-v2-${{ github.workflow }}-${{ github.job }}-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock', '.mise.toml', 'mise.lock') }}
|
|
678
|
+
# Cargo fingerprints validate restored artifacts; keep job-specific
|
|
679
|
+
# primary saves but reuse a prior workflow's dependency artifacts.
|
|
680
|
+
restore-keys: |
|
|
681
|
+
${{ runner.os }}-rust-build-v2-
|
|
682
|
+
- name: Setup
|
|
683
|
+
if: ${{ steps.profile.outputs.mise_required == 'true' }}
|
|
684
|
+
uses: jdx/mise-action@v4
|
|
685
|
+
with:
|
|
686
|
+
cache: true
|
|
687
|
+
install_args: ${{ steps.profile.outputs.mise_tools }}
|
|
688
|
+
- name: Use offline Cargo cache
|
|
689
|
+
if: inputs.install == 'true' && inputs.install-rust == 'true' && steps.rust-packages.outputs.cache-hit == 'true' && hashFiles('**/Cargo.lock') != ''
|
|
690
|
+
shell: bash
|
|
691
|
+
run: echo 'CARGO_NET_OFFLINE=true' >> "$GITHUB_ENV"
|
|
692
|
+
- name: Install
|
|
693
|
+
if: inputs.install == 'true'
|
|
694
|
+
shell: bash
|
|
695
|
+
env:
|
|
696
|
+
REPO_FOUNDRY_JAVASCRIPT_CACHE_HIT: ${{ steps.javascript-dependencies.outputs.cache-hit == 'true' || steps.javascript-bun-dependencies.outputs.restored == 'true' }}
|
|
697
|
+
REPO_FOUNDRY_PYTHON_CACHE_HIT: ${{ steps.python-environment.outputs.cache-hit }}
|
|
698
|
+
REPO_FOUNDRY_RUST_CACHE_HIT: ${{ steps.rust-packages.outputs.cache-hit }}
|
|
699
|
+
REPO_FOUNDRY_INSTALL_JAVASCRIPT: ${{ inputs.install-javascript }}
|
|
700
|
+
REPO_FOUNDRY_INSTALL_PYTHON: ${{ inputs.install-python }}
|
|
701
|
+
REPO_FOUNDRY_INSTALL_RUST: ${{ inputs.install-rust }}
|
|
702
|
+
REPO_FOUNDRY_TASK: ${{ inputs.task }}
|
|
703
|
+
run: bash .github/scripts/ci.sh install
|
|
704
|
+
- name: Measure Bun dependencies
|
|
705
|
+
id: javascript-bun-cache
|
|
706
|
+
if: >-
|
|
707
|
+
inputs.cache-save == 'true' &&
|
|
708
|
+
inputs.install == 'true' &&
|
|
709
|
+
inputs.install-javascript == 'true' &&
|
|
710
|
+
inputs.cache-installed != 'false' &&
|
|
711
|
+
steps.profile.outputs.javascript_package_manager == 'bun' &&
|
|
712
|
+
steps.profile.outputs.javascript_dependencies == 'true' &&
|
|
713
|
+
steps.javascript-bun-dependencies.outputs.restored != 'true' &&
|
|
714
|
+
!cancelled()
|
|
715
|
+
shell: bash
|
|
716
|
+
run: |
|
|
717
|
+
total_kib="$(find . -path './.git' -prune -o -type d -name node_modules -print0 |
|
|
718
|
+
xargs -0 -r du -sk |
|
|
719
|
+
awk '{ total += $1 } END { print total + 0 }')"
|
|
720
|
+
# Small Bun installs benefit from reuse; large monorepos are faster
|
|
721
|
+
# with the package cache and a clean linker pass.
|
|
722
|
+
if [ "$total_kib" -le 262144 ]; then
|
|
723
|
+
echo 'cacheable=true' >> "$GITHUB_OUTPUT"
|
|
724
|
+
else
|
|
725
|
+
echo "Skipping Bun dependency cache (${total_kib} KiB > 256 MiB)"
|
|
726
|
+
echo 'cacheable=false' >> "$GITHUB_OUTPUT"
|
|
727
|
+
fi
|
|
728
|
+
- name: Save Bun dependencies
|
|
729
|
+
if: >-
|
|
730
|
+
inputs.cache-save == 'true' &&
|
|
731
|
+
steps.javascript-bun-cache.outputs.cacheable == 'true' &&
|
|
732
|
+
!cancelled()
|
|
733
|
+
continue-on-error: true
|
|
734
|
+
uses: actions/cache/save@v5
|
|
735
|
+
with:
|
|
736
|
+
path: |
|
|
737
|
+
**/node_modules
|
|
738
|
+
key: ${{ runner.os }}-javascript-installed-v4-bun-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/.npmrc', '.github/template.yml', '.mise.toml', 'mise.lock') }}
|
|
739
|
+
- name: Save installed JavaScript dependencies
|
|
740
|
+
if: >-
|
|
741
|
+
inputs.cache-save == 'true' &&
|
|
742
|
+
inputs.install == 'true' &&
|
|
743
|
+
inputs.install-javascript == 'true' &&
|
|
744
|
+
steps.javascript-dependencies.outputs.cache-hit != 'true' &&
|
|
745
|
+
steps.profile.outputs.javascript_dependencies == 'true' &&
|
|
746
|
+
(steps.profile.outputs.javascript_package_manager == 'pnpm' ||
|
|
747
|
+
steps.profile.outputs.javascript_package_manager == 'yarn') &&
|
|
748
|
+
!cancelled()
|
|
749
|
+
continue-on-error: true
|
|
750
|
+
uses: actions/cache/save@v5
|
|
751
|
+
with:
|
|
752
|
+
path: |
|
|
753
|
+
**/node_modules
|
|
754
|
+
key: ${{ runner.os }}-javascript-installed-v3-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/.npmrc', '**/.yarnrc*', '**/.pnpmfile.cjs', '.github/template.yml', '.mise.toml', 'mise.lock') }}
|
|
755
|
+
- name: Save JavaScript packages
|
|
756
|
+
if: >-
|
|
757
|
+
inputs.cache-save == 'true' &&
|
|
758
|
+
inputs.install == 'true' &&
|
|
759
|
+
inputs.install-javascript == 'true' &&
|
|
760
|
+
steps.javascript-packages.outputs.cache-hit != 'true' &&
|
|
761
|
+
steps.profile.outputs.javascript_packages_cache == 'true' &&
|
|
762
|
+
steps.profile.outputs.javascript == 'true' &&
|
|
763
|
+
hashFiles('**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json') != '' &&
|
|
764
|
+
steps.javascript-dependencies.outputs.cache-hit != 'true' &&
|
|
765
|
+
steps.javascript-bun-dependencies.outputs.restored != 'true' &&
|
|
766
|
+
!cancelled()
|
|
767
|
+
continue-on-error: true
|
|
768
|
+
uses: actions/cache/save@v5
|
|
769
|
+
with:
|
|
770
|
+
path: |
|
|
771
|
+
~/.bun/install/cache
|
|
772
|
+
~/.cache/node/corepack
|
|
773
|
+
~/.npm
|
|
774
|
+
~/.cache/yarn
|
|
775
|
+
~/.local/share/pnpm/store
|
|
776
|
+
key: ${{ runner.os }}-javascript-${{ hashFiles('**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json') }}
|