From e0d7ad71f721e19a4343264e8399a5bd0f20fef7 Mon Sep 17 00:00:00 2001
From: Cees-Jan Kiewiet <ceesjank@gmail.com>
Date: Sun, 6 Oct 2024 21:04:06 +0200
Subject: [PATCH] Build, scan, test, and push

---
 .github/workflows/main.yml | 158 ++++++++++++++++++++++++++++++++++---
 .github/workflows/old.yml  |  36 +++++++++
 Dockerfile                 |   2 +
 3 files changed, 183 insertions(+), 13 deletions(-)
 create mode 100644 .github/workflows/old.yml

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3cef987..ac6d6d4 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,26 +1,152 @@
 name: Continuous Integration
+env:
+  DOCKER_IMAGE: ghcr.io/wyrihaximusnet/github-action-runner
 on:
   push:
-    branches:
-      - main
-  pull_request:
   schedule:
     - cron:  '0 0 * * 0'
 jobs:
-  build:
-    name: Build Image
+  supported-arch-matrix:
+    name: Supported processor architectures
     runs-on: ubuntu-latest
+    needs:
+      - lint-dockerfile
+    outputs:
+      arch: ${{ steps.supported-arch-matrix.outputs.arch }}
     steps:
-      - name: Get Time
-        id: time
-        uses: nanzm/get-time-action@v2.0
+      - uses: actions/checkout@v4
+      - id: supported-arch-matrix
+        name: Generate Arch
+        run: |
+          echo "arch=[\"linux/amd64\",\"linux/arm64\"]" >> $GITHUB_OUTPUT
+  lint-dockerfile:
+    name: Lint Dockerfile
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Lint Dockerfile
+        uses: docker://hadolint/hadolint:latest-debian
+        with:
+          entrypoint: hadolint
+          args: ./Dockerfile
+  build-docker-image:
+    name: Build ${{ matrix.platform }} image
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
+    needs:
+      - supported-arch-matrix
+      - lint-dockerfile
+    runs-on: ubuntu-latest
+    steps:
+      - name: Prepare
+        run: |
+          platform=${{ matrix.platform }}
+          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
+      - 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
+      - uses: actions/checkout@v4
+      - run: mkdir ./docker-image
+      - run: docker image build --platform=${{ matrix.platform }} --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` -t "${DOCKER_IMAGE}:${{ env.PLATFORM_PAIR }}" --no-cache .
+      - run: docker save "${DOCKER_IMAGE}:${{ env.PLATFORM_PAIR }}" -o ./docker-image/docker_image-${{ env.PLATFORM_PAIR }}.tar
+      - uses: actions/upload-artifact@v4
         with:
-          format: 'YYYY.MM.DD'
+          name: docker-image-${{ env.PLATFORM_PAIR }}
+          path: ./docker-image
+  scan-vulnerability:
+    name: Scan for vulnerabilities (${{ matrix.platform }})
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
+    needs:
+      - supported-arch-matrix
+      - build-docker-image
+    runs-on: ubuntu-latest
+    steps:
+      - name: Prepare
+        run: |
+          platform=${{ matrix.platform }}
+          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
       - uses: actions/checkout@v4
+      - uses: actions/download-artifact@v4
+        with:
+          name: docker-image-${{ env.PLATFORM_PAIR }}
+          path: /tmp/docker-image
+      - run: docker load --input /tmp/docker-image/docker_image-${{ env.PLATFORM_PAIR }}.tar
+      - run: rm -Rf /tmp/docker-image/
+      - run: echo -e "${{ env.DOCKER_IMAGE }}:${{ env.PLATFORM_PAIR }}" | 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 % || true'
+  tests:
+    name: Test ${{ matrix.platform }}
+    needs:
+      - supported-arch-matrix
+      - scan-vulnerability
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Prepare
+        run: |
+          platform=${{ matrix.platform }}
+          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v3
+      - uses: actions/checkout@v4
+      - uses: actions/download-artifact@v4
+        with:
+          name: docker-image-${{ env.PLATFORM_PAIR }}
+          path: /tmp/docker-image
+      - run: docker load --input /tmp/docker-image/docker_image-${{ env.PLATFORM_PAIR }}.tar
+      - run: docker image ls -a
+  push-image:
+#    if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/main'
+    name: Push
+    needs:
+      - supported-arch-matrix
+      - tests
+    runs-on: ubuntu-latest
+    services:
+      registry:
+        image: registry:2
+        ports:
+          - 5000:5000
+    steps:
       - 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/download-artifact@v4
+        with:
+          pattern: docker-image-*
+          path: /tmp/docker-image
+          merge-multiple: true
+      - run: ls -lasth /tmp/docker-image/
+      - run: |
+          for f in /tmp/docker-image/docker_image-*.tar; do
+            docker load --input $f
+          done
+      - run: rm -Rf /tmp/docker-image/
+      - run: docker images
+      - run: |
+          archs=${{ join(fromJson(needs.supported-arch-matrix.outputs.arch), ',') }}
+          for arch in ${archs//,/ }
+          do
+            docker tag "${{ env.DOCKER_IMAGE }}:${arch//\//-}" "localhost:5000/${{ env.DOCKER_IMAGE }}:${arch//\//-}"
+            docker push "localhost:5000/${{ env.DOCKER_IMAGE }}:${arch//\//-}"
+          done
+      - run: docker images
       - name: Login to GitHub Container Registry
         if: github.event_name != 'pull_request'
         uses: docker/login-action@v3
@@ -28,9 +154,15 @@ jobs:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GHCR_TOKEN }}
-      - name: Build and push
+      - name: Docker info
+        run: docker info
+      - name: Create merge Dockerfile
+        run: echo "FROM localhost:5000/${{ env.DOCKER_IMAGE }}:\${TARGETOS}-\${TARGETARCH}" >> docker-file-${{ matrix.registry }}-wyrihaximusnet-github-action-runner
+      - run: cat docker-file-${{ matrix.registry }}-wyrihaximusnet-github-action-runner
+      - name: Merged different arch images into one
         uses: docker/build-push-action@v6
         with:
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ghcr.io/wyrihaximusnet/docker-github-action-runner:latest,ghcr.io/wyrihaximusnet/docker-github-action-runner:${{ steps.time.outputs.time }}
-          platforms: linux/amd64,linux/arm64
+#          push: ${{ github.event_name != 'pull_request' }}
+          push: false
+          tags: ghcr.io/${{ env.DOCKER_IMAGE }}:latest,ghcr.io/${{ env.DOCKER_IMAGE }}:${{ steps.time.outputs.time }}
+          platforms: ${{ join(fromJson(needs.supported-arch-matrix.outputs.arch), ',') }}
diff --git a/.github/workflows/old.yml b/.github/workflows/old.yml
new file mode 100644
index 0000000..3cef987
--- /dev/null
+++ b/.github/workflows/old.yml
@@ -0,0 +1,36 @@
+name: Continuous Integration
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+  schedule:
+    - cron:  '0 0 * * 0'
+jobs:
+  build:
+    name: Build Image
+    runs-on: ubuntu-latest
+    steps:
+      - name: Get Time
+        id: time
+        uses: nanzm/get-time-action@v2.0
+        with:
+          format: 'YYYY.MM.DD'
+      - uses: actions/checkout@v4
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v3
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3
+      - name: Login to GitHub Container Registry
+        if: github.event_name != 'pull_request'
+        uses: docker/login-action@v3
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GHCR_TOKEN }}
+      - name: Build and push
+        uses: docker/build-push-action@v6
+        with:
+          push: ${{ github.event_name != 'pull_request' }}
+          tags: ghcr.io/wyrihaximusnet/docker-github-action-runner:latest,ghcr.io/wyrihaximusnet/docker-github-action-runner:${{ steps.time.outputs.time }}
+          platforms: linux/amd64,linux/arm64
diff --git a/Dockerfile b/Dockerfile
index c9625eb..a1f3db4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,10 @@
 # syntax=docker/dockerfile:1
+# hadolint ignore=DL3007
 FROM ghcr.io/actions/actions-runner:latest
 
 USER root
 
+# hadolint ignore=DL3008,DL3047,DL3009,DL4006,DL3015,DL4001
 RUN (echo 'DPkg::Post-Invoke {"/bin/rm -f /var/cache/apt/archives/*.deb || true";};' | tee /etc/apt/apt.conf.d/clean) &&\
     apt-get update &&\
     apt-get upgrade -y &&\