diff --git a/.github/workflows/apko-smoke-test.yaml b/.github/workflows/apko-smoke-test.yaml index 056e8a2..f6a6860 100644 --- a/.github/workflows/apko-smoke-test.yaml +++ b/.github/workflows/apko-smoke-test.yaml @@ -78,6 +78,23 @@ jobs: EXPECTED_VERSION: ${{ inputs.expected-version }} run: | set -euo pipefail + # Fetch the image up front so a runner that cannot run it fails here. + # Inside the loop below docker's own errors (no daemon, image absent) + # are captured as command output and only a narrow set of exit codes + # is fatal, so they would otherwise pass as a test that never ran. + docker pull --platform "linux/$IMAGE_ARCH" "$IMAGE" + + # `docker pull --platform` is happy to fetch a foreign arch, which + # then fails at `docker run` with an exit code the loop tolerates. No + # binfmt/qemu is registered on stock runners, so a smoke runner whose + # arch does not match the image can only produce a test that skips + # the image while reporting success. + pulled_arch="$(docker image inspect --format '{{.Architecture}}' "$IMAGE")" + if [ "$pulled_arch" != "$IMAGE_ARCH" ]; then + echo "FAIL: $IMAGE is $pulled_arch but this runner is $IMAGE_ARCH; the image cannot execute here" >&2 + exit 1 + fi + version_matched=false normalized_version="${EXPECTED_VERSION#v}" IFS=',' read -ra tests <<< "$SMOKE_TEST" diff --git a/actions/apko-plan/apko-plan.sh b/actions/apko-plan/apko-plan.sh index 9a70c04..50bc5dd 100755 --- a/actions/apko-plan/apko-plan.sh +++ b/actions/apko-plan/apko-plan.sh @@ -72,8 +72,10 @@ emit_outputs() { has_builds=$( [[ $(echo "$apko_matrix" | jq 'length') -gt 0 ]] && echo true || echo false ) smoke_matrix=$(echo "$apko_matrix" | jq -c --slurpfile config "$CONFIG" ' def trim: sub("^\\s+"; "") | sub("\\s+$"; ""); + # Both defaults must provide a docker daemon: the smoke test runs the + # published image, and a runner without one turns the test into a no-op. def smoke_runner($smoke_runners; $arch): - ($smoke_runners[$arch] // (if $arch == "arm64" then "ubuntu-24.04-arm" else "ubuntu-slim" end)); + ($smoke_runners[$arch] // (if $arch == "arm64" then "ubuntu-24.04-arm" else "ubuntu-24.04" end)); ($config[0].smoke_runners // {}) as $smoke_runners | [.[] | select((.smoke_test // "") != "") | . as $image diff --git a/actions/apko-plan/apko-plan.test.sh b/actions/apko-plan/apko-plan.test.sh index 34586bb..e937191 100755 --- a/actions/apko-plan/apko-plan.test.sh +++ b/actions/apko-plan/apko-plan.test.sh @@ -116,4 +116,39 @@ assert_json "$variant_apko" '[.[] | select(.tag_suffix == "-dev")][0].smoke_test assert_json "$variant_melange" 'length' '1' assert_json "$variant_smoke" 'length' '1' +# The default smoke runner must be able to run the built image. A runner +# without a docker daemon does not fail the job: `docker run` writes its error +# to the captured output and the loop only rejects a narrow set of exit codes, +# so every smoke test silently passes without the image ever starting. +default_runner_config="$TEST_DIR/default-runners.json" +jq 'del(.smoke_runners) | .apko_archs = "amd64,arm64"' "$CONFIG" > "$default_runner_config" + +default_runner_output="$TEST_DIR/default-runners.out" +GITHUB_EVENT_NAME=workflow_dispatch \ +GITHUB_REF_TYPE=branch \ +GITHUB_REF_NAME=main \ +GITHUB_OUTPUT="$default_runner_output" \ + "$SCRIPT_DIR/apko-plan.sh" "$default_runner_config" + +default_runner_smoke=$(output_value "$default_runner_output" smoke_matrix_json) +assert_json "$default_runner_smoke" '[.[] | select(.arch == "amd64")][0].runner' 'ubuntu-24.04' +assert_json "$default_runner_smoke" '[.[] | select(.arch == "arm64")][0].runner' 'ubuntu-24.04-arm' + +# An explicit smoke_runners entry still wins over the default, and an arch the +# override omits falls back to the default rather than to the overridden value. +partial_override_config="$TEST_DIR/partial-override.json" +jq '.smoke_runners = {"amd64": "ubuntu-latest"} | .apko_archs = "amd64,arm64"' \ + "$CONFIG" > "$partial_override_config" + +partial_override_output="$TEST_DIR/partial-override.out" +GITHUB_EVENT_NAME=workflow_dispatch \ +GITHUB_REF_TYPE=branch \ +GITHUB_REF_NAME=main \ +GITHUB_OUTPUT="$partial_override_output" \ + "$SCRIPT_DIR/apko-plan.sh" "$partial_override_config" + +partial_override_smoke=$(output_value "$partial_override_output" smoke_matrix_json) +assert_json "$partial_override_smoke" '[.[] | select(.arch == "amd64")][0].runner' 'ubuntu-latest' +assert_json "$partial_override_smoke" '[.[] | select(.arch == "arm64")][0].runner' 'ubuntu-24.04-arm' + echo "apko-plan tests passed"