diff --git a/.github/workflows/docker-build-publish.yml b/.github/workflows/docker-build-publish.yml index 77050da..348974a 100644 --- a/.github/workflows/docker-build-publish.yml +++ b/.github/workflows/docker-build-publish.yml @@ -58,6 +58,13 @@ on: type: string default: "" + skip_if_tag_exists: + description: > + If true, skip build when all images already have sha- tags. + required: false + type: string + default: "false" + env: description: > Multiline env vars, one per line: KEY=VALUE @@ -147,6 +154,9 @@ jobs: IMAGES: ${{ inputs.images }} BUILD_ARGS: ${{ inputs.build_args }} EXTRA_TAGS_INPUT: ${{ inputs.extra_tags }} + CHECKOUT_REPO: ${{ inputs.checkout_repo }} + CHECKOUT_PATH: ${{ inputs.checkout_path }} + SKIP_IF_TAG_EXISTS: ${{ inputs.skip_if_tag_exists }} CI_TOKEN: ${{ secrets.ci_token }} TRIVY_SEVERITY: ${{ inputs.trivy_severity }} run: | @@ -176,8 +186,38 @@ jobs: RAW_REF="${{ github.ref }}" SHA_FULL="${{ github.sha }}" + SOURCE_SHA_FULL="$SHA_FULL" + if [ -n "$CHECKOUT_REPO" ] && [ -d "$CHECKOUT_PATH/.git" ]; then + SOURCE_SHA_FULL=$(git -C "$CHECKOUT_PATH" rev-parse HEAD) + fi + SHA_FULL="$SOURCE_SHA_FULL" SHA_SHORT="${SHA_FULL:0:12}" + truthy() { + case "${1,,}" in + 1|true|yes|y|on) return 0;; + *) return 1;; + esac + } + + if truthy "$SKIP_IF_TAG_EXISTS"; then + missing=0 + while read -r img; do + IMAGE_NAME=$(echo "$img" | jq -r '.name') + FULL_IMAGE="${{ inputs.registry_host }}/$IMAGE_NAME" + if docker manifest inspect "$FULL_IMAGE:sha-$SHA_SHORT" >/dev/null 2>&1; then + echo "==== Found existing tag $FULL_IMAGE:sha-$SHA_SHORT ====" + else + echo "==== Missing tag $FULL_IMAGE:sha-$SHA_SHORT (will build) ====" + missing=1 + fi + done < <(echo "$IMAGES" | jq -c '.[]') + if [ "$missing" -eq 0 ]; then + echo "All images already have sha-$SHA_SHORT tag. Skipping build." + exit 0 + fi + fi + VERSION_TAGS=() if [[ "$RAW_REF" =~ ^refs/tags/v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then VERSION_TAGS+=("v${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}")