diff --git a/.github/workflows/images_build.yml b/.github/workflows/images_build.yml index 6b623e771..3cee093c6 100644 --- a/.github/workflows/images_build.yml +++ b/.github/workflows/images_build.yml @@ -36,12 +36,17 @@ env: IMAGES_PREFIX: "zabbix-" BASE_BUILD_NAME: "build-base" + BASE_CACHE_FILE_NAME: "base_image_metadata.json" + BUILD_CACHE_FILE_NAME: "base_build_image_metadata.json" MATRIX_FILE: "build.json" DOCKERFILES_DIRECTORY: "./Dockerfiles" OIDC_ISSUER: "https://token.actions.githubusercontent.com" - IDENITY_REGEX: "https://github.com/zabbix/zabbix-docker/.github/" + IDENTITY_REGEX: "https://github.com/zabbix/zabbix-docker/.github/" + + DOCKER_REGISTRY_TEST: "ghcr.io" + DOCKER_REPOSITORY_TEST: "zabbix" jobs: init_build: @@ -63,7 +68,9 @@ jobs: disable-sudo: true egress-policy: block allowed-endpoints: > + api.github.com:443 github.com:443 + objects.githubusercontent.com:443 - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -163,6 +170,7 @@ jobs: permissions: contents: read id-token: write + packages: write steps: - name: Block egress traffic uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -193,6 +201,7 @@ jobs: ftpmirror.your.org:80 fulcio.sigstore.dev:443 github.com:443 + ghcr.io:443 iad.mirror.rackspace.com:443 iad.mirror.rackspace.com:80 index.docker.io:443 @@ -251,6 +260,7 @@ jobs: uvermont.mm.fcix.net:443 yum.oracle.com:443 ziply.mm.fcix.net:443 + pkg-containers.githubusercontent.com:443 - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -279,13 +289,6 @@ jobs: with: driver-opts: image=moby/buildkit:master - - name: Login to DockerHub - if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Prepare Platform list id: platform env: @@ -305,18 +308,20 @@ jobs: id: meta uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: - images: ${{ env.DOCKER_REPOSITORY }}/${{ env.IMAGES_PREFIX }}${{ env.BASE_BUILD_NAME }} + images: | + ${{ format('{0}/{1}/{2}{3}', env.DOCKER_REGISTRY_TEST, env.DOCKER_REPOSITORY_TEST, env.IMAGES_PREFIX, env.BASE_BUILD_NAME ) }},enable=${{ env.AUTO_PUSH_IMAGES != 'true' }} + ${{ format('{0}/{1}{2}', env.DOCKER_REPOSITORY, env.IMAGES_PREFIX, env.BASE_BUILD_NAME ) }},enable=${{ env.AUTO_PUSH_IMAGES == 'true' }} context: ${{ env.TRUNK_ONLY_EVENT == 'true' && 'git' || '' }} tags: | type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},prefix=${{ matrix.os }}- type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},suffix=-${{ matrix.os }} - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,suffix=-${{ matrix.os }}-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && !contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && !contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,suffix=-${{ matrix.os }}-latest type=raw,enable=${{ (needs.init_build.outputs.current_branch != 'trunk') && (needs.init_build.outputs.is_default_branch == 'true') }},value=${{matrix.os}}-latest type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,prefix=${{ matrix.os }}- - type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,suffix=-${{ matrix.os }} + type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' || contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,suffix=-${{ matrix.os }} flavor: | - latest=${{ (needs.init_build.outputs.current_branch != 'trunk') && (matrix.os == 'alpine') && ( needs.init_build.outputs.is_default_branch == 'true' ) }} + latest=${{ (matrix.os == 'alpine') && (!contains(fromJSON('["workflow_dispatch"]'), github.event_name)) && ( needs.init_build.outputs.is_default_branch == 'true' ) }} - name: Prepare cache data id: cache_data @@ -328,7 +333,7 @@ jobs: cache_to=() cache_from+=("type=gha,scope=${IMAGE_TAG}") - cache_from+=("type=registry,ref=${IMAGE_TAG}") + #cache_from+=("type=registry,ref=${IMAGE_TAG}") cache_to+=("type=gha,mode=max,scope=${IMAGE_TAG}") @@ -350,14 +355,29 @@ jobs: echo "$cache_to" >> "$GITHUB_OUTPUT" echo 'EOF' >> "$GITHUB_OUTPUT" + - name: Login to DockerHub + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to ${{ env.DOCKER_REGISTRY_TEST }} + if: ${{ env.AUTO_PUSH_IMAGES != 'true' }} + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: ${{ env.DOCKER_REGISTRY_TEST }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and publish image id: docker_build uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ env.BASE_BUILD_NAME }}/${{ matrix.os }} - file: ${{ env.DOCKERFILES_DIRECTORY }}/${{ env.BASE_BUILD_NAME }}/${{ matrix.os }}/Dockerfile + context: ${{ format('{0}/{1}/{2}', env.DOCKERFILES_DIRECTORY, env.BASE_BUILD_NAME, matrix.os) }} + file: ${{ format('{0}/{1}/{2}/Dockerfile', env.DOCKERFILES_DIRECTORY, env.BASE_BUILD_NAME, matrix.os) }} platforms: ${{ steps.platform.outputs.list }} - push: ${{ env.AUTO_PUSH_IMAGES == 'true' }} + push: true tags: ${{ steps.meta.outputs.tags }} labels: | org.opencontainers.image.revision=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} @@ -371,10 +391,7 @@ jobs: DIGEST: ${{ steps.docker_build.outputs.digest }} TAGS: ${{ steps.meta.outputs.tags }} run: | - images="" - for tag in ${TAGS}; do - images+="${tag}@${DIGEST} " - done + images=$(printf "%s@${DIGEST}" "${TAGS[@]}") echo "::group::Images to sign" echo "$images" @@ -385,24 +402,24 @@ jobs: cosign sign --yes ${images} echo "::endgroup::" - - name: Image digest + - name: Image metadata env: - DIGEST: ${{ steps.docker_build.outputs.digest || fromJSON(steps.meta.outputs.json).tags[0] }} - CACHE_FILE_NAME: ${{ env.BASE_BUILD_NAME }}_${{ matrix.os }} + CACHE_FILE_NAME: ${{ env.BASE_CACHE_FILE_NAME }} + METADATA: ${{ steps.docker_build.outputs.metadata }} run: | - echo "::group::Image digest" - echo "$DIGEST" + echo "::group::Image metadata" + echo "${METADATA}" echo "::endgroup::" echo "::group::Cache file name" - echo "$CACHE_FILE_NAME" + echo "${CACHE_FILE_NAME}" echo "::endgroup::" - echo "$DIGEST" > "$CACHE_FILE_NAME" + echo "${METADATA}" > "$CACHE_FILE_NAME" - - name: Cache image digest + - name: Cache image metadata uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: - path: ${{ env.BASE_BUILD_NAME }}_${{ matrix.os }} + path: ${{ env.BASE_CACHE_FILE_NAME }} key: ${{ env.BASE_BUILD_NAME }}-${{ matrix.os }}-${{ github.run_id }} build_base_database: @@ -414,11 +431,11 @@ jobs: matrix: build: ${{ fromJson(needs.init_build.outputs.database) }} os: ${{ fromJson(needs.init_build.outputs.os) }} - runs-on: ubuntu-latest permissions: contents: read id-token: write + packages: write steps: - name: Block egress traffic uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -435,6 +452,7 @@ jobs: golang.org:443 google.golang.org:443 gopkg.in:443 + ghcr.io:443 index.docker.io:443 noto-website.storage.googleapis.com:443 production.cloudflare.docker.com:443 @@ -446,6 +464,7 @@ jobs: objects.githubusercontent.com:443 tuf-repo-cdn.sigstore.dev:443 rekor.sigstore.dev:443 + pkg-containers.githubusercontent.com:443 - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -474,13 +493,6 @@ jobs: with: driver-opts: image=moby/buildkit:master - - name: Login to DockerHub - if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Prepare Platform list id: platform env: @@ -500,65 +512,58 @@ jobs: id: meta uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: - images: ${{ env.DOCKER_REPOSITORY }}/${{ env.IMAGES_PREFIX }}${{ matrix.build }} + images: | + ${{ format('{0}/{1}/{2}{3}', env.DOCKER_REGISTRY_TEST, env.DOCKER_REPOSITORY_TEST, env.IMAGES_PREFIX, matrix.build ) }},enable=${{ env.AUTO_PUSH_IMAGES != 'true' }} + ${{ format('{0}/{1}{2}', env.DOCKER_REPOSITORY, env.IMAGES_PREFIX, matrix.build ) }},enable=${{ env.AUTO_PUSH_IMAGES == 'true' }} context: ${{ env.TRUNK_ONLY_EVENT == 'true' && 'git' || '' }} tags: | type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},prefix=${{ matrix.os }}- type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},suffix=-${{ matrix.os }} - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,suffix=-${{ matrix.os }}-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && (!contains(fromJSON('["workflow_dispatch"]'), github.event_name)) }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && (!contains(fromJSON('["workflow_dispatch"]'), github.event_name)) }},event=branch,suffix=-${{ matrix.os }}-latest type=raw,enable=${{ (needs.init_build.outputs.current_branch != 'trunk') && (needs.init_build.outputs.is_default_branch == 'true') }},value=${{matrix.os}}-latest type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,prefix=${{ matrix.os }}- - type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,suffix=-${{ matrix.os }} + type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' || contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,suffix=-${{ matrix.os }} flavor: | - latest=${{ (needs.init_build.outputs.current_branch != 'trunk') && (matrix.os == 'alpine') && ( needs.init_build.outputs.is_default_branch == 'true' ) }} + latest=${{ (matrix.os == 'alpine') && (!contains(fromJSON('["workflow_dispatch"]'), github.event_name)) && ( needs.init_build.outputs.is_default_branch == 'true' ) }} - - name: Download SHA256 tag of ${{ env.BASE_BUILD_NAME }}:${{ matrix.os }} + - name: Download metadata of ${{ env.BASE_BUILD_NAME }}:${{ matrix.os }} uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: - path: ${{ env.BASE_BUILD_NAME }}_${{ matrix.os }} + path: ${{ env.BASE_CACHE_FILE_NAME }} key: ${{ env.BASE_BUILD_NAME }}-${{ matrix.os }}-${{ github.run_id }} - - name: Retrieve ${{ env.BASE_BUILD_NAME }}:${{ matrix.os }} SHA256 tag + - name: Process ${{ env.BASE_BUILD_NAME }}:${{ matrix.os }} image metadata id: base_build env: - MATRIX_OS: ${{ matrix.os }} - DOCKER_REPOSITORY: ${{ env.DOCKER_REPOSITORY }} - BASE_IMAGE: ${{ env.BASE_BUILD_NAME }} - IMAGES_PREFIX: ${{ env.IMAGES_PREFIX }} + CACHE_FILE_NAME: ${{ env.BASE_CACHE_FILE_NAME }} run: | - BASE_TAG=$(cat "${BASE_IMAGE}_${MATRIX_OS}") - if [[ "${BASE_TAG}" == "sha256"* ]]; then - BUILD_BASE_IMAGE="${DOCKER_REPOSITORY}/${IMAGES_PREFIX}${BASE_IMAGE}@${BASE_TAG}" - else - BUILD_BASE_IMAGE=${BASE_TAG} - fi - - echo "::group::Base build image information" - echo "base_tag=${BASE_TAG}" - echo "base_build_image=${BUILD_BASE_IMAGE}" + echo "::group::Base image metadata" + cat "${CACHE_FILE_NAME}" echo "::endgroup::" - echo "base_tag=${BASE_TAG}" >> $GITHUB_OUTPUT - echo "base_build_image=${BUILD_BASE_IMAGE}" >> $GITHUB_OUTPUT + IMAGE_DIGEST=$(jq -r '."containerimage.digest"' "${CACHE_FILE_NAME}") + IMAGE_NAME=$(jq -r '."image.name"' "${CACHE_FILE_NAME}" | cut -d: -f1) + + echo "base_build_image=${IMAGE_NAME}@${IMAGE_DIGEST}" >> $GITHUB_OUTPUT - name: Verify ${{ env.BASE_BUILD_NAME }}:${{ matrix.os }} cosign if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} env: BASE_IMAGE: ${{ steps.base_build.outputs.base_build_image }} OIDC_ISSUER: ${{ env.OIDC_ISSUER }} - IDENITY_REGEX: ${{ env.IDENITY_REGEX }} + IDENTITY_REGEX: ${{ env.IDENTITY_REGEX }} run: | echo "::group::Image sign data" echo "OIDC issuer=$OIDC_ISSUER" - echo "Identity=$IDENITY_REGEX" + echo "Identity=$IDENTITY_REGEX" echo "Image to verify=$BASE_IMAGE" echo "::endgroup::" echo "::group::Verify signature" cosign verify \ --certificate-oidc-issuer-regexp "$OIDC_ISSUER" \ - --certificate-identity-regexp "$IDENITY_REGEX" \ + --certificate-identity-regexp "$IDENTITY_REGEX" \ "$BASE_IMAGE" echo "::endgroup::" @@ -597,23 +602,34 @@ jobs: echo "$cache_to" >> "$GITHUB_OUTPUT" echo 'EOF' >> "$GITHUB_OUTPUT" + - name: Login to DockerHub + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to DockerHub + if: ${{ env.AUTO_PUSH_IMAGES != 'true' }} + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build ${{ matrix.build }}/${{ matrix.os }} and push id: docker_build uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/${{ matrix.os }} - file: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/${{ matrix.os }}/Dockerfile + context: ${{ format('{0}/{1}/{2}/', env.DOCKERFILES_DIRECTORY, matrix.build, matrix.os) }} + file: ${{ format('{0}/{1}/{2}/Dockerfile', env.DOCKERFILES_DIRECTORY, matrix.build, matrix.os) }} platforms: ${{ steps.platform.outputs.list }} - push: ${{ env.AUTO_PUSH_IMAGES == 'true' }} + push: true tags: ${{ steps.meta.outputs.tags }} build-args: BUILD_BASE_IMAGE=${{ steps.base_build.outputs.base_build_image }} labels: | org.opencontainers.image.revision=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} org.opencontainers.image.created=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} - cache-from: | - type=gha,scope=${{ steps.base_build.outputs.base_build_image }} - type=registry,ref=${{ steps.base_build.outputs.base_build_image }} - cache-to: type=gha,mode=max,scope=${{ fromJSON(steps.meta.outputs.json).tags[0] }} - name: Sign the images with GitHub OIDC Token if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} @@ -621,10 +637,7 @@ jobs: DIGEST: ${{ steps.docker_build.outputs.digest }} TAGS: ${{ steps.meta.outputs.tags }} run: | - images="" - for tag in ${TAGS}; do - images+="${tag}@${DIGEST} " - done + images=$(printf "%s@${DIGEST}" "${TAGS[@]}") echo "::group::Images to sign" echo "$images" @@ -635,23 +648,24 @@ jobs: cosign sign --yes ${images} echo "::endgroup::" - - name: Image digest + - name: Image metadata env: - DIGEST: ${{ steps.docker_build.outputs.digest }} - CACHE_FILE_NAME: ${{ matrix.build }}_${{ matrix.os }} + CACHE_FILE_NAME: ${{ env.BUILD_CACHE_FILE_NAME }} + METADATA: ${{ steps.docker_build.outputs.metadata }} run: | - echo "::group::Image digest" - echo "$DIGEST" + echo "::group::Image metadata" + echo "${METADATA}" echo "::endgroup::" echo "::group::Cache file name" - echo "$CACHE_FILE_NAME" + echo "${CACHE_FILE_NAME}" echo "::endgroup::" - echo "$DIGEST" > $CACHE_FILE_NAME - - name: Caching SHA256 tag of the image + echo "${METADATA}" > "$CACHE_FILE_NAME" + + - name: Cache image metadata uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: - path: ${{ matrix.build }}_${{ matrix.os }} + path: ${{ env.BUILD_CACHE_FILE_NAME }} key: ${{ matrix.build }}-${{ matrix.os }}-${{ github.run_id }} build_images: @@ -668,6 +682,7 @@ jobs: permissions: contents: read id-token: write + packages: read steps: - name: Block egress traffic uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -748,6 +763,7 @@ jobs: pubmirror1.math.uh.edu:443 pubmirror3.math.uh.edu:80 quay.io:443 + ghcr.io:443 registry-1.docker.io:443 repo.ialab.dsu.edu:80 repos.eggycrew.com:80 @@ -786,6 +802,7 @@ jobs: objects.githubusercontent.com:443 tuf-repo-cdn.sigstore.dev:443 rekor.sigstore.dev:443 + pkg-containers.githubusercontent.com:443 - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -794,11 +811,13 @@ jobs: fetch-depth: 1 - name: Install cosign + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 with: cosign-release: 'v2.2.3' - name: Check cosign version + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} run: cosign version - name: Set up QEMU @@ -812,13 +831,6 @@ jobs: with: driver-opts: image=moby/buildkit:master - - name: Login to DockerHub - if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Prepare Platform list id: platform env: @@ -867,67 +879,65 @@ jobs: id: meta uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: - images: ${{ env.DOCKER_REPOSITORY }}/${{ env.IMAGES_PREFIX}}${{ matrix.build }} + images: | + ${{ format('{0}/{1}/{2}{3}', env.DOCKER_REGISTRY_TEST, env.DOCKER_REPOSITORY_TEST, env.IMAGES_PREFIX, matrix.build ) }},enable=${{ env.AUTO_PUSH_IMAGES != 'true' }} + ${{ format('{0}/{1}{2}', env.DOCKER_REPOSITORY, env.IMAGES_PREFIX, matrix.build ) }},enable=${{ env.AUTO_PUSH_IMAGES == 'true' }} context: ${{ env.TRUNK_ONLY_EVENT == 'true' && 'git' || '' }} tags: | type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},prefix=${{ matrix.os }}- type=semver,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},pattern={{version}},suffix=-${{ matrix.os }} - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest - type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' }},event=branch,suffix=-${{ matrix.os }}-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && !contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,prefix=${{ matrix.os }}-,suffix=-latest + type=ref,enable=${{ needs.init_build.outputs.current_branch != 'trunk' && !contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,suffix=-${{ matrix.os }}-latest type=raw,enable=${{ (needs.init_build.outputs.current_branch != 'trunk') && (needs.init_build.outputs.is_default_branch == 'true') }},value=${{matrix.os}}-latest type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,prefix=${{ matrix.os }}- - type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' }},event=branch,suffix=-${{ matrix.os }} + type=ref,enable=${{ needs.init_build.outputs.current_branch == 'trunk' || contains(fromJSON('["workflow_dispatch"]'), github.event_name) }},event=branch,suffix=-${{ matrix.os }} flavor: | - latest=${{ (needs.init_build.outputs.current_branch != 'trunk') && (matrix.os == 'alpine') && ( needs.init_build.outputs.is_default_branch == 'true' ) }} + latest=${{ (matrix.os == 'alpine') && (!contains(fromJSON('["workflow_dispatch"]'), github.event_name)) && ( needs.init_build.outputs.is_default_branch == 'true' ) }} - - name: Download SHA256 tag of ${{ steps.build_base_image.outputs.build_base }}:${{ matrix.os }} + - name: Download metadata of ${{ steps.build_base_image.outputs.build_base }}:${{ matrix.os }} uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 if: ${{ matrix.build != 'snmptraps' }} with: - path: ${{ steps.build_base_image.outputs.build_base }}_${{ matrix.os }} + path: ${{ env.BUILD_CACHE_FILE_NAME }} key: ${{ steps.build_base_image.outputs.build_base }}-${{ matrix.os }}-${{ github.run_id }} - - name: Retrieve ${{ steps.build_base_image.outputs.build_base }}:${{ matrix.os }} SHA256 tag + - name: Process ${{ steps.build_base_image.outputs.build_base }}:${{ matrix.os }} image metadata id: base_build if: ${{ matrix.build != 'snmptraps' }} env: - BUILD_BASE: ${{ steps.build_base_image.outputs.build_base }} - MATRIX_OS: ${{ matrix.os }} - DOCKER_REPOSITORY: ${{ env.DOCKER_REPOSITORY }} - IMAGES_PREFIX: ${{ env.IMAGES_PREFIX }} + CACHE_FILE_NAME: ${{ env.BUILD_CACHE_FILE_NAME }} run: | - BASE_TAG=$(cat "${BUILD_BASE}_${MATRIX_OS}") - BUILD_BASE_IMAGE=${DOCKER_REPOSITORY}/${IMAGES_PREFIX}${BUILD_BASE}@${BASE_TAG} - - echo "::group::Base build image information" - echo "base_tag=${BASE_TAG}" - echo "base_build_image=${BUILD_BASE_IMAGE}" + echo "::group::Base build image metadata" + cat "${CACHE_FILE_NAME}" echo "::endgroup::" - echo "base_tag=${BASE_TAG}" >> $GITHUB_OUTPUT - echo "base_build_image=${BUILD_BASE_IMAGE}" >> $GITHUB_OUTPUT + IMAGE_DIGEST=$(jq -r '."containerimage.digest"' "${CACHE_FILE_NAME}") + IMAGE_NAME=$(jq -r '."image.name"' "${CACHE_FILE_NAME}" | cut -d: -f1) + + echo "base_build_image=${IMAGE_NAME}@${IMAGE_DIGEST}" >> $GITHUB_OUTPUT - name: Verify ${{ steps.build_base_image.outputs.build_base }}:${{ matrix.os }} cosign if: ${{ matrix.build != 'snmptraps' && env.AUTO_PUSH_IMAGES == 'true' }} env: BASE_IMAGE: ${{ steps.base_build.outputs.base_build_image }} OIDC_ISSUER: ${{ env.OIDC_ISSUER }} - IDENITY_REGEX: ${{ env.IDENITY_REGEX }} + IDENTITY_REGEX: ${{ env.IDENTITY_REGEX }} run: | echo "::group::Image sign data" - echo "OIDC issuer=$OIDC_ISSUER" - echo "Identity=$IDENITY_REGEX" - echo "Image to verify=$BASE_IMAGE" + echo "OIDC issuer=${OIDC_ISSUER}" + echo "Identity=${IDENTITY_REGEX}" + echo "Image to verify=${BASE_IMAGE}" echo "::endgroup::" echo "::group::Verify signature" cosign verify \ - --certificate-oidc-issuer-regexp "$OIDC_ISSUER" \ - --certificate-identity-regexp "$IDENITY_REGEX" \ - "$BASE_IMAGE" + --certificate-oidc-issuer-regexp "${OIDC_ISSUER}" \ + --certificate-identity-regexp "${IDENTITY_REGEX}" \ + "${BASE_IMAGE}" echo "::endgroup::" - name: Prepare cache data + if: ${{ matrix.build != 'snmptraps' }} id: cache_data env: BASE_IMAGE_TAG: ${{ steps.base_build.outputs.base_build_image }} @@ -935,7 +945,6 @@ jobs: cache_from=() cache_to=() - cache_from+=("type=gha,scope=${BASE_IMAGE_TAG}") cache_from+=("type=registry,ref=${BASE_IMAGE_TAG}") echo "::group::Cache from data" @@ -948,12 +957,19 @@ jobs: echo "$cache_from" >> "$GITHUB_OUTPUT" echo 'EOF' >> "$GITHUB_OUTPUT" + - name: Login to DockerHub + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Build and push image id: docker_build uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/${{ matrix.os }} - file: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/${{ matrix.os }}/Dockerfile + context: ${{ format('{0}/{1}/{2}', env.DOCKERFILES_DIRECTORY, matrix.build, matrix.os) }} + file: ${{ format('{0}/{1}/{2}/Dockerfile', env.DOCKERFILES_DIRECTORY, matrix.build, matrix.os) }} platforms: ${{ steps.platform.outputs.list }} push: ${{ env.AUTO_PUSH_IMAGES == 'true' }} tags: ${{ steps.meta.outputs.tags }} @@ -961,7 +977,6 @@ jobs: labels: | org.opencontainers.image.revision=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} org.opencontainers.image.created=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} - cache-from: ${{ steps.cache_data.outputs.cache_from }} - name: Sign the images with GitHub OIDC Token if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} @@ -969,10 +984,7 @@ jobs: DIGEST: ${{ steps.docker_build.outputs.digest }} TAGS: ${{ steps.meta.outputs.tags }} run: | - images="" - for tag in ${TAGS}; do - images+="${tag}@${DIGEST} " - done + images=$(printf "%s@${DIGEST}" "${TAGS[@]}") echo "::group::Images to sign" echo "$images" @@ -983,10 +995,11 @@ jobs: cosign sign --yes ${images} echo "::endgroup::" - - name: Image digest + - name: Image metadata + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} env: - DIGEST: ${{ steps.docker_build.outputs.digest }} + METADATA: ${{ steps.docker_build.outputs.metadata }} run: | - echo "::group::Image digest" - echo "$DIGEST" + echo "::group::Image metadata" + echo "${METADATA}" echo "::endgroup::" diff --git a/.github/workflows/images_build_rhel.yml b/.github/workflows/images_build_rhel.yml index fa803125f..6f84de1e1 100644 --- a/.github/workflows/images_build_rhel.yml +++ b/.github/workflows/images_build_rhel.yml @@ -29,7 +29,8 @@ permissions: contents: read env: - AUTO_PUSH_IMAGES: ${{ contains(fromJSON('["workflow_dispatch", "push"]'), github.event_name) && 'false' || vars.AUTO_PUSH_IMAGES }} + TRUNK_ONLY_EVENT: ${{ contains(fromJSON('["schedule"]'), github.event_name) }} + AUTO_PUSH_IMAGES: ${{ ! contains(fromJSON('["workflow_dispatch", "push"]'), github.event_name) && vars.AUTO_PUSH_IMAGES }} LATEST_BRANCH: ${{ github.event.repository.default_branch }} TRUNK_GIT_BRANCH: "refs/heads/trunk" @@ -164,7 +165,7 @@ jobs: echo "secret_prefix=RHEL_${github_ref//.}" >> $GITHUB_OUTPUT echo "sha_short=$sha_short" >> $GITHUB_OUTPUT - - name: Cleanup cache + - name: Cleanup existing cache shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -205,11 +206,13 @@ jobs: fetch-depth: 1 - name: Install cosign + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 with: cosign-release: 'v2.2.3' - name: Check cosign version + if: ${{ env.AUTO_PUSH_IMAGES == 'true' }} run: cosign version - name: Fix string case @@ -231,7 +234,7 @@ jobs: id: build_image uses: redhat-actions/buildah-build@b4dc19b4ba891854660ab1f88a097d45aa158f76 # v2.12 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/rhel + context: ${{ format('{0}/{1}/rhel', env.DOCKERFILES_DIRECTORY, matrix.build) }} layers: false tags: ${{ steps.meta.outputs.tags }} containerfiles: | @@ -240,7 +243,7 @@ jobs: --pull --iidfile=${{ github.workspace }}/iidfile - - name: Prepare image metadata + - name: Image metadata id: image_metadata env: IMAGE_TAG: ${{ steps.build_image.outputs.image-with-tag }} @@ -279,7 +282,6 @@ jobs: IMAGE_TAG: ${{ steps.image_metadata.outputs.image_tag }} IMAGE_TAG_ID: ${{ steps.image_metadata.outputs.image_tag_id }} IMAGE_DIR: ${{ env.IMAGE_DIR }} - GITHUB_WORKSPACE: ${{ github.workspace }} run: | echo "::group::Result" echo "Image ${IMAGE_TAG} location: \"${IMAGE_DIR}/${IMAGE_TAG_ID}\"" @@ -310,13 +312,14 @@ jobs: if: ${{ (cancelled() || failure()) && ( steps.push_image.outcome == 'failure' || steps.push_image.outcome == 'cancelled') }} env: IMAGE_TAG_ID: ${{ steps.image_metadata.outputs.image_tag_id }} + IMAGE_DIR: ${{ env.IMAGE_DIR }} run: | echo "::group::Removing orphaned image" rm -rf "${IMAGE_DIR}/${IMAGE_TAG_ID}" echo "::endgroup::" build_base_database: - timeout-minutes: 180 + timeout-minutes: 90 needs: [ "build_base", "init_build"] name: Build ${{ matrix.build }} base (${{ matrix.arch }}) strategy: @@ -348,7 +351,7 @@ jobs: ${{ env.BASE_BUILD_NAME }}_${{ matrix.arch }}_tag key: ${{ env.BASE_BUILD_NAME }}-${{ matrix.arch }}-${{ github.run_id }} - - name: Pull ${{ env.BASE_BUILD_NAME }}:${{ matrix.arch }} image + - name: Pull ${{ env.BASE_BUILD_NAME }}:${{ matrix.arch }} image from local storage id: base_build env: MATRIX_ARCH: ${{ matrix.arch }} @@ -389,7 +392,7 @@ jobs: id: build_image uses: redhat-actions/buildah-build@b4dc19b4ba891854660ab1f88a097d45aa158f76 # v2.12 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/rhel + context: ${{ format('{0}/{1}/rhel', env.DOCKERFILES_DIRECTORY, matrix.build) }} layers: false tags: ${{ steps.meta.outputs.tags }} containerfiles: | @@ -423,7 +426,7 @@ jobs: echo "image_tag_id=${TAG_ID}" >> $GITHUB_OUTPUT echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT - - name: Cache image digest + - name: Cache image metadata uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: path: | @@ -437,7 +440,6 @@ jobs: IMAGE_TAG: ${{ steps.image_metadata.outputs.image_tag }} IMAGE_TAG_ID: ${{ steps.image_metadata.outputs.image_tag_id }} IMAGE_DIR: ${{ env.IMAGE_DIR }} - GITHUB_WORKSPACE: ${{ github.workspace }} run: | echo "::group::Result" echo "podman push \"${IMAGE_TAG}\" dir:\"${IMAGE_DIR}/${IMAGE_TAG_ID}\"" @@ -468,13 +470,14 @@ jobs: if: ${{ (cancelled() || failure()) && ( steps.push_image.outcome == 'failure' || steps.push_image.outcome == 'cancelled') }} env: IMAGE_TAG_ID: ${{ steps.image_metadata.outputs.image_tag_id }} + IMAGE_DIR: ${{ env.IMAGE_DIR }} run: | echo "::group::Removing orphaned image" rm -rf "${IMAGE_DIR}/${IMAGE_TAG_ID}" echo "::endgroup::" build_images: - timeout-minutes: 90 + timeout-minutes: 30 needs: [ "build_base_database", "init_build"] name: Build ${{ matrix.build }} image (${{ matrix.arch }}) strategy: @@ -580,7 +583,7 @@ jobs: id: build_image uses: redhat-actions/buildah-build@b4dc19b4ba891854660ab1f88a097d45aa158f76 # v2.12 with: - context: ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/rhel + context: ${{ format('{0}/{1}/rhel', env.DOCKERFILES_DIRECTORY, matrix.build) }} layers: false tags: ${{ steps.meta.outputs.tags }} labels: | @@ -588,6 +591,9 @@ jobs: org.opencontainers.image.created=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} containerfiles: | ${{ env.DOCKERFILES_DIRECTORY }}/${{ matrix.build }}/rhel/Dockerfile + extra-args: | + --pull + --iidfile=${{ github.workspace }}/iidfile build-args: BUILD_BASE_IMAGE=${{ steps.base_build.outputs.base_build_image }} - name: Log in to ${{ env.REGISTRY }} @@ -657,11 +663,24 @@ jobs: podman rmi -i -f "$PREFLIGHT_IMAGE" echo "::endgroup::" + - name: Image digest + env: + GITHUB_WORKSPACE: ${{ github.workspace }} + run: | + TAG_ID=$(cat $GITHUB_WORKSPACE/iidfile) + echo "::group::Image digest" + echo "$TAG_ID" + echo "::endgroup::" + - name: Post build image if: ${{ success() || failure() }} + env: + GITHUB_WORKSPACE: ${{ github.workspace }} run: | echo "::group::Result" + rm -rf "$GITHUB_WORKSPACE/iidfile" + echo "Removing working containers" buildah rm -a 2>/dev/null || true echo "Removing container data in storage not controlled by podman" @@ -674,7 +693,7 @@ jobs: echo "::endgroup::" clear_artifacts: - timeout-minutes: 90 + timeout-minutes: 10 needs: [ "build_images", "init_build"] name: Clear ${{ matrix.build }} image cache (${{ matrix.arch }}) strategy: