Skip to content

Commit d4dc9dd

Browse files
Copilotneilime
andcommitted
Fix: disable image-manifest cache for tagged pushes
Co-authored-by: neilime <[email protected]> Signed-off-by: Emilien Escalle <[email protected]>
1 parent 7f45d18 commit d4dc9dd

File tree

9 files changed

+441
-257
lines changed

9 files changed

+441
-257
lines changed

.github/workflows/__main-ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ jobs:
3737
with:
3838
images: |
3939
[
40-
"application-test"
40+
"application-test",
41+
"test-build-args-secrets",
42+
"test-caching-mono-arch-gha",
43+
"test-caching-multi-arch-gha"
4144
]
4245
4346
clean-with-cache:
@@ -47,7 +50,8 @@ jobs:
4750
prune-cache-images: true
4851
images: |
4952
[
50-
"test-build-args-secrets"
53+
"test-caching-mono-arch-registry",
54+
"test-caching-multi-arch-registry",
5155
]
5256
5357
helm-docs:

.github/workflows/__shared-ci.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,20 @@ jobs:
4747
needs: linter
4848
uses: ./.github/workflows/__test-action-helm-test-chart.yml
4949

50-
test-workflow-docker-build-images:
51-
name: Test docker build images
50+
test-workflow-docker-build-images-building:
51+
name: Test docker build images - Building
5252
needs: linter
53-
uses: ./.github/workflows/__test-workflow-docker-build-images.yml
53+
uses: ./.github/workflows/__test-workflow-docker-build-images-building.yml
54+
secrets: inherit
55+
56+
test-workflow-docker-build-images-caching:
57+
name: Test docker build images - Caching
58+
needs: linter
59+
uses: ./.github/workflows/__test-workflow-docker-build-images-caching.yml
60+
secrets: inherit
61+
62+
test-workflow-docker-build-images-platforms-and-signing:
63+
name: Test docker build images - Platforms and Signing
64+
needs: linter
65+
uses: ./.github/workflows/__test-workflow-docker-build-images-platforms-and-signing.yml
5466
secrets: inherit
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
name: Test for "docker-build-images" workflow - Building
3+
run-name: Test for "docker-build-images" workflow - Building
4+
5+
on: # yamllint disable-line rule:truthy
6+
workflow_call:
7+
8+
permissions:
9+
contents: read
10+
issues: read
11+
packages: write
12+
pull-requests: read
13+
id-token: write
14+
15+
# jscpd:ignore-start
16+
jobs:
17+
act-build-images-args-secrets:
18+
name: Arrange - Build with args, secrets
19+
uses: ./.github/workflows/docker-build-images.yml
20+
secrets:
21+
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
22+
build-secrets: |
23+
SECRET_TEST=test-secret
24+
SECRET_ANOTHER_TEST=another-test-secret
25+
build-secret-github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
26+
with:
27+
images: |
28+
[
29+
{
30+
"name": "test-build-args-secrets",
31+
"context": ".",
32+
"target": "test",
33+
"dockerfile": "./tests/application/Dockerfile",
34+
"platforms": ["linux/amd64"],
35+
"build-args": {
36+
"BUILD_RUN_ID": "${{ github.run_id }}",
37+
"BUILD_ARG_TEST": "test-arg",
38+
"BUILD_ARG_ANOTHER_TEST": "another-test-arg"
39+
},
40+
"secret-envs": {
41+
"SECRET_ENV_TEST": "GITHUB_ACTION",
42+
"SECRET_ENV_ANOTHER_TEST": "GITHUB_JOB"
43+
}
44+
}
45+
]
46+
build-secret-github-app-id: ${{ vars.CI_BOT_APP_ID }}
47+
build-secret-github-app-token-env: |
48+
SECRET_ENV_GITHUB_APP_TOKEN_1
49+
SECRET_ENV_GITHUB_APP_TOKEN_2
50+
51+
assert-build-args-secrets:
52+
name: Assert - Build with args, secrets
53+
needs: act-build-images-args-secrets
54+
runs-on: "ubuntu-latest"
55+
steps:
56+
- name: Check built images ouput
57+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
58+
with:
59+
script: |
60+
const assert = require("assert");
61+
62+
const builtImagesOutput = `${{ needs.act-build-images-args-secrets.outputs.built-images }}`;
63+
assert(builtImagesOutput.length, `"built-images" output is empty`);
64+
65+
// Check if is valid Json
66+
let builtImages = null;
67+
try {
68+
builtImages = JSON.parse(builtImagesOutput);
69+
} catch (error) {
70+
throw new Error(`"built-images" output is not a valid JSON: ${error}`);
71+
}
72+
73+
const expectedCreatedImages = [
74+
"test-build-args-secrets"
75+
];
76+
77+
assert(typeof builtImages === "object" && !Array.isArray(builtImages), `"built-images" output is not an object`);
78+
assert.equal(Object.keys(builtImages).length, expectedCreatedImages.length, `"built-images" output does not contain ${expectedCreatedImages.length} images`);
79+
80+
for (const image of expectedCreatedImages) {
81+
assert(builtImages[image], `"built-images" output does not contain "${image}" image`);
82+
}
83+
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
84+
with:
85+
registry: ghcr.io
86+
username: ${{ github.repository_owner }}
87+
password: ${{ github.token }}
88+
# jscpd:ignore-end
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
name: Test for "docker-build-images" workflow - Caching
3+
run-name: Test for "docker-build-images" workflow - Caching
4+
5+
on: # yamllint disable-line rule:truthy
6+
workflow_call:
7+
8+
permissions:
9+
contents: read
10+
issues: read
11+
packages: write
12+
pull-requests: read
13+
id-token: write
14+
15+
# jscpd:ignore-start
16+
jobs:
17+
arrange:
18+
name: Arrange
19+
runs-on: ubuntu-latest
20+
outputs:
21+
matrix: ${{ steps.define-matrix.outputs.result }}
22+
steps:
23+
- run: |
24+
if [ -z "${{ secrets.GITHUB_TOKEN }}" ]; then
25+
echo "GitHub token secret is not set"
26+
exit 1
27+
fi
28+
29+
- id: define-matrix
30+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
31+
with:
32+
result-encoding: json
33+
script: |
34+
const matrix = {
35+
include: [
36+
{
37+
name: "mono-arch - registry",
38+
"image-name": `test-caching-mono-arch-registry`,
39+
platforms: '["linux/amd64"]',
40+
"cache-type": "registry"
41+
},
42+
{
43+
name: "multi-arch - registry",
44+
"image-name": `test-caching-multi-arch-registry`,
45+
platforms: '["linux/amd64","linux/arm64"]',
46+
"cache-type": "registry"
47+
},
48+
{
49+
name: "mono-arch - gha",
50+
"image-name": `test-caching-mono-arch-gha`,
51+
platforms: '["linux/amd64"]',
52+
"cache-type": "gha"
53+
},
54+
{
55+
name: "multi-arch - gha",
56+
"image-name": `test-caching-multi-arch-gha`,
57+
platforms: '["linux/amd64","linux/arm64"]',
58+
"cache-type": "gha"
59+
}
60+
]
61+
};
62+
return matrix;
63+
64+
act-build-images-registry:
65+
name: Act - Build images - registry cache
66+
needs: arrange
67+
uses: ./.github/workflows/docker-build-images.yml
68+
secrets:
69+
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
70+
build-secret-github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
71+
with:
72+
cache-type: "registry"
73+
sign: false
74+
images: |
75+
[
76+
{
77+
"name": "test-caching-mono-arch-registry",
78+
"context": ".",
79+
"dockerfile": "./tests/application/Dockerfile",
80+
"build-args": { "BUILD_RUN_ID": "${{ github.run_id }}" },
81+
"target": "base",
82+
"platforms": ["linux/amd64"]
83+
},
84+
{
85+
"name": "test-caching-multi-arch-registry",
86+
"context": ".",
87+
"dockerfile": "./tests/application/Dockerfile",
88+
"build-args": { "BUILD_RUN_ID": "${{ github.run_id }}" },
89+
"target": "base",
90+
"platforms": ["linux/amd64","linux/arm64"]
91+
}
92+
]
93+
94+
act-build-images-gha:
95+
name: Act - Build images - gha cache
96+
needs: arrange
97+
uses: ./.github/workflows/docker-build-images.yml
98+
secrets:
99+
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
100+
build-secret-github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
101+
with:
102+
cache-type: "gha"
103+
sign: false
104+
images: |
105+
[
106+
{
107+
"name": "test-caching-mono-arch-gha",
108+
"context": ".",
109+
"dockerfile": "./tests/application/Dockerfile",
110+
"build-args": { "BUILD_RUN_ID": "${{ github.run_id }}" },
111+
"target": "base",
112+
"platforms": ["linux/amd64"]
113+
},
114+
{
115+
"name": "test-caching-multi-arch-gha",
116+
"context": ".",
117+
"dockerfile": "./tests/application/Dockerfile",
118+
"build-args": { "BUILD_RUN_ID": "${{ github.run_id }}" },
119+
"target": "base",
120+
"platforms": ["linux/amd64","linux/arm64"]
121+
}
122+
]
123+
124+
assert-images-cache:
125+
name: Assert - Cached images (${{ matrix.name }})
126+
needs: [arrange, act-build-images-registry, act-build-images-gha]
127+
runs-on: ubuntu-latest
128+
strategy:
129+
fail-fast: false
130+
matrix: ${{ fromJson(needs.arrange.outputs.matrix) }}
131+
steps:
132+
- name: Login to GitHub Container Registry
133+
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
134+
with:
135+
registry: ghcr.io
136+
username: ${{ github.repository_owner }}
137+
password: ${{ github.token }}
138+
139+
- name: Assert image and digest
140+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
141+
env:
142+
BUILT_IMAGES: ${{ needs[matrix.cache-type == 'registry' && 'act-build-images-registry' || 'act-build-images-gha' ].outputs.built-images }}
143+
EXPECTED_IMAGE: ghcr.io/${{ github.repository }}/${{ matrix.image-name }}
144+
with:
145+
script: |
146+
const assert = require("assert");
147+
148+
let expectedTag;
149+
150+
const isPullRequest = `${{ github.event_name }}` === "pull_request";
151+
if (isPullRequest) {
152+
const shortSha = `${{ github.sha }}`.substring(0, 7);
153+
expectedTag = `pr-${{ github.event.pull_request.number }}-${shortSha}`;
154+
} else {
155+
expectedTag = `${{ github.ref_name }}`;
156+
}
157+
158+
const builtImages = JSON.parse(process.env.BUILT_IMAGES);
159+
160+
const imageName = `${{ matrix.image-name }}`;
161+
assert(builtImages[imageName], `"built-images" output does not contain "${imageName}" image`);
162+
163+
const digest = builtImages[imageName].digest;
164+
assert(digest.length, `"built-images" output does not contain digest for "${{ matrix.image-name }}" image`);
165+
assert.match(digest, /^sha256:[0-9a-f]{64}$/, `"built-images" output does not contain valid digest for "${{ matrix.image-name }}" image`);
166+
167+
const expectedImage = process.env.EXPECTED_IMAGE;
168+
const expectedImageTag = `${expectedImage}:${expectedTag}@${digest}`;
169+
170+
const image = builtImages[imageName].images[0];
171+
172+
assert.equal(image, expectedImageTag, `"built-images" output is not valid. Expected "${expectedImage}", got "${image}"`);
173+
174+
await exec.exec('docker', ['pull', image]);
175+
176+
- name: Assert registry cache usage
177+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
178+
if: ${{ matrix.cache-type == 'registry' }}
179+
env:
180+
EXPECTED_IMAGE: ghcr.io/${{ github.repository }}/${{ matrix.image-name }}
181+
EXPECTED_PLATFORMS: ${{ matrix.platforms }}
182+
EXPECTED_CACHE_TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}
183+
with:
184+
script: |
185+
const expectedCacheImage = `${process.env.EXPECTED_IMAGE}/cache:${process.env.EXPECTED_CACHE_TAG}`;
186+
const expectedPlatforms = JSON.parse(process.env.EXPECTED_PLATFORMS);
187+
const expectedCacheImages = expectedPlatforms.map(platform => `${expectedCacheImage}-${platform.replace('/', '-')}`);
188+
189+
for (const cacheImage of expectedCacheImages) {
190+
await exec.exec('docker', ['manifest', 'inspect', cacheImage]);
191+
}
192+
193+
# jscpd:ignore-end

0 commit comments

Comments
 (0)