name: Verify and deploy API on: push: branches: [main] pull_request: workflow_dispatch: concurrency: group: pk-lab-server-production cancel-in-progress: true jobs: verify-deploy: runs-on: ubuntu-latest container: image: docker:27-cli timeout-minutes: 30 env: SOURCE_SERVER: ${{ gitea.server_url }} SOURCE_REPOSITORY: ${{ gitea.repository }} SOURCE_REVISION: ${{ gitea.sha }} DEPLOY_PORT: ${{ vars.DEPLOY_PORT || '18082' }} PUBLIC_BASE_URL: ${{ vars.PUBLIC_BASE_URL || '' }} CORS_ORIGINS: ${{ vars.CORS_ORIGINS || 'http://47.83.180.156:3000,http://47.83.180.156:3002,http://localhost:3000,http://localhost:3002' }} TEST_AUTH_ENABLED: ${{ vars.TEST_AUTH_ENABLED || 'true' }} POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} XHS_HUB_APP_ID: ${{ secrets.XHS_HUB_APP_ID }} XHS_HUB_APP_SECRET: ${{ secrets.XHS_HUB_APP_SECRET }} XHS_RICE_APP_ID: ${{ secrets.XHS_RICE_APP_ID }} XHS_RICE_APP_SECRET: ${{ secrets.XHS_RICE_APP_SECRET }} steps: - name: Prepare runner and fetch exact revision env: SOURCE_TOKEN: ${{ secrets.GITEA_TOKEN || gitea.token }} run: | set -eu apk add --no-cache python3 curl docker info >/dev/null python3 - <<'PY' import io, os, shutil, tarfile, tempfile, urllib.request from pathlib import Path url = f"{os.environ['SOURCE_SERVER'].rstrip('/')}/api/v1/repos/{os.environ['SOURCE_REPOSITORY']}/archive/{os.environ['SOURCE_REVISION']}.tar.gz" request = urllib.request.Request(url, headers={'Authorization': 'token ' + os.environ['SOURCE_TOKEN']}) with urllib.request.urlopen(request, timeout=60) as response: data = response.read() with tempfile.TemporaryDirectory() as directory: with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as archive: archive.extractall(directory, filter='data') roots = list(Path(directory).iterdir()) if len(roots) != 1: raise RuntimeError('Unexpected archive structure') shutil.copytree(roots[0], Path.cwd(), dirs_exist_ok=True) PY - name: Run checks in image build run: docker build --target test --tag "pk-lab-server:$SOURCE_REVISION-test" . - name: Build runtime image if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' run: docker build --target runtime --tag "pk-lab-server:$SOURCE_REVISION" . - name: Update permanent stack without deleting data if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' run: | set -eu test -n "$POSTGRES_PASSWORD" export DEPLOY_IMAGE="pk-lab-server:$SOURCE_REVISION" sh scripts/deploy.sh curl --fail --silent --show-error "http://127.0.0.1:$DEPLOY_PORT/health" - name: Probe public endpoint if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' && env.PUBLIC_BASE_URL != '' run: curl --fail --silent --show-error --connect-timeout 10 --max-time 20 "${PUBLIC_BASE_URL%/}/health"