Skip to content

Commit 07f0faf

Browse files
authored
Add support to compare platform variants (#29)
Add support to optionally compare image platform variants. Eg. linux/arm64 is equal to linux/arm64/v8 and both are heavily used on docker images.
1 parent 31074cf commit 07f0faf

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

.github/workflows/test.yml

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ env:
1111
DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
1212

1313
jobs:
14+
#####################################
15+
# Singe platform tests
16+
1417
test1:
1518
name: Test Update Needed
1619
runs-on: ubuntu-22.04
@@ -52,6 +55,26 @@ jobs:
5255
fi
5356
5457
test3:
58+
name: Test single platform
59+
runs-on: ubuntu-22.04
60+
steps:
61+
- name: Checkout Repository
62+
uses: actions/checkout@v3
63+
- name: Test Action
64+
id: test
65+
uses: ./
66+
with:
67+
base-image: alpine:3.17.1
68+
image: lucacome/alpine-amd64
69+
- name: Get Test Output
70+
run: echo "Workflow Docker Image ${{ steps.test.outputs.needs-updating }}"
71+
- name: Check value
72+
run: |
73+
if [[ "${{ steps.test.outputs.needs-updating }}" != "false" ]]; then
74+
exit 1
75+
fi
76+
77+
test4:
5578
name: Test Update Needed on ARM64
5679
runs-on: ubuntu-22.04
5780
steps:
@@ -72,7 +95,10 @@ jobs:
7295
exit 1
7396
fi
7497
75-
test4:
98+
#####################################
99+
# Test with multiple platforms
100+
101+
test5:
76102
name: Test Update Needed on multiple platforms
77103
runs-on: ubuntu-22.04
78104
steps:
@@ -93,7 +119,7 @@ jobs:
93119
exit 1
94120
fi
95121
96-
test5:
122+
test6:
97123
name: Test Update Not Needed on multiple platforms
98124
runs-on: ubuntu-22.04
99125
steps:
@@ -113,9 +139,11 @@ jobs:
113139
if [[ "${{ steps.test.outputs.needs-updating }}" != "false" ]]; then
114140
exit 1
115141
fi
142+
#####################################
143+
# Test with platform variants
116144

117-
test6:
118-
name: Test single platform
145+
test7:
146+
name: Test Update Needed on multiple platforms with variants
119147
runs-on: ubuntu-22.04
120148
steps:
121149
- name: Checkout Repository
@@ -124,8 +152,30 @@ jobs:
124152
id: test
125153
uses: ./
126154
with:
127-
base-image: alpine:3.17.1
128-
image: lucacome/alpine-amd64
155+
base-image: alpine:latest
156+
image: golang:1.14.15-alpine3.13
157+
platforms: linux/arm64/v8,linux/arm/v7,linux/amd64
158+
- name: Get Test Output
159+
run: echo "Workflow Docker Image ${{ steps.test.outputs.needs-updating }}"
160+
- name: Check value
161+
run: |
162+
if [[ "${{ steps.test.outputs.needs-updating }}" != "true" ]]; then
163+
exit 1
164+
fi
165+
166+
test8:
167+
name: Test Update Not Needed on multiple platforms with variants
168+
runs-on: ubuntu-22.04
169+
steps:
170+
- name: Checkout Repository
171+
uses: actions/checkout@v3
172+
- name: Test Action
173+
id: test
174+
uses: ./
175+
with:
176+
base-image: alpine:3.17.2
177+
image: alpine:3.17.2
178+
platforms: linux/arm64/v8,linux/arm/v7,linux/amd64
129179
- name: Get Test Output
130180
run: echo "Workflow Docker Image ${{ steps.test.outputs.needs-updating }}"
131181
- name: Check value

docker.sh

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ get_manifests() {
2828
fi
2929

3030
headers=$(cat headers | awk -F ': ' '{sub(/\r/,"\n",$2); print $1","$2}' | grep 'docker-content-digest\|content-type' | jq -R 'split(",") | {(if .[0] == "content-type" then "type" else "digest" end): .[1]}' | jq -s 'reduce .[] as $item ({}; . * $item)')
31-
manifest_v2=$(jq -r '. | select(.type == "application/vnd.docker.distribution.manifest.v2+json" or .type == "application/vnd.oci.image.manifest.v1+json") | [{digest: .digest, platform: "linux/amd64"}]' <<<"$headers")
31+
manifest_v2=$(jq -r '. | select(.type == "application/vnd.docker.distribution.manifest.v2+json" or .type == "application/vnd.oci.image.manifest.v1+json") | [{digest: .digest, platforms: ["linux/amd64"]}]' <<<"$headers")
3232
if [ ! -z "$manifest_v2" ]; then
3333
echo "$manifest_v2"
3434
return
3535
fi
3636

37-
jq -r '[.manifests[] | select(.platform.architecture | contains ("unknown") | not) | {digest: .digest, platform: (.platform.os +"/"+ .platform.architecture)}]' <<<"$manifest_list"
38-
37+
manifests_with_variant=$(jq -r '[.manifests[] | select(.platform.architecture | contains ("unknown") | not) | select(.platform.variant != null) | {digest: .digest, platforms: [(.platform.os +"/"+ .platform.architecture +"/"+ .platform.variant), (.platform.os +"/"+ .platform.architecture)] }]' <<<"$manifest_list")
38+
manifests_without_variant=$(jq -r '[.manifests[] | select(.platform.architecture | contains ("unknown") | not) | select(.platform.variant == null) | {digest: .digest, platforms: [(.platform.os +"/"+ .platform.architecture)]}]' <<<"$manifest_list")
39+
# Concat both lists
40+
echo "${manifests_with_variant}${manifests_without_variant}" | jq -s 'flatten(1)'
3941
}
4042

4143
get_layers() {
@@ -111,15 +113,15 @@ diff=false
111113
# loop through plafforms split by comma
112114
for platform in $(echo $platforms | tr -s ',' ' '); do
113115
# get the digest for the platform
114-
digest_base=$(jq -r ".[] | select(.platform == \"$platform\") | .digest" <<<"$manifests_base")
116+
digest_base=$(jq -r ".[] | select(.platforms[] == \"$platform\") | .digest" <<<"$manifests_base")
115117

116118
# if the digest is empty, then the platform is not present in the base image
117119
if [ -z "$digest_base" ]; then
118120
error "Platform $platform not found in the base image $base"
119121
fi
120122

121123
# get the digest for the platform
122-
digest_image=$(jq -r ".[] | select(.platform == \"$platform\") | .digest" <<<"$manifests_image")
124+
digest_image=$(jq -r ".[] | select(.platforms[] == \"$platform\") | .digest" <<<"$manifests_image")
123125

124126
# if the digest is empty, then the platform is not present in the image
125127
if [ -z "$digest_image" ]; then

0 commit comments

Comments
 (0)