Skip to content

Commit 28522c3

Browse files
committed
ci: Add container image build workflow
Signed-off-by: Anastassios Nanos <ananos@nubificus.co.uk>
1 parent 500d3d0 commit 28522c3

2 files changed

Lines changed: 198 additions & 1 deletion

File tree

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
name: Build agent containers
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
agent:
7+
default: 'node'
8+
required: true
9+
registry:
10+
default: 'harbor.nbfc.io'
11+
required: false
12+
workflow_dispatch:
13+
inputs:
14+
agent:
15+
default: 'node'
16+
required: true
17+
registry:
18+
default: 'harbor.nbfc.io'
19+
required: false
20+
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
23+
cancel-in-progress: true
24+
25+
env:
26+
REGISTRY: ${{ github.event.inputs.registry || 'harbor.nbfc.io' }}
27+
# NOTE: We assume that a project named after the repo owner exists in the
28+
# registry. The image will be uploaded as <repo_name> under the <repo_owner>
29+
# project.
30+
REGISTRY_IMAGE: ${{ github.event.inputs.registry || 'harbor.nbfc.io' }}/mlsysops/${{ inputs.agent }}-agent
31+
RUNNER_ARCH_MAP: '[{"amd64":"x86_64", "arm64":"aarch64", "arm":"armv7l"}]'
32+
33+
jobs:
34+
build:
35+
name: Build Docker Image
36+
runs-on: ${{ format('{0}-{1}', 'base-dind-2204', matrix.arch) }}
37+
strategy:
38+
matrix:
39+
arch: ["arm64", "amd64"]
40+
outputs:
41+
digest-amd64: ${{ steps.set-outputs.outputs.digest-amd64 }}
42+
digest-arm64: ${{ steps.set-outputs.outputs.digest-arm64 }}
43+
44+
steps:
45+
- name: Checkout repo
46+
uses: actions/checkout@v4
47+
48+
- name: Login to registry ${{ env.REGISTRY }}
49+
uses: docker/login-action@v3
50+
with:
51+
registry: ${{ env.REGISTRY }}
52+
username: ${{ secrets.HARBOR_USER }}
53+
password: ${{ secrets.HARBOR_SECRET }}
54+
55+
- name: Set up Docker Buildx
56+
uses: docker/setup-buildx-action@v3
57+
58+
- name: Extract Docker metadata
59+
id: meta
60+
uses: docker/metadata-action@v5
61+
with:
62+
images: ${{ env.REGISTRY_IMAGE }}
63+
tags: |
64+
type=sha,prefix=${{ matrix.arch }}-
65+
type=ref,event=branch,prefix=${{ matrix.arch }}-
66+
67+
- name: Build and push ${{ matrix.arch }} image
68+
id: build-and-push
69+
uses: docker/build-push-action@v6
70+
with:
71+
context: ./agents/${{ inputs.agent }}
72+
tags: ${{ steps.meta.outputs.tags }}
73+
labels: ${{ steps.meta.outputs.labels }}
74+
platforms: linux/${{ matrix.arch }}
75+
push: true
76+
file: ./agents/${{ inputs.agent }}/Dockerfile
77+
provenance: false
78+
build-args: |
79+
ARCHTAG=${{ fromJson(env.RUNNER_ARCH_MAP)[0][matrix.arch] }}
80+
BRANCH=${{ github.event.ref_name || github.ref_name }}
81+
82+
- name: Set ${{ matrix.arch }} digest output
83+
id: set-outputs
84+
run: |
85+
# Workaround for https://github.com/actions/runner/issues/2499
86+
echo "digest-${{ matrix.arch }}=${{ steps.build-and-push.outputs.digest }}" \
87+
>> "$GITHUB_OUTPUT"
88+
shell: bash
89+
90+
create-manifest:
91+
name: Create Merged Docker Image Manifest
92+
needs: [build]
93+
runs-on: 'base-dind-2204-amd64'
94+
outputs:
95+
digest-merged: ${{ steps.inspect.outputs.digest-merged }}
96+
97+
steps:
98+
- name: Checkout repo
99+
uses: actions/checkout@v4
100+
101+
- name: Login to registry ${{ inputs.REGISTRY }}
102+
uses: docker/login-action@v3
103+
with:
104+
registry: ${{ env.REGISTRY }}
105+
username: ${{ secrets.HARBOR_USER }}
106+
password: ${{ secrets.HARBOR_SECRET }}
107+
108+
- name: Set up Docker Buildx
109+
uses: docker/setup-buildx-action@v3
110+
111+
- name: Extract Docker metadata
112+
id: meta
113+
uses: docker/metadata-action@v5
114+
with:
115+
images: ${{ env.REGISTRY_IMAGE }}
116+
tags: |
117+
type=sha
118+
type=ref,event=branch
119+
type=raw,value=latest
120+
121+
- name: Create and push manifest
122+
run: |
123+
docker buildx imagetools create \
124+
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< \
125+
"$DOCKER_METADATA_OUTPUT_JSON") \
126+
${{ env.REGISTRY_IMAGE }}@${{ needs.build.outputs.digest-amd64 }} \
127+
${{ env.REGISTRY_IMAGE }}@${{ needs.build.outputs.digest-arm64 }}
128+
shell: bash
129+
130+
- name: Inspect merged image
131+
id: inspect
132+
run: |
133+
docker buildx imagetools inspect \
134+
${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
135+
digest=$(docker buildx imagetools inspect \
136+
${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} \
137+
--format '{{json .Manifest}}' | jq -r '.digest')
138+
if [[ -z "${digest}" ]]; then
139+
echo "Could not get merged image digest"
140+
exit 1
141+
fi
142+
echo "digest-merged=${digest}" >> "$GITHUB_OUTPUT"
143+
shell: bash
144+
145+
sign:
146+
name: Sign Docker Images
147+
needs: [build, create-manifest]
148+
runs-on: 'base-dind-2204-amd64'
149+
permissions:
150+
contents: read
151+
id-token: write
152+
153+
steps:
154+
- name: Install Cosign
155+
uses: sigstore/cosign-installer@v3
156+
157+
- name: Verify Cosign installation
158+
run: cosign version
159+
160+
- name: Login to registry ${{ env.REGISTRY }}
161+
uses: docker/login-action@v3
162+
with:
163+
registry: ${{ env.REGISTRY }}
164+
username: ${{ secrets.HARBOR_USER }}
165+
password: ${{ secrets.HARBOR_SECRET }}
166+
167+
- name: Sign published Docker images
168+
env:
169+
DIGESTS: >-
170+
${{ needs.create-manifest.outputs.digest-merged }}
171+
${{ needs.build.outputs.digest-amd64 }}
172+
${{ needs.build.outputs.digest-arm64 }}
173+
run: |
174+
for digest in ${DIGESTS}; do
175+
cosign sign --yes ${{ env.REGISTRY_IMAGE }}@${digest} \
176+
-a "repo=${{ github.repository }}" \
177+
-a "workflow=${{ github.workflow }}" \
178+
-a "ref=${{ github.sha }}" \
179+
-a "author=Nubificus LTD"
180+
done
181+
shell: bash

.github/workflows/ci.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,29 @@ jobs:
2626

2727
build-agent-pkg:
2828
#needs: [validate-files-and-commits, lint]
29-
name: Build
29+
name: Build python pkg
3030
if: |
3131
contains(github.event.pull_request.labels.*.name, 'ok-to-test') &&
3232
!contains(github.event.pull_request.labels.*.name, 'skip-build')
3333
uses: ./.github/workflows/build-mlsysops-pkg.yml
3434
secrets: inherit
3535

36+
build-agent-containers:
37+
needs: [build-agent-pkg]
38+
name: Build containers
39+
if: |
40+
contains(github.event.pull_request.labels.*.name, 'ok-to-test') &&
41+
!contains(github.event.pull_request.labels.*.name, 'skip-build')
42+
strategy:
43+
matrix:
44+
agent: ["node", "cluster", "continuum"]
45+
uses: ./.github/workflows/build-containers.yml
46+
secrets: inherit
47+
with:
48+
agent: ${{ matrix.agent }}
49+
50+
51+
3652
# lint:
3753
# name: Lint code
3854
# if: |

0 commit comments

Comments
 (0)