fix(ci): 消除 workflow 所有 heredoc,改为外置脚本调用

- 删除 Configure remote backend 步骤的 shell heredoc(导致 YAML L191 语法错误)
- 新增 scripts/render_backend_tf.py 外置脚本,接受 TF_STATE_ENDPOINT env 渲染 backend.tf
- provision job 新增 Checkout xworkspace-console 步骤,确保 scripts/ 在 runner 可用
- 新增 CLAUDE.md,明确禁止 workflow 内嵌 heredoc(shell/python),要求外置脚本

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Haitao Pan 2026-06-25 11:48:47 +08:00
parent f636366699
commit 9b3687e189
3 changed files with 93 additions and 17 deletions

View File

@ -153,6 +153,11 @@ jobs:
fi
[ "$missing" -eq 0 ] || { echo "::error::必需机密缺失,终止 provision"; exit 1; }
- name: Checkout xworkspace-console (scripts)
uses: actions/checkout@v4
with:
path: xw-console
- name: Checkout iac_modules
uses: actions/checkout@v4
with:
@ -183,23 +188,7 @@ jobs:
working-directory: ${{ env.ENV_DIR }}
env:
TF_STATE_ENDPOINT: ${{ steps.vault.outputs.TF_STATE_ENDPOINT }}
run: |
set -euo pipefail
# endpoints 块只能在 HCL 里配置,无法通过 -backend-config flag 传递。
# 用非引号 heredoc 将 endpoint URL 展开写入 backend.tf。
cat > backend.tf << TFEOF
terraform {
backend "s3" {
endpoints = { s3 = "${TF_STATE_ENDPOINT}" }
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
skip_s3_checksum = true
use_path_style = true
}
}
TFEOF
run: python3 $GITHUB_WORKSPACE/xw-console/scripts/render_backend_tf.py backend.tf
- name: generate.py render (YAML -> 显式 HCL + tfvars)
working-directory: ${{ env.VPS_ROOT }}

49
CLAUDE.md Normal file
View File

@ -0,0 +1,49 @@
# xworkspace-console — Agent 规范
## GitHub Actions Workflow 编写规则
### 禁止内嵌脚本shell heredoc / python heredoc
**严禁**在 `.github/workflows/``run:` 块里使用任何内嵌 heredoc
```yaml
# ❌ 禁止 — shell heredoc
run: |
cat > file.tf << EOF
content
EOF
# ❌ 禁止 — python 内联 heredoc
run: |
python3 - <<'PYEOF'
import os
...
PYEOF
```
**原因:**
- Shell heredoc 内容从列 1 开始,超出 YAML literal block 缩进范围,导致整个 workflow 文件 YAML 解析失败GitHub 丢失 `on:` 触发器。
- Python 内联 heredoc 同理,且难以维护和测试。
**正确做法外置脚本workflow 只做调用。**
```yaml
# ✅ 正确 — 外置 Python 脚本
- name: Checkout xworkspace-console (scripts)
uses: actions/checkout@v4
with:
path: xw-console
- name: Configure remote backend
env:
TF_STATE_ENDPOINT: ${{ steps.vault.outputs.TF_STATE_ENDPOINT }}
run: python3 $GITHUB_WORKSPACE/xw-console/scripts/render_backend_tf.py backend.tf
```
脚本存放在 `scripts/` 目录,命名规范 `动词_名词.py``动词-名词.sh`
### 其他规范
- workflow 使用的外置脚本必须在 `scripts/` 目录下,不得内嵌在 `run:` 块里。
- workflow 文件修改后必须用 `python3 -c "import yaml; yaml.safe_load(open(...))"` 验证 YAML 语法再提交。
- 不使用 GitHub Actions Secrets所有机密统一从 Vault (https://vault.svc.plus) OIDC 读取。

View File

@ -0,0 +1,38 @@
#!/usr/bin/env python3
"""
渲染 Terraform S3 backend 配置文件backend.tf
用法
TF_STATE_ENDPOINT=https://... python3 render_backend_tf.py [output_path]
默认输出到当前目录的 backend.tfterraform init working-directory 里执行
"""
import os
import sys
endpoint = os.environ.get("TF_STATE_ENDPOINT", "")
if not endpoint:
print("ERROR: TF_STATE_ENDPOINT is not set", file=sys.stderr)
sys.exit(1)
output = sys.argv[1] if len(sys.argv) > 1 else "backend.tf"
content = f"""\
terraform {{
backend "s3" {{
endpoints = {{ s3 = "{endpoint}" }}
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
skip_s3_checksum = true
use_path_style = true
}}
}}
"""
with open(output, "w") as f:
f.write(content)
print(f"backend.tf written to {output}")
print(f" endpoint = {endpoint[:40]}...")