四个生产工作流改用同一条发布修订:最近一次代码门禁成功的提交可以发布,后面只多文档不再挡住。生产环境拒绝测试验证码。63 个还没上生产的迁移写了分级、演练脚本和首发步骤。没有点任何生产按钮。 自测:发布修订 7 通过,演练安全 3 通过,tsc 0 错,lint 0 error。本机空库演练在服务角色读人物表处按设计停止(退出码 4,其他人物已确认行数为 0)。 Co-Authored-By: Grok (agent loop)
103 lines
4.4 KiB
YAML
103 lines
4.4 KiB
YAML
name: Jyotish Release Quality Gate (manual only)
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
release-quality-gate:
|
|
runs-on: xiaoxin
|
|
timeout-minutes: 45
|
|
env:
|
|
GITEA_SHA: ${{ gitea.sha }}
|
|
NODE_TOOL_SOURCE_IMAGE: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/node:22-bookworm-slim@sha256:ef343465b6a14bbdf2ab52f6e100ec0659a792464fcf72c462370d88b3df909c
|
|
NODE_TOOL_IMAGE: node:22-bookworm-slim
|
|
steps:
|
|
- name: Checkout current Gitea revision
|
|
run: |
|
|
set -euo pipefail
|
|
git init .
|
|
git remote remove origin 2>/dev/null || true
|
|
git remote add origin https://git.copse.top/root/Jyotisha.git
|
|
git fetch --no-tags origin "$GITEA_SHA"
|
|
git checkout --detach --force "$GITEA_SHA"
|
|
- name: Record whether main is docs-only ahead of the last staging gate
|
|
env:
|
|
GITEA_API_URL: ${{ gitea.api_url }}
|
|
GITEA_REPOSITORY: ${{ gitea.repository }}
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
RESOLVE_MODE: discover
|
|
run: |
|
|
set -euo pipefail
|
|
bash deploy/resolve-release-revision.sh | tee "$RUNNER_TEMP/release-revision.env"
|
|
release_sha="$(awk -F= '$1 == "release_sha" { print $2 }' "$RUNNER_TEMP/release-revision.env")"
|
|
head_sha="$(awk -F= '$1 == "head_sha" { print $2 }' "$RUNNER_TEMP/release-revision.env")"
|
|
[[ "$GITEA_SHA" == "$head_sha" ]] || { echo "dispatch the release gate from current main" >&2; exit 1; }
|
|
{
|
|
echo "### Release revision"
|
|
echo "- head_sha: ${head_sha}"
|
|
echo "- release_sha: ${release_sha}"
|
|
echo "- H relative to R is docs-only (is-docs-only-range.sh exited 0)"
|
|
} >>"$GITHUB_STEP_SUMMARY"
|
|
- name: Prepare pinned Node tooling
|
|
run: |
|
|
set -euo pipefail
|
|
if ! docker image inspect "$NODE_TOOL_SOURCE_IMAGE" >/dev/null 2>&1; then
|
|
for attempt in 1 2 3; do
|
|
if timeout 180 docker pull "$NODE_TOOL_SOURCE_IMAGE"; then
|
|
break
|
|
fi
|
|
if [ "$attempt" -eq 3 ]; then
|
|
echo "Failed to preload $NODE_TOOL_IMAGE after $attempt attempts" >&2
|
|
exit 1
|
|
fi
|
|
sleep $((attempt * 15))
|
|
done
|
|
fi
|
|
docker tag "$NODE_TOOL_SOURCE_IMAGE" "$NODE_TOOL_IMAGE"
|
|
docker image inspect "$NODE_TOOL_IMAGE" >/dev/null
|
|
tool_dir="$(mktemp -d "${RUNNER_TEMP:-/tmp}/jyotisha-node-tools.XXXXXX")"
|
|
container_id="$(docker create "$NODE_TOOL_IMAGE")"
|
|
trap 'docker rm -f "$container_id" >/dev/null 2>&1 || true' EXIT
|
|
docker cp "$container_id:/usr/local/bin/node" "$tool_dir/node"
|
|
docker cp "$container_id:/usr/local/lib/node_modules/npm" "$tool_dir/npm-package"
|
|
docker rm "$container_id" >/dev/null
|
|
trap - EXIT
|
|
ln -s "$tool_dir/npm-package/bin/npm-cli.js" "$tool_dir/npm"
|
|
chmod 0755 "$tool_dir/node" "$tool_dir/npm-package/bin/npm-cli.js"
|
|
test -n "${GITHUB_PATH:-}"
|
|
printf '%s\n' "$tool_dir" >> "$GITHUB_PATH"
|
|
export PATH="$tool_dir:$PATH"
|
|
node --version | grep -Eq '^v22\.'
|
|
npm --version
|
|
- name: Verify runner toolchain
|
|
run: |
|
|
set -euo pipefail
|
|
python3 --version
|
|
node --version
|
|
npm --version
|
|
docker version
|
|
docker compose version --short | grep -Eq '^v?2\.'
|
|
- name: Install dependencies and run release gate
|
|
env:
|
|
NEXT_PUBLIC_SUPABASE_URL: https://ci-placeholder.supabase.co
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY: ci-placeholder
|
|
PIP_INDEX_URL: https://mirrors.aliyun.com/pypi/simple/
|
|
NPM_CONFIG_REGISTRY: https://registry.npmmirror.com
|
|
run: |
|
|
set -euo pipefail
|
|
python3 -m venv .venv
|
|
export PATH="$PWD/.venv/bin:$PATH"
|
|
python -m pip install --upgrade pip
|
|
python -m pip install \
|
|
"mcp==1.28.1" \
|
|
"pydantic==2.13.4" \
|
|
"numpy==2.5.1" \
|
|
"pandas==2.3.3" \
|
|
"timezonefinder==8.2.5" \
|
|
-r requirements.txt -r requirements-dev.txt playwright
|
|
python -m playwright install --with-deps chromium
|
|
npm ci --prefix frontend
|
|
python scripts/run_quality_gate.py --profile release
|
|
python -m pytest -q --maxfail=1
|
|
python tests/run_all.py
|