Skip to content

Commit e2b261b

Browse files
committed
feat(docker-build-images): add cache-type input
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
1 parent 674d797 commit e2b261b

3 files changed

Lines changed: 148 additions & 34 deletions

File tree

.github/workflows/__test-workflow-docker-build-images.yml

Lines changed: 124 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,16 @@ jobs:
2424
exit 1
2525
fi
2626
27-
act:
27+
act-build-arch:
2828
needs: arrange
2929
uses: ./.github/workflows/docker-build-images.yml
3030
secrets:
3131
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
32-
build-secrets: |
33-
SECRET_REPOSITORY_OWNER=${{ github.repository_owner }}
34-
SECRET_REPOSITORY=${{ github.repository }}
3532
build-secret-github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
3633
with:
3734
# First image is multi arch
3835
# Second image is mono arch
39-
# Third image tests build args, secrets
36+
# Default caching
4037
images: |
4138
[
4239
{
@@ -55,31 +52,11 @@ jobs:
5552
"target": "prod",
5653
"platforms": ["linux/amd64"],
5754
"tag": "0.1.0"
58-
},
59-
{
60-
"name": "test-build-args-secrets",
61-
"context": ".",
62-
"target": "test",
63-
"dockerfile": "./tests/application/Dockerfile",
64-
"platforms": ["linux/amd64"],
65-
"build-args": {
66-
"BUILD_RUN_ID": "${{ github.run_id }}",
67-
"BUILD_REPOSITORY_OWNER": "${{ github.repository_owner }}",
68-
"BUILD_REPOSITORY": "${{ github.repository }}"
69-
},
70-
"secret-envs": {
71-
"SECRET_ENV_REPOSITORY_OWNER": "GITHUB_REPOSITORY_OWNER",
72-
"SECRET_ENV_REPOSITORY": "GITHUB_REPOSITORY"
73-
}
7455
}
7556
]
76-
build-secret-github-app-id: ${{ vars.CI_BOT_APP_ID }}
77-
build-secret-github-app-token-env: |
78-
SECRET_ENV_GITHUB_APP_TOKEN_1
79-
SECRET_ENV_GITHUB_APP_TOKEN_2
8057
81-
assert:
82-
needs: act
58+
assert-build-arch:
59+
needs: act-build-arch
8360
runs-on: "ubuntu-latest"
8461
steps:
8562
- name: Check built images ouput
@@ -88,7 +65,7 @@ jobs:
8865
script: |
8966
const assert = require("assert");
9067
91-
const builtImagesOutput = `${{ needs.act.outputs.built-images }}`;
68+
const builtImagesOutput = `${{ needs.act-build-arch.outputs.built-images }}`;
9269
assert(builtImagesOutput.length, `"built-images" output is empty`);
9370
9471
// Check if is valid Json
@@ -101,8 +78,7 @@ jobs:
10178
10279
const expectedCreatedImages = [
10380
"test-multi-arch",
104-
"test-mono-arch",
105-
"test-build-args-secrets"
81+
"test-mono-arch"
10682
];
10783
assert(typeof builtImages === "object" && !Array.isArray(builtImages), `"built-images" output is not an object`);
10884
assert.equal(Object.keys(builtImages).length, expectedCreatedImages.length, `"built-images" output does not contain ${expectedCreatedImages.length} images`);
@@ -162,7 +138,7 @@ jobs:
162138
script: |
163139
const assert = require("assert");
164140
165-
const image = `${{ fromJson(needs.act.outputs.built-images).test-multi-arch.images[0] }}`;
141+
const image = `${{ fromJson(needs.act-build-arch.outputs.built-images).test-multi-arch.images[0] }}`;
166142
167143
await exec.exec('docker', ['pull', image]);
168144
@@ -224,7 +200,7 @@ jobs:
224200
script: |
225201
const assert = require("assert");
226202
227-
const image = `${{ fromJson(needs.act.outputs.built-images).test-mono-arch.images[0] }}`;
203+
const image = `${{ fromJson(needs.act-build-arch.outputs.built-images).test-mono-arch.images[0] }}`;
228204
229205
await exec.exec('docker', ['pull', image]);
230206
@@ -263,4 +239,120 @@ jobs:
263239
);
264240
});
265241
242+
act-build-args-secrets-and-registry-caching:
243+
needs: arrange
244+
uses: ./.github/workflows/docker-build-images.yml
245+
secrets:
246+
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
247+
build-secrets: |
248+
SECRET_REPOSITORY_OWNER=${{ github.repository_owner }}
249+
SECRET_REPOSITORY=${{ github.repository }}
250+
build-secret-github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
251+
with:
252+
cache-type: registry
253+
images: |
254+
[
255+
{
256+
"name": "test-build-args-secrets",
257+
"context": ".",
258+
"target": "test",
259+
"dockerfile": "./tests/application/Dockerfile",
260+
"platforms": ["linux/amd64","linux/arm64"],
261+
"build-args": {
262+
"BUILD_RUN_ID": "${{ github.run_id }}",
263+
"BUILD_REPOSITORY_OWNER": "${{ github.repository_owner }}",
264+
"BUILD_REPOSITORY": "${{ github.repository }}"
265+
},
266+
"secret-envs": {
267+
"SECRET_ENV_REPOSITORY_OWNER": "GITHUB_REPOSITORY_OWNER",
268+
"SECRET_ENV_REPOSITORY": "GITHUB_REPOSITORY"
269+
}
270+
}
271+
]
272+
build-secret-github-app-id: ${{ vars.CI_BOT_APP_ID }}
273+
build-secret-github-app-token-env: |
274+
SECRET_ENV_GITHUB_APP_TOKEN_1
275+
SECRET_ENV_GITHUB_APP_TOKEN_2
276+
277+
assert-build-args-secrets-and-registry-caching:
278+
needs: act-build-args-secrets-and-registry-caching
279+
runs-on: "ubuntu-latest"
280+
steps:
281+
- name: Check built images ouput
282+
uses: actions/github-script@v7.0.1
283+
with:
284+
script: |
285+
const assert = require("assert");
286+
287+
const builtImagesOutput = `${{ needs.act-build-args-secrets-and-registry-caching.outputs.built-images }}`;
288+
assert(builtImagesOutput.length, `"built-images" output is empty`);
289+
290+
// Check if is valid Json
291+
let builtImages = null;
292+
try {
293+
builtImages = JSON.parse(builtImagesOutput);
294+
} catch (error) {
295+
throw new Error(`"built-images" output is not a valid JSON: ${error}`);
296+
}
297+
298+
const expectedCreatedImages = [
299+
"test-build-args-secrets"
300+
];
301+
302+
assert(typeof builtImages === "object" && !Array.isArray(builtImages), `"built-images" output is not an object`);
303+
assert.equal(Object.keys(builtImages).length, expectedCreatedImages.length, `"built-images" output does not contain ${expectedCreatedImages.length} images`);
304+
305+
for (const image of expectedCreatedImages) {
306+
assert(builtImages[image], `"built-images" output does not contain "${image}" image`);
307+
}
308+
- uses: docker/login-action@v3
309+
with:
310+
registry: ghcr.io
311+
username: ${{ github.repository_owner }}
312+
password: ${{ github.token }}
313+
314+
- name: Check docker image and cache
315+
uses: actions/github-script@v7.0.1
316+
with:
317+
script: |
318+
const assert = require("assert");
319+
320+
let expectedTag;
321+
322+
const isPullRequest = `${{ github.event_name }}` === "pull_request";
323+
if (isPullRequest) {
324+
const shortSha = `${{ github.sha }}`.substring(0, 7);
325+
expectedTag = `pr-${{ github.event.pull_request.number }}-${shortSha}`;
326+
} else {
327+
expectedTag = `${{ github.ref_name }}`;
328+
}
329+
330+
const expectedImage = `ghcr.io/hoverkraft-tech/ci-github-container/test-build-args-secrets`;
331+
const expectedImageTag = `${expectedImage}:${expectedTag}`;
332+
333+
const image = `${{ fromJson(needs.act-build-args-secrets-and-registry-caching.outputs.built-images).test-build-args-secrets.images[0] }}`;
334+
335+
assert.equal(image, expectedImageTag, `"built-images" output is not valid. Expected "${expectedImage}", got "${image}"`);
336+
337+
await exec.exec('docker', ['pull', image]);
338+
339+
let expectedCacheTag;
340+
341+
if (isPullRequest) {
342+
expectedCacheTag = `pr-${{ github.event.pull_request.number }}`;
343+
} else {
344+
expectedCacheTag = `${{ github.ref_name }}`;
345+
}
346+
347+
const cacheImage = `${expectedImage}/cache:${expectedCacheTag}`;
348+
349+
const cacheImages = [
350+
`${cacheImage}-linux-arm64`,
351+
`${cacheImage}-linux-amd64`
352+
];
353+
354+
for (const cacheImage of cacheImages) {
355+
await exec.exec('docker', ['manifest', 'inspect', cacheImage]);
356+
}
357+
266358
# jscpd:ignore-end

.github/workflows/docker-build-images.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ on: # yamllint disable-line rule:truthy
108108
required: false
109109
type: string
110110
default: ${{ github.repository_owner }}
111+
cache-type:
112+
description: |
113+
Cache type.
114+
See <https://docs.docker.com/build/cache/backends>.
115+
default: "gha"
116+
type: string
117+
required: false
111118
secrets:
112119
oci-registry-password:
113120
description: |
@@ -406,6 +413,7 @@ jobs:
406413
platform: ${{ matrix.image.platform }}
407414
secret-envs: ${{ steps.prepare-secret-envs.outputs.secret-envs }}
408415
secrets: ${{ secrets.build-secrets }}
416+
cache-type: ${{ inputs.cache-type }}
409417

410418
# FIXME: Set built images infos in file to be uploaded as artifacts, because github action does not handle job outputs for matrix
411419
# https://github.com/orgs/community/discussions/26639

actions/docker/build-image/action.yml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ inputs:
103103
List of secret environment variables to expose to the build (e.g., key=envname, MY_SECRET=MY_ENV_VAR).
104104
See <https://docs.docker.com/build/ci/github-actions/secrets/>.
105105
required: false
106+
cache-type:
107+
description: |
108+
Cache type.
109+
See <https://docs.docker.com/build/cache/backends>.
110+
default: "gha"
111+
required: false
106112

107113
runs:
108114
using: "composite"
@@ -141,6 +147,14 @@ runs:
141147
142148
echo "cache-flavor=$CACHE_FLAVOR" >> "$GITHUB_OUTPUT"
143149
150+
# Define cache image
151+
CACHE_TYPE="${{ inputs.cache-type }}"
152+
if [ "$CACHE_TYPE" = "registry" ]; then
153+
echo "cache-image=${{ steps.metadata.outputs.image }}/cache" >> "$GITHUB_OUTPUT"
154+
else
155+
echo "cache-image=${{ steps.metadata.outputs.image }}" >> "$GITHUB_OUTPUT"
156+
fi
157+
144158
# Check if docker exists
145159
if command -v docker &> /dev/null; then
146160
echo "docker-exists=true" >> "$GITHUB_OUTPUT"
@@ -188,10 +202,10 @@ runs:
188202
- id: cache
189203
uses: int128/docker-build-cache-config-action@v1.37.0
190204
with:
191-
image: ${{ steps.metadata.outputs.image }}/cache
205+
image: ${{ steps.get-docker-config.outputs.cache-image }}
192206
flavor: ${{ steps.get-docker-config.outputs.cache-flavor }}
193207
pull-request-cache: true
194-
cache-type: gha
208+
cache-type: ${{ inputs.cache-type }}
195209
extra-cache-to: "image-manifest=true,oci-mediatypes=true"
196210

197211
- if: steps.get-docker-config.outputs.docker-exists != 'true'

0 commit comments

Comments
 (0)