chore(deps): update all digest updates (#665) #402
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 test application | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - next | |
| tags: [v*] | |
| pull_request: | |
| paths: | |
| - ".env.dist" | |
| - ".github/workflows/build.yml" | |
| - "bin/**" | |
| - "deploy/**" | |
| - "docker-compose*.yml" | |
| - "kustomization.yaml" | |
| - "Makefile" | |
| - "target/**" | |
| - "test/**" | |
| concurrency: | |
| group: "${{ github.workflow }}-${{ github.ref }}" | |
| cancel-in-progress: true | |
| env: | |
| ADDITIONAL_DOCKER_IMAGES: "mysql:lts axllent/mailpit:v1.27 redis:8-alpine" | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| include: | |
| - context: target/mda | |
| image: mailserver-mda | |
| - context: target/mta | |
| image: mailserver-mta | |
| - context: target/filter | |
| image: mailserver-filter | |
| - context: target/web | |
| image: mailserver-web | |
| - context: target/ssl | |
| image: mailserver-ssl | |
| - context: target/unbound | |
| image: mailserver-unbound | |
| - context: test/bats | |
| image: mailserver-test | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Set up QEMU | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 | |
| - name: Log in to Container Registry (ghcr.io) | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Log in to Container Registry (docker.io) | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 | |
| with: | |
| username: ${{ vars.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Cache Docker layers | |
| uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5 | |
| with: | |
| path: ${{ runner.temp }}/.buildx-cache | |
| key: ${{ runner.os }}-buildx-${{ matrix.image }}-${{ github.ref }}-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-buildx-${{ matrix.image }}-${{ github.ref }}- | |
| ${{ runner.os }}-buildx-${{ matrix.image }}- | |
| - name: Extract Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 | |
| with: | |
| images: | | |
| ghcr.io/jeboehm/${{ matrix.image }} | |
| jeboehm/${{ matrix.image }} | |
| tags: | | |
| type=schedule | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=sha | |
| - name: Create banner | |
| run: .github/bin/create_banner.sh ${{ github.sha }} ${{ github.ref_name }} | |
| - name: Build and push Docker image | |
| if: ${{ github.event_name != 'pull_request' }} | |
| id: build-and-push | |
| uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 | |
| with: | |
| context: ${{ matrix.context }} | |
| platforms: linux/amd64,linux/arm64 | |
| push: ${{ matrix.image != 'mailserver-test' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=local,src=${{ runner.temp }}/.buildx-cache | |
| cache-to: type=local,dest=${{ runner.temp }}/.buildx-cache-new,mode=max | |
| - name: Build Docker image | |
| if: ${{ github.event_name == 'pull_request' }} | |
| id: build-and-save | |
| uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 | |
| with: | |
| context: ${{ matrix.context }} | |
| push: false | |
| tags: jeboehm/${{ matrix.image }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=local,src=${{ runner.temp }}/.buildx-cache | |
| cache-to: type=local,dest=${{ runner.temp }}/.buildx-cache-new,mode=max | |
| outputs: type=docker,dest=${{ runner.temp }}/${{ matrix.image }}.tar | |
| - # Temp fix | |
| # https://github.com/docker/build-push-action/issues/252 | |
| # https://github.com/moby/buildkit/issues/1896 | |
| name: Move cache | |
| run: | | |
| rm -rf ${{ runner.temp }}/.buildx-cache | |
| mv ${{ runner.temp }}/.buildx-cache-new ${{ runner.temp }}/.buildx-cache | |
| - name: Generate artifact attestation (ghcr.io) | |
| if: ${{ github.event_name != 'pull_request' && matrix.image != 'mailserver-test' }} | |
| uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3 | |
| with: | |
| subject-name: ghcr.io/jeboehm/${{ matrix.image }} | |
| subject-digest: ${{ steps.build-and-push.outputs.digest }} | |
| push-to-registry: true | |
| - name: Generate artifact attestation (docker.io) | |
| if: ${{ github.event_name != 'pull_request' && matrix.image != 'mailserver-test' }} | |
| uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3 | |
| with: | |
| subject-name: index.docker.io/jeboehm/${{ matrix.image }} | |
| subject-digest: ${{ steps.build-and-push.outputs.digest }} | |
| push-to-registry: true | |
| - name: Upload Docker image to artifacts | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | |
| with: | |
| name: docker-image-${{ matrix.image }} | |
| path: ${{ runner.temp }}/${{ matrix.image }}.tar | |
| retention-days: 1 | |
| test_container_image_efficiency: | |
| needs: build | |
| if: ${{ github.event_name == 'pull_request' }} | |
| runs-on: ubuntu-latest | |
| env: | |
| CI: "true" | |
| DIVE_VERSION: 0.13.1 # renovate: depName=wagoodman/dive | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Download Docker image artifacts | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | |
| with: | |
| path: images | |
| pattern: docker-image-* | |
| merge-multiple: true | |
| - name: Install Dive | |
| run: | | |
| curl -sfOL "https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.deb" | |
| sudo dpkg -i ./dive_${DIVE_VERSION}_linux_amd64.deb | |
| - name: Check container image efficiency | |
| run: | | |
| for image in $(ls images/); do | |
| echo "::group::Checking image ${image}" | |
| dive --ci-config .github/linters/.dive-ci.yml docker-archive://images/${image} | |
| echo "::endgroup::" | |
| done | |
| test_docker_matrix: | |
| needs: build | |
| if: ${{ github.event_name == 'pull_request' }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| TEST_CASE: | |
| - default | |
| - relayhost | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Download Docker image artifacts | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | |
| with: | |
| path: images | |
| pattern: docker-image-* | |
| merge-multiple: true | |
| - name: Docker load downloaded image artifacts | |
| run: | | |
| for image in $(ls images/); do | |
| docker load --input images/${image} | |
| done | |
| - name: Cache Docker images | |
| uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5 | |
| id: docker-images-cache | |
| with: | |
| path: /tmp/docker-images | |
| key: ${{ runner.os }}-images-additional-${{ github.ref }}-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-images-additional-${{ github.ref }}- | |
| ${{ runner.os }}-images-additional- | |
| - name: Load or pull Docker images | |
| run: | | |
| mkdir -p /tmp/docker-images | |
| read -a IMAGES <<< "${{ env.ADDITIONAL_DOCKER_IMAGES }}" | |
| for IMAGE in "${IMAGES[@]}"; do | |
| # Convert image name to filename-safe format | |
| FILENAME=$(echo "$IMAGE" | tr '/:' '-').tar | |
| CACHE_PATH="/tmp/docker-images/$FILENAME" | |
| if [ -f "$CACHE_PATH" ]; then | |
| echo "::group::Loading $IMAGE from cache" | |
| docker load --input "$CACHE_PATH" | |
| echo "::endgroup::" | |
| else | |
| echo "::group::Pulling $IMAGE from registry" | |
| docker pull "$IMAGE" | |
| docker save "$IMAGE" -o "$CACHE_PATH" | |
| echo "::endgroup::" | |
| fi | |
| done | |
| - name: Prepare environment | |
| run: | | |
| make .env | |
| cat .env .github/test-matrix/${{ matrix.TEST_CASE }}.env > .env.tmp | |
| awk -F= '{seen[$1]=$0} END {for (key in seen) print seen[key]}' .env.tmp > .env | |
| rm .env.tmp | |
| - name: Output environment | |
| run: cat .env | |
| - name: Start components | |
| run: make up | |
| - name: Load database fixtures | |
| run: make fixtures | |
| - name: Run tests | |
| run: bin/test.sh run --rm test | |
| - name: Collect logs | |
| if: failure() | |
| run: | | |
| make logs | |
| docker ps -a | |
| test_kubernetes_matrix: | |
| needs: build | |
| if: ${{ github.event_name == 'pull_request' }} | |
| runs-on: ubuntu-latest | |
| env: | |
| CLUSTER_NAME: kind | |
| POPEYE_VERSION: v0.22.1 # renovate: depName=derailed/popeye | |
| strategy: | |
| matrix: | |
| TEST_CASE: | |
| - default | |
| - relayhost | |
| - proxy | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Setup Kind | |
| uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1 | |
| with: | |
| cluster_name: ${{ env.CLUSTER_NAME }} | |
| - name: Install Popeye | |
| run: | | |
| curl -sfOL https://github.com/derailed/popeye/releases/download/${{ env.POPEYE_VERSION }}/popeye_linux_amd64.deb | |
| sudo dpkg -i popeye_linux_amd64.deb | |
| - name: Use kubectl context | |
| run: | | |
| kind get clusters | |
| kubectl config use-context kind-${{ env.CLUSTER_NAME }} | |
| - name: Restore cached Docker images | |
| uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5 | |
| id: docker-images-cache | |
| with: | |
| path: /tmp/docker-images | |
| key: ${{ runner.os }}-images-additional-${{ github.ref }}-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-images-additional-${{ github.ref }}- | |
| ${{ runner.os }}-images-additional- | |
| - name: Load cached Docker images | |
| if: steps.docker-images-cache.outputs.cache-hit == 'true' | |
| run: | | |
| read -a IMAGES <<< "${{ env.ADDITIONAL_DOCKER_IMAGES }}" | |
| for IMAGE in "${IMAGES[@]}"; do | |
| FILENAME=$(echo "$IMAGE" | tr '/:' '-').tar | |
| CACHE_PATH="/tmp/docker-images/$FILENAME" | |
| if [ -f "$CACHE_PATH" ]; then | |
| echo "::group::Loading $IMAGE from cache into kind cluster" | |
| kind load image-archive "$CACHE_PATH" | |
| echo "::endgroup::" | |
| fi | |
| done | |
| - name: Download docker image artifacts | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | |
| with: | |
| path: images | |
| pattern: docker-image-* | |
| merge-multiple: true | |
| - name: Load downloaded docker images | |
| run: | | |
| for image in $(ls images/); do | |
| echo "::group::Loading $image from downloaded artifacts into kind cluster" | |
| kind load image-archive images/${image} | |
| echo "::endgroup::" | |
| done | |
| - name: Prepare environment | |
| run: | | |
| make .env | |
| cat .env .github/test-matrix/${{ matrix.TEST_CASE }}.env > .env.tmp | |
| awk -F= '{seen[$1]=$0} END {for (key in seen) print seen[key]}' .env.tmp > .env | |
| rm .env.tmp | |
| - name: Prepare tls certs | |
| run: make kubernetes-tls | |
| - name: Deploy Kubernetes resources | |
| run: make kubernetes-deploy-helper kubernetes-up | |
| - name: Wait for all pods to be ready | |
| run: make kubernetes-wait | |
| - name: Run tests | |
| run: make kubernetes-test | |
| - name: Run Popeye | |
| run: make popeye-score | |
| - name: Get pod status on failure | |
| if: failure() | |
| run: | | |
| make kubernetes-logs | |
| kubectl get pods -o wide | |
| test_trivy_vulnerabilities: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - image: mailserver-mda | |
| - image: mailserver-mta | |
| - image: mailserver-filter | |
| - image: mailserver-web | |
| - image: mailserver-ssl | |
| - image: mailserver-unbound | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Download Docker image artifacts | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | |
| with: | |
| path: images | |
| pattern: docker-image-${{ matrix.image }} | |
| merge-multiple: true | |
| - name: Run Trivy vulnerability scanner | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 | |
| with: | |
| input: "images/${{ matrix.image }}.tar" | |
| format: "sarif" | |
| output: "trivy-results.sarif" | |
| severity: "CRITICAL,HIGH" | |
| - name: Log in to Container Registry (ghcr.io) | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run Trivy vulnerability scanner | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 | |
| with: | |
| image-ref: "ghcr.io/jeboehm/${{ matrix.image }}:latest" | |
| format: "sarif" | |
| output: "trivy-results.sarif" | |
| severity: "CRITICAL,HIGH" | |
| - name: Upload Trivy scan results to GitHub Security tab | |
| if: always() | |
| uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4 | |
| with: | |
| sarif_file: "trivy-results.sarif" | |
| category: "${{ matrix.image }}" |