diff --git a/.github/workflows/build-and-push-component.yaml b/.github/workflows/build-and-push-component.yaml index 312595fc2..974dd1baf 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.1.0 - 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/image-names + echo "${{ inputs.image_name }}:${{ inputs.image_tag }}" >> "/tmp/image-names/${{ inputs.bake_target_name }}" + + - name: Upload image names + if: inputs.post_image_tags + uses: actions/upload-artifact@v4 + with: + name: image-names-${{ github.run_id }}-${{ inputs.bake_target_name }} + path: /tmp/image-names/* + if-no-files-found: error diff --git a/.github/workflows/reusable-build-and-push.yml b/.github/workflows/reusable-build-and-push.yml index c9e87e228..63c5539a2 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.1.1 @@ -39,98 +52,90 @@ 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: image-names-${{ github.run_id }}-* + merge-multiple: true + path: /tmp/image-names + + - name: Get image names + run: | + ## + ## Cat out the image names from the directory, prefixing (* `) and suffixing (`) them to create + ## markdown list items and saving this multiline string with base64 encoding to a Github env. + ## + ## Example: + ## + ## * `ghcr.io/openclarity/vmclarity-apiserver:latest` + ## * `ghcr.io/openclarity/vmclarity-orchestrator:latest` + ## * `ghcr.io/openclarity/vmclarity-ui-backend:latest` + + set -o pipefail + + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + { + echo "image-names<<$EOF"; cat /tmp/image-names/* | sed "s/.*/* \`&\`/"; echo "$EOF" + } >> "$GITHUB_ENV" + - name: Post comment with image tags uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2.9.0 with: @@ -140,11 +145,6 @@ jobs: header: image-tags 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.image-names }} diff --git a/.github/workflows/reusable-end-to-end-testing.yml b/.github/workflows/reusable-end-to-end-testing.yml index 4a2bd8a33..873a07bb7 100644 --- a/.github/workflows/reusable-end-to-end-testing.yml +++ b/.github/workflows/reusable-end-to-end-testing.yml @@ -7,6 +7,11 @@ on: required: true type: string description: 'Image tag to build and push.' + registry_name: + required: false + type: string + description: 'Registry name used for container image names. Default is `ghcr.io/openclarity`.' + default: ghcr.io/openclarity use_release_repository: required: false type: boolean @@ -15,9 +20,40 @@ on: jobs: images: - uses: ./.github/workflows/reusable-image-names.yml - with: - use_release_repository: ${{ inputs.use_release_repository }} + runs-on: ubuntu-latest + outputs: + apiserver-image: ${{ steps.images.outputs.apiserver-image }} + orchestrator-image: ${{ steps.images.outputs.orchestrator-image }} + ui-backend-image: ${{ steps.images.outputs.ui-backend-image }} + ui-image: ${{ steps.images.outputs.ui-image }} + cli-image: ${{ steps.images.outputs.cli-image }} + cr-discovery-server-image: ${{ steps.images.outputs.cr-discovery-server-image }} + steps: + - name: Set container image names + id: images + run: | + ## + ## Determine the image name suffix based on the release type + ## + + # Remove trailing slash characters(s) + # shellcheck disable=SC2001 + registry="$(sed -e 's@/*$@@' <<< ${{ inputs.registry_name }})" + + # Set image name suffix + suffix=-dev + if [ "${{ inputs.use_release_repository }}" == "true" ]; then + suffix= + fi + + { + echo "apiserver-image=${registry}/vmclarity-apiserver${suffix}" + echo "orchestrator-image=${registry}/vmclarity-orchestrator${suffix}" + echo "ui-backend-image=${registry}/vmclarity-ui-backend${suffix}" + echo "ui-image=${registry}/vmclarity-ui${suffix}" + echo "cli-image=${registry}/vmclarity-cli${suffix}" + echo "cr-discovery-server-image=${registry}/vmclarity-cr-discovery-server${suffix}" + } >> "$GITHUB_OUTPUT" run: runs-on: ubuntu-latest @@ -52,5 +88,6 @@ jobs: VMCLARITY_E2E_UI_IMAGE: ${{ format('{0}:{1}', needs.images.outputs.ui-image, inputs.image_tag) }} VMCLARITY_E2E_UIBACKEND_IMAGE: ${{ format('{0}:{1}', needs.images.outputs.ui-backend-image, inputs.image_tag) }} VMCLARITY_E2E_SCANNER_IMAGE: ${{ format('{0}:{1}', needs.images.outputs.cli-image, inputs.image_tag) }} + VMCLARITY_E2E_CR_DISCOVERY_SERVER_IMAGE: ${{ format('{0}:{1}', needs.images.outputs.cr-discovery-server-image, inputs.image_tag) }} run: | make e2e diff --git a/.github/workflows/reusable-image-names.yml b/.github/workflows/reusable-image-names.yml deleted file mode 100644 index 00647fcf4..000000000 --- a/.github/workflows/reusable-image-names.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Container Image Names - -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 - use_release_repository: - required: false - type: boolean - description: 'If set to true the image published to the release repository is used otherwise the development.' - default: false - outputs: - apiserver-image: - value: ${{ jobs.images.outputs.apiserver-image }} - description: 'Name of the container image for VMClarity API Server' - orchestrator-image: - value: ${{ jobs.images.outputs.orchestrator-image }} - description: 'Name of the contaienr image for VMClarity Orchestrator' - ui-backend-image: - value: ${{ jobs.images.outputs.ui-backend-image }} - description: 'Name of the container image for VMClarity UI Backend Server' - ui-image: - value: ${{ jobs.images.outputs.ui-image }} - description: 'Name of the container image for VMClarity UI Server' - cli-image: - value: ${{ jobs.images.outputs.cli-image }} - description: 'Name of the container image for VMClarity CLI' - cr-discovery-server-image: - value: ${{ jobs.images.outputs.cr-discovery-server-image }} - description: 'Name of the container image for VMClarity ContainerRuntime Discovery Server' - -jobs: - images: - runs-on: ubuntu-latest - outputs: - apiserver-image: ${{ steps.images.outputs.apiserver-image }} - orchestrator-image: ${{ steps.images.outputs.orchestrator-image }} - ui-backend-image: ${{ steps.images.outputs.ui-backend-image }} - ui-image: ${{ steps.images.outputs.ui-image }} - cli-image: ${{ steps.images.outputs.cli-image }} - cr-discovery-server-image: ${{ steps.images.outputs.cr-discovery-server-image }} - steps: - - name: Set container image names - id: images - run: | - ## - ## Determine the image name suffix based on the release type - ## - - # Remove trailing slash characters(s) - # shellcheck disable=SC2001 - registry="$(sed -e 's@/*$@@' <<< ${{ inputs.registry_name }})" - - # Set image nam suffix - suffix=-dev - if [ "${{ inputs.use_release_repository }}" == "true" ]; then - suffix= - fi - - { - echo "apiserver-image=${registry}/vmclarity-apiserver${suffix}" - echo "orchestrator-image=${registry}/vmclarity-orchestrator${suffix}" - echo "ui-backend-image=${registry}/vmclarity-ui-backend${suffix}" - echo "ui-image=${registry}/vmclarity-ui${suffix}" - echo "cli-image=${registry}/vmclarity-cli${suffix}" - echo "cr-discovery-server-image=${registry}/vmclarity-cr-discovery-server${suffix}" - } >> "$GITHUB_OUTPUT"