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:
parent
f636366699
commit
9b3687e189
23
.github/workflows/deploy-ai-workspace-iac.yaml
vendored
23
.github/workflows/deploy-ai-workspace-iac.yaml
vendored
@ -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
49
CLAUDE.md
Normal 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 读取。
|
||||
38
scripts/render_backend_tf.py
Normal file
38
scripts/render_backend_tf.py
Normal 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.tf(terraform 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]}...")
|
||||
Loading…
Reference in New Issue
Block a user