ci(release): deploy production from runtime builder
This commit is contained in:
+32
-43
@@ -148,57 +148,45 @@ jobs:
|
||||
|
||||
deploy-production:
|
||||
name: Deploy Production
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker:27-cli
|
||||
runs-on: runtime-builder
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: build-production-runtime-images
|
||||
|
||||
steps:
|
||||
- name: Sync release artifact to production workspace
|
||||
- name: Deploy production over SSH
|
||||
shell: sh
|
||||
env:
|
||||
PRODUCTION_SSH_HOST: ${{ secrets.PRODUCTION_SSH_HOST }}
|
||||
PRODUCTION_SSH_USER: ${{ secrets.PRODUCTION_SSH_USER }}
|
||||
PRODUCTION_SSH_KEY: ${{ secrets.PRODUCTION_SSH_KEY }}
|
||||
run: |
|
||||
set -eu
|
||||
docker run --rm -e GITHUB_REF_NAME="${GITHUB_REF_NAME}" -v /:/host docker:27-cli sh -lc '
|
||||
set -eu
|
||||
release_tar="/host/var/lib/xiaoxia-saas-production/release-${GITHUB_REF_NAME}.tar.gz"
|
||||
test -f "$release_tar"
|
||||
mkdir -p /host/var/lib/xiaoxia-saas-production
|
||||
rm -rf /host/var/lib/xiaoxia-saas-production/repo
|
||||
mkdir -p /host/var/lib/xiaoxia-saas-production/repo
|
||||
tar -xzf "$release_tar" -C /host/var/lib/xiaoxia-saas-production/repo
|
||||
test -f /host/var/lib/xiaoxia-saas-production/repo/apps/web/dist/index.html
|
||||
'
|
||||
|
||||
- name: Verify production env file
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
docker run --rm -v /:/host docker:27-cli sh -lc 'test -f /host/var/lib/xiaoxia-saas-production/.env'
|
||||
|
||||
- name: Prepare production env
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
docker run --rm -v /:/host docker:27-cli sh -lc 'cp /host/var/lib/xiaoxia-saas-production/.env /host/var/lib/xiaoxia-saas-production/repo/.env'
|
||||
|
||||
- name: Deploy production stack
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
docker run --rm \
|
||||
-e GITHUB_REF_NAME="${GITHUB_REF_NAME}" \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /:/host \
|
||||
docker:27-cli sh -lc '
|
||||
chmod +x /host/var/lib/xiaoxia-saas-production/repo/infra/docker/deploy-production.sh && \
|
||||
RELEASE_VERSION="${GITHUB_REF_NAME}" /host/var/lib/xiaoxia-saas-production/repo/infra/docker/deploy-production.sh
|
||||
'
|
||||
|
||||
- name: Verify production health
|
||||
shell: sh
|
||||
run: |
|
||||
production_host="${PRODUCTION_SSH_HOST:-47.98.113.167}"
|
||||
production_user="${PRODUCTION_SSH_USER:-root}"
|
||||
mkdir -p ~/.ssh
|
||||
if [ -n "${PRODUCTION_SSH_KEY:-}" ]; then
|
||||
key_path="$HOME/.ssh/id_ed25519"
|
||||
printf '%s\n' "$PRODUCTION_SSH_KEY" > "$key_path"
|
||||
chmod 600 "$key_path"
|
||||
else
|
||||
key_path="/root/.ssh/xiaoxia_runtime_builder"
|
||||
test -f "$key_path"
|
||||
fi
|
||||
ssh-keyscan -H "$production_host" >> ~/.ssh/known_hosts
|
||||
ssh -i "$key_path" "$production_user@$production_host" \
|
||||
"RELEASE_VERSION='${GITHUB_REF_NAME}' sh -s" <<'REMOTE_DEPLOY'
|
||||
set -eu
|
||||
release_tar="/var/lib/xiaoxia-saas-production/release-${RELEASE_VERSION}.tar.gz"
|
||||
test -f "$release_tar"
|
||||
test -f "/var/lib/xiaoxia-saas-production/runtime-images-${RELEASE_VERSION}.tar"
|
||||
mkdir -p /var/lib/xiaoxia-saas-production
|
||||
rm -rf /var/lib/xiaoxia-saas-production/repo
|
||||
mkdir -p /var/lib/xiaoxia-saas-production/repo
|
||||
tar -xzf "$release_tar" -C /var/lib/xiaoxia-saas-production/repo
|
||||
test -f /var/lib/xiaoxia-saas-production/repo/apps/web/dist/index.html
|
||||
test -f /var/lib/xiaoxia-saas-production/.env
|
||||
cp /var/lib/xiaoxia-saas-production/.env /var/lib/xiaoxia-saas-production/repo/.env
|
||||
sh /var/lib/xiaoxia-saas-production/repo/infra/docker/deploy-production.sh
|
||||
i=0
|
||||
while [ "$i" -lt 30 ]; do
|
||||
if wget -qO- http://127.0.0.1:8001/health; then
|
||||
@@ -208,3 +196,4 @@ jobs:
|
||||
sleep 2
|
||||
done
|
||||
exit 1
|
||||
REMOTE_DEPLOY
|
||||
|
||||
@@ -58,10 +58,10 @@ On `v*` tag push:
|
||||
4. It builds `apps/web/dist` in a Node Docker container, not on production.
|
||||
5. It packages `release-<tag>.tar.gz` with the prebuilt Web dist.
|
||||
6. It uploads both `runtime-images-<tag>.tar` and `release-<tag>.tar.gz` to production.
|
||||
7. `deploy-production` runs after the build job succeeds.
|
||||
8. `deploy-production` extracts the prebuilt release artifact, loads `/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar`, and restarts API/Worker/Web.
|
||||
7. `deploy-production` runs after the build job succeeds, on `runtime-builder`, and drives production over SSH.
|
||||
8. `deploy-production` extracts the prebuilt release artifact on production, loads `/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar`, and restarts API/Worker/Web.
|
||||
|
||||
If either the release tar or runtime image tar is missing, production deploy must fail.
|
||||
If either the release tar or runtime image tar is missing, production deploy must fail. The production deploy job intentionally also runs on `runtime-builder` because Gitea `needs` scheduling previously skipped the downstream `ubuntu-latest` deploy job after a successful cross-runner build.
|
||||
|
||||
## Preflight checks on runner
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ def test_gitea_production_deploy_uses_production_ports():
|
||||
assert "GITHUB_TOKEN: ${{ github.token }}" in workflow
|
||||
assert "WEB_PORT=3001" not in production_section
|
||||
assert "http://127.0.0.1:8001/health" in production_section
|
||||
assert "RELEASE_VERSION=\"${GITHUB_REF_NAME}\"" in production_section
|
||||
assert "RELEASE_VERSION='${GITHUB_REF_NAME}' sh -s" in production_section
|
||||
assert "http://127.0.0.1:8000/health" not in production_section
|
||||
|
||||
|
||||
@@ -173,9 +173,12 @@ def test_gitea_production_deploy_requires_runtime_builder_job():
|
||||
assert "runtime-images-${GITHUB_REF_NAME}.tar" in build_section
|
||||
assert "release-${GITHUB_REF_NAME}.tar.gz" in build_section
|
||||
assert "needs: build-production-runtime-images" in production_section
|
||||
assert "Sync release artifact to production workspace" in production_section
|
||||
assert "release_tar=\"/host/var/lib/xiaoxia-saas-production/release-${GITHUB_REF_NAME}.tar.gz\"" in production_section
|
||||
assert "runs-on: runtime-builder" in production_section
|
||||
assert "Deploy production over SSH" in production_section
|
||||
assert "release_tar=\"/var/lib/xiaoxia-saas-production/release-${RELEASE_VERSION}.tar.gz\"" in production_section
|
||||
assert "runtime-images-${RELEASE_VERSION}.tar" in production_section
|
||||
assert "apps/web/dist/index.html" in production_section
|
||||
assert "sh /var/lib/xiaoxia-saas-production/repo/infra/docker/deploy-production.sh" in production_section
|
||||
|
||||
|
||||
def test_build_host_runbook_requires_off_production_runtime_builds():
|
||||
|
||||
Reference in New Issue
Block a user