name: CD Production (volcengine-102) on: push: tags: - "v*" workflow_dispatch: inputs: tag: description: "要部署的已存在 tag(如 v1.2.0)" required: true type: string env: PIP_INDEX_URL: https://mirrors.aliyun.com/pypi/simple/ PIP_TRUSTED_HOST: mirrors.aliyun.com NPM_CONFIG_REGISTRY: https://registry.npmmirror.com # deploy-volcengine-102.sh 读取此变量作为 ssh Host alias, # alias 在下方 Setup SSH 步骤写入 ~/.ssh/config。 AGENTEVAL_PROD_HOST: agenteval-prod # 生产机实际部署目录(覆盖脚本默认 /opt/agenteval) AGENTEVAL_PROD_DIR: /opt/sola/AgentEvalTool jobs: # 门禁:部署前必须全绿(tag push 不触发 CI workflow,因此 CD 自带 test job) test: name: Pre-deploy checks runs-on: agenteval-ci steps: - name: Checkout shell: bash run: | set -euo pipefail git clone "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@git.solahqb22.cn/${{ github.repository }}.git" . TARGET_TAG="${{ github.event.inputs.tag }}" if [ -n "$TARGET_TAG" ]; then git checkout --detach "tags/$TARGET_TAG" else git checkout --detach "$GITHUB_SHA" fi git --no-pager log -1 --oneline - name: Install backend deps run: pip install --no-cache-dir -e ".[dev]" - name: Install frontend deps working-directory: frontend/web run: npm ci --no-audit --no-fund - name: CI checks run: scripts/ci-check.sh deploy: name: Deploy volcengine-102 needs: test runs-on: agenteval-ci steps: - name: Checkout shell: bash run: | set -euo pipefail git clone "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@git.solahqb22.cn/${{ github.repository }}.git" . TARGET_TAG="${{ github.event.inputs.tag }}" if [ -n "$TARGET_TAG" ]; then git checkout --detach "tags/$TARGET_TAG" else git checkout --detach "$GITHUB_SHA" fi # 部署只读(git archive 为本地操作),回收 remote URL 中的 token git remote set-url origin "https://git.solahqb22.cn/${{ github.repository }}.git" git --no-pager log -1 --oneline # 安全门:tag 名必须与 pyproject 版本一致,防止错 tag 误发布 - name: Version gate (tag == pyproject version) shell: bash run: | set -euo pipefail TAG_NAME="${{ github.event.inputs.tag }}" TAG_NAME="${TAG_NAME:-$GITHUB_REF_NAME}" case "$TAG_NAME" in v*) ;; *) echo "tag must start with 'v': $TAG_NAME"; exit 1 ;; esac PYVER=$(python3 -c "import re; print(re.search(r'^version\s*=\s*\"([^\"]+)\"', open('pyproject.toml').read(), re.M).group(1))") if [ "${TAG_NAME#v}" != "$PYVER" ]; then echo "version mismatch: tag=$TAG_NAME pyproject=$PYVER" exit 1 fi echo "version gate OK: $TAG_NAME" - name: Setup SSH shell: bash run: | set -euo pipefail mkdir -p ~/.ssh && chmod 700 ~/.ssh umask 077 printf '%s\n' "${{ secrets.PROD_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 printf '%s\n' "${{ secrets.PROD_KNOWN_HOSTS }}" > ~/.ssh/known_hosts { echo "Host agenteval-prod" echo " HostName ${{ secrets.PROD_HOST }}" echo " User ${{ secrets.PROD_SSH_USER }}" echo " IdentityFile ~/.ssh/id_ed25519" echo " IdentitiesOnly yes" echo " StrictHostKeyChecking yes" } > ~/.ssh/config chmod 600 ~/.ssh/config ssh -o ConnectTimeout=10 agenteval-prod "echo ssh-ok" # 部署逻辑零重写:git archive HEAD → rsync → 备份数据卷 → # docker compose build(注入 IMAGE_TAG/BUILD_COMMIT/BUILD_TIME)→ # up -d → 健康检查(version+commit 双校验)→ 6 个认证 API smoke - name: Deploy production run: scripts/deploy-volcengine-102.sh