From 301a6ab1a73c86969515af37c010483ee1d44021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20J=C3=A1ky?= Date: Thu, 8 Feb 2024 16:16:03 +0100 Subject: [PATCH] ci: use Docker Bake for build and push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: András Jáky --- .../workflows/build-and-push-component.yaml | 72 +++++---- .github/workflows/reusable-build-and-push.yml | 151 ++++++++---------- 2 files changed, 112 insertions(+), 111 deletions(-) diff --git a/.github/workflows/build-and-push-component.yaml b/.github/workflows/build-and-push-component.yaml index 83d89eecb1..d0611f5ed2 100644 --- a/.github/workflows/build-and-push-component.yaml +++ b/.github/workflows/build-and-push-component.yaml @@ -3,10 +3,6 @@ name: 'Build and Push Component' on: workflow_call: inputs: - dockerfile: - required: true - type: string - description: 'Dockerfile to build and push' image_name: required: true type: string @@ -24,6 +20,16 @@ on: required: true type: string description: 'The build timestamp to be used for binaries.' + bake_target_name: + required: true + type: string + description: 'Docker Bake target name.' + post_image_tags: + required: false + type: boolean + description: | + If set to true the image tags pushed to the repository are posted as comment for the Pull Request. + Only works if the event type is `pull_request`. jobs: build-vars: @@ -34,22 +40,14 @@ jobs: - name: Set build variables id: build-vars run: | - - ## - ## Extract the image name - ## - ## $ basename ghcr.io/openclarity/vmclarity-ui-dev - ## vmclarity-ui-dev - ## - image_name="$(basename ${{ inputs.image_name }})" - + ## ## Set digests cache name ## ## Example: digest-1234-a2850e9cc4e2b3a3 ## - - image_name_hash="$(sha256sum <<< "${image_name}" | cut -f1 -d' ')" + + image_name_hash="$(sha256sum <<< "${{ inputs.bake_target_name }}" | cut -f1 -d' ')" printf "digests-cache-name=digest-%s-%.16s" "${{ github.run_id }}" "${image_name_hash}" >> "$GITHUB_OUTPUT" build-and-push: @@ -84,28 +82,28 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5 - id: build + uses: docker/bake-action@v4 + id: bake with: - context: . - platforms: ${{ matrix.platform }} - file: ${{ inputs.dockerfile }} - outputs: type=image,name=${{ inputs.image_name }},push-by-digest=true,name-canonical=true,push=${{ inputs.push }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache - build-args: | - VERSION=${{ inputs.image_tag }} - BUILD_TIMESTAMP=${{ inputs.timestamp }} - COMMIT_HASH=${{ github.sha }} + targets: ${{ inputs.bake_target_name }} + set: | + *.platform=${{ matrix.platform }} + *.output=type=image,name=${{ inputs.image_name }},push-by-digest=true,name-canonical=true,push=${{ inputs.push }} + *.tags= + *.cache-to=type=local,dest=/tmp/.buildx-cache + *.cache-from=type=local,src=/tmp/.buildx-cache + env: + VERSION: ${{ inputs.image_tag }} + BUILD_TIMESTAMP: ${{ inputs.timestamp }} + COMMIT_HASH: ${{ github.sha }} - name: Export digest if: inputs.push id: digest run: | mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" + digest=$(jq -r '."${{ inputs.bake_target_name }}"."containerimage.digest"'<<< '${{ steps.bake.outputs.metadata }}') touch "/tmp/digests/${digest#sha256:}" - echo "digest=${digest#sha256:}" >> "$GITHUB_OUTPUT" - name: Upload digests @@ -152,4 +150,18 @@ jobs: - name: Inspect image run: | - docker buildx imagetools inspect ${{ inputs.image_name }}:${{ inputs.image_tag }} + docker buildx imagetools inspect ${{ inputs.image_name }}:${{ inputs.image_tag }} + + - name: Save image name + if: inputs.post_image_tags + run: | + mkdir -p /tmp/images + echo "* \`${{ inputs.image_name }}:${{ inputs.image_tag }}\`" >> "/tmp/images/${{ inputs.bake_target_name }}" + + - name: Upload image names + if: inputs.post_image_tags + uses: actions/upload-artifact@v4 + with: + name: ${{ github.run_id }}-${{ inputs.bake_target_name }} + path: /tmp/images/* + if-no-files-found: error diff --git a/.github/workflows/reusable-build-and-push.yml b/.github/workflows/reusable-build-and-push.yml index 66763c192b..07d5948f36 100644 --- a/.github/workflows/reusable-build-and-push.yml +++ b/.github/workflows/reusable-build-and-push.yml @@ -3,6 +3,11 @@ name: Build & Push on: workflow_call: inputs: + registry_name: + required: false + type: string + description: 'Registry name used for container image names. Default is `ghcr.io/openclarity`.' + default: ghcr.io/openclarity image_tag: required: true type: string @@ -23,12 +28,20 @@ on: description: | If set to true the image tags pushed to the repository are posted as comment for the Pull Request. Only works if the event type is `pull_request`. + bake-group: + required: false + type: string + description: 'Name of the Docker Bake group of targets' + default: default jobs: - timestamp: + prepare: runs-on: ubuntu-latest outputs: timestamp: ${{ steps.timestamp.outputs.timestamp }} + registry: ${{ steps.registry.outputs.registry }} + suffix: ${{ steps.suffix.outputs.suffix }} + targets: ${{ steps.targets.outputs.targets }} steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 @@ -39,98 +52,78 @@ jobs: ## ## Set timestamp variable ## - + echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_OUTPUT" - images: - uses: ./.github/workflows/reusable-image-names.yml - with: - use_release_repository: ${{ inputs.use_release_repository }} + - name: Set registry + id: registry + run: | + ## + ## Determine the image name registry + ## - vmclarity-apiserver: - needs: - - images - - timestamp - uses: ./.github/workflows/build-and-push-component.yaml - with: - dockerfile: Dockerfile.apiserver - image_name: ${{ needs.images.outputs.apiserver-image }} - image_tag: ${{ inputs.image_tag }} - push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + # Remove trailing slash characters(s) + # shellcheck disable=SC2001 + echo "registry=$(sed -e 's@/*$@@' <<< ${{ inputs.registry_name }})" >> "$GITHUB_OUTPUT" - vmclarity-orchestrator: - needs: - - images - - timestamp - uses: ./.github/workflows/build-and-push-component.yaml - with: - dockerfile: Dockerfile.orchestrator - image_name: ${{ needs.images.outputs.orchestrator-image }} - image_tag: ${{ inputs.image_tag }} - push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + - name: Set suffix + id: suffix + run: | + ## + ## Determine the image name suffix based on the release type + ## - vmclarity-ui-backend: - needs: - - images - - timestamp - uses: ./.github/workflows/build-and-push-component.yaml - with: - dockerfile: Dockerfile.uibackend - image_name: ${{ needs.images.outputs.ui-backend-image }} - image_tag: ${{ inputs.image_tag }} - push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + # Set image name suffix + suffix=-dev + if [ "${{ inputs.use_release_repository }}" == "true" ]; then + suffix= + fi - vmclarity-ui: - needs: - - images - - timestamp - uses: ./.github/workflows/build-and-push-component.yaml - with: - dockerfile: Dockerfile.ui - image_name: ${{ needs.images.outputs.ui-image }} - image_tag: ${{ inputs.image_tag }} - push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + echo "suffix=${suffix}" >> "$GITHUB_OUTPUT" - vmclarity-cli: - needs: - - images - - timestamp - uses: ./.github/workflows/build-and-push-component.yaml - with: - dockerfile: Dockerfile.cli - image_name: ${{ needs.images.outputs.cli-image }} - image_tag: ${{ inputs.image_tag }} - push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + - name: List targets + id: targets + uses: docker/bake-action/subaction/list-targets@v4 + with: + target: ${{ inputs.bake-group }} - vmclarity-cr-discovery-server: + build-and-push: needs: - - images - - timestamp + - prepare + strategy: + fail-fast: false + matrix: + target: ${{ fromJson(needs.prepare.outputs.targets) }} uses: ./.github/workflows/build-and-push-component.yaml with: - dockerfile: Dockerfile.cr-discovery-server - image_name: ${{ needs.images.outputs.cr-discovery-server-image }} + image_name: "${{ needs.prepare.outputs.registry }}/${{ matrix.target }}${{ needs.prepare.outputs.suffix }}" image_tag: ${{ inputs.image_tag }} push: ${{ inputs.push }} - timestamp: ${{ needs.timestamp.outputs.timestamp }} + timestamp: ${{ needs.prepare.outputs.timestamp }} + bake_target_name: ${{ matrix.target }} + post_image_tags: ${{ inputs.post_image_tags }} post-images: if: github.event_name == 'pull_request' && inputs.post_image_tags runs-on: ubuntu-latest needs: - - images - - vmclarity-apiserver - - vmclarity-orchestrator - - vmclarity-ui-backend - - vmclarity-ui - - vmclarity-cli - - vmclarity-cr-discovery-server + - prepare + - build-and-push steps: + - name: Download image names + uses: actions/download-artifact@v4 + with: + pattern: ${{ github.run_id }}-* + merge-multiple: true + path: /tmp/images + + - name: Get image names + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + { + echo "images<<$EOF"; cat /tmp/images/*; echo "$EOF" + } >> "$GITHUB_ENV" + - name: Post comment with image tags uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2 with: @@ -138,13 +131,9 @@ jobs: hide_classify: "OUTDATED" skip_unchanged: true header: image-tags + append: true message: | Hey! - + Your images are ready: - * `${{ format('{0}:{1}', needs.images.outputs.apiserver-image, inputs.image_tag) }}` - * `${{ format('{0}:{1}', needs.images.outputs.orchestrator-image, inputs.image_tag) }}` - * `${{ format('{0}:{1}', needs.images.outputs.ui-backend-image, inputs.image_tag) }}` - * `${{ format('{0}:{1}', needs.images.outputs.ui-image, inputs.image_tag) }}` - * `${{ format('{0}:{1}', needs.images.outputs.cli-image, inputs.image_tag) }}` - * `${{ format('{0}:{1}', needs.images.outputs.cr-discovery-server-image, inputs.image_tag) }}` + ${{ env.images }}