# One job on purpose. The checks (eslint, vue-tsc, cargo test) live in the # Dockerfile stages, so this workflow needs a single job image — one that has # docker, git and node. Splitting the checks into their own jobs would mean # `container: rust:...`, and a JavaScript action like `actions/checkout` needs # node inside the job container, which the rust image does not have. # # Deliberately no third-party actions beyond `checkout`: a self-hosted Forgejo # runner resolves `uses:` against its own mirror, and `docker/*` is usually not # there. Plain docker commands work everywhere. name: build on: push: branches: [main] workflow_dispatch: env: IMAGE: registry.tibiscuit.ch/vm-selector jobs: image: runs-on: ubuntu-latest env: # Secrets are read into the environment here, not interpolated into the # shell commands below: `${{ secrets.X }}` inside a `run:` ends up in the # process arguments, and the `secrets` context is not usable in `if:`. REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} PORTAINER_WEBHOOK: ${{ secrets.PORTAINER_WEBHOOK }} steps: - uses: actions/checkout@v4 # Turns itself on as soon as the registry has authentication and the two # secrets exist; skipped while the registry is open. - name: Log in to the registry if: env.REGISTRY_USERNAME != '' run: echo "$REGISTRY_PASSWORD" | docker login registry.tibiscuit.ch -u "$REGISTRY_USERNAME" --password-stdin - name: Build and push run: | set -eu docker build \ --build-arg GIT_HASH="${{ github.sha }}" \ --tag "$IMAGE:${{ github.sha }}" \ --tag "$IMAGE:latest" \ . docker push "$IMAGE:${{ github.sha }}" docker push "$IMAGE:latest" # Portainer re-pulls the image and recreates the stack. Enable # "Re-pull image" on the webhook, otherwise :latest stays the old layer. - name: Redeploy on Portainer if: env.PORTAINER_WEBHOOK != '' run: curl -fsS -X POST "$PORTAINER_WEBHOOK"