@norskvideo/ctl-dev-kit 0.1.27 → 0.1.28
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/conventions/build-image.yml +108 -27
- package/package.json +1 -1
|
@@ -1,21 +1,43 @@
|
|
|
1
|
-
# Build
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
1
|
+
# Build + publish a PRODUCT container image, multi-arch (linux/amd64 +
|
|
2
|
+
# linux/arm64), to Docker Hub. Single-sourced in @norskvideo/ctl-dev-kit
|
|
3
|
+
# (conventions/build-image.yml) and drift-gated -- edit the dev-kit source, never
|
|
4
|
+
# the copy.
|
|
5
|
+
#
|
|
6
|
+
# Multi-arch house style: native build per arch (no QEMU), each arch pushes its
|
|
7
|
+
# own `:<label>-<arch>` tag to Docker Hub, then a publish job combines them with
|
|
8
|
+
# `docker buildx imagetools create` into the multi-arch manifest. Each publish
|
|
9
|
+
# writes two tags:
|
|
10
|
+
# <repo>:<label> immutable, label = YYYY-MM-DD-<sha8> (what deployments pin)
|
|
11
|
+
# <repo>:<channel> moving (latest | rc | nightly)
|
|
12
|
+
#
|
|
13
|
+
# The one per-repo value is the masked PUBLISH_IMAGE env: set to a product's
|
|
14
|
+
# Docker Hub repo (norskvideo org) it builds + publishes both arches; left empty
|
|
15
|
+
# the build runs as a standalone-build proof (both arches) and publishes nothing
|
|
16
|
+
# -- for a product that is not deployed yet.
|
|
17
|
+
#
|
|
18
|
+
# CHANNEL: push-to-main publishes `latest` (matches the retired in-monorepo
|
|
19
|
+
# pipeline, so :latest + the dated tags stay fresh for installers/deployments).
|
|
20
|
+
# workflow_dispatch can publish any channel. When the product channel model
|
|
21
|
+
# (rc -> latest promotion) lands, flip the push default to `nightly` and let the
|
|
22
|
+
# promotion gate move `latest`.
|
|
23
|
+
#
|
|
24
|
+
# Repo-local for now; to be hoisted into id3as/ci-workflows as a reusable
|
|
25
|
+
# workflow (RFC 0001 Workstream E).
|
|
13
26
|
name: build-image
|
|
14
27
|
|
|
15
28
|
on:
|
|
16
29
|
push:
|
|
17
30
|
branches: [main]
|
|
18
31
|
workflow_dispatch:
|
|
32
|
+
inputs:
|
|
33
|
+
channel:
|
|
34
|
+
description: "Moving channel tag to publish (latest | rc | nightly)."
|
|
35
|
+
type: string
|
|
36
|
+
default: latest
|
|
37
|
+
dry_run:
|
|
38
|
+
description: "Build + stage both arches, skip the Docker Hub publish."
|
|
39
|
+
type: boolean
|
|
40
|
+
default: false
|
|
19
41
|
|
|
20
42
|
permissions:
|
|
21
43
|
contents: read
|
|
@@ -32,10 +54,44 @@ env:
|
|
|
32
54
|
PUBLISH_IMAGE: ""
|
|
33
55
|
|
|
34
56
|
jobs:
|
|
35
|
-
|
|
57
|
+
# Compute the immutable label ONCE, so both arch builds and the manifest share
|
|
58
|
+
# it (a per-job `date` could straddle midnight and disagree).
|
|
59
|
+
label:
|
|
36
60
|
runs-on: x64
|
|
61
|
+
outputs:
|
|
62
|
+
label: ${{ steps.gen.outputs.label }}
|
|
63
|
+
channel: ${{ steps.gen.outputs.channel }}
|
|
64
|
+
# `publish` is derived here (in a step, where the env context is readable)
|
|
65
|
+
# because the env context is NOT available in a job-level `if:` -- the
|
|
66
|
+
# publish job gates on this output instead of on PUBLISH_IMAGE directly.
|
|
67
|
+
publish: ${{ steps.gen.outputs.publish }}
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v5
|
|
70
|
+
with:
|
|
71
|
+
clean: false
|
|
72
|
+
- id: gen
|
|
73
|
+
run: |
|
|
74
|
+
label="$(date -u +%Y-%m-%d)-$(git rev-parse --short=8 HEAD)"
|
|
75
|
+
channel="${{ github.event.inputs.channel || 'latest' }}"
|
|
76
|
+
if [ -n "${PUBLISH_IMAGE}" ]; then publish=true; else publish=false; fi
|
|
77
|
+
echo "label=${label}" >> "$GITHUB_OUTPUT"
|
|
78
|
+
echo "channel=${channel}" >> "$GITHUB_OUTPUT"
|
|
79
|
+
echo "publish=${publish}" >> "$GITHUB_OUTPUT"
|
|
80
|
+
echo "label=${label} channel=${channel} publish=${publish}"
|
|
81
|
+
|
|
82
|
+
build:
|
|
83
|
+
needs: label
|
|
84
|
+
strategy:
|
|
85
|
+
fail-fast: false
|
|
86
|
+
matrix:
|
|
87
|
+
include:
|
|
88
|
+
- runner: x64
|
|
89
|
+
arch: amd64
|
|
90
|
+
- runner: ar-arm-vm
|
|
91
|
+
arch: arm64
|
|
92
|
+
runs-on: ${{ matrix.runner }}
|
|
37
93
|
steps:
|
|
38
|
-
# clean: false -- the integration suite (shared
|
|
94
|
+
# clean: false -- the integration suite (shared pool) leaves root-owned
|
|
39
95
|
# bind-mount dirs under test-temp/ that a non-root git clean can't remove
|
|
40
96
|
# (EACCES). This job never needs them; skip the clean so it doesn't choke on
|
|
41
97
|
# another workflow's leftovers.
|
|
@@ -43,12 +99,12 @@ jobs:
|
|
|
43
99
|
with:
|
|
44
100
|
clean: false
|
|
45
101
|
|
|
46
|
-
- name: Build product image (copy-only, via the dev-kit driver)
|
|
102
|
+
- name: Build product image (copy-only, via the dev-kit driver, native ${{ matrix.arch }})
|
|
47
103
|
run: |
|
|
48
104
|
if [ -n "${PUBLISH_IMAGE}" ]; then
|
|
49
|
-
IMAGE_TAG="${PUBLISH_IMAGE}:${{
|
|
105
|
+
IMAGE_TAG="${PUBLISH_IMAGE}:${{ needs.label.outputs.label }}-${{ matrix.arch }}"
|
|
50
106
|
else
|
|
51
|
-
IMAGE_TAG="norsk-ctl-product:${{
|
|
107
|
+
IMAGE_TAG="norsk-ctl-product:${{ needs.label.outputs.label }}-${{ matrix.arch }}"
|
|
52
108
|
fi
|
|
53
109
|
echo "IMAGE_TAG=${IMAGE_TAG}" >> "$GITHUB_ENV"
|
|
54
110
|
export IMAGE_TAG
|
|
@@ -65,26 +121,51 @@ jobs:
|
|
|
65
121
|
username: norskvideo
|
|
66
122
|
password: ${{ secrets.DOCKER_PAT }}
|
|
67
123
|
|
|
68
|
-
- name: Push image to Docker Hub
|
|
124
|
+
- name: Push the per-arch image to Docker Hub
|
|
69
125
|
if: ${{ env.PUBLISH_IMAGE != '' }}
|
|
126
|
+
run: docker push "$IMAGE_TAG"
|
|
127
|
+
|
|
128
|
+
# Combine the per-arch images into a multi-arch manifest and write the two
|
|
129
|
+
# published tags. Skipped for a build-only product (empty PUBLISH_IMAGE) and on
|
|
130
|
+
# a dry run.
|
|
131
|
+
publish:
|
|
132
|
+
needs: [label, build]
|
|
133
|
+
if: ${{ needs.label.outputs.publish == 'true' && !inputs.dry_run }}
|
|
134
|
+
runs-on: x64
|
|
135
|
+
steps:
|
|
136
|
+
- uses: actions/checkout@v5
|
|
137
|
+
with:
|
|
138
|
+
clean: false
|
|
139
|
+
|
|
140
|
+
- name: Log in to Docker Hub
|
|
141
|
+
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
|
142
|
+
with:
|
|
143
|
+
username: norskvideo
|
|
144
|
+
password: ${{ secrets.DOCKER_PAT }}
|
|
145
|
+
|
|
146
|
+
- name: Create + push the multi-arch manifest (dated label + channel)
|
|
70
147
|
run: |
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
docker
|
|
148
|
+
label="${{ needs.label.outputs.label }}"
|
|
149
|
+
channel="${{ needs.label.outputs.channel }}"
|
|
150
|
+
# buildx imagetools create, not `docker manifest create`: the arm64
|
|
151
|
+
# runner's containerd image store pushes single-arch images wrapped in
|
|
152
|
+
# an OCI index, which `docker manifest create` refuses to nest. imagetools
|
|
153
|
+
# accepts index sources and writes every -t tag in one push.
|
|
154
|
+
docker buildx imagetools create \
|
|
155
|
+
-t "${PUBLISH_IMAGE}:${label}" \
|
|
156
|
+
-t "${PUBLISH_IMAGE}:${channel}" \
|
|
157
|
+
"${PUBLISH_IMAGE}:${label}-amd64" \
|
|
158
|
+
"${PUBLISH_IMAGE}:${label}-arm64"
|
|
74
159
|
|
|
75
160
|
# Report this pipeline's result to the aggregated product CI dashboard
|
|
76
|
-
# (id3as/ci-workflows) instead of posting its own pony
|
|
161
|
+
# (id3as/ci-workflows) instead of posting its own pony -- the dashboard renders
|
|
77
162
|
# the pony/emoji from the dispatched result. always() so a red or manual run
|
|
78
163
|
# still reports.
|
|
79
164
|
notify:
|
|
80
|
-
needs: build
|
|
165
|
+
needs: [build, publish]
|
|
81
166
|
if: ${{ !cancelled() }}
|
|
82
167
|
runs-on: x64
|
|
83
168
|
steps:
|
|
84
|
-
# clean: false -- the integration suite (shared x64 pool) leaves root-owned
|
|
85
|
-
# bind-mount dirs under test-temp/ that a non-root git clean can't remove
|
|
86
|
-
# (EACCES). This job never needs them; skip the clean so it doesn't choke on
|
|
87
|
-
# another workflow's leftovers.
|
|
88
169
|
- uses: actions/checkout@v5
|
|
89
170
|
with:
|
|
90
171
|
clean: false
|