diff --git a/.github/actions/apply-oci-labels/action.yml b/.github/actions/apply-oci-labels/action.yml index af29915..3fc9963 100644 --- a/.github/actions/apply-oci-labels/action.yml +++ b/.github/actions/apply-oci-labels/action.yml @@ -26,11 +26,11 @@ inputs: required: false default: "" dockerfile: - description: "Path to the Dockerfile. The last FROM line drives base.name / base.digest resolution unless base-name/base-digest overrides are set." + description: "Path to the Dockerfile. The first `ARG BASE_IMAGE=:` line drives base.name / base.digest resolution unless base-name/base-digest overrides are set." required: false default: "./Dockerfile" base-name: - description: "Override for org.opencontainers.image.base.name. Set this for build systems where the Dockerfile is not parseable (Family B-E)." + description: "Override for org.opencontainers.image.base.name. Set this for build systems where the Dockerfile declares no ARG BASE_IMAGE (Family B-E)." required: false default: "" base-digest: @@ -121,21 +121,16 @@ runs: exit 1 fi - # Export ARG defaults from the Dockerfile so envsubst can expand ${...} in FROM. - # Only ARGs with a default value (ARG NAME=VALUE) are considered. - while IFS= read -r line; do - if [[ "${line}" =~ ^[[:space:]]*ARG[[:space:]]+([A-Za-z_][A-Za-z0-9_]*)=([^[:space:]]+) ]]; then - export "${BASH_REMATCH[1]}=${BASH_REMATCH[2]}" - fi - done < "${DOCKERFILE}" - - # Last FROM wins. Strip an optional --platform=... flag and a trailing `AS `. - raw=$(grep -E '^[[:space:]]*FROM[[:space:]]' "${DOCKERFILE}" | tail -n1 \ - | sed -E 's/^[[:space:]]*FROM[[:space:]]+(--platform=[^[:space:]]+[[:space:]]+)?([^[:space:]]+).*/\2/') - base_name=$(envsubst <<< "${raw}") + # First `ARG BASE_IMAGE=:` wins. The runtime FROM in + # docker-images Dockerfiles is always `FROM ${BASE_IMAGE}`, so the ARG + # default carries the fully-qualified base reference. + base_name=$(grep -E '^[[:space:]]*ARG[[:space:]]+BASE_IMAGE=' "${DOCKERFILE}" \ + | head -n1 \ + | sed -E 's/^[[:space:]]*ARG[[:space:]]+BASE_IMAGE=//' \ + | sed -E 's/^"(.*)"$/\1/; s/^'\''(.*)'\''$/\1/') if [ -z "${base_name}" ]; then - echo "::error::failed to resolve base image from ${DOCKERFILE}" >&2 + echo "::error::no ARG BASE_IMAGE=... declaration found in ${DOCKERFILE} and no base-name override given" >&2 exit 1 fi fi diff --git a/.github/actions/apply-oci-labels/testdata/Dockerfile b/.github/actions/apply-oci-labels/testdata/Dockerfile index 8e5342f..e7f1514 100644 --- a/.github/actions/apply-oci-labels/testdata/Dockerfile +++ b/.github/actions/apply-oci-labels/testdata/Dockerfile @@ -2,8 +2,8 @@ # # Minimal Dockerfile consumed by .github/workflows/apply-oci-labels-ci.yml to # exercise the action's Dockerfile-parsing path. The image is never built; the -# action only reads the last FROM line and substitutes the ARG default to -# resolve org.opencontainers.image.base.name. +# action only reads the first `ARG BASE_IMAGE=...` line to resolve +# org.opencontainers.image.base.name. -ARG BCI_VERSION=15.7-56.15 -FROM registry.suse.com/bci/bci-micro:${BCI_VERSION} +ARG BASE_IMAGE=registry.suse.com/bci/bci-micro:15.7-56.15 +FROM ${BASE_IMAGE} diff --git a/.github/workflows/apply-oci-labels-ci.yml b/.github/workflows/apply-oci-labels-ci.yml index b639949..7906641 100644 --- a/.github/workflows/apply-oci-labels-ci.yml +++ b/.github/workflows/apply-oci-labels-ci.yml @@ -28,9 +28,9 @@ jobs: matrix: arch: [amd64, arm64] case: - # Exercises Dockerfile parsing + ARG substitution + imagetools digest - # resolution against a real released BCI tag. base.digest is checked - # by regex so the test stays green if SUSE re-pushes the tag. + # Exercises ARG BASE_IMAGE extraction + imagetools digest resolution + # against a real released BCI tag. base.digest is checked by regex so + # the test stays green if SUSE re-pushes the tag. - name: from-dockerfile base-name: "" base-digest: ""