Skip to content

Commit fad2d5a

Browse files
ci: continuous image generation in github registry (#74)
Signed-off-by: Carlos Feria <[email protected]>
1 parent 7aa9eab commit fad2d5a

File tree

4 files changed

+261
-7
lines changed

4 files changed

+261
-7
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
name: Reusable Build and Push Image
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
registry:
7+
description: Registry hostname + namespace of image
8+
required: true
9+
type: string
10+
image_name:
11+
description: The name of the image
12+
required: true
13+
type: string
14+
containerfile:
15+
description: Path to Dockerfile or Containerfile for build
16+
required: true
17+
type: string
18+
pre_build_cmd:
19+
description: "Command to run before building images"
20+
required: false
21+
type: string
22+
architectures:
23+
description: Valid JSON string representing architectures to build
24+
default: '["amd64", "arm64"]'
25+
type: string
26+
required: false
27+
build-args:
28+
description: "Build args to be passed to buildah bud. Separate arguments by newline."
29+
default: ""
30+
required: false
31+
type: string
32+
extra-args:
33+
description: "Extra args to be passed to buildah bud. Separate arguments by newline. Do not use quotes."
34+
default: ""
35+
required: false
36+
type: string
37+
context:
38+
description: "Path to directory to use as the build context."
39+
default: "."
40+
required: false
41+
type: string
42+
swap-size-gb:
43+
description: "Swap space to create, in Gigabytes."
44+
default: ""
45+
required: false
46+
type: string
47+
secrets:
48+
registry_username:
49+
description: "Registry username"
50+
required: true
51+
registry_password:
52+
description: "Registry password"
53+
required: true
54+
outputs:
55+
tag:
56+
description: "The tag of the image pushed to the registry"
57+
value: ${{ jobs.prepare.outputs.tag }}
58+
digest:
59+
description: "The digest of the image pushed to the registry"
60+
value: ${{ jobs.manifest.outputs.digest }}
61+
62+
jobs:
63+
prepare:
64+
runs-on: ubuntu-latest
65+
outputs:
66+
tag: ${{ steps.define-tag.outputs.tag }}
67+
steps:
68+
- name: Define & sanitize tag
69+
id: define-tag
70+
shell: bash
71+
run: |
72+
tag=${{ github.ref == 'refs/heads/main' && 'latest' || github.ref_name }}
73+
74+
# Replace "/" by "-" as "/" is not a valid character for a container tag
75+
tag="${tag#release/}"
76+
echo $tag
77+
echo "tag=$tag" >> "$GITHUB_OUTPUT"
78+
79+
build:
80+
needs: [ prepare ]
81+
runs-on: ubuntu-latest
82+
env:
83+
tag: ${{ needs.prepare.outputs.tag }}
84+
strategy:
85+
matrix:
86+
architecture: ${{ fromJSON(inputs.architectures) }}
87+
steps:
88+
- name: Get more swap space
89+
shell: bash
90+
if: "${{ inputs.swap-size-gb != '' }}"
91+
run: |
92+
echo "Before swap"
93+
free -h
94+
swapon --show
95+
96+
# Make swap
97+
SWAP_FILE="$(swapon --show=NAME | tail -n 1)"
98+
export SWAP_FILE
99+
sudo swapoff "${SWAP_FILE}"
100+
sudo rm "${SWAP_FILE}"
101+
sudo fallocate -l "${{ inputs.swap-size-gb }}"G "${SWAP_FILE}"
102+
sudo chmod 600 "${SWAP_FILE}"
103+
sudo mkswap "${SWAP_FILE}"
104+
sudo swapon "${SWAP_FILE}"
105+
106+
echo "After swap"
107+
free -h
108+
swapon --show
109+
110+
- name: Maximize disk space
111+
shell: bash
112+
run: |
113+
echo "Space before clearing:"
114+
df . -h
115+
sudo rm -rf /usr/share/dotnet
116+
sudo rm -rf /opt/ghc
117+
sudo rm -rf "/usr/local/share/boost"
118+
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
119+
echo "Space after clearing:"
120+
df . -h
121+
122+
- name: Checkout
123+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
124+
125+
- name: Configure QEMU
126+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #v3
127+
with:
128+
platforms: all
129+
130+
- name: Image meta
131+
id: meta
132+
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f #v5
133+
with:
134+
images: ${{ inputs.registry }}/${{ inputs.image_name }}
135+
tags: |
136+
type=schedule
137+
type=semver,pattern={{version}}
138+
type=semver,pattern={{major}}.{{minor}}
139+
type=semver,pattern={{major}}
140+
type=ref,event=branch
141+
type=ref,event=pr
142+
type=sha
143+
144+
- name: Run pre build command
145+
shell: bash
146+
run: "${{ inputs.pre_build_cmd }}"
147+
if: "${{ inputs.pre_build_cmd != '' }}"
148+
149+
- name: Build Image
150+
id: build
151+
uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 #v2
152+
with:
153+
image: ${{ inputs.image_name }}
154+
tags: ${{ env.tag }}-${{ matrix.architecture }}
155+
build-args: ${{ inputs.build-args }}
156+
extra-args: "--no-cache --rm ${{ inputs.extra-args }}"
157+
archs: ${{ matrix.architecture }}
158+
labels: ${{ steps.meta.outputs.labels }}
159+
containerfiles: ${{ inputs.containerfile }}
160+
context: ${{ inputs.context }}
161+
162+
- name: Push To Registry
163+
uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2
164+
id: push
165+
with:
166+
image: ${{ steps.build.outputs.image }}
167+
tags: ${{ env.tag }}-${{ matrix.architecture }}
168+
username: ${{ secrets.registry_username }}
169+
password: ${{ secrets.registry_password }}
170+
registry: ${{ inputs.registry }}
171+
172+
manifest:
173+
needs: [ prepare, build ]
174+
runs-on: ubuntu-latest
175+
outputs:
176+
digest: ${{ steps.push.outputs.digest }}
177+
env:
178+
tag: ${{ needs.prepare.outputs.tag }}
179+
steps:
180+
- name: Log in to registry
181+
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 #v1
182+
with:
183+
username: ${{ secrets.registry_username }}
184+
password: ${{ secrets.registry_password }}
185+
registry: ${{ inputs.registry }}
186+
187+
- name: Create manifest
188+
shell: bash
189+
run: |
190+
podman manifest create "${{ inputs.registry }}/${{ inputs.image_name }}:${{ env.tag }}"
191+
for arch in $(echo '${{ inputs.architectures }}' | jq -r '.[]'); do
192+
podman manifest add \
193+
"${{ inputs.registry }}/${{ inputs.image_name }}:${{ env.tag }}" \
194+
"${{ inputs.registry }}/${{ inputs.image_name }}:${{ env.tag }}-${arch}"
195+
done
196+
197+
- name: Push To Registry
198+
uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c #v2
199+
id: push
200+
with:
201+
image: ${{ inputs.image_name }}
202+
tags: ${{ env.tag }}
203+
username: ${{ secrets.registry_username }}
204+
password: ${{ secrets.registry_password }}
205+
registry: ${{ inputs.registry }}

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ jobs:
1515
ci:
1616
runs-on: ubuntu-latest
1717
steps:
18-
- uses: actions/checkout@v5
18+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
1919
- name: Use Node.js
20-
uses: actions/setup-node@v4
20+
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
2121
with:
2222
node-version: 22
2323
cache: npm

.github/workflows/deploy.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ jobs:
2626
url: ${{ steps.deployment.outputs.page_url }}
2727
runs-on: ubuntu-latest
2828
steps:
29-
- uses: actions/checkout@v5
30-
- uses: actions/setup-node@v4
29+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
30+
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
3131
with:
3232
node-version: 22
3333
cache: npm
@@ -36,11 +36,11 @@ jobs:
3636
- name: Build
3737
run: NODE_ENV=development BASE_URL=/rhtas-console-ui/ MOCK=on npm run build
3838
- name: Setup Pages
39-
uses: actions/configure-pages@v5
39+
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
4040
- name: Upload artifact
41-
uses: actions/upload-pages-artifact@v3
41+
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b #v4
4242
with:
4343
path: "./client/dist"
4444
- name: Deploy to GitHub Pages
4545
id: deployment
46-
uses: actions/deploy-pages@v4
46+
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4

.github/workflows/image-build.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Multiple Architecture Image Build
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- "main"
8+
- "release/*"
9+
tags:
10+
- "v*"
11+
12+
concurrency:
13+
group: build-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
ui-image-build:
18+
uses: ./.github/workflows/build-push-images.yaml
19+
with:
20+
registry: "ghcr.io"
21+
image_name: "${{ github.repository_owner }}/rhtas-console-ui"
22+
containerfile: "./Dockerfile"
23+
architectures: '[ "amd64", "arm64" ]'
24+
extra-args: "--ulimit nofile=4096:4096"
25+
secrets:
26+
registry_username: ${{ github.actor }}
27+
registry_password: ${{ secrets.GITHUB_TOKEN }}
28+
29+
attestations:
30+
needs: ui-image-build
31+
runs-on: ubuntu-latest
32+
permissions:
33+
id-token: write
34+
contents: read
35+
attestations: write
36+
packages: write
37+
steps:
38+
- name: Log in to registry
39+
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 #v1
40+
with:
41+
username: ${{ github.actor }}
42+
password: ${{ secrets.GITHUB_TOKEN }}
43+
registry: ghcr.io
44+
- name: Generate artifact attestation
45+
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3
46+
with:
47+
subject-name: ghcr.io/${{ github.repository_owner }}/rhtas-console-ui
48+
subject-digest: ${{ needs.ui-image-build.outputs.digest }}
49+
push-to-registry: true

0 commit comments

Comments
 (0)