87 lines
3.1 KiB
YAML
87 lines
3.1 KiB
YAML
name: Deploy Production
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
image_tag:
|
|
description: Image tag to promote to production, for example sha-<commit>
|
|
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 <<EOF
|
|
APP_IMAGE=${APP_IMAGE}
|
|
MIGRATOR_IMAGE=${MIGRATOR_IMAGE}
|
|
APP_HOST_PORT=${APP_HOST_PORT}
|
|
GHCR_USERNAME=${GHCR_USERNAME}
|
|
GHCR_TOKEN=${GHCR_TOKEN}
|
|
EOF
|
|
scp -P "${SSH_PORT:-22}" deploy.env \
|
|
"${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}:${{ secrets.PROD_DEPLOY_PATH }}/deploy.env"
|
|
ssh -p "${SSH_PORT:-22}" "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}" 'bash -se' <<'EOF'
|
|
set -euo pipefail
|
|
cd "${{ secrets.PROD_DEPLOY_PATH }}"
|
|
tar xzf deploy-bundle.tgz
|
|
rm -f deploy-bundle.tgz
|
|
set -a
|
|
. ./deploy.env
|
|
set +a
|
|
bash tooling/deploy/deploy-compose.sh production
|
|
rm -f deploy.env
|
|
EOF
|