name: Build and Push Image on: [push] jobs: test: name: Unit tests runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout uses: actions/checkout@v4 # NOTE: no actions/setup-python here. That action downloads a Python # build from GitHub, which this runner cannot reach reliably - the job # hung on it. The runner image already carries a usable python3, so # the tests use it directly. # # The version is checked against the container image's Python so the # tests run on the same interpreter the app ships in. - name: Show the Python version run: | python3 --version python3 -c "import sys; assert sys.version_info[:2] >= (3, 11), \ 'the runner python is too old for the pinned requirements'" - name: Install dependencies run: | python3 -m venv .venv . .venv/bin/activate pip install --upgrade pip pip install -r requirements-dev.txt - name: Run tests run: | . .venv/bin/activate python -m pytest tests/ -q # NOTE: the build job deliberately does NOT have a kubeconfig. The # `KUBEC_CONFIG_BUILDX` secret is cluster-admin-equivalent, and a build step # that has no need of the cluster should not be able to read it. The deploy # step, added in a later PR, gets its own job with the kubeconfig - that way # a compromised dependency in the build cannot reach the cluster. build: name: Build and push image runs-on: ubuntu-latest container: catthehacker/ubuntu:act-latest needs: test if: gitea.ref == 'refs/heads/master' # A build that has not finished in 15 minutes is wedged — the qemu # multi-arch crash used to hang the buildkit pod for exactly this long. # A timeout stops it occupying a runner indefinitely. timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx (remote -> persistent buildkit daemon) uses: docker/setup-buildx-action@v3 with: # The `kubernetes` driver talks to the cluster API, which needs the # k3s CA certificate. The job container does not have it, so the # bootstrap failed with "x509: certificate signed by unknown # authority". # # The `remote` driver talks straight to the buildkit daemon that is # already running in the cluster, so no cluster API access (and no # kubeconfig) is needed at all. This is the same pattern the # wedding-photos workflow uses successfully. # # NOTE: `endpoint` must be passed as a top-level key. The action # appends it as the POSITIONAL argument to # `buildx create --driver remote `; putting it in # driver-opts instead yields "ERROR: no remote endpoint provided". driver: remote endpoint: tcp://buildkit.gitea-runner.svc:1234 - name: Login to Docker Registry uses: docker/login-action@v3 with: registry: git.aridgwayweb.com username: armistace password: ${{ secrets.REG_PASSWORD }} - name: Build Base Image uses: docker/build-push-action@v5 with: context: . push: true file: base.Dockerfile # amd64 only. A multi-arch build runs qemu emulation, which crashes # the buildkit pod on this NUC (exit 255, SandboxChanged) and the # build then hangs for many minutes. The cluster is amd64. platforms: linux/amd64 tags: | git.aridgwayweb.com/armistace/beer_base_image:latest - name: Build and Push uses: docker/build-push-action@v5 with: context: . push: true file: flask.Dockerfile platforms: linux/amd64 tags: | git.aridgwayweb.com/armistace/beer-data:latest