name: Deploy Production on: workflow_dispatch: inputs: image_tag: description: Image tag to promote to production, for example sha- required: true type: string permissions: contents: read jobs: deploy: name: Deploy To Production runs-on: ubuntu-latest environment: production timeout-minutes: 30 concurrency: group: deploy-production cancel-in-progress: false steps: - uses: actions/checkout@v4 - id: vars name: Resolve image refs run: | owner="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" repo="$(basename '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" image_tag="${{ inputs.image_tag }}" echo "app_image=ghcr.io/${owner}/${repo}-app:${image_tag}" >> "$GITHUB_OUTPUT" echo "migrator_image=ghcr.io/${owner}/${repo}-migrator:${image_tag}" >> "$GITHUB_OUTPUT" - name: Prepare SSH env: SSH_PRIVATE_KEY: ${{ secrets.PROD_SSH_KEY }} SSH_HOST: ${{ secrets.PROD_SSH_HOST }} SSH_PORT: ${{ secrets.PROD_SSH_PORT }} run: | install -m 700 -d ~/.ssh printf '%s\n' "${SSH_PRIVATE_KEY}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -p "${SSH_PORT:-22}" -H "${SSH_HOST}" >> ~/.ssh/known_hosts - name: Bundle deploy assets run: tar czf deploy-bundle.tgz docker-compose.cicd.yml tooling/deploy - name: Copy deploy assets to production env: SSH_PORT: ${{ secrets.PROD_SSH_PORT }} run: | ssh -p "${SSH_PORT:-22}" "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}" \ "mkdir -p '${{ secrets.PROD_DEPLOY_PATH }}'" scp -P "${SSH_PORT:-22}" deploy-bundle.tgz \ "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}:${{ secrets.PROD_DEPLOY_PATH }}/deploy-bundle.tgz" - name: Run production deployment env: APP_IMAGE: ${{ steps.vars.outputs.app_image }} MIGRATOR_IMAGE: ${{ steps.vars.outputs.migrator_image }} APP_HOST_PORT: ${{ secrets.PROD_APP_HOST_PORT }} GHCR_USERNAME: ${{ secrets.PROD_GHCR_USERNAME }} GHCR_TOKEN: ${{ secrets.PROD_GHCR_TOKEN }} SSH_PORT: ${{ secrets.PROD_SSH_PORT }} run: | cat > deploy.env <