Build and Push #312
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Push | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "v*" | |
| pull_request: | |
| branches: | |
| - main | |
| schedule: | |
| - cron: "0 3 * * *" | |
| permissions: | |
| contents: read | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_BASE: ghcr.io/patbaumgartner/distroless-buildpack-builder-java-tiny | |
| jobs: | |
| build-stack-build: | |
| name: Build stack – build image | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| outputs: | |
| image: ${{ steps.meta.outputs.tags }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Log in to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 | |
| with: | |
| images: | | |
| ${{ env.IMAGE_BASE }}/build | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push build stack image | |
| id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: ./stack/build | |
| platforms: linux/amd64,linux/arm64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # sbom and provenance add extra OCI manifests to the image index; | |
| # the pack CLI misidentifies these as platform manifests and fails | |
| # with "missing required env var 'CNB_USER_ID'". | |
| sbom: false | |
| provenance: false | |
| - name: Generate SBOM with Syft (build stack) | |
| if: github.event_name != 'pull_request' | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| image: ${{ env.IMAGE_BASE }}/build:latest | |
| artifact-name: sbom-build-stack.spdx.json | |
| output-file: sbom-build-stack.spdx.json | |
| - name: Attest build stack image (GHCR) | |
| if: github.event_name != 'pull_request' | |
| uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 | |
| with: | |
| subject-name: ${{ env.IMAGE_BASE }}/build | |
| subject-digest: ${{ steps.build.outputs.digest }} | |
| push-to-registry: true | |
| build-stack-run: | |
| name: Build stack – run image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| outputs: | |
| image: ${{ steps.meta.outputs.tags }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Log in to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 | |
| with: | |
| images: | | |
| ${{ env.IMAGE_BASE }}/run | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push run stack image | |
| id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: ./stack/run | |
| platforms: linux/amd64,linux/arm64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # sbom and provenance add extra OCI manifests to the image index; | |
| # the pack CLI misidentifies these as platform manifests and fails | |
| # with "missing required env var 'CNB_USER_ID'". | |
| sbom: false | |
| provenance: false | |
| - name: Generate SBOM with Syft (run stack) | |
| if: github.event_name != 'pull_request' | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| image: ${{ env.IMAGE_BASE }}/run:latest | |
| artifact-name: sbom-run-stack.spdx.json | |
| output-file: sbom-run-stack.spdx.json | |
| - name: Attest run stack image (GHCR) | |
| if: github.event_name != 'pull_request' | |
| uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 | |
| with: | |
| subject-name: ${{ env.IMAGE_BASE }}/run | |
| subject-digest: ${{ steps.build.outputs.digest }} | |
| push-to-registry: true | |
| validate-builder: | |
| name: Validate builder locally | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build-stack-build | |
| - build-stack-run | |
| if: | | |
| always() && | |
| github.event_name != 'pull_request' && | |
| (needs.build-stack-run.result == 'success') && | |
| (needs.build-stack-build.result == 'success' || needs.build-stack-build.result == 'skipped') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Set up pack CLI | |
| uses: buildpacks/github-actions/setup-pack@c1c71086a0e89a65c04ea113390227fd7f05d9df # v6.0.0 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build stack images locally (single-arch) | |
| run: | | |
| docker build -t "${{ env.IMAGE_BASE }}/build:latest" ./stack/build | |
| docker build -t "${{ env.IMAGE_BASE }}/run:latest" ./stack/run | |
| - name: Create local builder | |
| run: | | |
| pack builder create validate-builder:ci \ | |
| --config builder.toml \ | |
| --pull-policy if-not-present | |
| - name: Build Java sample with local builder | |
| run: | | |
| pack build validate-app:ci \ | |
| --path ./samples/java \ | |
| --builder validate-builder:ci \ | |
| --trust-builder \ | |
| --pull-policy if-not-present | |
| - name: Verify Java sample responds correctly | |
| run: | | |
| docker run -d --name validate-test -p 8099:8080 validate-app:ci | |
| for i in $(seq 1 30); do | |
| RESP=$(curl -sf http://localhost:8099/ 2>/dev/null || echo "") | |
| if echo "${RESP}" | grep -qi "hello"; then | |
| echo "Validation passed: ${RESP}" | |
| break | |
| fi | |
| echo "Waiting... (${i}/30)" | |
| sleep 3 | |
| done | |
| echo "${RESP}" | grep -qi "hello" | |
| docker rm -f validate-test | |
| build-builder: | |
| name: Build builder image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| needs: | |
| - build-stack-build | |
| - build-stack-run | |
| - validate-builder | |
| if: | | |
| always() && | |
| github.event_name != 'pull_request' && | |
| (needs.build-stack-run.result == 'success') && | |
| (needs.build-stack-build.result == 'success' || needs.build-stack-build.result == 'skipped') && | |
| needs.validate-builder.result == 'success' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Set up pack CLI | |
| uses: buildpacks/github-actions/setup-pack@c1c71086a0e89a65c04ea113390227fd7f05d9df # v6.0.0 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Determine builder tag | |
| id: tag | |
| run: | | |
| if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then | |
| echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tag=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create and publish builder to GHCR | |
| run: | | |
| pack builder create "${{ env.IMAGE_BASE }}:${{ steps.tag.outputs.tag }}" \ | |
| --config ./builder.toml \ | |
| --publish | |
| cleanup-packages: | |
| name: Cleanup old package versions | |
| runs-on: ubuntu-latest | |
| needs: [build-builder] | |
| if: github.event_name != 'pull_request' | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: Delete old versions – builder image | |
| uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 | |
| with: | |
| package-name: distroless-buildpack-builder-java-tiny | |
| package-type: container | |
| min-versions-to-keep: 20 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Delete old versions – build stack image | |
| uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 | |
| with: | |
| package-name: distroless-buildpack-builder-java-tiny/build | |
| package-type: container | |
| min-versions-to-keep: 20 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Delete old versions – run stack image | |
| uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 | |
| with: | |
| package-name: distroless-buildpack-builder-java-tiny/run | |
| package-type: container | |
| min-versions-to-keep: 20 | |
| token: ${{ secrets.GITHUB_TOKEN }} |