name: Deploy on: push: branches: [main] tags: ["v*"] # Required repository secrets: # REGISTRY registry hostname (git.librete.ch) # REGISTRY_USER robot account or PAT username (libretech-bot) # REGISTRY_PASS PAT with write:package # DEPLOY_HOST SSH target, e.g. root@cloud.librete.ch # DEPLOY_KEY passphrase-less private key (PEM) # DEPLOY_PATH remote stack dir (/srv/librenotes) # HEALTH_URL https://ln.cloud.librete.ch/healthz # # Required repository variable: # DEPLOY_ENABLED set to "true" to enable the workflow # # Image: ${REGISTRY}/public/librenotes # main pushes → :main + : # tag pushes → : + :latest # # The host's /srv/librenotes/.env pins LIBRENOTES_IMAGE once # (e.g. =git.librete.ch/public/librenotes:main). Main pushes # update :main rolling so a `compose pull` picks up the new image # without rewriting any file. Tag pin / rollback is a manual edit # of LIBRENOTES_IMAGE in .env followed by `compose pull && up -d`. jobs: deploy: runs-on: ubuntu-latest # Custom Gitea runner image: Ubuntu 24.04 + docker CLI + node + git # + perl + ssh, runner user pre-joined to docker gid 998 so the # auto-mounted /var/run/docker.sock is writable without --user root. container: image: git.librete.ch/libretech/runner-image:v2 timeout-minutes: 20 if: ${{ vars.DEPLOY_ENABLED == 'true' }} steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ${{ secrets.REGISTRY }} username: ${{ secrets.REGISTRY_USER }} password: ${{ secrets.REGISTRY_PASS }} - id: meta uses: docker/metadata-action@v5 with: images: ${{ secrets.REGISTRY }}/public/librenotes tags: | type=ref,event=branch type=ref,event=tag type=sha,format=short type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }} - uses: docker/build-push-action@v6 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | VERSION=${{ steps.meta.outputs.version }} BUILDTIME=${{ github.event.head_commit.timestamp }} - name: Deploy to host env: DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }} HEALTH_URL: ${{ secrets.HEALTH_URL }} run: | mkdir -p ~/.ssh && chmod 700 ~/.ssh printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/id_deploy chmod 600 ~/.ssh/id_deploy ssh -i ~/.ssh/id_deploy \ -o StrictHostKeyChecking=accept-new \ "$DEPLOY_HOST" \ "set -e cd '$DEPLOY_PATH' git pull --ff-only docker compose -f compose.yaml -f compose.netcup.yaml pull docker compose -f compose.yaml -f compose.netcup.yaml up -d --remove-orphans" # Wait up to 60s for /healthz to return 200. for i in $(seq 1 12); do curl -fsS "$HEALTH_URL" >/dev/null && exit 0 sleep 5 done echo "deploy health check failed"; exit 1