name: Deploy Production # Production promotion. The APPROVAL GATE is the git tag: production only ever # deploys a tagged release cut on main (see docs/WORKFLOW.md §5). Cutting the tag # is the deliberate, auditable "approve to go live" action — and the tag doubles # as the rollback target. workflow_dispatch adds a manual "Run workflow" button # for re-deploys/rollbacks. # # STATUS: inactive until (a) the Linux production server exists and (b) a # self-hosted Gitea runner is registered on it with labels [self-hosted, production]. # Tag pushes before then will queue harmlessly. This file is the wiring, ready to # switch on — review the deploy step for your server before first use. on: push: tags: ['v*'] workflow_dispatch: inputs: ref: description: 'Tag or commit to deploy (e.g. v1.2.0)' required: true jobs: deploy: runs-on: [self-hosted, production] steps: - uses: actions/checkout@v4 with: # Deploy the exact tag that triggered the run (immutable), or the # ref given to a manual dispatch. ref: ${{ github.event.inputs.ref || github.ref_name }} fetch-depth: 0 - name: Deploy release to production run: | echo "Deploying ${{ github.event.inputs.ref || github.ref_name }} to production" # deploy/.env lives on the server (never in git). up.sh validates it, # builds the Linux images, applies EF migrations on boot, and starts # the stack behind the nginx reverse proxy. ./deploy/up.sh --proxy - name: Smoke check run: | sleep 5 curl -fsS http://localhost/ >/dev/null && echo "Prod responding on :80" || \ { echo "Smoke check failed"; exit 1; }