From ae22b50fd186a3821a2566a19942618eb3375e19 Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Sat, 28 Sep 2024 16:57:59 +0200 Subject: [PATCH] Build multi arch images --- .github/workflows/main.yml | 287 +++++++++++++++++++++---------------- 1 file changed, 165 insertions(+), 122 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7960d3b..94e5e28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,5 @@ name: Continuous Integration env: - DOCKER_IMAGE: wyrihaximusnet/redirect DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING: '{"ghcr.io":"GHCR_TOKEN","docker.io":"HUB_PASSCODE"}' on: push: @@ -72,131 +71,175 @@ jobs: - generate-image-strategy - lint-dockerfile runs-on: ubuntu-latest + services: + registry: + image: registry:2 + ports: + - 5000:5000 steps: + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host - uses: actions/checkout@v4 - run: cp -R $(echo -e "./images/$(ls ./images/ | shuf -n 1)") ./images/random if: matrix.image == 'random' - - run: docker image build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` -t "${DOCKER_IMAGE}:${{ matrix.image }}" --no-cache --build-arg VERSION=$TAG_VERSION ./images/${{ matrix.image }}/ - run: mkdir ./docker-image - - run: docker save "${DOCKER_IMAGE}:${{ matrix.image }}" -o ./docker-image/docker_image.tar - - uses: actions/upload-artifact@master - with: - name: docker-image-${{ matrix.image }} - path: ./docker-image - scan-vulnerability: - name: Scan ${{ matrix.image }} for vulnerabilities - strategy: - fail-fast: false - matrix: - image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} - needs: - - generate-image-strategy - - build-docker-image - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@master - with: - name: docker-image-${{ matrix.image }} - path: ./docker-image - - run: docker load --input ./docker-image/docker_image.tar - - run: rm -Rf ./docker-image/ - - run: echo -e "${DOCKER_IMAGE}:${{ matrix.image }}" | xargs -I % sh -c 'docker run -v /tmp/trivy:/var/lib/trivy -v /var/run/docker.sock:/var/run/docker.sock -t aquasec/trivy:latest --cache-dir /var/lib/trivy image --exit-code 1 --no-progress --format table %' - tests: - name: Test ${{ matrix.image }} against ${{ matrix.rule }} - needs: - - generate-image-strategy - - generate-rule-strategy - - scan-vulnerability - strategy: - fail-fast: false - matrix: - image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} - rule: ${{ fromJson(needs.generate-rule-strategy.outputs.rules) }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@master - with: - name: docker-image-${{ matrix.image }} - path: ./docker-image - - run: docker load --input ./docker-image/docker_image.tar - - name: Start image ${{ matrix.image }} - run: docker run -d --rm -v ${GITHUB_WORKSPACE}/${REDIRECT_CONFIG_FILE}:/etc/redirect/config.yaml ${DOCKER_IMAGE}:${{ matrix.image }} - env: - IMAGE: ${{ steps.build.outputs.tag }} - REDIRECT_CONFIG_FILE: tests/rules/${{ matrix.rule }}/config.yaml - - name: Get running image ID - id: ps - run: printf "::set-output name=id::%s" $(docker ps --format "{{.ID}}") - env: - IMAGE: ${{ steps.build.outputs.tag }} - - name: Get running image IP - id: inspect - run: printf "::set-output name=ip::%s" $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${IMAGE_ID}) - env: - IMAGE_ID: ${{ steps.ps.outputs.id }} - - name: Sleep 13 seconds before attempting to connect - run: sleep 13 - - name: Test that redirect port is reachable - run: curl http://${IMAGE_IP}:7132/ - env: - IMAGE_IP: ${{ steps.inspect.outputs.ip }} - - name: Test that metrics port is reachable - run: curl http://${IMAGE_IP}:7133/ - env: - IMAGE_IP: ${{ steps.inspect.outputs.ip }} - - name: Run unit tests ${{ matrix.rule }} against ${{ matrix.image }} - run: docker run -i loadimpact/k6 run -u 1000 -d 30s -e IMAGE_IP=${IMAGE_IP} -< ${SCRIPT_FILEIMAGE} - env: - IMAGE: ${{ matrix.image }} - IMAGE_IP: ${{ steps.inspect.outputs.ip }} - IMAGE_ID: ${{ steps.ps.outputs.id }} - SCRIPT_FILEIMAGE: ./tests/rules/${{ matrix.rule }}/unit.js - - name: Run metrics tests ${{ matrix.rule }} against ${{ matrix.image }} - run: docker run -i loadimpact/k6 run -u 10 -d 10s -e IMAGE_IP=${IMAGE_IP} -< ${SCRIPT_FILEIMAGE} - env: - IMAGE: ${{ matrix.image }} - IMAGE_IP: ${{ steps.inspect.outputs.ip }} - IMAGE_ID: ${{ steps.ps.outputs.id }} - SCRIPT_FILEIMAGE: ./tests/rules/${{ matrix.rule }}/metrics.js - - name: Docker logs for image ${{ matrix.image }} - run: docker logs ${IMAGE_ID} - env: - IMAGE_ID: ${{ steps.ps.outputs.id }} - push-image: - if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master' - name: Push ${{ matrix.image }} to ${{ matrix.registry }} - strategy: - fail-fast: false - matrix: - registry: ${{ fromJson(needs.registry-matrix.outputs.registry) }} - image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} - needs: - - generate-image-strategy - - tests - - registry-matrix - runs-on: ubuntu-latest - steps: - - uses: actions/download-artifact@master + - name: Build and export + uses: docker/build-push-action@v6 with: - name: docker-image-${{ matrix.image }} - path: ./docker-image - - run: docker load --input ./docker-image/docker_image.tar - - run: rm -Rf ./docker-image/ - - name: Login to ${{ matrix.registry }} + context: ./images/${{ matrix.image }}/ + file: ./images/${{ matrix.image }}/Dockerfile +# tags: wyrihaximusnet/redirect:${{ matrix.image }} + platforms: linux/amd64 + labels: ${{ steps.meta.outputs.labels }} +# platforms: linux/amd64,linux/arm64 + outputs: type=image,name=localhost:5000/wyrihaximusnet/redirect,push-by-digest=true,name-canonical=true,push=true +# outputs: type=tar,dest=./docker-image/docker_image.tar +# build-args: | +# BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` +# VCS_REF=`git rev-parse --short HEAD` + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Export digest run: | - echo "${{ env.DOCKER_PASSWORD }}" | \ - docker login ${{ matrix.registry }} \ - --username "${{ env.DOCKER_USER }}" \ - --password-stdin - env: - DOCKER_USER: ${{ secrets.HUB_USERNAME }} - DOCKER_PASSWORD: ${{ secrets[fromJson(env.DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING)[matrix.registry]] }} - - name: Docker info - run: docker info - - run: docker tag ${DOCKER_IMAGE}:${{ matrix.image }} ${{ matrix.registry }}/${DOCKER_IMAGE}:${{ matrix.image }} - - name: Echo full tag - run: echo -e "${{ matrix.registry }}/${DOCKER_IMAGE}:${{ matrix.image }}" - - name: Push image to Docker Hub - run: docker push "${{ matrix.registry }}/${DOCKER_IMAGE}:${{ matrix.image }}" + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 +# scan-vulnerability: +# name: Scan ${{ matrix.image }} for vulnerabilities +# strategy: +# fail-fast: false +# matrix: +# image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} +# needs: +# - generate-image-strategy +# - build-docker-image +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: actions/download-artifact@master +# with: +# name: docker-image-${{ matrix.image }} +# path: ./docker-image +# - run: docker load --input ./docker-image/docker_image.tar +# - run: docker image ls -a +# - run: docker manifest inspect $(echo "wyrihaximusnet/redirect:${{ matrix.image }}" | tr '[:upper:]' '[:lower:]') +# - run: docker manifest inspect $(echo "wyrihaximusnet/redirect:${{ matrix.image }}" | tr '[:upper:]' '[:lower:]') | docker run --rm -i backplane/jq '([.manifests[].platform | select(.os != "unknown")]?) | .[] | (.os + "/" + .architecture)' | docker run --rm -i backplane/jq -s '. | join(",")' +# - run: rm -Rf ./docker-image/ +# - run: echo -e "wyrihaximusnet/redirect:${{ matrix.image }}" | xargs -I % sh -c 'docker run -v /tmp/trivy:/var/lib/trivy -v /var/run/docker.sock:/var/run/docker.sock -t aquasec/trivy:latest --cache-dir /var/lib/trivy image --exit-code 1 --no-progress --format table %' +# tests: +# name: Test ${{ matrix.image }} against ${{ matrix.rule }} +# needs: +# - generate-image-strategy +# - generate-rule-strategy +# - scan-vulnerability +# strategy: +# fail-fast: false +# matrix: +# image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} +# rule: ${{ fromJson(needs.generate-rule-strategy.outputs.rules) }} +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: actions/download-artifact@v4 +# with: +# name: docker-image-${{ matrix.image }} +# path: ./docker-image +# - run: docker load --input ./docker-image/docker_image.tar +# - run: docker image ls -a +# - run: docker manifest inspect $(echo "wyrihaximusnet/redirect:${{ matrix.image }}" | tr '[:upper:]' '[:lower:]') +# - run: docker manifest inspect $(echo "wyrihaximusnet/redirect:${{ matrix.image }}" | tr '[:upper:]' '[:lower:]') | docker run --rm -i backplane/jq '([.manifests[].platform | select(.os != "unknown")]?) | .[] | (.os + "/" + .architecture)' | docker run --rm -i backplane/jq -s '. | join(",")' +# - name: Start image ${{ matrix.image }} +# run: docker run -d --rm -v ${GITHUB_WORKSPACE}/${REDIRECT_CONFIG_FILE}:/etc/redirect/config.yaml wyrihaximusnet/redirect:${{ matrix.image }} +# env: +# IMAGE: ${{ steps.build.outputs.tag }} +# REDIRECT_CONFIG_FILE: tests/rules/${{ matrix.rule }}/config.yaml +# - name: Get running image ID +# id: ps +# run: printf "::set-output name=id::%s" $(docker ps --format "{{.ID}}") +# env: +# IMAGE: ${{ steps.build.outputs.tag }} +# - name: Get running image IP +# id: inspect +# run: printf "::set-output name=ip::%s" $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${IMAGE_ID}) +# env: +# IMAGE_ID: ${{ steps.ps.outputs.id }} +# - name: Sleep 13 seconds before attempting to connect +# run: sleep 13 +# - name: Test that redirect port is reachable +# run: curl http://${IMAGE_IP}:7132/ +# env: +# IMAGE_IP: ${{ steps.inspect.outputs.ip }} +# - name: Test that metrics port is reachable +# run: curl http://${IMAGE_IP}:7133/ +# env: +# IMAGE_IP: ${{ steps.inspect.outputs.ip }} +# - name: Run unit tests ${{ matrix.rule }} against ${{ matrix.image }} +# run: docker run -i loadimpact/k6 run -u 1000 -d 30s -e IMAGE_IP=${IMAGE_IP} -< ${SCRIPT_FILEIMAGE} +# env: +# IMAGE: ${{ matrix.image }} +# IMAGE_IP: ${{ steps.inspect.outputs.ip }} +# IMAGE_ID: ${{ steps.ps.outputs.id }} +# SCRIPT_FILEIMAGE: ./tests/rules/${{ matrix.rule }}/unit.js +# - name: Run metrics tests ${{ matrix.rule }} against ${{ matrix.image }} +# run: docker run -i loadimpact/k6 run -u 10 -d 10s -e IMAGE_IP=${IMAGE_IP} -< ${SCRIPT_FILEIMAGE} +# env: +# IMAGE: ${{ matrix.image }} +# IMAGE_IP: ${{ steps.inspect.outputs.ip }} +# IMAGE_ID: ${{ steps.ps.outputs.id }} +# SCRIPT_FILEIMAGE: ./tests/rules/${{ matrix.rule }}/metrics.js +# - name: Docker logs for image ${{ matrix.image }} +# run: docker logs ${IMAGE_ID} +# env: +# IMAGE_ID: ${{ steps.ps.outputs.id }} +# push-image: +# if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master' +# name: Push ${{ matrix.image }} to ${{ matrix.registry }} +# strategy: +# fail-fast: false +# matrix: +# registry: ${{ fromJson(needs.registry-matrix.outputs.registry) }} +# image: ${{ fromJson(needs.generate-image-strategy.outputs.images) }} +# needs: +# - generate-image-strategy +# - tests +# - registry-matrix +# runs-on: ubuntu-latest +# steps: +# - uses: actions/download-artifact@v4 +# with: +# name: docker-image-${{ matrix.image }} +# path: ./docker-image +# - run: docker load --input ./docker-image/docker_image.tar +# - run: rm -Rf ./docker-image/ +# - name: Login to ${{ matrix.registry }} +# run: | +# echo "${{ env.DOCKER_PASSWORD }}" | \ +# docker login ${{ matrix.registry }} \ +# --username "${{ env.DOCKER_USER }}" \ +# --password-stdin +# env: +# DOCKER_USER: ${{ secrets.HUB_USERNAME }} +# DOCKER_PASSWORD: ${{ secrets[fromJson(env.DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING)[matrix.registry]] }} +# - name: Docker info +# run: docker info +# - run: docker tag wyrihaximusnet/redirect:${{ matrix.image }} ${{ matrix.registry }}/wyrihaximusnet/redirect:${{ matrix.image }} +# - name: Echo full tag +# run: echo -e "${{ matrix.registry }}/wyrihaximusnet/redirect:${{ matrix.image }}" +# - name: Push image to Docker Hub +# run: docker push "${{ matrix.registry }}/wyrihaximusnet/redirect:${{ matrix.image }}"