@kungfu-tech/buildchain 2.11.14-alpha.5 → 2.11.14-alpha.7
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/AGENTS.md +11 -0
- package/actions/promote-buildchain-ref/README.md +8 -5
- package/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +27 -22
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/kfd-claims.json +19 -5
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +5 -5
- package/dist/site/page-registry.json +17 -12
- package/dist/site/public-surface-audit.json +9 -3
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-model.json +1 -1
- package/dist/site/site-manifest.json +9 -9
- package/dist/site/workflow-registry.json +9 -0
- package/docs/MAP.md +3 -1
- package/docs/release-flow.md +9 -3
- package/docs/release-governance.md +43 -2
- package/docs/reusable-build-surface.md +16 -1
- package/docs/runtime-train-validation.md +14 -4
- package/package.json +1 -1
- package/packages/core/release-line-dry-run.js +9 -2
- package/scripts/check-inventory.mjs +53 -0
- package/scripts/generate-site-bundle.mjs +1 -1
- package/scripts/runtime-ref-core.mjs +32 -5
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"status": "passed",
|
|
5
5
|
"summary": {
|
|
6
6
|
"cliCommandCount": 75,
|
|
7
|
-
"workflowCount":
|
|
7
|
+
"workflowCount": 38,
|
|
8
8
|
"actionCount": 4,
|
|
9
9
|
"sitePageCount": 45,
|
|
10
10
|
"docCommandRefCount": 237,
|
|
@@ -684,6 +684,12 @@
|
|
|
684
684
|
],
|
|
685
685
|
"inputCount": 1
|
|
686
686
|
},
|
|
687
|
+
{
|
|
688
|
+
"id": "buildchain-alpha-self-dogfood",
|
|
689
|
+
"path": ".github/workflows/buildchain-alpha-self-dogfood.yml",
|
|
690
|
+
"inputs": [],
|
|
691
|
+
"inputCount": 0
|
|
692
|
+
},
|
|
687
693
|
{
|
|
688
694
|
"id": "buildchain-patrol-daily",
|
|
689
695
|
"path": ".github/workflows/buildchain-patrol-daily.yml",
|
|
@@ -2540,8 +2546,8 @@
|
|
|
2540
2546
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
2541
2547
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
2542
2548
|
"cliRegistryDigest": "3c0729f5351eb82fe26625fa5aabf30903f45f68af2431e02860f85ada468ac9",
|
|
2543
|
-
"workflowRegistryDigest": "
|
|
2544
|
-
"pageRegistryDigest": "
|
|
2549
|
+
"workflowRegistryDigest": "5875dd6440e9585dc8ce86fc61af8546a60ae1140ed25789199adead2846d4fe",
|
|
2550
|
+
"pageRegistryDigest": "de7377d68eb8b3069b83a2096de8ea24153090e746649015388224b9997e2340"
|
|
2545
2551
|
},
|
|
2546
2552
|
"comparison": {
|
|
2547
2553
|
"missingCliRegistry": [],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-publication-release-registry",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-11T00:08:19.877Z",
|
|
5
|
+
"publishedAt": "2026-07-11T00:08:19.877Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "7d3f049ffc8b567c3afad9fa9f8e974b50fd3b90",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"package": {
|
|
34
34
|
"name": "@kungfu-tech/buildchain",
|
|
35
|
-
"version": "2.11.14-alpha.
|
|
35
|
+
"version": "2.11.14-alpha.7",
|
|
36
36
|
"versionSource": "package.json#version"
|
|
37
37
|
},
|
|
38
38
|
"sourceKind": "package-site-bundle",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-release-model",
|
|
4
4
|
"exactTags": "v-prefixed exact tags are immutable release records.",
|
|
5
|
-
"floatingTags": "vX, vX.Y, and vX.Y-alpha are channel pointers updated by Buildchain transactions.",
|
|
5
|
+
"floatingTags": "vX, vX-alpha, vX.Y, and vX.Y-alpha are channel pointers updated by Buildchain transactions; vX-alpha follows the highest minor in major X with a published alpha.",
|
|
6
6
|
"channelBranches": [
|
|
7
7
|
"dev/vX/vX.Y",
|
|
8
8
|
"alpha/vX/vX.Y",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-manifest",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-11T00:08:19.877Z",
|
|
5
|
+
"publishedAt": "2026-07-11T00:08:19.877Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "7d3f049ffc8b567c3afad9fa9f8e974b50fd3b90",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "2.11.14-alpha.
|
|
40
|
+
"version": "2.11.14-alpha.7",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"entrypoint": "buildchain-site.json",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"path": "docs/MAP.md",
|
|
54
54
|
"plane": "use",
|
|
55
55
|
"exists": true,
|
|
56
|
-
"digest": "sha256:
|
|
56
|
+
"digest": "sha256:02987c6bf99441eddc630fa4050fd109c15923047a4591e26d54a714c124539a"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"id": "install",
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
"path": "docs/reusable-build-surface.md",
|
|
206
206
|
"plane": "use",
|
|
207
207
|
"exists": true,
|
|
208
|
-
"digest": "sha256:
|
|
208
|
+
"digest": "sha256:4611e4ae47091687f50b489ccc6caba911f13bb1f73b27a5d44581d8a6450d06"
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
211
|
"id": "publish-transaction",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
"path": "docs/release-governance.md",
|
|
222
222
|
"plane": "why",
|
|
223
223
|
"exists": true,
|
|
224
|
-
"digest": "sha256:
|
|
224
|
+
"digest": "sha256:69c4146640626bc03b93ac178e250745e45939ba9443f3ba27207a35522036c4"
|
|
225
225
|
},
|
|
226
226
|
{
|
|
227
227
|
"id": "release-flow",
|
|
@@ -229,7 +229,7 @@
|
|
|
229
229
|
"path": "docs/release-flow.md",
|
|
230
230
|
"plane": "verify",
|
|
231
231
|
"exists": true,
|
|
232
|
-
"digest": "sha256:
|
|
232
|
+
"digest": "sha256:c05905de6a905d1ce0dd977986175b8bc1ad908c6c2eee946809693ea2cb91de"
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
235
|
"id": "runtime-train-validation",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
"path": "docs/runtime-train-validation.md",
|
|
238
238
|
"plane": "verify",
|
|
239
239
|
"exists": true,
|
|
240
|
-
"digest": "sha256:
|
|
240
|
+
"digest": "sha256:1872e511b31c04ba75fc3a005c7a4f857c8b06ecadfedb75bc35b2ce70e7764a"
|
|
241
241
|
},
|
|
242
242
|
{
|
|
243
243
|
"id": "versioning",
|
|
@@ -343,6 +343,15 @@
|
|
|
343
343
|
"capabilityGroup": "api-cli-reference",
|
|
344
344
|
"status": "repository-internal"
|
|
345
345
|
},
|
|
346
|
+
{
|
|
347
|
+
"id": "buildchain-alpha-self-dogfood",
|
|
348
|
+
"path": ".github/workflows/buildchain-alpha-self-dogfood.yml",
|
|
349
|
+
"inputs": [],
|
|
350
|
+
"inputCount": 0,
|
|
351
|
+
"surface": "repository-workflow",
|
|
352
|
+
"capabilityGroup": "api-cli-reference",
|
|
353
|
+
"status": "active"
|
|
354
|
+
},
|
|
346
355
|
{
|
|
347
356
|
"id": "buildchain-patrol-daily",
|
|
348
357
|
"path": ".github/workflows/buildchain-patrol-daily.yml",
|
package/docs/MAP.md
CHANGED
|
@@ -111,9 +111,11 @@ replace them.
|
|
|
111
111
|
|
|
112
112
|
- **ABV / old workflows / old action repositories** -> [`release-governance.md`](release-governance.md)
|
|
113
113
|
and [`migration-inventory.md`](migration-inventory.md).
|
|
114
|
-
- **v2 / v2.0 / v2.0-alpha / exact tags / floating tags** ->
|
|
114
|
+
- **v2 / v2-alpha / v2.0 / v2.0-alpha / exact tags / floating tags** ->
|
|
115
115
|
[`release-governance.md`](release-governance.md) and
|
|
116
116
|
[`release-flow.md`](release-flow.md).
|
|
117
|
+
- **Buildchain self-dogfood / released alpha canary / stable compatibility lane** ->
|
|
118
|
+
[`release-governance.md`](release-governance.md#buildchain-alpha-self-dogfood).
|
|
117
119
|
- **v2.1 vs v2.2 / when to open a new minor line** ->
|
|
118
120
|
[`versioning.md`](versioning.md).
|
|
119
121
|
- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)
|
package/docs/release-flow.md
CHANGED
|
@@ -53,6 +53,7 @@ for the versioned policy and evidence contract.
|
|
|
53
53
|
| Exact alpha tag | `v2.0.3-alpha.0` | immutable | audit ref for one tested prerelease |
|
|
54
54
|
| Exact release tag | `v2.0.2` | immutable | audit ref for one production release |
|
|
55
55
|
| Floating alpha tag | `v2.0-alpha` | moves | latest test channel for a minor line |
|
|
56
|
+
| Floating major alpha tag | `v2-alpha` | moves | latest test channel on the highest published alpha minor for a major line |
|
|
56
57
|
| Floating minor tag | `v2.0` | moves | latest production patch on a minor line |
|
|
57
58
|
| Floating major tag | `v2` | moves | selected stable major entrypoint |
|
|
58
59
|
|
|
@@ -68,8 +69,8 @@ refs/tags/v*.*.*
|
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
Do not apply immutable-tag rulesets to every `refs/tags/v*` ref. Buildchain
|
|
71
|
-
must be able to update floating channel tags such as `v2`, `v2.0`,
|
|
72
|
-
`v2
|
|
72
|
+
must be able to update floating channel tags such as `v2`, `v2.0`, `v2.0-alpha`,
|
|
73
|
+
and `v2-alpha` after the exact tag and publish evidence are valid. A ruleset that
|
|
73
74
|
matches all `v*` tags also matches floating tags, so release finalization can
|
|
74
75
|
fail with GitHub protected-ref errors even though the exact release tag and
|
|
75
76
|
published artifacts are already durable.
|
|
@@ -77,7 +78,7 @@ published artifacts are already durable.
|
|
|
77
78
|
The intended governance split is:
|
|
78
79
|
|
|
79
80
|
- exact tags such as `v2.0.14` and `v2.0.15-alpha.0` are immutable audit refs;
|
|
80
|
-
- floating tags such as `v2`, `v2.0`,
|
|
81
|
+
- floating tags such as `v2`, `v2.0`, `v2.0-alpha`, and `v2-alpha` are mutable channel refs
|
|
81
82
|
owned by the Buildchain promotion token;
|
|
82
83
|
- protected branches still require reviewed channel PRs before Buildchain can
|
|
83
84
|
move any exact or floating release refs.
|
|
@@ -134,6 +135,7 @@ sequenceDiagram
|
|
|
134
135
|
Promote->>Promote: write and verify version state
|
|
135
136
|
Promote->>Tags: create or reuse vX.Y.Z-alpha.N
|
|
136
137
|
Promote->>Tags: move vX.Y-alpha
|
|
138
|
+
Promote->>Tags: move vX-alpha when X.Y is the highest published alpha minor
|
|
137
139
|
Promote->>Alpha: move alpha/vX/vX.Y
|
|
138
140
|
Promote->>Dev: move dev/vX/vX.Y
|
|
139
141
|
```
|
|
@@ -143,6 +145,7 @@ Result:
|
|
|
143
145
|
```text
|
|
144
146
|
vX.Y.Z-alpha.N
|
|
145
147
|
vX.Y-alpha
|
|
148
|
+
vX-alpha when X.Y is the highest published alpha minor
|
|
146
149
|
alpha/vX/vX.Y
|
|
147
150
|
dev/vX/vX.Y
|
|
148
151
|
```
|
|
@@ -177,6 +180,7 @@ sequenceDiagram
|
|
|
177
180
|
Promote->>Promote: prepare vX.Y.(Z+1)-alpha.0
|
|
178
181
|
Promote->>Tags: create or reuse vX.Y.(Z+1)-alpha.0
|
|
179
182
|
Promote->>Tags: move vX.Y-alpha
|
|
183
|
+
Promote->>Tags: move vX-alpha when X.Y is the highest published alpha minor
|
|
180
184
|
Promote->>Alpha: move alpha/vX/vX.Y
|
|
181
185
|
Promote->>Dev: move dev/vX/vX.Y
|
|
182
186
|
```
|
|
@@ -195,6 +199,7 @@ point at the production version-state commit, while:
|
|
|
195
199
|
```text
|
|
196
200
|
vX.Y.(Z+1)-alpha.0
|
|
197
201
|
vX.Y-alpha
|
|
202
|
+
vX-alpha when X.Y is the highest published alpha minor
|
|
198
203
|
alpha/vX/vX.Y
|
|
199
204
|
dev/vX/vX.Y
|
|
200
205
|
```
|
|
@@ -235,6 +240,7 @@ It should also prepare:
|
|
|
235
240
|
```text
|
|
236
241
|
v2.0.3-alpha.0 exact next alpha tag
|
|
237
242
|
v2.0-alpha floating alpha tag
|
|
243
|
+
v2-alpha floating major alpha tag when v2.0 is the highest published alpha minor
|
|
238
244
|
alpha/v2/v2.0 alpha channel branch
|
|
239
245
|
dev/v2/v2.0 development channel branch
|
|
240
246
|
```
|
|
@@ -128,13 +128,14 @@ This is why Buildchain maintains both exact and floating refs:
|
|
|
128
128
|
- `v2` is the selected stable major-line entrypoint;
|
|
129
129
|
- `v2.0.3-alpha.0` is immutable alpha evidence;
|
|
130
130
|
- `v2.0-alpha` is the latest test channel for the `2.0` line.
|
|
131
|
+
- `v2-alpha` is the latest test channel on the highest published alpha minor in major `2`.
|
|
131
132
|
|
|
132
133
|
A release does not mean "minor is complete." It means "this patch on this minor
|
|
133
134
|
line is now production."
|
|
134
135
|
|
|
135
136
|
GitHub repository rules must preserve that distinction. Exact tags such as
|
|
136
137
|
`v2.0.2` and `v2.0.3-alpha.0` should be immutable. Floating channel tags such as
|
|
137
|
-
`v2`, `v2.0`,
|
|
138
|
+
`v2`, `v2.0`, `v2.0-alpha`, and `v2-alpha` must remain movable by the Buildchain promotion
|
|
138
139
|
token after governance checks and publish evidence pass. A tag ruleset that
|
|
139
140
|
protects every `refs/tags/v*` ref is too broad because it also locks the
|
|
140
141
|
floating channel tags that Buildchain is required to update. Prefer exact-tag
|
|
@@ -159,9 +160,47 @@ Buildchain then:
|
|
|
159
160
|
6. Moves `dev/vX/vX.Y` to the same generated alpha commit when this is a
|
|
160
161
|
fast-forward update.
|
|
161
162
|
7. Moves `vX.Y-alpha` to the same generated alpha commit.
|
|
163
|
+
8. Moves `vX-alpha` only when `X.Y` is the highest minor in major `X` with a published alpha; older minor alpha work records a skip and cannot move the major channel backwards.
|
|
162
164
|
|
|
163
165
|
This keeps the test channel self-describing. If a consumer checks out
|
|
164
|
-
`v2.0-alpha`, the manifests and exact alpha tag agree.
|
|
166
|
+
`v2.0-alpha` or `v2-alpha`, the manifests and exact alpha tag agree. The major
|
|
167
|
+
alpha ref removes routine consumer edits when Buildchain opens a newer minor,
|
|
168
|
+
while exact tags and SHAs remain the reproducible audit choice.
|
|
169
|
+
|
|
170
|
+
### Buildchain Alpha Self-Dogfood
|
|
171
|
+
|
|
172
|
+
Buildchain continuously consumes its own current major alpha through
|
|
173
|
+
`.github/workflows/buildchain-alpha-self-dogfood.yml`. The workflow calls the
|
|
174
|
+
released outer reusable workflow at `@v2-alpha` without a runtime override, so
|
|
175
|
+
both the workflow shell and its default runtime must resolve through the same
|
|
176
|
+
floating alpha channel. A parallel stable lane checks out `v2` and runs the
|
|
177
|
+
same declared install, build, and verify lifecycle directly. The direct stable
|
|
178
|
+
lane is intentional: it preserves stable-runtime compatibility without
|
|
179
|
+
requiring the previous stable outer workflow to understand a self-call identity
|
|
180
|
+
fix that has not reached stable yet. Both lanes use a single GitHub-hosted Linux
|
|
181
|
+
fixture to keep the recurring check bounded.
|
|
182
|
+
|
|
183
|
+
The reusable build trust gate reads `job.workflow_ref`, which identifies the
|
|
184
|
+
called workflow and its selected ref. It does not infer the runtime from
|
|
185
|
+
`github.workflow_ref`, because GitHub defines that context as the caller
|
|
186
|
+
workflow identity during a reusable call.
|
|
187
|
+
|
|
188
|
+
The evidence job resolves `v2-alpha` and `v2` through the GitHub refs API,
|
|
189
|
+
compares those immutable SHAs with the reusable workflow outputs, verifies the
|
|
190
|
+
`alpha` and `stable` classifications, and uploads a JSON evidence artifact.
|
|
191
|
+
The canary runs after successful Buildchain ref promotion, on a daily fallback
|
|
192
|
+
schedule, and on manual dispatch. It shares the release-promotion concurrency
|
|
193
|
+
group, so another promotion cannot move the floating refs between runtime
|
|
194
|
+
resolution and evidence comparison.
|
|
195
|
+
|
|
196
|
+
This is a post-publication consumer canary, not a release bootstrap. Source
|
|
197
|
+
verification still runs the current commit, and
|
|
198
|
+
`buildchain-ref-promotion.yml` still passes the verified exact SHA into the
|
|
199
|
+
promotion workflow. Patrol, dev-merge, repair, and promotion defaults remain on
|
|
200
|
+
stable or exact refs so a broken alpha cannot prevent Buildchain from publishing
|
|
201
|
+
its fix. When Buildchain opens a new major, inventory validation requires this
|
|
202
|
+
workflow's fixed GitHub `uses` refs to move from `vN`/`vN-alpha` to the new
|
|
203
|
+
major; GitHub does not allow expressions in a reusable-workflow `uses` ref.
|
|
165
204
|
|
|
166
205
|
If `dev/vX/vX.Y` has already advanced before generated alpha version-state
|
|
167
206
|
bookkeeping can sync back, Buildchain records `skipped-non-fast-forward` for the
|
|
@@ -201,6 +240,7 @@ Buildchain then:
|
|
|
201
240
|
`vX.Y.(Z+1)-alpha.0`.
|
|
202
241
|
10. Moves `alpha/vX/vX.Y`, `dev/vX/vX.Y`, and `vX.Y-alpha` to that next alpha
|
|
203
242
|
commit.
|
|
243
|
+
11. Moves `vX-alpha` to that next alpha only when this remains the highest published alpha minor.
|
|
204
244
|
|
|
205
245
|
The production channel and the test channel therefore intentionally diverge
|
|
206
246
|
after release: production stays on the release commit, while alpha/dev continue
|
|
@@ -513,6 +553,7 @@ When the loop succeeds, maintainers and consumers can rely on these facts:
|
|
|
513
553
|
not a hidden manual button;
|
|
514
554
|
- every test channel has an exact alpha tag such as `v2.0.3-alpha.0`;
|
|
515
555
|
- every alpha minor line has a floating tag such as `v2.0-alpha`;
|
|
556
|
+
- every major with a published alpha has a cross-minor floating tag such as `v2-alpha`, owned by its highest published alpha minor;
|
|
516
557
|
- version manifests match the tag visible from the same commit;
|
|
517
558
|
- production releases are derived from the alpha tree that was tested;
|
|
518
559
|
- manual non-dry-run promotion cannot bypass PR review and verification;
|
|
@@ -214,6 +214,21 @@ The lock is intentionally small. It does not copy the full contract. The full
|
|
|
214
214
|
contract remains in the Buildchain ref and package; the consumer records only
|
|
215
215
|
what it accepted and the policy used to compare future floating-ref movement.
|
|
216
216
|
|
|
217
|
+
Alpha-channel consumers select the matching workflow shell:
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
jobs:
|
|
221
|
+
build:
|
|
222
|
+
uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2-alpha
|
|
223
|
+
with:
|
|
224
|
+
buildchain-contract-lock-path: .buildchain/contract-lock.json
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The runtime follows the called workflow through `job.workflow_ref`. Callers may
|
|
228
|
+
also pass `buildchain-ref: v2-alpha` explicitly; official floating refs are
|
|
229
|
+
ordinary channel selections and are allowed on pull requests and pushes. Train
|
|
230
|
+
refs and exact SHAs remain trusted manual overrides.
|
|
231
|
+
|
|
217
232
|
## Locked Source Checkout Cache
|
|
218
233
|
|
|
219
234
|
Self-hosted runners that build large repositories can opt into a locked source
|
|
@@ -309,7 +324,7 @@ The reusable workflow exposes the resolved contract:
|
|
|
309
324
|
| `buildchain-runtime-ref` | Runtime ref selected after applying the empty-default or override policy |
|
|
310
325
|
| `buildchain-runtime-sha` | Immutable Buildchain runtime commit used by all runtime checkouts |
|
|
311
326
|
| `buildchain-runtime-class` | `stable`, `alpha`, `train`, `exact-sha`, or `development` |
|
|
312
|
-
| `buildchain-runtime-override` | `true` when a
|
|
327
|
+
| `buildchain-runtime-override` | `true` when a train or exact-SHA `buildchain-ref` override was accepted |
|
|
313
328
|
| `buildchain-runtime-trust-decision` | Runtime override trust decision |
|
|
314
329
|
| `buildchain-contract-lock-status` | `unchanged`, `compatible-drift`, `breaking-drift`, `missing-lock`, `non-floating-runtime`, or first-release `runtime-contract-unavailable` |
|
|
315
330
|
| `buildchain-contract-lock-drift` | `true` when the floating runtime SHA or contract digest changed |
|
|
@@ -5,6 +5,14 @@ committed workflow YAML. Runtime trains provide a temporary validation pointer
|
|
|
5
5
|
for Buildchain changes that are ready for downstream testing but not yet
|
|
6
6
|
promoted through the normal `dev -> alpha -> release` chain.
|
|
7
7
|
|
|
8
|
+
Official floating channels are not runtime overrides. A consumer that
|
|
9
|
+
deliberately follows `@v2-alpha` gets the matching runtime on pull requests and
|
|
10
|
+
pushes because the reusable workflow reads the called workflow identity from
|
|
11
|
+
`job.workflow_ref`. Passing `buildchain-ref: v2-alpha` explicitly is also
|
|
12
|
+
accepted when the caller wants the channel binding visible in its input set.
|
|
13
|
+
The caller's `github.workflow_ref` is not used for this inference because it
|
|
14
|
+
identifies the caller workflow during reusable calls.
|
|
15
|
+
|
|
8
16
|
## Train refs
|
|
9
17
|
|
|
10
18
|
A train ref is a branch in the Buildchain repository:
|
|
@@ -111,10 +119,12 @@ summary. The evidence should include:
|
|
|
111
119
|
|
|
112
120
|
## Trust and limitation
|
|
113
121
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
122
|
+
Official floating channel refs such as `v2` and `v2-alpha` may be selected on
|
|
123
|
+
pull requests and pushes. Train refs and arbitrary exact-SHA overrides still
|
|
124
|
+
fail closed unless the event is `workflow_dispatch` and the actor has write,
|
|
125
|
+
maintain, or admin permission on the caller repository. Pull requests,
|
|
126
|
+
including fork-originated pull requests, cannot use train or exact-SHA
|
|
127
|
+
overrides.
|
|
118
128
|
|
|
119
129
|
Runtime train validation covers Buildchain runtime scripts, CLI code, local
|
|
120
130
|
actions, configuration parsing, and lifecycle behavior. It cannot validate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.11.14-alpha.
|
|
3
|
+
"version": "2.11.14-alpha.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
|
|
6
6
|
"repository": "https://github.com/kungfu-systems/buildchain",
|
|
@@ -23,7 +23,7 @@ function parseTags(input) {
|
|
|
23
23
|
: String(input || "").split(",").map((tag) => tag.trim()).filter(Boolean);
|
|
24
24
|
for (const tag of tags) {
|
|
25
25
|
if (
|
|
26
|
-
!/^v\d+$|^v\d+\.\d+$|^v\d+\.\d+-alpha$|^v\d+\.\d+\.\d+$|^v\d+\.\d+\.\d+-alpha\.\d+$/.test(tag)
|
|
26
|
+
!/^v\d+$|^v\d+-alpha$|^v\d+\.\d+$|^v\d+\.\d+-alpha$|^v\d+\.\d+\.\d+$|^v\d+\.\d+\.\d+-alpha\.\d+$/.test(tag)
|
|
27
27
|
) {
|
|
28
28
|
throw new Error(`Unsupported buildchain dry-run tag: ${tag}`);
|
|
29
29
|
}
|
|
@@ -42,6 +42,7 @@ function getPromotionRule(targetRef, sourceRef = "") {
|
|
|
42
42
|
sourceRef: sourceRef || "release/vN/vN.M",
|
|
43
43
|
releasePrefix: nextMajor ? `v${nextMajor}.0` : "v(N+1).0",
|
|
44
44
|
majorTag: nextMajor ? `v${nextMajor}` : "v(N+1)",
|
|
45
|
+
majorAlphaTag: nextMajor ? `v${nextMajor}-alpha` : "v(N+1)-alpha",
|
|
45
46
|
minorTag: nextMajor ? `v${nextMajor}.0` : "v(N+1).0",
|
|
46
47
|
alphaTag: nextMajor ? `v${nextMajor}.0-alpha` : "v(N+1).0-alpha",
|
|
47
48
|
exactReleasePattern: nextMajor ? `v${nextMajor}.0.0` : "v(N+1).0.0",
|
|
@@ -69,6 +70,7 @@ function getPromotionRule(targetRef, sourceRef = "") {
|
|
|
69
70
|
minor,
|
|
70
71
|
releasePrefix,
|
|
71
72
|
majorTag: `v${major}`,
|
|
73
|
+
majorAlphaTag: `v${major}-alpha`,
|
|
72
74
|
minorTag: releasePrefix,
|
|
73
75
|
alphaTag: `${releasePrefix}-alpha`,
|
|
74
76
|
sourceRef: channel === "alpha" ? `dev/v${major}/v${major}.${minor}` : `alpha/v${major}/v${major}.${minor}`,
|
|
@@ -193,7 +195,10 @@ function explainReleaseLineDryRun({
|
|
|
193
195
|
kind: "alpha",
|
|
194
196
|
action: "would create or reuse immutable alpha evidence tag",
|
|
195
197
|
});
|
|
196
|
-
plan.floatingRefs.push(
|
|
198
|
+
plan.floatingRefs.push(
|
|
199
|
+
{ ref: rule.alphaTag, kind: "tag", action: "would move to alpha version-state commit" },
|
|
200
|
+
{ ref: rule.majorAlphaTag, kind: "tag", action: "would move when this is the highest published alpha minor" },
|
|
201
|
+
);
|
|
197
202
|
plan.branchUpdates.push(
|
|
198
203
|
{ ref: targetRef, action: "would move to alpha version-state commit" },
|
|
199
204
|
{ ref: `dev/v${rule.major}/v${rule.major}.${rule.minor}`, action: "would align dev with the published alpha state" },
|
|
@@ -211,6 +216,7 @@ function explainReleaseLineDryRun({
|
|
|
211
216
|
{ ref: rule.minorTag, kind: "tag", action: "would move to production release commit" },
|
|
212
217
|
{ ref: rule.majorTag, kind: "tag", action: "would move when no newer minor line owns the major tag" },
|
|
213
218
|
{ ref: rule.alphaTag, kind: "tag", action: "would move to next alpha version-state commit" },
|
|
219
|
+
{ ref: rule.majorAlphaTag, kind: "tag", action: "would move when this is the highest published alpha minor" },
|
|
214
220
|
);
|
|
215
221
|
plan.branchUpdates.push(
|
|
216
222
|
{ ref: targetRef, action: "would move to production release commit" },
|
|
@@ -234,6 +240,7 @@ function explainReleaseLineDryRun({
|
|
|
234
240
|
{ ref: rule.minorTag, kind: "tag", action: "would move to next-major release commit" },
|
|
235
241
|
{ ref: rule.majorTag, kind: "tag", action: "would move to next-major release commit" },
|
|
236
242
|
{ ref: rule.alphaTag, kind: "tag", action: "would move to next-major alpha commit" },
|
|
243
|
+
{ ref: rule.majorAlphaTag, kind: "tag", action: "would move to next-major alpha commit" },
|
|
237
244
|
);
|
|
238
245
|
plan.branchUpdates.push(
|
|
239
246
|
{ ref: targetRef, action: "would move to next-major release commit" },
|
|
@@ -71,6 +71,7 @@ const requiredPaths = [
|
|
|
71
71
|
".github/workflows/buildchain-patrol-daily.yml",
|
|
72
72
|
".github/workflows/buildchain-patrol-weekly.yml",
|
|
73
73
|
".github/workflows/buildchain-patrol-monthly.yml",
|
|
74
|
+
".github/workflows/buildchain-alpha-self-dogfood.yml",
|
|
74
75
|
".github/workflows/release-candidate-promote.yml",
|
|
75
76
|
".github/workflows/release-propagation.yml",
|
|
76
77
|
".github/workflows/npm-publish.yml",
|
|
@@ -97,6 +98,58 @@ if (rootPackage.name !== "@kungfu-tech/buildchain") {
|
|
|
97
98
|
if (rootPackage.private !== false) {
|
|
98
99
|
throw new Error("root package must be publishable with private=false");
|
|
99
100
|
}
|
|
101
|
+
const selfDogfoodWorkflow = fs.readFileSync(
|
|
102
|
+
path.join(root, ".github/workflows/buildchain-alpha-self-dogfood.yml"),
|
|
103
|
+
"utf8",
|
|
104
|
+
);
|
|
105
|
+
const selfDogfoodMajor = String(rootPackage.version || "").match(/^(\d+)\./)?.[1];
|
|
106
|
+
if (!selfDogfoodMajor) {
|
|
107
|
+
throw new Error("root package version must expose a numeric major for self-dogfood");
|
|
108
|
+
}
|
|
109
|
+
for (const requiredSnippet of [
|
|
110
|
+
`/.github/workflows/.build.yml@v${selfDogfoodMajor}-alpha`,
|
|
111
|
+
`ref: v${selfDogfoodMajor}`,
|
|
112
|
+
`echo "ref=v${selfDogfoodMajor}"`,
|
|
113
|
+
`const alphaRef = "v${selfDogfoodMajor}-alpha"`,
|
|
114
|
+
`const stableRef = "v${selfDogfoodMajor}"`,
|
|
115
|
+
]) {
|
|
116
|
+
if (!selfDogfoodWorkflow.includes(requiredSnippet)) {
|
|
117
|
+
throw new Error(`Buildchain self-dogfood workflow missing current-major snippet: ${requiredSnippet}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const reusableBuildWorkflow = fs.readFileSync(
|
|
121
|
+
path.join(root, ".github/workflows/.build.yml"),
|
|
122
|
+
"utf8",
|
|
123
|
+
);
|
|
124
|
+
for (const requiredSnippet of [
|
|
125
|
+
"BUILDCHAIN_WORKFLOW_REF: ${{ job.workflow_ref }}",
|
|
126
|
+
"process.env.BUILDCHAIN_WORKFLOW_REF || process.env.GITHUB_WORKFLOW_REF",
|
|
127
|
+
'replace(/^refs\\/(?:heads|tags)\\//, "")',
|
|
128
|
+
]) {
|
|
129
|
+
if (!reusableBuildWorkflow.includes(requiredSnippet)) {
|
|
130
|
+
throw new Error(`reusable build workflow missing called-workflow identity: ${requiredSnippet}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (const requiredSnippet of [
|
|
134
|
+
"group: buildchain-release-promotion-${{ github.repository }}",
|
|
135
|
+
"cancel-in-progress: false",
|
|
136
|
+
]) {
|
|
137
|
+
if (!selfDogfoodWorkflow.includes(requiredSnippet)) {
|
|
138
|
+
throw new Error(`Buildchain self-dogfood workflow missing promotion serialization: ${requiredSnippet}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const actionlintConfig = fs.readFileSync(
|
|
142
|
+
path.join(root, ".github/actionlint.yaml"),
|
|
143
|
+
"utf8",
|
|
144
|
+
);
|
|
145
|
+
for (const requiredSnippet of [
|
|
146
|
+
".github/workflows/.build.yml:",
|
|
147
|
+
'property "workflow_ref" is not defined in object type',
|
|
148
|
+
]) {
|
|
149
|
+
if (!actionlintConfig.includes(requiredSnippet)) {
|
|
150
|
+
throw new Error(`actionlint config missing scoped job.workflow_ref compatibility rule: ${requiredSnippet}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
100
153
|
const packageDependencySections = ["dependencies", "optionalDependencies", "peerDependencies"];
|
|
101
154
|
const exoticDependencyPattern =
|
|
102
155
|
/^(?:git(?:\+ssh|\+https|\+http|\+file)?:|github:|gitlab:|bitbucket:|https?:|file:|link:|workspace:)/i;
|
|
@@ -872,7 +872,7 @@ function buildSiteBundle() {
|
|
|
872
872
|
schemaVersion: 1,
|
|
873
873
|
contract: "kungfu-buildchain-release-model",
|
|
874
874
|
exactTags: "v-prefixed exact tags are immutable release records.",
|
|
875
|
-
floatingTags: "vX, vX.Y, and vX.Y-alpha are channel pointers updated by Buildchain transactions.",
|
|
875
|
+
floatingTags: "vX, vX-alpha, vX.Y, and vX.Y-alpha are channel pointers updated by Buildchain transactions; vX-alpha follows the highest minor in major X with a published alpha.",
|
|
876
876
|
channelBranches: ["dev/vX/vX.Y", "alpha/vX/vX.Y", "release/vX/vX.Y", "publish-gate/major"],
|
|
877
877
|
protectedDevelopmentBranches: ["dev/vX/vX.Y"],
|
|
878
878
|
releasePassport: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const EXACT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
2
2
|
const TRAIN_REF_RE = /^train\/v\d+\/v\d+\.\d+\/[A-Za-z0-9._/-]+$/;
|
|
3
|
+
const OFFICIAL_CHANNEL_REF_RE = /^v\d+(?:\.\d+)?(?:-alpha)?$/;
|
|
3
4
|
|
|
4
5
|
export function parseWorkflowShellRef(workflowRef = "", fallback = "v2", buildchainRepository = "kungfu-systems/buildchain") {
|
|
5
6
|
const value = String(workflowRef || "");
|
|
@@ -8,7 +9,7 @@ export function parseWorkflowShellRef(workflowRef = "", fallback = "v2", buildch
|
|
|
8
9
|
return fallback;
|
|
9
10
|
}
|
|
10
11
|
const ref = value.split("@").pop()?.trim();
|
|
11
|
-
return ref || fallback;
|
|
12
|
+
return (ref || fallback).replace(/^refs\/(?:heads|tags)\//, "");
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export function classifyBuildchainRuntimeRef(ref = "") {
|
|
@@ -28,13 +29,34 @@ export function classifyBuildchainRuntimeRef(ref = "") {
|
|
|
28
29
|
return "development";
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
export function isOfficialBuildchainChannelRef(ref = "") {
|
|
33
|
+
const value = String(ref || "").trim().replace(/^refs\/tags\//, "");
|
|
34
|
+
return OFFICIAL_CHANNEL_REF_RE.test(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
export function normalizeRequestedRuntimeRef(requestedRef = "") {
|
|
32
38
|
const requested = String(requestedRef || "").trim();
|
|
33
39
|
if (!requested) {
|
|
34
|
-
return { ref: "", fullRef: "", class: "", exactSha: false };
|
|
40
|
+
return { ref: "", fullRef: "", class: "", exactSha: false, officialChannel: false };
|
|
41
|
+
}
|
|
42
|
+
if (isOfficialBuildchainChannelRef(requested)) {
|
|
43
|
+
const channelRef = requested.replace(/^refs\/tags\//, "");
|
|
44
|
+
return {
|
|
45
|
+
ref: channelRef,
|
|
46
|
+
fullRef: channelRef,
|
|
47
|
+
class: classifyBuildchainRuntimeRef(channelRef),
|
|
48
|
+
exactSha: false,
|
|
49
|
+
officialChannel: true,
|
|
50
|
+
};
|
|
35
51
|
}
|
|
36
52
|
if (EXACT_SHA_RE.test(requested)) {
|
|
37
|
-
return {
|
|
53
|
+
return {
|
|
54
|
+
ref: requested,
|
|
55
|
+
fullRef: requested,
|
|
56
|
+
class: "exact-sha",
|
|
57
|
+
exactSha: true,
|
|
58
|
+
officialChannel: false,
|
|
59
|
+
};
|
|
38
60
|
}
|
|
39
61
|
const trainRef = requested.replace(/^refs\/heads\//, "");
|
|
40
62
|
if (!TRAIN_REF_RE.test(trainRef)) {
|
|
@@ -47,6 +69,7 @@ export function normalizeRequestedRuntimeRef(requestedRef = "") {
|
|
|
47
69
|
fullRef: `refs/heads/${trainRef}`,
|
|
48
70
|
class: "train",
|
|
49
71
|
exactSha: false,
|
|
72
|
+
officialChannel: false,
|
|
50
73
|
};
|
|
51
74
|
}
|
|
52
75
|
|
|
@@ -71,15 +94,16 @@ export function resolveRuntimeSelection({
|
|
|
71
94
|
};
|
|
72
95
|
}
|
|
73
96
|
const normalized = normalizeRequestedRuntimeRef(requested);
|
|
97
|
+
const runtimeOverride = !normalized.officialChannel;
|
|
74
98
|
return {
|
|
75
99
|
requestedRef: requested,
|
|
76
100
|
runtimeRef: normalized.ref,
|
|
77
101
|
runtimeFullRef: normalized.fullRef,
|
|
78
102
|
runtimeClass: normalized.class,
|
|
79
|
-
runtimeOverride
|
|
103
|
+
runtimeOverride,
|
|
80
104
|
workflowShellRef: workflowShellRef || defaultStableRef,
|
|
81
105
|
rollbackRef: workflowShellRef || defaultStableRef,
|
|
82
|
-
trustDecision: "override-requested",
|
|
106
|
+
trustDecision: normalized.officialChannel ? "official-channel" : "override-requested",
|
|
83
107
|
};
|
|
84
108
|
}
|
|
85
109
|
|
|
@@ -91,6 +115,9 @@ export function validateRuntimeOverrideTrust({
|
|
|
91
115
|
if (!String(requestedRef || "").trim()) {
|
|
92
116
|
return { ok: true, decision: "stable-default" };
|
|
93
117
|
}
|
|
118
|
+
if (isOfficialBuildchainChannelRef(requestedRef)) {
|
|
119
|
+
return { ok: true, decision: "official-channel" };
|
|
120
|
+
}
|
|
94
121
|
if (eventName !== "workflow_dispatch") {
|
|
95
122
|
return {
|
|
96
123
|
ok: false,
|