@kungfu-tech/buildchain 2.12.0 → 2.12.1-alpha.2
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/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +57 -11
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/kfd-claims.json +79 -7
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +3 -2
- package/dist/site/node-api-registry.json +15 -2
- package/dist/site/page-registry.json +51 -5
- package/dist/site/public-surface-audit.json +40 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +1 -0
- package/dist/site/site-manifest.json +6 -6
- package/dist/site/workflow-registry.json +38 -0
- package/docs/MAP.md +3 -0
- package/docs/release-governance.md +16 -0
- package/docs/stable-candidate-patrol.md +172 -0
- package/package.json +2 -1
- package/packages/core/buildchain-config.js +58 -0
- package/packages/core/index.js +15 -0
- package/packages/core/stable-candidate-ledger.js +276 -0
- package/scripts/generate-site-bundle.mjs +5 -0
- package/scripts/stable-candidate-patrol.mjs +448 -0
- package/scripts/stable-candidate-policy.mjs +25 -0
|
@@ -489,6 +489,19 @@
|
|
|
489
489
|
"capabilityGroup": "release-passport-trust",
|
|
490
490
|
"status": "active"
|
|
491
491
|
},
|
|
492
|
+
{
|
|
493
|
+
"id": "buildchain-stable-candidate-patrol",
|
|
494
|
+
"path": ".github/workflows/buildchain-stable-candidate-patrol.yml",
|
|
495
|
+
"inputs": [
|
|
496
|
+
"buildchain-ref",
|
|
497
|
+
"dry-run",
|
|
498
|
+
"release-now"
|
|
499
|
+
],
|
|
500
|
+
"inputCount": 3,
|
|
501
|
+
"surface": "repository-patrol",
|
|
502
|
+
"capabilityGroup": "governance-versioning",
|
|
503
|
+
"status": "active"
|
|
504
|
+
},
|
|
492
505
|
{
|
|
493
506
|
"id": "candidate-lab",
|
|
494
507
|
"path": ".github/workflows/candidate-lab.yml",
|
|
@@ -805,6 +818,31 @@
|
|
|
805
818
|
"capabilityGroup": "api-cli-reference",
|
|
806
819
|
"status": "compatibility-fixture"
|
|
807
820
|
},
|
|
821
|
+
{
|
|
822
|
+
"id": "stable-candidate-patrol",
|
|
823
|
+
"path": ".github/workflows/stable-candidate-patrol.yml",
|
|
824
|
+
"inputs": [
|
|
825
|
+
"auto-approve",
|
|
826
|
+
"auto-merge",
|
|
827
|
+
"auto-promote",
|
|
828
|
+
"buildchain-ref",
|
|
829
|
+
"buildchain-repository",
|
|
830
|
+
"dry-run",
|
|
831
|
+
"hold",
|
|
832
|
+
"hold-reason",
|
|
833
|
+
"ledger-ref",
|
|
834
|
+
"minimum-soak-seconds",
|
|
835
|
+
"release-now",
|
|
836
|
+
"required-checks",
|
|
837
|
+
"revoke-reason",
|
|
838
|
+
"revoked-versions",
|
|
839
|
+
"target-branch"
|
|
840
|
+
],
|
|
841
|
+
"inputCount": 15,
|
|
842
|
+
"surface": "repository-patrol",
|
|
843
|
+
"capabilityGroup": "governance-versioning",
|
|
844
|
+
"status": "active"
|
|
845
|
+
},
|
|
808
846
|
{
|
|
809
847
|
"id": "verify",
|
|
810
848
|
"path": ".github/workflows/verify.yml",
|
package/docs/MAP.md
CHANGED
|
@@ -99,6 +99,7 @@ replace them.
|
|
|
99
99
|
| How do self-hosted runners relay large artifacts through S3 before GitHub artifacts? | [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay) | use | stable |
|
|
100
100
|
| How do self-hosted runners reuse local Git checkout caches without weakening source locks? | [`reusable-build-surface.md`](reusable-build-surface.md#locked-source-checkout-cache) | use | stable |
|
|
101
101
|
| How do I validate an unreleased Buildchain runtime train while keeping `@v2`? | [`runtime-train-validation.md`](runtime-train-validation.md) | use | stable |
|
|
102
|
+
| How do I automatically qualify alpha candidates and publish the newest non-revoked qualified candidate at a fixed window? | [`stable-candidate-patrol.md`](stable-candidate-patrol.md) | use | preview |
|
|
102
103
|
| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |
|
|
103
104
|
| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |
|
|
104
105
|
| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |
|
|
@@ -117,6 +118,8 @@ replace them.
|
|
|
117
118
|
[`release-flow.md`](release-flow.md).
|
|
118
119
|
- **Buildchain self-dogfood / released alpha canary / stable compatibility lane** ->
|
|
119
120
|
[`release-governance.md`](release-governance.md#buildchain-alpha-self-dogfood).
|
|
121
|
+
- **qualified alpha ledger / scheduled stable selection / hold and revoke** ->
|
|
122
|
+
[`stable-candidate-patrol.md`](stable-candidate-patrol.md).
|
|
120
123
|
- **v2.1 vs v2.2 / when to open a new minor line** ->
|
|
121
124
|
[`versioning.md`](versioning.md).
|
|
122
125
|
- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)
|
|
@@ -303,6 +303,15 @@ Compatible work should still be batched until a stable release has a concrete
|
|
|
303
303
|
consumer need. Changing the interval, canary set, attestors, product path
|
|
304
304
|
boundary, or soak time is a reviewed policy change.
|
|
305
305
|
|
|
306
|
+
Repositories that want a predictable scheduled stable window can use
|
|
307
|
+
[`Stable Candidate Patrol`](stable-candidate-patrol.md). It persists each exact
|
|
308
|
+
alpha independently, qualifies it after repository-declared checks and soak,
|
|
309
|
+
and selects the newest qualified non-revoked candidate. A newer soaking alpha
|
|
310
|
+
does not invalidate an older qualified candidate. The selected tree enters the
|
|
311
|
+
existing strict `publish-gate/release/<line>/<version> -> release/<line>` PR
|
|
312
|
+
path, so scheduled selection changes release intent timing without weakening
|
|
313
|
+
source locks, review, verification, publish transactions, or passports.
|
|
314
|
+
|
|
306
315
|
If release finalization is resumed after generated version-state bookkeeping was
|
|
307
316
|
partially applied, Buildchain applies the same recovery rule: the current
|
|
308
317
|
release head may be the generated commit, or a historical merge commit that
|
|
@@ -445,6 +454,7 @@ patrol workflow family:
|
|
|
445
454
|
| `.github/workflows/patrol-daily.yml` | daily | lightweight inspection plus ready dev PR maintenance |
|
|
446
455
|
| `.github/workflows/patrol-weekly.yml` | weekly | release-state, passport, gate, and stale-state health checks as they are added |
|
|
447
456
|
| `.github/workflows/patrol-monthly.yml` | monthly | governance, permission, branch-protection, and workflow drift checks as they are added |
|
|
457
|
+
| `.github/workflows/stable-candidate-patrol.yml` | repository-selected release window | qualify immutable alpha candidates and open the exact source-lock stable PR |
|
|
448
458
|
|
|
449
459
|
The cadence names describe patrol intensity, not release cadence:
|
|
450
460
|
|
|
@@ -453,6 +463,12 @@ The cadence names describe patrol intensity, not release cadence:
|
|
|
453
463
|
- monthly patrol is for structural drift checks that should not block ordinary
|
|
454
464
|
development velocity.
|
|
455
465
|
|
|
466
|
+
Stable Candidate Patrol is separate from those maintenance cadences because its
|
|
467
|
+
caller-owned cron is a release-intent window. Its candidate ledger and selection
|
|
468
|
+
remain generic; registry-specific side effects still run through the normal
|
|
469
|
+
repository `lifecycle.publish` transaction. See
|
|
470
|
+
[`stable-candidate-patrol.md`](stable-candidate-patrol.md).
|
|
471
|
+
|
|
456
472
|
Consumers should schedule thin callers and keep their YAML declarative. For
|
|
457
473
|
example:
|
|
458
474
|
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: preview
|
|
3
|
+
period: ongoing
|
|
4
|
+
theme: stable-candidate-patrol
|
|
5
|
+
doc_type: architecture-and-usage
|
|
6
|
+
source_level: local-files
|
|
7
|
+
confidence: high
|
|
8
|
+
sensitivity: public
|
|
9
|
+
evidence_grade: A
|
|
10
|
+
review_state: self-reviewed
|
|
11
|
+
last_reviewed: 2026-07-11
|
|
12
|
+
ai_provenance:
|
|
13
|
+
model_family: GPT-5
|
|
14
|
+
product: Codex
|
|
15
|
+
generated_at: 2026-07-11
|
|
16
|
+
visible_context: Buildchain candidate passport, stable gate, Patrol, publish transaction, exact source-lock PR contracts, tests, and user consensus.
|
|
17
|
+
invisible_context_boundary: No credentials, private logs, or unpublished consumer content were used.
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Stable Candidate Patrol
|
|
21
|
+
|
|
22
|
+
Buildchain can treat every exact alpha as an independent stable candidate. A
|
|
23
|
+
new alpha creates a new candidate; it does not silently revoke an older alpha
|
|
24
|
+
that already completed its checks and soak interval.
|
|
25
|
+
|
|
26
|
+
## Candidate lifecycle
|
|
27
|
+
|
|
28
|
+
The durable ledger contract is `kungfu-buildchain-stable-candidate-ledger`:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
registered -> soaking -> qualified -> promoted
|
|
32
|
+
\-> revoked
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Each entry binds an exact alpha version to one immutable commit SHA. Registering
|
|
36
|
+
the same version at another SHA fails closed. Qualification records the required
|
|
37
|
+
checks, their completion times, the derived soak start, and elapsed time.
|
|
38
|
+
|
|
39
|
+
Scheduled selection chooses the newest `qualified` candidate that is neither
|
|
40
|
+
`revoked` nor already `promoted`. A newer alpha that is still `soaking` does not
|
|
41
|
+
hide an older qualified candidate. Once a stable version is promoted, remaining
|
|
42
|
+
alphas for that exact stable version are closed because that immutable stable
|
|
43
|
+
version has been consumed; their later product changes continue through the
|
|
44
|
+
next patch alpha prepared by the normal release transaction.
|
|
45
|
+
|
|
46
|
+
## Repository policy
|
|
47
|
+
|
|
48
|
+
Declare the default once in `.buildchain/buildchain.toml`:
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
[release.stable]
|
|
52
|
+
strategy = "latest-qualified-alpha"
|
|
53
|
+
timezone = "Asia/Shanghai"
|
|
54
|
+
publish_at = "03:00"
|
|
55
|
+
minimum_soak_seconds = 3600
|
|
56
|
+
required_checks = [
|
|
57
|
+
"alpha-release",
|
|
58
|
+
"workflow:Build",
|
|
59
|
+
"status:buildchain-canary/consumer",
|
|
60
|
+
]
|
|
61
|
+
auto_promote = true
|
|
62
|
+
auto_merge = true
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Check identifiers use these forms:
|
|
66
|
+
|
|
67
|
+
- `alpha-release`: the exact GitHub prerelease publication fact;
|
|
68
|
+
- `workflow:<name>`: a successful Actions workflow run on the exact candidate SHA;
|
|
69
|
+
- `status:<context>`: a successful commit status on the exact candidate SHA;
|
|
70
|
+
- an unprefixed value: an exact status context or check-run name.
|
|
71
|
+
|
|
72
|
+
Candidate discovery uses immutable exact alpha Git tags. When a repository also
|
|
73
|
+
publishes GitHub prereleases, `alpha-release` binds qualification to that public
|
|
74
|
+
release fact. Repositories that intentionally disable GitHub Releases omit
|
|
75
|
+
`alpha-release` and declare their own exact-SHA workflow/status evidence; tag
|
|
76
|
+
commit time remains the earliest possible soak start.
|
|
77
|
+
|
|
78
|
+
`publish_at` and `timezone` are the auditable policy declaration. GitHub only
|
|
79
|
+
starts scheduled workflows from caller-owned cron, so the thin caller keeps the
|
|
80
|
+
matching UTC trigger:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
name: Stable Candidate Patrol
|
|
84
|
+
|
|
85
|
+
on:
|
|
86
|
+
schedule:
|
|
87
|
+
- cron: "0 19 * * *" # 03:00 Asia/Shanghai
|
|
88
|
+
workflow_dispatch:
|
|
89
|
+
inputs:
|
|
90
|
+
release-now:
|
|
91
|
+
description: Exact alpha selected by explicit human authority
|
|
92
|
+
required: false
|
|
93
|
+
default: ""
|
|
94
|
+
|
|
95
|
+
permissions:
|
|
96
|
+
contents: write
|
|
97
|
+
pull-requests: write
|
|
98
|
+
checks: read
|
|
99
|
+
statuses: read
|
|
100
|
+
|
|
101
|
+
jobs:
|
|
102
|
+
stable:
|
|
103
|
+
uses: kungfu-systems/buildchain/.github/workflows/stable-candidate-patrol.yml@v2
|
|
104
|
+
with:
|
|
105
|
+
release-now: ${{ inputs.release-now }}
|
|
106
|
+
dry-run: false
|
|
107
|
+
secrets:
|
|
108
|
+
promotion-token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The promotion token must be repository-owned and capable of creating the
|
|
112
|
+
machine ledger branch, exact source-lock branch, and pull request. Repositories
|
|
113
|
+
that require an approving review can set `auto-approve: true` only when their
|
|
114
|
+
GitHub Actions policy explicitly allows the caller token to approve the PR;
|
|
115
|
+
otherwise a repository-owned App or review bot supplies the approval. The
|
|
116
|
+
generated PR may use auto-merge, but it never bypasses the target branch checks.
|
|
117
|
+
|
|
118
|
+
## Exact-source stable promotion
|
|
119
|
+
|
|
120
|
+
For a selected `2.12.0-alpha.4`, Patrol creates the immutable source branch:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
publish-gate/release/v2/v2.12/2.12.0-alpha.4
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
and opens it against `release/v2/v2.12`. This is an existing strict Buildchain
|
|
127
|
+
governance path. The PR freezes the qualified candidate even if `v2.12-alpha`
|
|
128
|
+
or `alpha/v2/v2.12` has already moved to alpha.5. Normal Verify,
|
|
129
|
+
release-candidate resolution, source-tree equivalence, publish transaction,
|
|
130
|
+
passport, registry, tag, and floating-ref checks still run.
|
|
131
|
+
|
|
132
|
+
## Hold, revoke, and immediate release
|
|
133
|
+
|
|
134
|
+
Persistent repository controls can be supplied as reusable-workflow inputs or
|
|
135
|
+
repository variables:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
BUILDCHAIN_STABLE_HOLD=true
|
|
139
|
+
BUILDCHAIN_STABLE_HOLD_REASON=release freeze
|
|
140
|
+
BUILDCHAIN_STABLE_REVOKED_ALPHA_VERSIONS=2.12.0-alpha.5,2.12.0-alpha.7
|
|
141
|
+
BUILDCHAIN_STABLE_REVOKE_REASON=consumer regression
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Revocation is explicit evidence; publishing a newer alpha alone is not
|
|
145
|
+
revocation. A manual `workflow_dispatch` `release-now` chooses one exact,
|
|
146
|
+
non-revoked candidate immediately. It may bypass the scheduled soak decision,
|
|
147
|
+
but cannot change candidate SHA, reuse a consumed stable version, or bypass the
|
|
148
|
+
source-lock PR and publish transaction.
|
|
149
|
+
|
|
150
|
+
For Buildchain's own stable gate, Patrol automatically projects that explicit
|
|
151
|
+
human decision into the exact-candidate `BUILDCHAIN_STABLE_RELEASE_NOW` and
|
|
152
|
+
reason variables. A later Patrol run removes them after it observes the public
|
|
153
|
+
stable release. This is an internal compatibility projection, not a manual user
|
|
154
|
+
step; the durable authority record remains the candidate ledger entry and PR.
|
|
155
|
+
|
|
156
|
+
## Durable recovery
|
|
157
|
+
|
|
158
|
+
The default ledger ref is derived from the release line, for example:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
buildchain/candidate-ledger/v2/v2.12
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
It stores `.buildchain/stable-candidate-ledger.json`. Patrol runs are serialized
|
|
165
|
+
per repository and release line. Repeated runs reuse the same exact source-lock
|
|
166
|
+
branch and PR, while later runs observe the public stable release and mark the
|
|
167
|
+
candidate `promoted`.
|
|
168
|
+
|
|
169
|
+
When Patrol is enabled after a stable version already exists, it reconstructs
|
|
170
|
+
that consumed patch from GitHub Release truth and closes historical alpha
|
|
171
|
+
candidates for the same stable version. It never attempts to republish an
|
|
172
|
+
already claimed exact stable version.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.1-alpha.2",
|
|
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",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"./publication-package": "./packages/core/publication-package.js",
|
|
31
31
|
"./kfd-gate": "./packages/core/kfd-gate.js",
|
|
32
32
|
"./release-candidate": "./packages/core/release-candidate.js",
|
|
33
|
+
"./stable-candidate-ledger": "./packages/core/stable-candidate-ledger.js",
|
|
33
34
|
"./release-passport": "./packages/core/release-passport.js",
|
|
34
35
|
"./release-propagation": "./packages/core/release-propagation.js",
|
|
35
36
|
"./surface-manifest": "./packages/core/surface-manifest.js",
|
|
@@ -19,6 +19,7 @@ const SUPPORTED_PUBLISH_MODES = new Set(["publish-final-version", "promote-exist
|
|
|
19
19
|
const SUPPORTED_PUBLISH_AUTH = new Set(["trusted-publishing", "npm-token"]);
|
|
20
20
|
const SUPPORTED_PUBLISH_KINDS = new Set(["npm-package", "npm-paper-package"]);
|
|
21
21
|
const SUPPORTED_PACKAGE_SET_ORDER = new Set(["as-provided", "platforms-first-main-last"]);
|
|
22
|
+
const SUPPORTED_STABLE_RELEASE_STRATEGIES = new Set(["manual", "latest-qualified-alpha"]);
|
|
22
23
|
const SUPPORTED_NATIVE_COMPILER_CACHE = new Set(["auto", "ccache", "sccache", "none"]);
|
|
23
24
|
const WEB_SURFACE_CHANNELS = ["preview", "staging", "production"];
|
|
24
25
|
const SUPPORTED_CHANNEL_VISIBILITY = new Set(["ephemeral", "protected", "public", "internal"]);
|
|
@@ -180,6 +181,9 @@ export function normalizeBuildchainConfig(config) {
|
|
|
180
181
|
if (normalized.publish !== undefined) {
|
|
181
182
|
normalized.publish = normalizePublishSection(normalized.publish);
|
|
182
183
|
}
|
|
184
|
+
if (normalized.release !== undefined) {
|
|
185
|
+
normalized.release = normalizeReleaseSection(normalized.release);
|
|
186
|
+
}
|
|
183
187
|
if (normalized.channels !== undefined) {
|
|
184
188
|
normalized.channels = normalizeChannelsSection(normalized.channels, normalized.project);
|
|
185
189
|
}
|
|
@@ -215,6 +219,59 @@ export function normalizeBuildchainConfig(config) {
|
|
|
215
219
|
return normalized;
|
|
216
220
|
}
|
|
217
221
|
|
|
222
|
+
function normalizeReleaseSection(release) {
|
|
223
|
+
assertPlainObject(release, "release");
|
|
224
|
+
const normalized = { ...release };
|
|
225
|
+
if (release.stable !== undefined) {
|
|
226
|
+
assertPlainObject(release.stable, "release.stable");
|
|
227
|
+
const strategy = release.stable.strategy === undefined
|
|
228
|
+
? "manual"
|
|
229
|
+
: assertString(release.stable.strategy, "release.stable.strategy");
|
|
230
|
+
if (!SUPPORTED_STABLE_RELEASE_STRATEGIES.has(strategy)) {
|
|
231
|
+
throw new Error("release.stable.strategy must be one of manual or latest-qualified-alpha");
|
|
232
|
+
}
|
|
233
|
+
const minimumSoakSeconds = release.stable.minimum_soak_seconds === undefined
|
|
234
|
+
? 3600
|
|
235
|
+
: Number(release.stable.minimum_soak_seconds);
|
|
236
|
+
if (!Number.isInteger(minimumSoakSeconds) || minimumSoakSeconds < 0) {
|
|
237
|
+
throw new Error("release.stable.minimum_soak_seconds must be a non-negative integer");
|
|
238
|
+
}
|
|
239
|
+
normalized.stable = {
|
|
240
|
+
strategy,
|
|
241
|
+
timezone: release.stable.timezone === undefined
|
|
242
|
+
? "UTC"
|
|
243
|
+
: assertString(release.stable.timezone, "release.stable.timezone"),
|
|
244
|
+
publishAt: release.stable.publish_at === undefined
|
|
245
|
+
? "03:00"
|
|
246
|
+
: assertString(release.stable.publish_at, "release.stable.publish_at"),
|
|
247
|
+
minimumSoakSeconds,
|
|
248
|
+
requiredChecks: normalizeStringArray(release.stable.required_checks, "release.stable.required_checks"),
|
|
249
|
+
ledgerRef: release.stable.ledger_ref === undefined
|
|
250
|
+
? ""
|
|
251
|
+
: assertString(release.stable.ledger_ref, "release.stable.ledger_ref"),
|
|
252
|
+
autoPromote: optionalBoolean(release.stable.auto_promote, strategy === "latest-qualified-alpha"),
|
|
253
|
+
autoMerge: optionalBoolean(release.stable.auto_merge, false),
|
|
254
|
+
};
|
|
255
|
+
if (!/^([01]\d|2[0-3]):[0-5]\d$/.test(normalized.stable.publishAt)) {
|
|
256
|
+
throw new Error("release.stable.publish_at must be HH:MM in 24-hour time");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return normalized;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function getStableReleasePolicy(loadedConfig) {
|
|
263
|
+
return loadedConfig?.config?.release?.stable || {
|
|
264
|
+
strategy: "manual",
|
|
265
|
+
timezone: "UTC",
|
|
266
|
+
publishAt: "03:00",
|
|
267
|
+
minimumSoakSeconds: 3600,
|
|
268
|
+
requiredChecks: [],
|
|
269
|
+
ledgerRef: "",
|
|
270
|
+
autoPromote: false,
|
|
271
|
+
autoMerge: false,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
218
275
|
function normalizeFactsSection(facts) {
|
|
219
276
|
assertPlainObject(facts, "facts");
|
|
220
277
|
return {
|
|
@@ -1389,6 +1446,7 @@ export function validateBuildchainConfig(
|
|
|
1389
1446
|
})),
|
|
1390
1447
|
lifecycleStages,
|
|
1391
1448
|
publish: loadedConfig.config.publish,
|
|
1449
|
+
release: loadedConfig.config.release,
|
|
1392
1450
|
facts: loadedConfig.config.facts,
|
|
1393
1451
|
publication: loadedConfig.config.publication,
|
|
1394
1452
|
};
|
package/packages/core/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export {
|
|
|
3
3
|
getLifecycleStage,
|
|
4
4
|
getNativeDiagnosticsProfile,
|
|
5
5
|
getPublishContract,
|
|
6
|
+
getStableReleasePolicy,
|
|
6
7
|
getVersionStrategy,
|
|
7
8
|
loadBuildchainConfig,
|
|
8
9
|
loadConfiguredAnchorManifest,
|
|
@@ -13,6 +14,20 @@ export {
|
|
|
13
14
|
validateBuildchainConfig,
|
|
14
15
|
} from "./buildchain-config.js";
|
|
15
16
|
|
|
17
|
+
export {
|
|
18
|
+
STABLE_CANDIDATE_LEDGER_CONTRACT,
|
|
19
|
+
STABLE_CANDIDATE_STATES,
|
|
20
|
+
createStableCandidateLedger,
|
|
21
|
+
markStableCandidatePromoted,
|
|
22
|
+
normalizeStableCandidateLedger,
|
|
23
|
+
qualifyStableCandidate,
|
|
24
|
+
registerStableCandidate,
|
|
25
|
+
revokeStableCandidate,
|
|
26
|
+
selectStableCandidate,
|
|
27
|
+
setStableCandidateHold,
|
|
28
|
+
stableCandidatePromotionRefs,
|
|
29
|
+
} from "./stable-candidate-ledger.js";
|
|
30
|
+
|
|
16
31
|
export {
|
|
17
32
|
assertPackageManager,
|
|
18
33
|
commandForKungfuUpgrade,
|