name: build-and-publish on: push: branches: [main] # Files that can't change the image. Skipping them avoids a pointless rebuild that Watchtower # would then redeploy — a few seconds of downtime on a live site for a docs-only commit. paths-ignore: ["renovate.json", "**.md"] # Lets `rebuild-all-apps.sh` force a rebuild (e.g. to roll out an urgent platform fix immediately # instead of waiting for a Renovate bump PR). workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Tests run BEFORE the image is built, and they gate it. # # They cannot run inside `docker build` — Testcontainers needs a Docker daemon and there is none # in a build. So Maven runs as a sibling container instead, mounting the volume act_runner gave # this job (discovered from our own container rather than guessed) and sharing the host network so # the ports Testcontainers publishes are reachable as localhost. # Tests run BEFORE the image and gate it. # # They cannot run inside `docker build` — Testcontainers needs a Docker daemon and a build has # none. Maven runs as a sibling container instead, mounting the volume act_runner gave this job # and sharing the host network so the ports Testcontainers publishes are reachable as localhost. # # The volume is mounted at the full repo path, not at /workspace, so it is matched on # GITHUB_WORKSPACE rather than a guess. - name: Test run: | set -euo pipefail VOL=$(docker inspect "$(hostname)" \ --format "{{range .Mounts}}{{if eq .Destination \"$GITHUB_WORKSPACE\"}}{{.Name}}{{end}}{{end}}") if [ -z "$VOL" ]; then echo "could not find this job's workspace volume — refusing to skip the tests" >&2 exit 1 fi echo "workspace volume: $VOL" docker run --rm --network host \ -v "$VOL":/w \ -v /var/run/docker.sock:/var/run/docker.sock \ -e TESTCONTAINERS_RYUK_DISABLED=true \ -e MAVEN_USER="${{ secrets.REGISTRY_USER }}" \ -e MAVEN_TOKEN="${{ secrets.REGISTRY_TOKEN }}" \ -w /w \ maven:3.9-eclipse-temurin-25 \ mvn -B -ntp -s .gitea/ci-settings.xml -DskipFrontend=true verify - name: Log in to the Gitea container registry run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.thebennett.net -u "${{ secrets.REGISTRY_USER }}" --password-stdin # The platform is now referenced by an immutable RELEASE version, so a cached maven layer can't # silently hold an old build — layer caching is safe again (and much faster). - name: Build image env: DOCKER_BUILDKIT: "1" MAVEN_USER: ${{ secrets.REGISTRY_USER }} MAVEN_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | docker build \ --secret id=maven_user,env=MAVEN_USER \ --secret id=maven_token,env=MAVEN_TOKEN \ --build-arg GIT_SHA=${{ github.sha }} \ -t git.thebennett.net/reformedwitness/confessions-of-grace:latest \ -t git.thebennett.net/reformedwitness/confessions-of-grace:${{ github.sha }} . - name: Scan image (Trivy) run: | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --no-progress \ git.thebennett.net/reformedwitness/confessions-of-grace:latest || true docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed \ --pkg-types library --exit-code 1 --no-progress \ git.thebennett.net/reformedwitness/confessions-of-grace:latest - name: Push image run: | docker push git.thebennett.net/reformedwitness/confessions-of-grace:latest docker push git.thebennett.net/reformedwitness/confessions-of-grace:${{ github.sha }}