Skip to content

Commit fc8d7f0

Browse files
authored
Add tests to test size of the image to catch regressions (#40)
Add a test to catch a scenario like introduced in hazelcast/hazelcast-docker#1137, using https://github.com/wagoodman/dive
1 parent fd973aa commit fc8d7f0

File tree

7 files changed

+113
-0
lines changed

7 files changed

+113
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Test assert-image-size action
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
test:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout repository
11+
uses: actions/checkout@v6
12+
13+
- name: Test scripts
14+
run: ./assert-image-size/test_scripts.sh
15+
16+
- name: Run assert-image-size
17+
uses: ./assert-image-size
18+
with:
19+
image: hazelcast/hazelcast:5.0.1-slim

.github/workflows/test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ jobs:
1010
- name: Checkout
1111
uses: actions/checkout@v6
1212

13+
test-assert-image-size:
14+
uses: ./.github/workflows/test-assert-image-size.yml
15+
secrets: inherit
16+
1317
test-check-base-images:
1418
uses: ./.github/workflows/test-check-base-images.yml
1519

@@ -44,6 +48,7 @@ jobs:
4448
assert-all-jobs-succeeded:
4549
runs-on: ubuntu-latest
4650
needs:
51+
- test-assert-image-size
4752
- test-check-base-images
4853
- test-check-if-latest-lts-release
4954
- test-check-redhat-service-status

assert-image-size/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# assert-image-size
2+
3+
A GitHub Action that validates image isn't excessively large / wasting space using [`dive`](https://github.com/wagoodman/dive).
4+
5+
Docker images are built of overlaid [layers](https://docs.docker.com/get-started/docker-concepts/building-images/understanding-image-layers), building on top of one-another. When downloading an image, each layer is downloaded.
6+
7+
If one layer contains a file that is subsequently removed or modified in a subsequent layer, this intermediate state will still be present in the layer to be downloaded, bloating the overall image. An example of this occurred in <https://github.com/hazelcast/hazelcast-docker/pull/1137>.
8+
9+
This action asserts that the amount of wasted space in an image is below a % threshold.

assert-image-size/action.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Test image size
2+
description: Test image isn't excessively large / wasting space
3+
4+
inputs:
5+
image:
6+
description: Image name to test
7+
required: true
8+
minimum_efficiency:
9+
description: Minimum efficiency percentage required - 0-1 scale
10+
required: false
11+
default: 0.95
12+
13+
runs:
14+
using: "composite"
15+
steps:
16+
- shell: bash
17+
run: |
18+
. ${GITHUB_ACTION_PATH}/assert-image-size.functions.sh
19+
20+
assert_image_size "${IMAGE}" "${MINIMUM_EFFICIENCY}"
21+
env:
22+
IMAGE: ${{ inputs.image }}
23+
MINIMUM_EFFICIENCY: ${{ inputs.minimum_efficiency }}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function assert_image_size() {
2+
local image=$1
3+
local minimum_efficiency=$2
4+
5+
local config_file
6+
config_file=$(mktemp)
7+
8+
# https://github.com/wagoodman/dive/blob/main/README.md#ci-integration
9+
yq eval -n "
10+
.rules.lowestEfficiency = ${minimum_efficiency} |
11+
.rules.highestWastedBytes = \"disabled\" |
12+
.rules.highestUserWastedPercent = \"disabled\"
13+
" > "${config_file}"
14+
15+
docker run --rm \
16+
--env CI=true \
17+
--volume /var/run/docker.sock:/var/run/docker.sock \
18+
--volume "${config_file}:/.dive-ci" \
19+
docker.io/wagoodman/dive:latest \
20+
"${image}"
21+
22+
return $?
23+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
set -eu ${RUNNER_DEBUG:+-x}
4+
5+
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
6+
7+
# Source the latest version of assert.sh unit testing library and include in current shell
8+
source /dev/stdin <<< "$(curl --silent https://raw.githubusercontent.com/hazelcast/assert.sh/main/assert.sh)"
9+
10+
. "$SCRIPT_DIR"/assert-image-size.functions.sh
11+
12+
TESTS_RESULT=0
13+
14+
function assert_assert_image_size {
15+
local image=$1
16+
local minimum_efficiency=$2
17+
local expected_exit_code=$3
18+
assert_image_size "${image}" "${minimum_efficiency}" && true
19+
local actual_exit_code=$?
20+
local msg="Expected exit code for \"${image}\" / \"${minimum_efficiency}\""
21+
assert_eq "${expected_exit_code}" "${actual_exit_code}" "${msg}" && log_success "${msg}" || TESTS_RESULT=$?
22+
}
23+
24+
log_header "Tests for assert_image_size"
25+
# expected efficiency: 99.8541 %
26+
assert_assert_image_size hazelcast/hazelcast:5.0.1-slim 0.95 0
27+
assert_assert_image_size hazelcast/hazelcast:5.0.1-slim 0.99999999999 1
28+
29+
assert_eq 0 "$TESTS_RESULT" "All tests should pass"

assert-image-size/test_scripts.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
4+
5+
find "$SCRIPT_DIR" -name "*_tests.sh" -print0 | xargs -0 -n1 bash

0 commit comments

Comments
 (0)