ci: gate production deploy on tests
Some checks failed
CI / test (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped

This commit is contained in:
2026-09-11 13:26:59 +03:00
parent 2d19eef9c2
commit 880ac6c53e
3 changed files with 64 additions and 64 deletions

View File

@@ -5,6 +5,7 @@ on:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
test:
@@ -22,3 +23,65 @@ jobs:
- run: python -m pip install -r requirements.txt
- run: python -m pytest -q
- run: node --check app/static/admin.js
deploy:
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'workflow_dispatch'
needs: test
runs-on: ubuntu-latest
concurrency:
group: production-deploy
cancel-in-progress: false
env:
PROD_PATH: /srv/miem_workers
RELEASE_NAME: miem-workers-release-${{ github.run_id }}.tar
steps:
- uses: actions/checkout@v4
- name: Prepare release
shell: bash
run: |
set -euo pipefail
tar --exclude=.git --exclude=.env -cf "$RUNNER_TEMP/$RELEASE_NAME" .
printf '%s\n' "$PROD_SSH_KEY" > "$RUNNER_TEMP/deploy_key"
printf '%s\n' "$PROD_KNOWN_HOSTS" > "$RUNNER_TEMP/known_hosts"
chmod 600 "$RUNNER_TEMP/deploy_key" "$RUNNER_TEMP/known_hosts"
env:
PROD_SSH_KEY: ${{ secrets.PROD_SSH_KEY }}
PROD_KNOWN_HOSTS: ${{ secrets.PROD_KNOWN_HOSTS }}
- name: Upload release
shell: bash
run: |
set -euo pipefail
scp -i "$RUNNER_TEMP/deploy_key" \
-o BatchMode=yes \
-o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" \
"$RUNNER_TEMP/$RELEASE_NAME" \
"$PROD_USER@$PROD_HOST:/tmp/$RELEASE_NAME"
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}
- name: Deploy and verify
shell: bash
run: |
set -euo pipefail
ssh -i "$RUNNER_TEMP/deploy_key" \
-o BatchMode=yes \
-o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" \
"$PROD_USER@$PROD_HOST" \
"PROD_PATH='$PROD_PATH' RELEASE_NAME='$RELEASE_NAME' bash -s" <<'REMOTE'
set -euo pipefail
cd "$PROD_PATH"
mkdir -p "$HOME/backups/miem_workers"
backup="$HOME/backups/miem_workers/miem_workers-$(date +%Y%m%d-%H%M%S).sql"
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > "$backup"
docker run --rm \
-v "/tmp/$RELEASE_NAME:/src/release.tar:ro" \
-v "$PROD_PATH":/dst \
alpine:3.20 sh -c 'tar -xf /src/release.tar -C /dst'
docker compose up -d --build
curl --fail --silent --show-error http://127.0.0.1:8000/api/health
docker compose ps
rm -f "/tmp/$RELEASE_NAME"
REMOTE
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}

View File

@@ -1,63 +0,0 @@
name: Deploy production
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
env:
PROD_PATH: /srv/miem_workers
steps:
- uses: actions/checkout@v4
- name: Prepare release
shell: bash
run: |
set -euo pipefail
tar --exclude=.git --exclude=.env -cf "$RUNNER_TEMP/miem-workers-release.tar" .
printf '%s\n' "$PROD_SSH_KEY" > "$RUNNER_TEMP/deploy_key"
printf '%s\n' "$PROD_KNOWN_HOSTS" > "$RUNNER_TEMP/known_hosts"
chmod 600 "$RUNNER_TEMP/deploy_key" "$RUNNER_TEMP/known_hosts"
env:
PROD_SSH_KEY: ${{ secrets.PROD_SSH_KEY }}
PROD_KNOWN_HOSTS: ${{ secrets.PROD_KNOWN_HOSTS }}
- name: Upload release
shell: bash
run: |
set -euo pipefail
scp -i "$RUNNER_TEMP/deploy_key" \
-o BatchMode=yes \
-o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" \
"$RUNNER_TEMP/miem-workers-release.tar" \
"$PROD_USER@$PROD_HOST:/tmp/miem-workers-release.tar"
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}
- name: Deploy and verify
shell: bash
run: |
set -euo pipefail
ssh -i "$RUNNER_TEMP/deploy_key" \
-o BatchMode=yes \
-o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" \
"$PROD_USER@$PROD_HOST" \
"PROD_PATH='$PROD_PATH' bash -s" <<'REMOTE'
set -euo pipefail
cd "$PROD_PATH"
mkdir -p "$HOME/backups/miem_workers"
backup="$HOME/backups/miem_workers/miem_workers-$(date +%Y%m%d-%H%M%S).sql"
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > "$backup"
docker run --rm \
-v /tmp/miem-workers-release.tar:/src/release.tar:ro \
-v "$PROD_PATH":/dst \
alpine:3.20 sh -c 'tar -xf /src/release.tar -C /dst'
docker compose up -d --build
curl --fail --silent --show-error http://127.0.0.1:8000/api/health
docker compose ps
rm -f /tmp/miem-workers-release.tar
REMOTE
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}

View File

@@ -122,7 +122,7 @@ docker compose exec postgres pg_dump -U miem miem_workers > backup.sql
docker compose down
```
Production deploy выполняется workflow `Deploy production` после push в `main` или вручную. Для него нужны Actions secrets `PROD_HOST`, `PROD_USER`, `PROD_SSH_KEY` и `PROD_KNOWN_HOSTS`; `.env` и ключи в репозиторий не добавляются. Перед обновлением workflow сохраняет PostgreSQL backup в домашний каталог deploy-пользователя, пересобирает `api` и `worker` и проверяет `/api/health`.
Production deploy выполняется job `deploy` workflow `CI` после успешного `test` на push в `main` или вручную. Для него нужны Actions secrets `PROD_HOST`, `PROD_USER`, `PROD_SSH_KEY` и `PROD_KNOWN_HOSTS`; `.env` и ключи в репозиторий не добавляются. Перед обновлением workflow сохраняет PostgreSQL backup в домашний каталог deploy-пользователя, пересобирает `api` и `worker` и проверяет `/api/health`. Одновременно выполняется только один production deploy.
## Проверки