code-foundry 0.26.0 → 0.27.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/.githooks/pre-commit +3 -4
- package/.github/CONTRIBUTING.md +10 -13
- package/.github/actions/setup/action.yml +68 -3
- package/.github/code-foundry.yml +6 -1
- package/.github/workflows/ci.yml +29 -24
- package/.github/workflows/ci_self-ci.yml +1 -1
- package/.github/workflows/codeql.yml +23 -29
- package/.github/workflows/codeql_self-ci.yml +1 -1
- package/.github/workflows/draft-pr.yml +2 -2
- package/.github/workflows/release-pr.yml +4 -4
- package/.github/workflows/release.yml +17 -29
- package/.github/workflows/security.yml +24 -19
- package/.github/workflows/security_self-ci.yml +1 -1
- package/.github/workflows/test.yml +20 -20
- package/.github/workflows/test_self-ci.yml +1 -1
- package/AGENTS.md +13 -10
- package/CHANGELOG.md +29 -0
- package/README.md +16 -6
- package/docs/CONFIGURATION.md +10 -1
- package/docs/INITIALIZATION.md +6 -5
- package/docs/RELEASES.md +5 -0
- package/docs/WORKFLOWS.md +12 -5
- package/package.json +7 -3
- package/src/cli.mjs +29 -25
- package/src/commands/doctor.mjs +70 -0
- package/src/commands/sync.mjs +224 -0
- package/src/lib/config.mjs +38 -0
- package/src/lib/profile.mjs +114 -0
- package/src/runtime.mjs +321 -0
- package/.github/scripts/bootstrap.sh +0 -21
- package/.github/scripts/changed-files.sh +0 -96
- package/.github/scripts/ci.sh +0 -641
- package/.github/scripts/codeql-languages.sh +0 -91
- package/.github/scripts/doctor.sh +0 -98
- package/.github/scripts/format-fast-path.sh +0 -80
- package/.github/scripts/init-repo.sh +0 -268
- package/.github/scripts/pre-commit.sh +0 -67
- package/.github/scripts/profile.sh +0 -186
- package/.github/scripts/security.sh +0 -214
- package/.github/scripts/sitecustomize.py +0 -17
- package/.github/scripts/sync-codeowners.sh +0 -76
- package/.github/scripts/sync-protection.sh +0 -138
- package/.github/scripts/sync-template.sh +0 -748
- package/.github/scripts/turbo-cache-probe.sh +0 -102
package/.githooks/pre-commit
CHANGED
package/.github/CONTRIBUTING.md
CHANGED
|
@@ -48,14 +48,14 @@ docs/* test/* refactor/* │ │
|
|
|
48
48
|
| `staging` | Integration branch | Target normal pull requests here. Required checks must pass before merge. |
|
|
49
49
|
| `feat/*`, `fix/*`, `chore/*`, `refactor/*`, `docs/*`, `test/*` | Focused work | Branch from `staging`; keep changes small and reviewable. |
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
The default Git workflow is `staging-release`: topic branches merge into `staging`, then a promotion PR moves validated changes into `main`, followed by the versioned release PR. The default merge strategy is `rebase`, which preserves the linear Conventional Commit history. Configure `merge_strategy` as `squash` or `merge` in `.github/code-foundry.yml` when the repository intentionally uses another policy. Re-align `staging` with `main` after a release when needed.
|
|
52
52
|
|
|
53
53
|
## Before you start
|
|
54
54
|
|
|
55
55
|
### Toolchain
|
|
56
56
|
|
|
57
|
-
1.
|
|
58
|
-
2.
|
|
57
|
+
1. Run `npx code-foundry init` to detect the repository and enable hooks.
|
|
58
|
+
2. Follow `toolchain: auto` in `.github/code-foundry.yml`; install mise only if the repository already uses it or explicitly selects it.
|
|
59
59
|
3. Use `npx code-foundry doctor` when setup, lockfiles, or hooks appear out of sync.
|
|
60
60
|
4. Use the repository's existing package manager and lockfile. Do not introduce a second package manager.
|
|
61
61
|
5. Copy `.env.example` to the appropriate local environment file when provided. Never commit the copy.
|
|
@@ -74,17 +74,14 @@ If the worktree is dirty, stop and understand the existing changes before switch
|
|
|
74
74
|
|
|
75
75
|
## Local validation
|
|
76
76
|
|
|
77
|
-
The
|
|
77
|
+
The repository runtime detects supported tools and skips checks that do not apply:
|
|
78
78
|
|
|
79
79
|
```sh
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
bash .github/scripts/ci.sh integration
|
|
86
|
-
bash .github/scripts/ci.sh e2e
|
|
87
|
-
bash .github/scripts/ci.sh smoke
|
|
80
|
+
npx code-foundry doctor
|
|
81
|
+
npm run format:check # or the package manager's equivalent
|
|
82
|
+
npm run lint
|
|
83
|
+
npm run type-check
|
|
84
|
+
npm test
|
|
88
85
|
Security and dependency audits run through the GitHub Security workflow.
|
|
89
86
|
```
|
|
90
87
|
|
|
@@ -110,7 +107,7 @@ For maintainers, trusted contributors, and automation agents:
|
|
|
110
107
|
|
|
111
108
|
8. Push the branch and open a pull request into `staging`.
|
|
112
109
|
9. Address review feedback and failed checks on the same branch.
|
|
113
|
-
10.
|
|
110
|
+
10. Merge using the repository's configured `merge_strategy` after required checks pass and the change is ready.
|
|
114
111
|
|
|
115
112
|
### Internal agent handoff
|
|
116
113
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: Repository Setup
|
|
2
|
-
description:
|
|
2
|
+
description: Select mise or native language tooling and optionally install project dependencies.
|
|
3
3
|
|
|
4
4
|
inputs:
|
|
5
5
|
install:
|
|
@@ -85,6 +85,16 @@ runs:
|
|
|
85
85
|
run: |
|
|
86
86
|
tracked_files="$(git ls-files)"
|
|
87
87
|
|
|
88
|
+
toolchain="auto"
|
|
89
|
+
if [ -f .github/code-foundry.yml ]; then
|
|
90
|
+
configured_toolchain="$(awk -F': ' '/^toolchain:/ {print $2; exit}' .github/code-foundry.yml)"
|
|
91
|
+
[ -n "$configured_toolchain" ] && toolchain="$configured_toolchain"
|
|
92
|
+
fi
|
|
93
|
+
if [ "$toolchain" = auto ] && [ -f .mise.toml ]; then
|
|
94
|
+
toolchain=mise
|
|
95
|
+
fi
|
|
96
|
+
printf 'toolchain_mode=%s\n' "$toolchain" >> "$GITHUB_OUTPUT"
|
|
97
|
+
|
|
88
98
|
has_tracked_regex() {
|
|
89
99
|
printf '%s\n' "$tracked_files" | grep -Eq "$1"
|
|
90
100
|
}
|
|
@@ -428,6 +438,61 @@ runs:
|
|
|
428
438
|
REPO_FOUNDRY_TASK_RUST: ${{ inputs.task-rust }}
|
|
429
439
|
REPO_FOUNDRY_CACHE_PACKAGES: ${{ inputs.cache-packages }}
|
|
430
440
|
|
|
441
|
+
- name: Install native test libraries
|
|
442
|
+
if: >-
|
|
443
|
+
inputs.install == 'true' &&
|
|
444
|
+
inputs.task == 'unit' &&
|
|
445
|
+
hashFiles('**/package.json') != '' &&
|
|
446
|
+
steps.profile.outputs.javascript == 'true'
|
|
447
|
+
shell: bash
|
|
448
|
+
run: |
|
|
449
|
+
if node -e '
|
|
450
|
+
const fs = require("node:fs");
|
|
451
|
+
const p = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
452
|
+
const all = { ...p.dependencies, ...p.devDependencies, ...p.optionalDependencies };
|
|
453
|
+
process.exit(all["matchstick-as"] ? 0 : 1);
|
|
454
|
+
' 2>/dev/null; then
|
|
455
|
+
sudo apt-get update -qq
|
|
456
|
+
sudo apt-get install -y -qq libpq5
|
|
457
|
+
fi
|
|
458
|
+
|
|
459
|
+
- name: Setup Node
|
|
460
|
+
if: >-
|
|
461
|
+
steps.profile.outputs.toolchain_mode != 'mise' &&
|
|
462
|
+
steps.profile.outputs.javascript == 'true' &&
|
|
463
|
+
steps.profile.outputs.javascript_package_manager != 'bun'
|
|
464
|
+
uses: actions/setup-node@v5
|
|
465
|
+
with:
|
|
466
|
+
node-version: 24
|
|
467
|
+
cache: ${{ steps.profile.outputs.javascript_package_manager == 'npm' && 'npm' || steps.profile.outputs.javascript_package_manager == 'pnpm' && 'pnpm' || steps.profile.outputs.javascript_package_manager == 'yarn' && 'yarn' || '' }}
|
|
468
|
+
|
|
469
|
+
- name: Setup Bun
|
|
470
|
+
if: >-
|
|
471
|
+
steps.profile.outputs.toolchain_mode != 'mise' &&
|
|
472
|
+
steps.profile.outputs.javascript == 'true' &&
|
|
473
|
+
steps.profile.outputs.javascript_package_manager == 'bun'
|
|
474
|
+
uses: oven-sh/setup-bun@v2
|
|
475
|
+
with:
|
|
476
|
+
bun-version: 1.3.14
|
|
477
|
+
|
|
478
|
+
- name: Enable Corepack
|
|
479
|
+
if: >-
|
|
480
|
+
steps.profile.outputs.toolchain_mode != 'mise' &&
|
|
481
|
+
(steps.profile.outputs.javascript_package_manager == 'pnpm' ||
|
|
482
|
+
steps.profile.outputs.javascript_package_manager == 'yarn')
|
|
483
|
+
shell: bash
|
|
484
|
+
run: corepack enable
|
|
485
|
+
|
|
486
|
+
- name: Setup Python
|
|
487
|
+
if: steps.profile.outputs.toolchain_mode != 'mise' && steps.profile.outputs.python == 'true'
|
|
488
|
+
uses: actions/setup-python@v6
|
|
489
|
+
with:
|
|
490
|
+
python-version: '3.13'
|
|
491
|
+
|
|
492
|
+
- name: Setup Rust
|
|
493
|
+
if: steps.profile.outputs.toolchain_mode != 'mise' && steps.profile.outputs.rust == 'true'
|
|
494
|
+
uses: dtolnay/rust-toolchain@stable
|
|
495
|
+
|
|
431
496
|
- name: Setup uv
|
|
432
497
|
if: >-
|
|
433
498
|
steps.profile.outputs.python == 'true' &&
|
|
@@ -658,7 +723,7 @@ runs:
|
|
|
658
723
|
path: ~/.cargo/advisory-db
|
|
659
724
|
# The advisory database is independent of project dependencies. Keep
|
|
660
725
|
# it warm for Security without invalidating it on every lockfile edit.
|
|
661
|
-
key: ${{ runner.os }}-rust-advisory-${{ hashFiles('.
|
|
726
|
+
key: ${{ runner.os }}-rust-advisory-${{ hashFiles('.code-foundry/src/runtime.mjs') }}
|
|
662
727
|
restore-keys: |
|
|
663
728
|
${{ runner.os }}-rust-advisory-
|
|
664
729
|
- name: Cache Rust builds
|
|
@@ -701,7 +766,7 @@ runs:
|
|
|
701
766
|
REPO_FOUNDRY_INSTALL_PYTHON: ${{ inputs.install-python }}
|
|
702
767
|
REPO_FOUNDRY_INSTALL_RUST: ${{ inputs.install-rust }}
|
|
703
768
|
REPO_FOUNDRY_TASK: ${{ inputs.task }}
|
|
704
|
-
run:
|
|
769
|
+
run: node .code-foundry/src/runtime.mjs ci install
|
|
705
770
|
- name: Measure Bun dependencies
|
|
706
771
|
id: javascript-bun-cache
|
|
707
772
|
if: >-
|
package/.github/code-foundry.yml
CHANGED
|
@@ -3,12 +3,17 @@ version: 1
|
|
|
3
3
|
profile: auto
|
|
4
4
|
languages: typescript
|
|
5
5
|
features: all
|
|
6
|
+
codeql: auto
|
|
7
|
+
dependency_review: auto
|
|
6
8
|
package_manager: bun
|
|
9
|
+
toolchain: auto
|
|
7
10
|
runtime_repository: 0xPlayerOne/code-foundry
|
|
8
|
-
runtime_ref: v0.
|
|
11
|
+
runtime_ref: v0.26.0
|
|
9
12
|
release_type: node
|
|
10
13
|
npm_publish: true
|
|
11
14
|
license: agpl-3.0-or-later
|
|
15
|
+
git_workflow: staging-release
|
|
16
|
+
merge_strategy: rebase
|
|
12
17
|
runner: ubuntu-latest
|
|
13
18
|
unit_runner: ubuntu-slim
|
|
14
19
|
cache_packages: auto
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -53,23 +53,23 @@ jobs:
|
|
|
53
53
|
path: .code-foundry
|
|
54
54
|
sparse-checkout: |
|
|
55
55
|
.github/actions
|
|
56
|
-
|
|
56
|
+
src/lib
|
|
57
|
+
src/runtime.mjs
|
|
57
58
|
- name: Install runtime
|
|
58
59
|
run: |
|
|
59
|
-
mkdir -p .github/actions
|
|
60
|
+
mkdir -p .github/actions
|
|
60
61
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
61
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
62
62
|
- name: Detect
|
|
63
63
|
id: applicability
|
|
64
|
-
run:
|
|
65
|
-
- name: Fast path
|
|
66
|
-
if: steps.applicability.outputs.applicable == 'true'
|
|
67
|
-
run: bash .github/scripts/format-fast-path.sh
|
|
64
|
+
run: node .code-foundry/src/runtime.mjs ci should_run format >> "$GITHUB_OUTPUT"
|
|
68
65
|
- name: Setup
|
|
69
66
|
if: steps.applicability.outputs.applicable == 'true'
|
|
70
67
|
uses: ./.github/actions/setup
|
|
71
68
|
with:
|
|
72
|
-
|
|
69
|
+
# Repository format scripts normally call a project-local formatter
|
|
70
|
+
# (for example, Prettier). Install dependencies before running them;
|
|
71
|
+
# otherwise a clean runner cannot resolve the declared tool.
|
|
72
|
+
install: 'true'
|
|
73
73
|
cache-format: 'true'
|
|
74
74
|
cache-lint: 'false'
|
|
75
75
|
cache-build: 'false'
|
|
@@ -79,7 +79,7 @@ jobs:
|
|
|
79
79
|
task-rust: 'false'
|
|
80
80
|
- name: Format
|
|
81
81
|
if: steps.applicability.outputs.applicable == 'true'
|
|
82
|
-
run:
|
|
82
|
+
run: node .code-foundry/src/runtime.mjs ci format
|
|
83
83
|
|
|
84
84
|
lint:
|
|
85
85
|
name: Lint
|
|
@@ -95,15 +95,15 @@ jobs:
|
|
|
95
95
|
path: .code-foundry
|
|
96
96
|
sparse-checkout: |
|
|
97
97
|
.github/actions
|
|
98
|
-
|
|
98
|
+
src/lib
|
|
99
|
+
src/runtime.mjs
|
|
99
100
|
- name: Install runtime
|
|
100
101
|
run: |
|
|
101
|
-
mkdir -p .github/actions
|
|
102
|
+
mkdir -p .github/actions
|
|
102
103
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
103
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
104
104
|
- name: Detect
|
|
105
105
|
id: applicability
|
|
106
|
-
run:
|
|
106
|
+
run: node .code-foundry/src/runtime.mjs ci should_run lint >> "$GITHUB_OUTPUT"
|
|
107
107
|
- name: Setup
|
|
108
108
|
if: steps.applicability.outputs.applicable == 'true'
|
|
109
109
|
uses: ./.github/actions/setup
|
|
@@ -113,7 +113,7 @@ jobs:
|
|
|
113
113
|
task: lint
|
|
114
114
|
- name: Lint
|
|
115
115
|
if: steps.applicability.outputs.applicable == 'true'
|
|
116
|
-
run:
|
|
116
|
+
run: node .code-foundry/src/runtime.mjs ci lint
|
|
117
117
|
|
|
118
118
|
type-check:
|
|
119
119
|
name: Type-Check
|
|
@@ -129,15 +129,15 @@ jobs:
|
|
|
129
129
|
path: .code-foundry
|
|
130
130
|
sparse-checkout: |
|
|
131
131
|
.github/actions
|
|
132
|
-
|
|
132
|
+
src/lib
|
|
133
|
+
src/runtime.mjs
|
|
133
134
|
- name: Install runtime
|
|
134
135
|
run: |
|
|
135
|
-
mkdir -p .github/actions
|
|
136
|
+
mkdir -p .github/actions
|
|
136
137
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
137
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
138
138
|
- name: Detect
|
|
139
139
|
id: applicability
|
|
140
|
-
run:
|
|
140
|
+
run: node .code-foundry/src/runtime.mjs ci should_run type_check >> "$GITHUB_OUTPUT"
|
|
141
141
|
- name: Setup
|
|
142
142
|
if: steps.applicability.outputs.applicable == 'true'
|
|
143
143
|
uses: ./.github/actions/setup
|
|
@@ -147,11 +147,16 @@ jobs:
|
|
|
147
147
|
task: type_check
|
|
148
148
|
- name: Type-Check
|
|
149
149
|
if: steps.applicability.outputs.applicable == 'true'
|
|
150
|
-
run:
|
|
150
|
+
run: node .code-foundry/src/runtime.mjs ci type_check
|
|
151
151
|
|
|
152
152
|
build:
|
|
153
153
|
name: Build
|
|
154
154
|
runs-on: ${{ inputs.runner }}
|
|
155
|
+
env:
|
|
156
|
+
# Framework builds may validate server-side configuration at build time.
|
|
157
|
+
# Consumers can provide the real value; the fallback is intentionally
|
|
158
|
+
# CI-only and must never be used at runtime.
|
|
159
|
+
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET || 'code-foundry-ci-placeholder-0123456789' }}
|
|
155
160
|
steps:
|
|
156
161
|
- name: Checkout
|
|
157
162
|
uses: actions/checkout@v7
|
|
@@ -163,15 +168,15 @@ jobs:
|
|
|
163
168
|
path: .code-foundry
|
|
164
169
|
sparse-checkout: |
|
|
165
170
|
.github/actions
|
|
166
|
-
|
|
171
|
+
src/lib
|
|
172
|
+
src/runtime.mjs
|
|
167
173
|
- name: Install runtime
|
|
168
174
|
run: |
|
|
169
|
-
mkdir -p .github/actions
|
|
175
|
+
mkdir -p .github/actions
|
|
170
176
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
171
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
172
177
|
- name: Detect
|
|
173
178
|
id: applicability
|
|
174
|
-
run:
|
|
179
|
+
run: node .code-foundry/src/runtime.mjs ci should_run build >> "$GITHUB_OUTPUT"
|
|
175
180
|
- name: Setup
|
|
176
181
|
if: steps.applicability.outputs.applicable == 'true'
|
|
177
182
|
uses: ./.github/actions/setup
|
|
@@ -181,4 +186,4 @@ jobs:
|
|
|
181
186
|
task: build
|
|
182
187
|
- name: Build
|
|
183
188
|
if: steps.applicability.outputs.applicable == 'true'
|
|
184
|
-
run:
|
|
189
|
+
run: node .code-foundry/src/runtime.mjs ci build
|
|
@@ -41,6 +41,7 @@ jobs:
|
|
|
41
41
|
timeout-minutes: 10
|
|
42
42
|
outputs:
|
|
43
43
|
languages: ${{ steps.languages.outputs.languages }}
|
|
44
|
+
enabled: ${{ steps.languages.outputs.enabled }}
|
|
44
45
|
code_security: ${{ steps.security.outputs.status }}
|
|
45
46
|
actions_available: ${{ steps.languages.outputs.actions_available }}
|
|
46
47
|
actions_changed: ${{ steps.languages.outputs.actions_changed }}
|
|
@@ -61,14 +62,13 @@ jobs:
|
|
|
61
62
|
GH_TOKEN: ${{ github.token }}
|
|
62
63
|
run: |
|
|
63
64
|
status="disabled"
|
|
64
|
-
if [ "${{ github.event.repository.
|
|
65
|
+
if [ "${{ github.event.repository.visibility }}" = "public" ]; then
|
|
65
66
|
status="enabled"
|
|
66
67
|
else
|
|
67
68
|
status="$(gh api "repos/${GITHUB_REPOSITORY}" --jq '.security_and_analysis.code_security.status // "disabled"' 2>/dev/null || printf 'disabled')"
|
|
68
69
|
fi
|
|
69
70
|
printf 'status=%s\n' "$status" >> "$GITHUB_OUTPUT"
|
|
70
71
|
- name: Checkout
|
|
71
|
-
if: ${{ !github.event.repository.private || steps.security.outputs.status == 'enabled' }}
|
|
72
72
|
uses: actions/checkout@v7
|
|
73
73
|
with:
|
|
74
74
|
fetch-depth: 2
|
|
@@ -85,7 +85,6 @@ jobs:
|
|
|
85
85
|
package-lock.json
|
|
86
86
|
sparse-checkout-cone-mode: false
|
|
87
87
|
- name: Runtime
|
|
88
|
-
if: ${{ !github.event.repository.private || steps.security.outputs.status == 'enabled' }}
|
|
89
88
|
uses: actions/checkout@v7
|
|
90
89
|
with:
|
|
91
90
|
repository: ${{ inputs.runtime-repository }}
|
|
@@ -93,31 +92,26 @@ jobs:
|
|
|
93
92
|
path: .code-foundry
|
|
94
93
|
sparse-checkout: |
|
|
95
94
|
.github/actions
|
|
96
|
-
|
|
95
|
+
src/lib
|
|
96
|
+
src/runtime.mjs
|
|
97
97
|
- name: Install runtime
|
|
98
|
-
if: ${{ !github.event.repository.private || steps.security.outputs.status == 'enabled' }}
|
|
99
98
|
run: |
|
|
100
|
-
mkdir -p .github/actions
|
|
99
|
+
mkdir -p .github/actions
|
|
101
100
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
102
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
103
101
|
- id: languages
|
|
104
102
|
name: Detect languages
|
|
105
103
|
env:
|
|
106
104
|
CODEQL_BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
|
|
107
105
|
REPO_FOUNDRY_CODE_SECURITY: ${{ steps.security.outputs.status }}
|
|
108
106
|
REPO_FOUNDRY_PRIVATE: ${{ github.event.repository.private }}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
echo 'languages=[]' >> "$GITHUB_OUTPUT"
|
|
112
|
-
else
|
|
113
|
-
bash .github/scripts/codeql-languages.sh
|
|
114
|
-
fi
|
|
107
|
+
REPO_FOUNDRY_VISIBILITY: ${{ github.event.repository.visibility }}
|
|
108
|
+
run: node .code-foundry/src/runtime.mjs codeql
|
|
115
109
|
|
|
116
110
|
analyze-actions:
|
|
117
111
|
name: Analyze (Actions)
|
|
118
112
|
needs: detect
|
|
119
113
|
if: >-
|
|
120
|
-
|
|
114
|
+
needs.detect.outputs.enabled == 'true' &&
|
|
121
115
|
needs.detect.outputs.actions_available == 'true' &&
|
|
122
116
|
needs.detect.outputs.actions_changed == 'true'
|
|
123
117
|
runs-on: ${{ inputs.runner }}
|
|
@@ -133,12 +127,12 @@ jobs:
|
|
|
133
127
|
path: .code-foundry
|
|
134
128
|
sparse-checkout: |
|
|
135
129
|
.github/actions
|
|
136
|
-
|
|
130
|
+
src/lib
|
|
131
|
+
src/runtime.mjs
|
|
137
132
|
- name: Install runtime
|
|
138
133
|
run: |
|
|
139
|
-
mkdir -p .github/actions
|
|
134
|
+
mkdir -p .github/actions
|
|
140
135
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
141
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
142
136
|
- name: Analyze
|
|
143
137
|
uses: ./.github/actions/codeql
|
|
144
138
|
with:
|
|
@@ -150,7 +144,7 @@ jobs:
|
|
|
150
144
|
name: Analyze (TypeScript)
|
|
151
145
|
needs: detect
|
|
152
146
|
if: >-
|
|
153
|
-
|
|
147
|
+
needs.detect.outputs.enabled == 'true' &&
|
|
154
148
|
needs.detect.outputs.javascript_available == 'true' &&
|
|
155
149
|
needs.detect.outputs.javascript_changed == 'true'
|
|
156
150
|
runs-on: ${{ inputs.runner }}
|
|
@@ -166,12 +160,12 @@ jobs:
|
|
|
166
160
|
path: .code-foundry
|
|
167
161
|
sparse-checkout: |
|
|
168
162
|
.github/actions
|
|
169
|
-
|
|
163
|
+
src/lib
|
|
164
|
+
src/runtime.mjs
|
|
170
165
|
- name: Install runtime
|
|
171
166
|
run: |
|
|
172
|
-
mkdir -p .github/actions
|
|
167
|
+
mkdir -p .github/actions
|
|
173
168
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
174
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
175
169
|
- name: Analyze
|
|
176
170
|
uses: ./.github/actions/codeql
|
|
177
171
|
with:
|
|
@@ -183,7 +177,7 @@ jobs:
|
|
|
183
177
|
name: Analyze (Python)
|
|
184
178
|
needs: detect
|
|
185
179
|
if: >-
|
|
186
|
-
|
|
180
|
+
needs.detect.outputs.enabled == 'true' &&
|
|
187
181
|
needs.detect.outputs.python_available == 'true' &&
|
|
188
182
|
needs.detect.outputs.python_changed == 'true'
|
|
189
183
|
runs-on: ${{ inputs.runner }}
|
|
@@ -199,12 +193,12 @@ jobs:
|
|
|
199
193
|
path: .code-foundry
|
|
200
194
|
sparse-checkout: |
|
|
201
195
|
.github/actions
|
|
202
|
-
|
|
196
|
+
src/lib
|
|
197
|
+
src/runtime.mjs
|
|
203
198
|
- name: Install runtime
|
|
204
199
|
run: |
|
|
205
|
-
mkdir -p .github/actions
|
|
200
|
+
mkdir -p .github/actions
|
|
206
201
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
207
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
208
202
|
- name: Analyze
|
|
209
203
|
uses: ./.github/actions/codeql
|
|
210
204
|
with:
|
|
@@ -216,7 +210,7 @@ jobs:
|
|
|
216
210
|
name: Analyze (Rust)
|
|
217
211
|
needs: detect
|
|
218
212
|
if: >-
|
|
219
|
-
|
|
213
|
+
needs.detect.outputs.enabled == 'true' &&
|
|
220
214
|
needs.detect.outputs.rust_available == 'true' &&
|
|
221
215
|
needs.detect.outputs.rust_changed == 'true'
|
|
222
216
|
runs-on: ${{ inputs.runner }}
|
|
@@ -232,12 +226,12 @@ jobs:
|
|
|
232
226
|
path: .code-foundry
|
|
233
227
|
sparse-checkout: |
|
|
234
228
|
.github/actions
|
|
235
|
-
|
|
229
|
+
src/lib
|
|
230
|
+
src/runtime.mjs
|
|
236
231
|
- name: Install runtime
|
|
237
232
|
run: |
|
|
238
|
-
mkdir -p .github/actions
|
|
233
|
+
mkdir -p .github/actions
|
|
239
234
|
cp -R .code-foundry/.github/actions/. .github/actions/
|
|
240
|
-
cp -R .code-foundry/.github/scripts/. .github/scripts/
|
|
241
235
|
- name: Analyze
|
|
242
236
|
uses: ./.github/actions/codeql
|
|
243
237
|
with:
|
|
@@ -29,7 +29,7 @@ jobs:
|
|
|
29
29
|
id: check-pr
|
|
30
30
|
run: |
|
|
31
31
|
BRANCH="${{ github.ref_name }}"
|
|
32
|
-
EXISTING=$(gh pr list --limit 1 --base staging --head "$BRANCH" --state open --json number,title 2>/dev/null |
|
|
32
|
+
EXISTING=$(gh pr list --limit 1 --base staging --head "$BRANCH" --state open --json number,title 2>/dev/null | node -e 'let d=""; process.stdin.on("data", c => d += c).on("end", () => console.log(JSON.parse(d || "[]").length))')
|
|
33
33
|
echo "existing=$EXISTING" >> "$GITHUB_OUTPUT"
|
|
34
34
|
|
|
35
35
|
- name: Create
|
|
@@ -51,7 +51,7 @@ jobs:
|
|
|
51
51
|
if: steps.check-pr.outputs.existing == '0'
|
|
52
52
|
run: |
|
|
53
53
|
BRANCH="${{ github.ref_name }}"
|
|
54
|
-
PR_NUMBER=$(gh pr list --limit 1 --base staging --head "$BRANCH" --state open --json number 2>/dev/null |
|
|
54
|
+
PR_NUMBER=$(gh pr list --limit 1 --base staging --head "$BRANCH" --state open --json number 2>/dev/null | node -e 'let d=""; process.stdin.on("data", c => d += c).on("end", () => console.log(JSON.parse(d || "[]")[0]?.number || ""))')
|
|
55
55
|
if [ -n "$PR_NUMBER" ]; then
|
|
56
56
|
gh pr ready "$PR_NUMBER"
|
|
57
57
|
fi
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
--base main \
|
|
36
36
|
--head staging \
|
|
37
37
|
--state open \
|
|
38
|
-
--json number |
|
|
38
|
+
--json number | node -e 'let d=""; process.stdin.on("data", c => d += c).on("end", () => console.log(JSON.parse(d || "[]").length))')
|
|
39
39
|
COMPARE_URL="repos/${GITHUB_REPOSITORY}/compare/main...staging"
|
|
40
40
|
TOTAL_COMMITS=$(gh api "$COMPARE_URL?per_page=1" --jq '.total_commits // 0')
|
|
41
41
|
echo "existing=$EXISTING" >> "$GITHUB_OUTPUT"
|
|
@@ -53,12 +53,12 @@ jobs:
|
|
|
53
53
|
COMPARE_URL="repos/${GITHUB_REPOSITORY}/compare/main...staging"
|
|
54
54
|
COMPARE_FILE="$RUNNER_TEMP/release-compare.json"
|
|
55
55
|
gh api "$COMPARE_URL?per_page=100" > "$COMPARE_FILE"
|
|
56
|
-
TOTAL_COMMITS=$(
|
|
56
|
+
TOTAL_COMMITS=$(node -e 'const d=require(process.argv[1]); console.log(d.total_commits || 0)' "$COMPARE_FILE")
|
|
57
57
|
if [ "$TOTAL_COMMITS" -gt 100 ]; then
|
|
58
58
|
LAST_PAGE=$(( (TOTAL_COMMITS + 99) / 100 ))
|
|
59
59
|
gh api "$COMPARE_URL?per_page=100&page=$LAST_PAGE" > "$COMPARE_FILE"
|
|
60
60
|
fi
|
|
61
|
-
COMMITS=$(
|
|
61
|
+
COMMITS=$(node -e 'const d=require(process.argv[1]); for (const c of d.commits || []) console.log(`- ${c.commit.message.split("\\n")[0]} (${c.sha.slice(0, 7)})`)' "$COMPARE_FILE")
|
|
62
62
|
if [ -z "$COMMITS" ]; then
|
|
63
63
|
COMMITS='- No commits found since main.'
|
|
64
64
|
fi
|
|
@@ -87,7 +87,7 @@ jobs:
|
|
|
87
87
|
### Validation
|
|
88
88
|
|
|
89
89
|
- Required CI, test, security, and CodeQL checks must pass before merge.
|
|
90
|
-
- Merge
|
|
90
|
+
- Merge using the repository's configured \`merge_strategy\` (default: **rebase**).
|
|
91
91
|
- After merge, Release Please opens a separate versioned release PR with the changelog.
|
|
92
92
|
EOF
|
|
93
93
|
|
|
@@ -41,36 +41,24 @@ jobs:
|
|
|
41
41
|
filter: blob:none
|
|
42
42
|
- name: Detect release profile
|
|
43
43
|
id: profile
|
|
44
|
-
shell: bash
|
|
45
44
|
run: |
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
fi
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
case "$release_type" in
|
|
67
|
-
node|python|rust|simple) ;;
|
|
68
|
-
none) npm_publish=false ;;
|
|
69
|
-
*) echo "Unsupported release_type: $release_type" >&2; exit 2 ;;
|
|
70
|
-
esac
|
|
71
|
-
if [ ! -f package.json ]; then npm_publish=false; fi
|
|
72
|
-
printf 'release_type=%s\n' "$release_type" >> "$GITHUB_OUTPUT"
|
|
73
|
-
printf 'npm_publish=%s\n' "$npm_publish" >> "$GITHUB_OUTPUT"
|
|
45
|
+
node <<'NODE'
|
|
46
|
+
const fs = require('node:fs')
|
|
47
|
+
const config = fs.existsSync('.github/code-foundry.yml')
|
|
48
|
+
? Object.fromEntries(fs.readFileSync('.github/code-foundry.yml', 'utf8').split(/\r?\n/).flatMap((line) => {
|
|
49
|
+
const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*?)\s*$/)
|
|
50
|
+
return match ? [[match[1], match[2].replace(/\s+#.*$/, '').replace(/^['"]|['"]$/g, '')]] : []
|
|
51
|
+
}))
|
|
52
|
+
: {}
|
|
53
|
+
let releaseType = config.release_type || 'auto'
|
|
54
|
+
let npmPublish = config.npm_publish || 'false'
|
|
55
|
+
if (releaseType === 'auto') {
|
|
56
|
+
releaseType = fs.existsSync('package.json') ? 'node' : fs.existsSync('pyproject.toml') ? 'python' : fs.existsSync('Cargo.toml') ? 'rust' : fs.existsSync('version.txt') ? 'simple' : 'none'
|
|
57
|
+
}
|
|
58
|
+
if (!['node', 'python', 'rust', 'simple', 'none'].includes(releaseType)) throw new Error(`Unsupported release_type: ${releaseType}`)
|
|
59
|
+
if (releaseType === 'none' || !fs.existsSync('package.json')) npmPublish = 'false'
|
|
60
|
+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `release_type=${releaseType}\nnpm_publish=${npmPublish}\n`)
|
|
61
|
+
NODE
|
|
74
62
|
- name: Release Please
|
|
75
63
|
id: release
|
|
76
64
|
if: steps.profile.outputs.release_type != 'none'
|