Files
playbook/.gitea/workflows/prepare.yml
T
csh d83707de23 🔧 chore(workflows): migrate to prepare + worktree model and merge checks
- add prepare.yml: install tools + maintain shared bare repo, anchors the workflow_run chain
- add checks.yml: merge lint + full test suite into a single workflow_run consumer job
- remove standards-check.yml and test.yml (superseded by checks.yml)
- convert sync-tsl-playbook and update-thirdparty-skills to worktree-model consumers
- unify workflow/job/step display names and emoji
2026-07-21 17:29:24 +08:00

213 lines
7.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: 🧰 准备环境
on:
push:
# 主分支:下游 sync / thirdparty 消费者只关心 main。
# 其它分支(含 ci bot 推送的 tsl-playbook / thirdparty/skill 分支)跑 Prepare 纯属空耗,故在此过滤。
branches:
- main
pull_request:
# PR:为下游 checks 消费者(standards + tests)预备 bare 仓库。
# PR 的 github.sha 是 Gitea 生成的 merge commit,不在 refs/heads/*
# 故下面的 fetch 额外取 PR ref 并按事件类型选校验目标。
branches:
- main
workflow_dispatch:
schedule:
# thirdparty 快照每日轮询:Prepare 定时成功后,update-thirdparty-skills 通过 workflow_run 触发。
- cron: "17 3 * * *"
concurrency:
group: prepare-${{ github.repository }}
cancel-in-progress: false
env:
ACCESS_TOKEN: ${{ secrets.WORKFLOW }}
WORKSPACE_ROOT: "/data/workspace"
jobs:
prepare:
runs-on: standard-ubuntu-22
permissions:
contents: read
steps:
- name: 🔧 检查并安装共享工具
id: tools
shell: bash
run: |
set -euo pipefail
declare -A package_for=(
[git]="git"
[python3]="python3"
[curl]="curl"
[flock]="util-linux"
[realpath]="coreutils"
)
required_commands=(git python3 curl flock realpath)
missing_commands=()
missing_packages=()
declare -A seen_packages=()
for command in "${required_commands[@]}"; do
if ! command -v "$command" >/dev/null 2>&1; then
package="${package_for[$command]}"
missing_commands+=("$command")
if [[ -z "${seen_packages[$package]+x}" ]]; then
missing_packages+=("$package")
seen_packages[$package]=1
fi
fi
done
installed=false
if [ "${#missing_packages[@]}" -gt 0 ]; then
echo "缺失命令: ${missing_commands[*]}"
echo "准备安装: ${missing_packages[*]}"
if [ "$(id -u)" -eq 0 ]; then
APT=(apt-get)
elif command -v sudo >/dev/null 2>&1; then
APT=(sudo apt-get)
else
echo "无法安装缺失命令;当前用户不是 root 且没有 sudo" >&2
echo "命令: ${missing_commands[*]}" >&2
echo "包: ${missing_packages[*]}" >&2
exit 1
fi
"${APT[@]}" update -qq
"${APT[@]}" install -y -qq "${missing_packages[@]}"
installed=true
fi
for command in "${required_commands[@]}"; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "安装后仍找不到命令: $command (${package_for[$command]})" >&2
exit 1
fi
done
{
echo "## Prepare 环境"
echo ""
echo "| 命令 | 版本 |"
echo "| --- | --- |"
for command in "${required_commands[@]}"; do
version_output=$("$command" --version 2>&1 || true)
version_line=${version_output%%$'\n'*}
version_line=${version_line//|/\\|}
printf '| `%s` | `%s` |\n' "$command" "$version_line"
done
echo ""
if [ "$installed" = true ]; then
echo "安装的包:\`${missing_packages[*]}\`"
else
echo "安装的包:无,所有命令已存在。"
fi
} >> "$GITHUB_STEP_SUMMARY"
echo "installed=$installed" >> "$GITHUB_OUTPUT"
- name: 📥 准备共享 bare 仓库
shell: bash
run: |
set -euo pipefail
REPO_NAME="${{ github.event.repository.name }}"
REMOTE_URL="${{ github.server_url }}/${{ github.repository }}.git"
EVENT_NAME="${{ github.event_name }}"
REPOSITORY_DIR="${WORKSPACE_ROOT}/${REPO_NAME}/repository.git"
# 校验目标 SHA 因事件而异:
# - pull_requestgithub.sha 是 Gitea 生成的 merge commit,不在
# refs/heads/* 里,直接校验会失败;改用 PR head SHA,并在下方额外
# fetch PR ref 把 head 提交拉进 bare 仓库。下游 workflow_run 消费者
# 读到的 head_sha 也正是这个 PR head,两者一致。
# - 其它事件(push / schedule / dispatch):沿用 github.sha。
if [ "$EVENT_NAME" = "pull_request" ]; then
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
PR_NUMBER="${{ github.event.pull_request.number }}"
else
HEAD_SHA="${{ github.sha }}"
PR_NUMBER=""
fi
case "$HEAD_SHA" in
''|*[!0-9a-fA-F]*)
echo "无效的触发提交 SHA: $HEAD_SHA" >&2
exit 1
;;
esac
case "$REMOTE_URL" in
https://*) ;;
*)
echo "拒绝通过非 HTTPS remote 使用 WORKFLOW token: $REMOTE_URL" >&2
exit 1
;;
esac
if [ -z "$ACCESS_TOKEN" ]; then
echo "未配置 WORKFLOW secret,无法读取仓库" >&2
exit 1
fi
mkdir -p "$(dirname "$REPOSITORY_DIR")"
if [ ! -e "$REPOSITORY_DIR" ]; then
git init --bare "$REPOSITORY_DIR"
else
if [ ! -d "$REPOSITORY_DIR" ]; then
echo "共享仓库路径存在但不是目录: $REPOSITORY_DIR" >&2
exit 1
fi
if ! is_bare=$(git --git-dir="$REPOSITORY_DIR" rev-parse --is-bare-repository 2>/dev/null) || \
[ "$is_bare" != "true" ]; then
echo "共享仓库路径不是有效 bare 仓库: $REPOSITORY_DIR" >&2
exit 1
fi
fi
if git --git-dir="$REPOSITORY_DIR" remote get-url origin >/dev/null 2>&1; then
git --git-dir="$REPOSITORY_DIR" remote set-url origin "$REMOTE_URL"
else
git --git-dir="$REPOSITORY_DIR" remote add origin "$REMOTE_URL"
fi
git \
-c credential.helper= \
-c 'credential.helper=!f() { test "$1" = get || exit 0; printf "%s\n" username=oauth2; printf "%s\n" "password=${ACCESS_TOKEN}"; }; f' \
-c credential.interactive=never \
--git-dir="$REPOSITORY_DIR" fetch \
--prune --prune-tags --tags --force origin \
'+refs/heads/*:refs/remotes/origin/*'
# PR head 不在 refs/heads/*,按需补取 PR ref 把 head 提交拉进 bare 仓库。
# 先试 PR head SHA 是否已在库(同仓库分支 PR 的 head 常已随 refs/heads/*
# 到位),不在再按 PR 号 fetch Gitea 的 refs/pull/<n>/head。
if [ -n "$PR_NUMBER" ] && \
! git --git-dir="$REPOSITORY_DIR" cat-file -e "${HEAD_SHA}^{commit}" 2>/dev/null; then
git \
-c credential.helper= \
-c 'credential.helper=!f() { test "$1" = get || exit 0; printf "%s\n" username=oauth2; printf "%s\n" "password=${ACCESS_TOKEN}"; }; f' \
-c credential.interactive=never \
--git-dir="$REPOSITORY_DIR" fetch --force origin \
"+refs/pull/${PR_NUMBER}/head:refs/remotes/origin/pull/${PR_NUMBER}/head" || true
fi
if ! git --git-dir="$REPOSITORY_DIR" cat-file -e "${HEAD_SHA}^{commit}"; then
echo "共享仓库中不存在触发提交: $HEAD_SHA(事件: $EVENT_NAME" >&2
exit 1
fi
resolved_sha=$(git --git-dir="$REPOSITORY_DIR" rev-parse "${HEAD_SHA}^{commit}")
{
echo ""
echo "## Prepare 仓库"
echo ""
echo "- bare 仓库:\`$REPOSITORY_DIR\`"
echo "- 触发提交:\`$resolved_sha\`"
echo "- 远端:\`$REMOTE_URL\`"
} >> "$GITHUB_STEP_SUMMARY"
echo "Prepare 完成: $REPOSITORY_DIR @ $resolved_sha"