ci(release): package web artifact on runtime builder
This commit is contained in:
+33
-21
@@ -99,7 +99,25 @@ jobs:
|
||||
chmod +x scripts/build_release_images.sh
|
||||
scripts/build_release_images.sh "${GITHUB_REF_NAME}"
|
||||
|
||||
- name: Upload runtime image artifact
|
||||
- name: Build web artifact
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
docker run --rm \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace/apps/web \
|
||||
docker.m.daocloud.io/library/node:20 \
|
||||
sh -lc 'npm ci && npm run build'
|
||||
|
||||
- name: Package release source artifact
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
mkdir -p dist/release-artifacts
|
||||
tar --exclude=.git --exclude=apps/web/node_modules \
|
||||
-czf "dist/release-artifacts/xiaoxia-release-${GITHUB_REF_NAME}.tar.gz" .
|
||||
|
||||
- name: Upload runtime image and release artifacts
|
||||
shell: sh
|
||||
env:
|
||||
PRODUCTION_SSH_HOST: ${{ secrets.PRODUCTION_SSH_HOST }}
|
||||
@@ -121,6 +139,8 @@ jobs:
|
||||
ssh-keyscan -H "$production_host" >> ~/.ssh/known_hosts
|
||||
scp -i "$key_path" "dist/release-images/xiaoxia-runtime-images-${GITHUB_REF_NAME}.tar" \
|
||||
"$production_user@$production_host:/var/lib/xiaoxia-saas-production/runtime-images-${GITHUB_REF_NAME}.tar"
|
||||
scp -i "$key_path" "dist/release-artifacts/xiaoxia-release-${GITHUB_REF_NAME}.tar.gz" \
|
||||
"$production_user@$production_host:/var/lib/xiaoxia-saas-production/release-${GITHUB_REF_NAME}.tar.gz"
|
||||
|
||||
deploy-production:
|
||||
name: Deploy Production
|
||||
@@ -131,29 +151,20 @@ jobs:
|
||||
needs: build-production-runtime-images
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
- name: Sync release artifact to production workspace
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
archive_url="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
|
||||
wget --header="Authorization: token ${GITHUB_TOKEN}" -O /tmp/repo.tar.gz "$archive_url"
|
||||
tar -xzf /tmp/repo.tar.gz --strip-components=1 -C .
|
||||
rm -f /tmp/repo.tar.gz
|
||||
|
||||
- name: Sync code to production workspace
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
tar --exclude=.git -cf - . | docker run --rm -i \
|
||||
-v /:/host \
|
||||
docker:27-cli \
|
||||
sh -lc '
|
||||
set -eu
|
||||
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 -xf - -C /host/var/lib/xiaoxia-saas-production/repo
|
||||
'
|
||||
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
|
||||
@@ -172,6 +183,7 @@ jobs:
|
||||
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 '
|
||||
|
||||
@@ -54,11 +54,13 @@ On `v*` tag push:
|
||||
|
||||
1. `build-production-runtime-images` runs on `runtime-builder`.
|
||||
2. It executes `scripts/build_release_images.sh <tag>`.
|
||||
3. It uploads `dist/release-images/xiaoxia-runtime-images-<tag>.tar` to production.
|
||||
4. `deploy-production` runs after the build job succeeds.
|
||||
5. `deploy-production` loads `/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar` and restarts API/Worker/Web.
|
||||
3. It builds `apps/web/dist` in a Node Docker container, not on production.
|
||||
4. It packages `release-<tag>.tar.gz` with the prebuilt Web dist.
|
||||
5. It uploads both `runtime-images-<tag>.tar` and `release-<tag>.tar.gz` to production.
|
||||
6. `deploy-production` runs after the build job succeeds.
|
||||
7. `deploy-production` extracts the prebuilt release artifact, loads `/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar`, and restarts API/Worker/Web.
|
||||
|
||||
If the tar is missing, production deploy must fail.
|
||||
If either the release tar or runtime image tar is missing, production deploy must fail.
|
||||
|
||||
## Preflight checks on runner
|
||||
|
||||
|
||||
@@ -161,12 +161,19 @@ def test_gitea_production_deploy_requires_runtime_builder_job():
|
||||
|
||||
assert "runs-on: runtime-builder" in build_section
|
||||
assert "scripts/build_release_images.sh \"${GITHUB_REF_NAME}\"" in build_section
|
||||
assert "docker.m.daocloud.io/library/node:20" in build_section
|
||||
assert "npm ci && npm run build" in build_section
|
||||
assert "dist/release-artifacts/xiaoxia-release-${GITHUB_REF_NAME}.tar.gz" in build_section
|
||||
assert "PRODUCTION_SSH_HOST" in build_section
|
||||
assert "PRODUCTION_SSH_USER" in build_section
|
||||
assert "PRODUCTION_SSH_KEY" in build_section
|
||||
assert "/root/.ssh/xiaoxia_runtime_builder" in build_section
|
||||
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 "apps/web/dist/index.html" in production_section
|
||||
|
||||
|
||||
def test_build_host_runbook_requires_off_production_runtime_builds():
|
||||
@@ -189,6 +196,8 @@ def test_runtime_builder_runner_runbook_matches_workflow():
|
||||
assert "/root/.ssh/xiaoxia_runtime_builder" in runbook
|
||||
assert "Do not install this runner on the current production host" in runbook
|
||||
assert "production deploy waits for the image job" in runbook
|
||||
assert "release-<tag>.tar.gz" in runbook
|
||||
assert "prebuilt Web dist" in runbook
|
||||
|
||||
|
||||
def test_deployment_docs_forbid_production_runtime_builds():
|
||||
|
||||
Reference in New Issue
Block a user