name: Promote production on: workflow_dispatch: inputs: sha: description: Full git SHA already published to GHCR (same digest used by staging) required: true type: string confirm: description: Type PRODUCTION to confirm promotion of the given SHA required: true type: string permissions: contents: read packages: write concurrency: group: deploy-production cancel-in-progress: false env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: promote: name: promote-production runs-on: ubuntu-latest steps: - name: Guard confirmation run: | if [ "${{ inputs.confirm }}" != "PRODUCTION" ]; then echo "Confirmation must be exactly PRODUCTION" >&2 exit 1 fi - name: Checkout repository scripts uses: actions/checkout@v4 - name: Set image metadata id: meta run: | SHA="${{ inputs.sha }}" SHORT_SHA="${SHA:0:7}" IMAGE="${REGISTRY}/${IMAGE_NAME}" IMAGE="$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]')" echo "sha=${SHA}" >> "$GITHUB_OUTPUT" echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT" echo "image=${IMAGE}" >> "$GITHUB_OUTPUT" - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Point :production at existing SHA digest (no rebuild) run: | docker buildx imagetools create \ --tag "${{ steps.meta.outputs.image }}:production" \ "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.sha }}" - name: Deploy production on Dokploy env: DOKPLOY_URL: ${{ secrets.DOKPLOY_URL }} DOKPLOY_API_KEY: ${{ secrets.DOKPLOY_API_KEY }} DOKPLOY_COMPOSE_ID: ${{ secrets.DOKPLOY_PRODUCTION_COMPOSE_ID }} DEPLOY_TITLE: "production ${{ steps.meta.outputs.short_sha }}" run: | chmod +x scripts/deploy/dokploy-deploy.sh ./scripts/deploy/dokploy-deploy.sh - name: Smoke production env: SMOKE_BASE_URL: ${{ secrets.PRODUCTION_URL }} run: | chmod +x scripts/deploy/smoke.sh ./scripts/deploy/smoke.sh