Files
miem_workers/.gitea/workflows/ci.yml
T
codex 5128fac6e5
CI / test (pull_request) Successful in 10m22s
CI / Fingerprint diagnostics (production deployment temporarily disabled) (pull_request) Has been skipped
feat: add first-login usage guide
2026-10-12 11:05:04 +03:00

125 lines
4.7 KiB
YAML

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
diagnostic_only:
description: 'Print key fingerprint; production deployment is temporarily disabled'
type: boolean
default: true
jobs:
test:
runs-on: ubuntu-latest
env:
DATABASE_URL: sqlite:///./ci.db
PYTHONUNBUFFERED: "1"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install -r requirements.txt
- run: python -m pytest -q
- run: node --check app/static/admin.js
- run: node --check app/static/council.js
- run: node --check app/static/users.js
- run: node --check app/static/guide.js
- run: sh -n infra/postgres-backup.sh
- run: sh -n infra/install-postgres-backup-cron.sh
deploy:
# Production deployment is disabled until separate Workers deployment access is installed.
name: Fingerprint diagnostics (production deployment temporarily disabled)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.diagnostic_only == 'true'
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
id: prepare
shell: bash
run: |
set +x
set -euo pipefail
backend_version="$(sed -n 's/^BACKEND_VERSION = "\(.*\)"$/\1/p' app/version.py)"
case "$backend_version" in
''|*[!0-9.]*) exit 1 ;;
esac
echo "backend_version=$backend_version" >> "$GITHUB_OUTPUT"
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: Deployment key fingerprint
shell: bash
run: |
set +x
set -euo pipefail
trap 'rm -f "$RUNNER_TEMP/deploy_key" "$RUNNER_TEMP/known_hosts"' EXIT
ssh-keygen -y -P '' -f "$RUNNER_TEMP/deploy_key" | ssh-keygen -lf - -E sha256 | awk '{print $2}'
- name: Upload release
if: ${{ false }}
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:$RELEASE_NAME"
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}
- name: Deploy and verify
if: ${{ false }}
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' EXPECTED_BACKEND_VERSION='$EXPECTED_BACKEND_VERSION' bash -s" <<'REMOTE'
set -euo pipefail
cd "$PROD_PATH"
release="$HOME/$RELEASE_NAME"
test -f "$release"
archive_version="$(tar -xOf "$release" ./app/version.py | sed -n 's/^BACKEND_VERSION = "\(.*\)"$/\1/p')"
test "$archive_version" = "$EXPECTED_BACKEND_VERSION"
docker run --rm \
-v "$release:/src/release.tar:ro" \
-v "$PROD_PATH":/dst \
alpine:3.20 sh -c 'tar -xf /src/release.tar -C /dst'
sh /srv/miem_workers/infra/install-postgres-backup-cron.sh
docker compose up -d --build
runtime_version="$(docker compose exec -T api python -c 'from app.version import BACKEND_VERSION; print(BACKEND_VERSION)')"
test "$runtime_version" = "$EXPECTED_BACKEND_VERSION"
health="$(curl --fail --silent --show-error http://127.0.0.1:8000/api/health)"
case "$health" in
*"\"status\":\"ok\""*"\"backend_version\":\"$EXPECTED_BACKEND_VERSION\""*) ;;
*) echo "Unexpected health response: $health" >&2; exit 1 ;;
esac
docker compose ps
rm -f "$release"
REMOTE
env:
PROD_HOST: ${{ secrets.PROD_HOST }}
PROD_USER: ${{ secrets.PROD_USER }}
EXPECTED_BACKEND_VERSION: ${{ steps.prepare.outputs.backend_version }}