@norskvideo/ctl-dev-kit 0.2.64 → 0.2.65
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/build/flake.nix +1 -1
- package/build/flake.sdk-app.nix +2 -2
- package/build/refresh-ctl-pin.sh +1 -1
- package/conventions/CLAUDE.core.md +10 -7
- package/conventions/bot-prs.yml +91 -61
- package/conventions/build-docs.yml +2 -2
- package/conventions/build-image.yml +8 -7
- package/conventions/bump.sdk-app.yml +808 -0
- package/conventions/bump.yml +916 -0
- package/conventions/check-drift.ts +52 -60
- package/conventions/ctl-pin-agreement.ts +3 -4
- package/conventions/docs-site.md +3 -3
- package/conventions/integration-testing.md +1 -1
- package/conventions/integration.yml +6 -5
- package/conventions/publish-docs.yml +2 -2
- package/conventions/smoke.yml +2 -2
- package/conventions/sync-drift.ts +61 -24
- package/create-product/canon.ts +2 -6
- package/create-product/create-product.ts +1 -3
- package/create-product/turnkey.ts +2 -2
- package/docs-theme/README.md +1 -1
- package/package.json +1 -1
- package/conventions/sync-ctl-packages.yml +0 -309
- package/conventions/sync-dev-kit.yml +0 -404
- package/conventions/upgrade-latest.sdk-app.yml +0 -456
- package/conventions/upgrade-latest.yml +0 -567
package/build/flake.nix
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# integration) uses, so image builds never depend on the
|
|
14
14
|
# ctl binary channel.
|
|
15
15
|
#
|
|
16
|
-
# The norsk-ctl pin below is bumped nightly by
|
|
16
|
+
# The norsk-ctl pin below is bumped nightly by bump.yml; by hand with
|
|
17
17
|
# packages/dev-kit/build/refresh-ctl-pin.sh (writes ctlVersion + hashes)
|
|
18
18
|
{
|
|
19
19
|
description = "norsk-ctl product build + dev shell";
|
package/build/flake.sdk-app.nix
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# an sdk-app's dev loop is its own SDK app plus a Norsk engine, not a
|
|
11
11
|
# ctl-launched product container. It still PINS one: `ctlVersion` below is the
|
|
12
12
|
# norsk-ctl the product's CI tiers (smoke) launch it with, read from here so a
|
|
13
|
-
# result belongs to a commit, and moved nightly by
|
|
13
|
+
# result belongs to a commit, and moved nightly by bump.yml. Decision: bun for tooling (install / build /
|
|
14
14
|
# test), Node for the shipped runtime (the SDK's blessed runtime).
|
|
15
15
|
#
|
|
16
16
|
# nixpkgs is pinned to the same rev the Studio flake uses, so bun matches the
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
outputs = { self, nixpkgs, nixpkgs-biome }:
|
|
31
31
|
let
|
|
32
|
-
# The norsk-ctl CI runs (see above);
|
|
32
|
+
# The norsk-ctl CI runs (see above); bump.yml moves it to `latest`.
|
|
33
33
|
ctlVersion = "0.1.0-2026-09-15-81bbde8";
|
|
34
34
|
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
|
|
35
35
|
forAllSystems = f: builtins.listToAttrs (map (s: { name = s; value = f s; }) systems);
|
package/build/refresh-ctl-pin.sh
CHANGED
|
@@ -36,4 +36,4 @@ done
|
|
|
36
36
|
|
|
37
37
|
perl -0pi -e "s{(ctlVersion = \")[^\"]*(\")}{\${1}$ver\${2}}" "$flake"
|
|
38
38
|
echo "updated $flake"
|
|
39
|
-
echo "this is the starter's pin; each product's own flake.nix is bumped nightly by
|
|
39
|
+
echo "this is the starter's pin; each product's own flake.nix is bumped nightly by bump.yml"
|
|
@@ -79,17 +79,20 @@
|
|
|
79
79
|
(`norsk-ctl serve`) + `norsk-ctl` on PATH (the nix shell) + `NORSK_LICENSE_FILE`.
|
|
80
80
|
Anything the daemon can't see for you — a stored template, a rebuilt image — is
|
|
81
81
|
stale until this loop re-runs; don't debug a ghost.
|
|
82
|
-
- **The shared CI
|
|
83
|
-
|
|
82
|
+
- **The shared CI workflows are single-sourced too.** `.github/workflows/bump.yml`
|
|
83
|
+
and the rest are copied verbatim from `@norskvideo/ctl-dev-kit` (`conventions/`),
|
|
84
84
|
same as this core block and `nix/ctl-shell.nix`; `check:drift` fails CI if a copy
|
|
85
85
|
diverges. Only the `product:` key is per-repo. Never hand-edit the copy — edit
|
|
86
86
|
the dev-kit source and re-sync.
|
|
87
87
|
- **CI runs the norsk-ctl this repo pins** (`flake.nix` `ctlVersion`), never S3's
|
|
88
|
-
moving `latest`; only a `ctl-candidate` run tests a channel (`rc`).
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
moving `latest`; only a `ctl-candidate` run tests a channel (`rc`). One nightly
|
|
89
|
+
bump, `bump.yml`, moves the dev-kit, the ctl-* and moq-* packages, and the
|
|
90
|
+
engine/Studio/norsk-ctl pins together, and never pushes to main: it opens one PR
|
|
91
|
+
on `bump/nightly`, and `bot-prs` merges it once checks, smoke, integration and
|
|
92
|
+
the guides gate (build-image) are green on it. A red bump PR is the alarm for a
|
|
93
|
+
bad upstream change, and names what moved; main stays green. To land the rest
|
|
94
|
+
without a bad component: `gh workflow run bump.yml -f components=<the others>`
|
|
95
|
+
(`dev-kit`, `ctl-packages`, `pins`).
|
|
93
96
|
- **Flaky checks stay out of gates, never out of sight.** The guides gate runs
|
|
94
97
|
the deterministic tiers; the engine tier runs beside it and reports (summary,
|
|
95
98
|
warning, cell detail) without gating until norsk-ctl task 57 is fixed. A
|
package/conventions/bot-prs.yml
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
# Land the
|
|
1
|
+
# Land the nightly bump's green PR; put a red one on the product dashboard.
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
# the norsk-ctl pin
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
3
|
+
# One bot keeps a product fresh: bump.yml, which moves the dev-kit, the ctl-* /
|
|
4
|
+
# moq-* npm family, and the Norsk nightly pair and norsk-ctl pin in one run and
|
|
5
|
+
# opens one PR on bump/nightly (ci-workflows docs/dashboard/ci-fragility.md,
|
|
6
|
+
# proposal B2). It never pushes to main (proposal B): its own gate is lint,
|
|
7
|
+
# typecheck and unit tests, and the tiers that break on an upstream change --
|
|
8
|
+
# smoke, integration and the guides that gate build-image's publish -- run on
|
|
9
|
+
# the PR. This workflow is what lands it. Until bump.yml, three bots did that
|
|
10
|
+
# job, each with its own branch (upgrade-latest/*, sync-dev-kit/*,
|
|
11
|
+
# chore/sync-ctl-packages); those are still triaged, so their PRs still in
|
|
12
|
+
# flight when a product moves to bump.yml land or are reported like any other.
|
|
13
|
+
# Nothing used to act on bot PRs: green
|
|
11
14
|
# ones sat unmerged (studio's ctl-sdk was twenty releases behind on 2026-10-03,
|
|
12
15
|
# its PR open since 09-03) and red ones were invisible, because the bot that
|
|
13
16
|
# opened them reports success. With a product count that only goes up, "someone
|
|
@@ -23,8 +26,9 @@
|
|
|
23
26
|
# push alone cannot gate, and still runs on main after the merge. "Nothing
|
|
24
27
|
# failed yet" is not enough: a slow tier that has not started has no check
|
|
25
28
|
# run at all, so bot-prs used to merge before integration had begun;
|
|
26
|
-
# - it conflicts with main -> re-run
|
|
27
|
-
#
|
|
29
|
+
# - it conflicts with main -> re-run bump.yml, ONCE per head, so it rebuilds
|
|
30
|
+
# the night from today's main (see below). Asked FIRST, whatever its
|
|
31
|
+
# checks say: the rebuild re-runs them all on the new base;
|
|
28
32
|
# - a check failed, it still conflicts after that rebuild, or it is a draft
|
|
29
33
|
# (the bot's own gate was red) -> list it, and report this repo's `bot-prs`
|
|
30
34
|
# cell RED on the product dashboard, which is the Discord message people
|
|
@@ -34,24 +38,30 @@
|
|
|
34
38
|
# workflow is broken, or does not run on PRs), so that is red too.
|
|
35
39
|
# The cell goes green again once nothing is red.
|
|
36
40
|
#
|
|
37
|
-
# Why the conflict rebuild: the three bots
|
|
38
|
-
# each
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# from main when run:
|
|
44
|
-
# closes any older PR
|
|
41
|
+
# Why the conflict rebuild: when the three bots fired within minutes of each
|
|
42
|
+
# other, each writing package.json and bun.lock from main as it stood,
|
|
43
|
+
# whichever landed first left the others conflicting, and a bot rebuilt its
|
|
44
|
+
# branch only on its next DAILY run (2026-10-09: commentary, probe and reuters
|
|
45
|
+
# each had a sync-ctl-packages PR "needing a human" that a re-run fixed). One
|
|
46
|
+
# bump ends that, but a human's merge to main can still make bump/nightly
|
|
47
|
+
# conflict. bump.yml rebuilds from main when run: it force-pushes bump/nightly
|
|
48
|
+
# from today's main and closes any older bump PR, and an old bot's PR for each
|
|
49
|
+
# component it moved -- so it is the rebuild for those branches too, whose own
|
|
50
|
+
# workflows the move to bump.yml deleted. The marker comment caps it at one
|
|
45
51
|
# rebuild per head, so a rebuild that still conflicts goes to a human instead
|
|
46
52
|
# of looping every hour.
|
|
47
53
|
#
|
|
54
|
+
# It triages the bot PRs that target one base: main, unless a dispatch names
|
|
55
|
+
# another (`base`). A trial of a dev-kit change against a throwaway branch is
|
|
56
|
+
# triaged, rebuilt and merged there, never on main, and reports nothing.
|
|
57
|
+
#
|
|
48
58
|
# Runs when any gating tier finishes (the prompt path), hourly as a sweep,
|
|
49
59
|
# and on demand. No checkout: it only talks to the GitHub API, so it needs none
|
|
50
60
|
# of the runner-workspace steps the building workflows carry.
|
|
51
61
|
#
|
|
52
62
|
# Single-sourced in @norskvideo/ctl-dev-kit (conventions/bot-prs.yml) and copied
|
|
53
63
|
# verbatim into each product repo -- it reads its dashboard key from this repo's
|
|
54
|
-
#
|
|
64
|
+
# bump.yml rather than carrying one -- so sync-drift creates it where
|
|
55
65
|
# absent and check:drift fails a copy that diverges. Never hand-edit the copy.
|
|
56
66
|
name: bot-prs
|
|
57
67
|
|
|
@@ -62,6 +72,10 @@ on:
|
|
|
62
72
|
schedule:
|
|
63
73
|
- cron: "23 * * * *"
|
|
64
74
|
workflow_dispatch:
|
|
75
|
+
inputs:
|
|
76
|
+
base:
|
|
77
|
+
description: "Triage the bot PRs that target this branch. main, unless trialling on a throwaway branch."
|
|
78
|
+
default: main
|
|
65
79
|
|
|
66
80
|
permissions:
|
|
67
81
|
contents: read
|
|
@@ -96,6 +110,7 @@ jobs:
|
|
|
96
110
|
READ_TOKEN: ${{ github.token }}
|
|
97
111
|
WRITE_TOKEN: ${{ secrets.CI_DISPATCH_TOKEN }}
|
|
98
112
|
REPO: ${{ github.repository }}
|
|
113
|
+
BASE: ${{ inputs.base || 'main' }}
|
|
99
114
|
run: |
|
|
100
115
|
set -euo pipefail
|
|
101
116
|
api="https://api.github.com/repos/$REPO"
|
|
@@ -114,12 +129,14 @@ jobs:
|
|
|
114
129
|
exit 1
|
|
115
130
|
}
|
|
116
131
|
|
|
117
|
-
# The
|
|
132
|
+
# The bump owns bump/nightly (see bump.yml's PR step); the other three
|
|
133
|
+
# are the retired bots' branches, still landed while in flight.
|
|
118
134
|
pulls="$(gh_api "$api/pulls?state=open&per_page=100")"
|
|
119
135
|
expect "listing open PRs" 'type == "array"' "$pulls"
|
|
120
|
-
prs="$(jq -c --arg repo "$REPO" '
|
|
136
|
+
prs="$(jq -c --arg repo "$REPO" --arg base "$BASE" '
|
|
121
137
|
[.[] | select(.head.repo.full_name == $repo)
|
|
122
|
-
| select(.
|
|
138
|
+
| select(.base.ref == $base)
|
|
139
|
+
| select(.head.ref | test("^(bump/nightly$|upgrade-latest/|sync-dev-kit/|chore/sync-ctl-packages$)"))
|
|
123
140
|
| {number, ref: .head.ref, sha: .head.sha, draft, url: .html_url}]' <<<"$pulls")"
|
|
124
141
|
|
|
125
142
|
# Does this workflow (on stdin) run on pull_request? Only its `on:` block
|
|
@@ -204,12 +221,12 @@ jobs:
|
|
|
204
221
|
fi
|
|
205
222
|
}
|
|
206
223
|
|
|
207
|
-
# The workflow that
|
|
224
|
+
# The workflow that rebuilds each bot branch: bump.yml, for the retired
|
|
225
|
+
# bots' branches too (their workflows went when bump.yml arrived, and
|
|
226
|
+
# bump.yml supersedes their PRs for every component it moves).
|
|
208
227
|
producer() {
|
|
209
228
|
case "$1" in
|
|
210
|
-
upgrade-latest/*) echo
|
|
211
|
-
sync-dev-kit/*) echo sync-dev-kit.yml ;;
|
|
212
|
-
chore/sync-ctl-packages) echo sync-ctl-packages.yml ;;
|
|
229
|
+
bump/nightly | upgrade-latest/* | sync-dev-kit/* | chore/sync-ctl-packages) echo bump.yml ;;
|
|
213
230
|
*) echo "" ;;
|
|
214
231
|
esac
|
|
215
232
|
}
|
|
@@ -220,31 +237,14 @@ jobs:
|
|
|
220
237
|
while IFS= read -r pr; do
|
|
221
238
|
[ -n "$pr" ] || continue
|
|
222
239
|
n="$(jq -r .number <<<"$pr")"; ref="$(jq -r .ref <<<"$pr")"; sha="$(jq -r .sha <<<"$pr")"
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
# Every tier that runs on a bot PR must have PASSED on this head.
|
|
232
|
-
required="$(tiers_for "$sha")"
|
|
233
|
-
wf_runs="$(gh_api "$api/actions/runs?head_sha=$sha&per_page=100")"
|
|
234
|
-
expect "reading workflow runs for #$n" '.workflow_runs | type == "array"' "$wf_runs"
|
|
235
|
-
verdict="$(tier_verdict "$required" "$wf_runs" "$(date +%s)")"
|
|
236
|
-
case "$verdict" in
|
|
237
|
-
ok) ;;
|
|
238
|
-
red\ *) red+=("#$n $ref: ${verdict#red }"); continue ;;
|
|
239
|
-
rerun\ *)
|
|
240
|
-
for id in ${verdict#rerun }; do
|
|
241
|
-
code="$(gh_actions -o /dev/null -w '%{http_code}' -X POST "$api/actions/runs/$id/rerun")"
|
|
242
|
-
echo "#$n $ref: a gating tier (run $id) was cancelled; re-running it (HTTP $code)"
|
|
243
|
-
done
|
|
244
|
-
continue ;;
|
|
245
|
-
*) echo "#$n $ref: ${verdict#wait }; next time"; continue ;;
|
|
246
|
-
esac
|
|
247
|
-
# GitHub computes mergeability lazily; ask until it has an answer.
|
|
240
|
+
# Mergeability FIRST, before the checks are judged. A rebuild re-runs
|
|
241
|
+
# every tier on today's base, so a conflicting PR is rebuilt whatever
|
|
242
|
+
# its checks say: relay #11 (2026-10-10) carried a smoke failure from
|
|
243
|
+
# before main moved, was reported red for it, and sat conflicting
|
|
244
|
+
# for 90 minutes with its rebuild never asked for. Only a PR that
|
|
245
|
+
# still conflicts after its rebuild, or merges cleanly with red
|
|
246
|
+
# checks, is red. GitHub computes mergeability lazily; ask until it
|
|
247
|
+
# has an answer.
|
|
248
248
|
mergeable=null
|
|
249
249
|
for _ in 1 2 3 4 5; do
|
|
250
250
|
mergeable="$(gh_api "$api/pulls/$n" | jq -r .mergeable)"
|
|
@@ -262,9 +262,9 @@ jobs:
|
|
|
262
262
|
elif jq -e --arg m "$marker" 'any(.[]; .body | contains($m))' >/dev/null <<<"$comments"; then
|
|
263
263
|
red+=("#$n $ref: still does not merge cleanly with main after $wf rebuilt it")
|
|
264
264
|
else
|
|
265
|
-
code="$(gh_actions -o /dev/null -w '%{http_code}' -X POST "$api/actions/workflows/$wf/dispatches" -d '{
|
|
265
|
+
code="$(gh_actions -o /dev/null -w '%{http_code}' -X POST "$api/actions/workflows/$wf/dispatches" -d "$(jq -nc --arg b "$BASE" '{ref:$b, inputs:{base:$b}}')")"
|
|
266
266
|
if [ "$code" = "204" ]; then
|
|
267
|
-
body="$marker -- it conflicted with
|
|
267
|
+
body="$marker -- it conflicted with $BASE, so $wf was re-run to rebuild the bump from today's $BASE. If the rebuilt branch conflicts too, this PR is reported for a human."
|
|
268
268
|
gh_write -o /dev/null -X POST "$api/issues/$n/comments" -d "$(jq -nc --arg b "$body" '{body:$b}')" || true
|
|
269
269
|
rebuilt+=("#$n")
|
|
270
270
|
echo "#$n $ref: conflicts with main; re-ran $wf to rebuild it"
|
|
@@ -274,6 +274,30 @@ jobs:
|
|
|
274
274
|
fi
|
|
275
275
|
continue
|
|
276
276
|
fi
|
|
277
|
+
runs="$(gh_api "$api/commits/$sha/check-runs?per_page=100")"
|
|
278
|
+
expect "reading checks for #$n" '.check_runs | type == "array"' "$runs"
|
|
279
|
+
failed="$(jq -r '[.check_runs[] | select(.conclusion | IN("failure","cancelled","timed_out","action_required","startup_failure")) | .name] | unique | join(", ")' <<<"$runs")"
|
|
280
|
+
pending="$(jq -r '[.check_runs[] | select(.status != "completed")] | length' <<<"$runs")"
|
|
281
|
+
passed="$(jq -r '[.check_runs[] | select(.conclusion == "success")] | length' <<<"$runs")"
|
|
282
|
+
if [ -n "$failed" ]; then red+=("#$n $ref: failing $failed"); continue; fi
|
|
283
|
+
if [ "$(jq -r .draft <<<"$pr")" = "true" ]; then red+=("#$n $ref: draft (its bot's gate was red)"); continue; fi
|
|
284
|
+
if [ "$pending" -gt 0 ] || [ "$passed" -eq 0 ]; then echo "#$n $ref: checks not finished; next time"; continue; fi
|
|
285
|
+
# Every tier that runs on a bot PR must have PASSED on this head.
|
|
286
|
+
required="$(tiers_for "$sha")"
|
|
287
|
+
wf_runs="$(gh_api "$api/actions/runs?head_sha=$sha&per_page=100")"
|
|
288
|
+
expect "reading workflow runs for #$n" '.workflow_runs | type == "array"' "$wf_runs"
|
|
289
|
+
verdict="$(tier_verdict "$required" "$wf_runs" "$(date +%s)")"
|
|
290
|
+
case "$verdict" in
|
|
291
|
+
ok) ;;
|
|
292
|
+
red\ *) red+=("#$n $ref: ${verdict#red }"); continue ;;
|
|
293
|
+
rerun\ *)
|
|
294
|
+
for id in ${verdict#rerun }; do
|
|
295
|
+
code="$(gh_actions -o /dev/null -w '%{http_code}' -X POST "$api/actions/runs/$id/rerun")"
|
|
296
|
+
echo "#$n $ref: a gating tier (run $id) was cancelled; re-running it (HTTP $code)"
|
|
297
|
+
done
|
|
298
|
+
continue ;;
|
|
299
|
+
*) echo "#$n $ref: ${verdict#wait }; next time"; continue ;;
|
|
300
|
+
esac
|
|
277
301
|
# sha pins the merge to what was checked: a bot force-pushing the
|
|
278
302
|
# branch meanwhile makes this refuse rather than land unchecked code.
|
|
279
303
|
res="$(gh_write -X PUT "$api/pulls/$n/merge" -d "$(jq -nc --arg sha "$sha" '{merge_method:"squash", sha:$sha}')")"
|
|
@@ -304,7 +328,8 @@ jobs:
|
|
|
304
328
|
|
|
305
329
|
- name: Report to the product dashboard
|
|
306
330
|
# Always: a triage that broke is exactly what nobody would otherwise see.
|
|
307
|
-
|
|
331
|
+
# But only for main: a trial against another base must not paint the board.
|
|
332
|
+
if: always() && (inputs.base || 'main') == 'main'
|
|
308
333
|
env:
|
|
309
334
|
TOKEN: ${{ secrets.CI_DISPATCH_TOKEN }}
|
|
310
335
|
READ_TOKEN: ${{ github.token }}
|
|
@@ -317,13 +342,18 @@ jobs:
|
|
|
317
342
|
REPO: ${{ github.repository }}
|
|
318
343
|
run: |
|
|
319
344
|
set -euo pipefail
|
|
320
|
-
# The dashboard key is the one
|
|
321
|
-
#
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
345
|
+
# The dashboard key is the one bump.yml reports under, read from it so
|
|
346
|
+
# this file can stay byte-identical across products; upgrade-latest.yml
|
|
347
|
+
# carried it before bump.yml did. -f: a 404 must not read as a key.
|
|
348
|
+
product=""
|
|
349
|
+
for wf in bump.yml upgrade-latest.yml; do
|
|
350
|
+
product="$(curl -fsS -H "Authorization: Bearer $READ_TOKEN" -H "Accept: application/vnd.github.raw" \
|
|
351
|
+
"https://api.github.com/repos/$REPO/contents/.github/workflows/$wf" 2>/dev/null \
|
|
352
|
+
| sed -nE 's/^[[:space:]]*product:[[:space:]]*([^[:space:]]+).*/\1/p' | head -1 || true)"
|
|
353
|
+
[ -z "$product" ] || break
|
|
354
|
+
done
|
|
325
355
|
if [ -z "$product" ] || [ "$product" = "__PRODUCT__" ]; then
|
|
326
|
-
echo "::warning::no product key in
|
|
356
|
+
echo "::warning::no product key in bump.yml; not reporting to the dashboard"
|
|
327
357
|
exit 0
|
|
328
358
|
fi
|
|
329
359
|
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
@@ -190,14 +190,14 @@ jobs:
|
|
|
190
190
|
done <<<"$left"
|
|
191
191
|
|
|
192
192
|
# The norsk-ctl this commit pins (flake.nix ctlVersion, moved by
|
|
193
|
-
#
|
|
193
|
+
# bump.yml's nightly PR), never S3's moving `latest`: a guide run is then
|
|
194
194
|
# a real repeat, and a red belongs to a commit (ci-fragility proposal A).
|
|
195
195
|
- name: Download the pinned norsk-ctl binary (flake.nix ctlVersion)
|
|
196
196
|
run: |
|
|
197
197
|
set -euo pipefail
|
|
198
198
|
S3="https://s3.eu-west-1.amazonaws.com/norsk.video/norsk-ctl"
|
|
199
199
|
ver="$( { sed -nE 's/^[[:space:]]*ctlVersion = "([^"]+)";.*/\1/p' flake.nix 2>/dev/null || true; } | head -1)"
|
|
200
|
-
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (
|
|
200
|
+
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (the nightly bump.yml moves it); add ctlVersion = \"<version>\"; to flake.nix."; exit 1; }
|
|
201
201
|
echo "norsk-ctl pinned by flake.nix ctlVersion -> $ver"
|
|
202
202
|
curl -fsSL --retry 3 --retry-all-errors --retry-delay 2 "$S3/$ver/norsk-ctl-$ver-linux-x64" -o "$RUNNER_TEMP/norsk-ctl"
|
|
203
203
|
chmod +x "$RUNNER_TEMP/norsk-ctl"
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
# (rc -> latest promotion) lands, flip the push default to `nightly` and let the
|
|
22
22
|
# promotion gate move `latest`.
|
|
23
23
|
#
|
|
24
|
-
# BOT PRs: on a pull request from a bot branch (
|
|
25
|
-
# sync-dev-kit
|
|
24
|
+
# BOT PRs: on a pull request from a bot branch (bump/nightly, and the retired
|
|
25
|
+
# bots' upgrade-latest/*, sync-dev-kit/* and chore/sync-ctl-packages, which the
|
|
26
|
+
# PR that brings bump.yml rides on) the workflow builds both arches and
|
|
26
27
|
# runs the guides gate exactly as a push would (the deterministic tiers gate;
|
|
27
28
|
# the engine tier reports beside it), and publishes, records and
|
|
28
29
|
# reports nothing. A bump reaches main only once that has passed on it, and
|
|
@@ -69,7 +70,7 @@ jobs:
|
|
|
69
70
|
# Compute the immutable label ONCE, so both arch builds and the manifest share
|
|
70
71
|
# it (a per-job `date` could straddle midnight and disagree).
|
|
71
72
|
label:
|
|
72
|
-
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && (startsWith(github.head_ref, 'upgrade-latest/') || startsWith(github.head_ref, 'sync-dev-kit/') || github.head_ref == 'chore/sync-ctl-packages')) }}
|
|
73
|
+
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && (github.head_ref == 'bump/nightly' || startsWith(github.head_ref, 'upgrade-latest/') || startsWith(github.head_ref, 'sync-dev-kit/') || github.head_ref == 'chore/sync-ctl-packages')) }}
|
|
73
74
|
runs-on: x64
|
|
74
75
|
outputs:
|
|
75
76
|
label: ${{ steps.gen.outputs.label }}
|
|
@@ -430,7 +431,7 @@ jobs:
|
|
|
430
431
|
done <<<"$left"
|
|
431
432
|
|
|
432
433
|
# The norsk-ctl this commit pins (flake.nix ctlVersion, moved by
|
|
433
|
-
#
|
|
434
|
+
# bump.yml's nightly PR), never S3's moving `latest`: a guide run is then
|
|
434
435
|
# a real repeat, and a red belongs to a commit (ci-fragility proposal A).
|
|
435
436
|
- name: Download the pinned norsk-ctl binary (flake.nix ctlVersion)
|
|
436
437
|
if: ${{ steps.plan.outputs.guides == 'run' }}
|
|
@@ -438,7 +439,7 @@ jobs:
|
|
|
438
439
|
set -euo pipefail
|
|
439
440
|
S3="https://s3.eu-west-1.amazonaws.com/norsk.video/norsk-ctl"
|
|
440
441
|
ver="$( { sed -nE 's/^[[:space:]]*ctlVersion = "([^"]+)";.*/\1/p' flake.nix 2>/dev/null || true; } | head -1)"
|
|
441
|
-
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (
|
|
442
|
+
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (the nightly bump.yml moves it); add ctlVersion = \"<version>\"; to flake.nix."; exit 1; }
|
|
442
443
|
echo "norsk-ctl pinned by flake.nix ctlVersion -> $ver"
|
|
443
444
|
curl -fsSL --retry 3 --retry-all-errors --retry-delay 2 "$S3/$ver/norsk-ctl-$ver-linux-x64" -o "$RUNNER_TEMP/norsk-ctl"
|
|
444
445
|
chmod +x "$RUNNER_TEMP/norsk-ctl"
|
|
@@ -630,14 +631,14 @@ jobs:
|
|
|
630
631
|
done <<<"$left"
|
|
631
632
|
|
|
632
633
|
# The norsk-ctl this commit pins (flake.nix ctlVersion, moved by
|
|
633
|
-
#
|
|
634
|
+
# bump.yml's nightly PR), never S3's moving `latest`: a guide run is then
|
|
634
635
|
# a real repeat, and a red belongs to a commit (ci-fragility proposal A).
|
|
635
636
|
- name: Download the pinned norsk-ctl binary (flake.nix ctlVersion)
|
|
636
637
|
run: |
|
|
637
638
|
set -euo pipefail
|
|
638
639
|
S3="https://s3.eu-west-1.amazonaws.com/norsk.video/norsk-ctl"
|
|
639
640
|
ver="$( { sed -nE 's/^[[:space:]]*ctlVersion = "([^"]+)";.*/\1/p' flake.nix 2>/dev/null || true; } | head -1)"
|
|
640
|
-
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (
|
|
641
|
+
[ -n "$ver" ] || { echo "::error::flake.nix pins no ctlVersion. CI runs the norsk-ctl this commit pins (the nightly bump.yml moves it); add ctlVersion = \"<version>\"; to flake.nix."; exit 1; }
|
|
641
642
|
echo "norsk-ctl pinned by flake.nix ctlVersion -> $ver"
|
|
642
643
|
curl -fsSL --retry 3 --retry-all-errors --retry-delay 2 "$S3/$ver/norsk-ctl-$ver-linux-x64" -o "$RUNNER_TEMP/norsk-ctl"
|
|
643
644
|
chmod +x "$RUNNER_TEMP/norsk-ctl"
|