♻️ refactor(ci): use fixed workflow slots
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
workspace_fail() {
|
||||
echo "bootstrap_workspace.sh: $*" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
split_repository_slug() {
|
||||
local repo_slug=$1
|
||||
local owner repo_name
|
||||
|
||||
if [[ "${repo_slug}" != */* ]]; then
|
||||
workspace_fail "repository slug must look like owner/repo: ${repo_slug}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
owner=${repo_slug%%/*}
|
||||
repo_name=${repo_slug#*/}
|
||||
|
||||
printf '%s\n%s\n' "${owner}" "${repo_name}"
|
||||
}
|
||||
|
||||
sanitize_job_name() {
|
||||
local value=${1:-job}
|
||||
|
||||
value=$(printf '%s' "${value}" | tr ' /:@' '-----')
|
||||
value=$(printf '%s' "${value}" | tr -cd '[:alnum:]._-')
|
||||
value=$(printf '%s' "${value}" | sed -E 's/-+/-/g; s/^-//; s/-$//')
|
||||
|
||||
if [ -z "${value}" ]; then
|
||||
value="job"
|
||||
fi
|
||||
|
||||
printf '%s\n' "${value}"
|
||||
}
|
||||
|
||||
build_job_identity() {
|
||||
local run_id=${1:-0}
|
||||
local run_attempt=${2:-1}
|
||||
local job_name=${3:-job}
|
||||
|
||||
printf '%s-%s-%s\n' "${run_id}" "${run_attempt}" "${job_name}"
|
||||
}
|
||||
|
||||
build_mirror_path() {
|
||||
local mirror_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
|
||||
printf '%s/%s/%s.git\n' "${mirror_root}" "${owner}" "${repo_name}"
|
||||
}
|
||||
|
||||
build_job_workspace_root() {
|
||||
local workspace_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
local job_identity=$4
|
||||
|
||||
printf '%s/%s/%s/%s\n' "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}"
|
||||
}
|
||||
|
||||
build_job_repo_dir() {
|
||||
local workspace_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
local job_identity=$4
|
||||
|
||||
printf '%s/repo\n' "$(build_job_workspace_root "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")"
|
||||
}
|
||||
|
||||
with_repo_lock() {
|
||||
local lock_path=$1
|
||||
shift
|
||||
|
||||
mkdir -p "$(dirname "${lock_path}")"
|
||||
|
||||
if ! command -v flock >/dev/null 2>&1; then
|
||||
workspace_fail "flock is required for mirror synchronization"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exec {lock_fd}>"${lock_path}"
|
||||
flock "${lock_fd}"
|
||||
"$@"
|
||||
local status=$?
|
||||
flock -u "${lock_fd}"
|
||||
eval "exec ${lock_fd}>&-"
|
||||
|
||||
return "${status}"
|
||||
}
|
||||
|
||||
ensure_bare_mirror_unlocked() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
|
||||
mkdir -p "$(dirname "${mirror_path}")"
|
||||
|
||||
if [ -d "${mirror_path}" ]; then
|
||||
git -C "${mirror_path}" remote set-url origin "${remote_url}"
|
||||
git -C "${mirror_path}" fetch --prune --prune-tags --tags origin
|
||||
else
|
||||
git clone --mirror "${remote_url}" "${mirror_path}" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_bare_mirror() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
local lock_path
|
||||
|
||||
lock_path="${mirror_path}.lock"
|
||||
with_repo_lock "${lock_path}" ensure_bare_mirror_unlocked "${remote_url}" "${mirror_path}"
|
||||
}
|
||||
|
||||
create_job_workspace_from_mirror() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
local job_workspace=$3
|
||||
local repo_dir=$4
|
||||
|
||||
rm -rf "${job_workspace}"
|
||||
mkdir -p "${job_workspace}"
|
||||
git clone --shared "${mirror_path}" "${repo_dir}" >/dev/null
|
||||
git -C "${repo_dir}" remote set-url origin "${remote_url}"
|
||||
}
|
||||
|
||||
cleanup_job_workspace() {
|
||||
local job_workspace=$1
|
||||
|
||||
if [ -z "${job_workspace}" ] || [ "${job_workspace}" = "/" ]; then
|
||||
workspace_fail "refusing to remove invalid workspace path: ${job_workspace}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "${job_workspace}"
|
||||
}
|
||||
|
||||
prepare_job_workspace() {
|
||||
local repo_slug=$1
|
||||
local remote_url=$2
|
||||
local mirror_root=$3
|
||||
local workspace_root=$4
|
||||
local run_id=$5
|
||||
local run_attempt=${6:-1}
|
||||
local job_name=${7:-job}
|
||||
local owner repo_name safe_job_name job_identity mirror_path job_workspace repo_dir
|
||||
local slug_parts
|
||||
|
||||
mapfile -t slug_parts < <(split_repository_slug "${repo_slug}")
|
||||
owner=${slug_parts[0]}
|
||||
repo_name=${slug_parts[1]}
|
||||
safe_job_name=$(sanitize_job_name "${job_name}")
|
||||
job_identity=$(build_job_identity "${run_id}" "${run_attempt}" "${safe_job_name}")
|
||||
mirror_path=$(build_mirror_path "${mirror_root}" "${owner}" "${repo_name}")
|
||||
job_workspace=$(build_job_workspace_root "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")
|
||||
repo_dir=$(build_job_repo_dir "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")
|
||||
|
||||
ensure_bare_mirror "${remote_url}" "${mirror_path}"
|
||||
create_job_workspace_from_mirror "${remote_url}" "${mirror_path}" "${job_workspace}" "${repo_dir}"
|
||||
|
||||
printf 'REPO_OWNER=%s\n' "${owner}"
|
||||
printf 'REPO_NAME=%s\n' "${repo_name}"
|
||||
printf 'JOB_IDENTITY=%s\n' "${job_identity}"
|
||||
printf 'MIRROR_PATH=%s\n' "${mirror_path}"
|
||||
printf 'JOB_WORKSPACE=%s\n' "${job_workspace}"
|
||||
printf 'REPO_DIR=%s\n' "${repo_dir}"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
bootstrap_workspace.sh prepare-job-workspace <repo-slug> <remote-url> <mirror-root> <workspace-root> <run-id> <run-attempt> <job-name>
|
||||
bootstrap_workspace.sh cleanup-job-workspace <job-workspace>
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local command=${1:-}
|
||||
|
||||
case "${command}" in
|
||||
prepare-job-workspace)
|
||||
[ $# -eq 8 ] || {
|
||||
print_usage
|
||||
return 1
|
||||
}
|
||||
shift
|
||||
prepare_job_workspace "$@"
|
||||
;;
|
||||
cleanup-job-workspace)
|
||||
[ $# -eq 2 ] || {
|
||||
print_usage
|
||||
return 1
|
||||
}
|
||||
shift
|
||||
cleanup_job_workspace "$1"
|
||||
;;
|
||||
*)
|
||||
print_usage
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
set -euo pipefail
|
||||
main "$@"
|
||||
fi
|
||||
@@ -29,16 +29,21 @@ env:
|
||||
# - GIT_TOKEN: 用于 git clone/push
|
||||
# - API_TOKEN: 用于 API 调用
|
||||
ACCESS_TOKEN: ${{ secrets.WORKFLOW }}
|
||||
GIT_CONFIG_COUNT: "3"
|
||||
GIT_CONFIG_KEY_0: "credential.helper"
|
||||
GIT_CONFIG_VALUE_0: ""
|
||||
GIT_CONFIG_KEY_1: "credential.helper"
|
||||
GIT_CONFIG_VALUE_1: '!f() { test "$1" = get || exit 0; printf "%s\n" username=oauth2; printf "%s\n" "password=${ACCESS_TOKEN}"; }; f'
|
||||
GIT_CONFIG_KEY_2: "credential.interactive"
|
||||
GIT_CONFIG_VALUE_2: "never"
|
||||
|
||||
# ===== 工作区配置 =====
|
||||
# 持久化 mirror 缓存目录
|
||||
MIRROR_ROOT: "/data/git-mirrors"
|
||||
# 每个 job 的独立临时工作目录根路径
|
||||
JOB_WORKSPACE_ROOT: "/home/workspace/jobs"
|
||||
WORKSPACE_DIR: "/data/workspace"
|
||||
WORKSPACE_SLOT: "release"
|
||||
|
||||
# ===== 分支配置 =====
|
||||
# 主分支名称(用于推送 CHANGELOG 更新)
|
||||
# 如果留空,会自动检测(main 或 master)
|
||||
# 必须明确配置主分支(例如 main 或 master)
|
||||
MAIN_BRANCH: "main"
|
||||
|
||||
# ===== 服务器配置 =====
|
||||
@@ -233,6 +238,7 @@ jobs:
|
||||
- name: 📥 准备隔离仓库
|
||||
id: clone
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "======================================"
|
||||
echo "🚀 开始准备仓库"
|
||||
echo "======================================"
|
||||
@@ -240,106 +246,69 @@ jobs:
|
||||
REPO_SLUG="${{ github.repository }}"
|
||||
REPO_NAME="${{ github.event.repository.name }}"
|
||||
MAIN_BRANCH="${{ env.MAIN_BRANCH }}"
|
||||
RUN_ATTEMPT="${{ github.run_attempt }}"
|
||||
JOB_NAME="${{ github.job }}"
|
||||
SERVER_HOST="${GITHUB_SERVER_URL#http://}"
|
||||
SERVER_HOST="${SERVER_HOST#https://}"
|
||||
REMOTE_URL="https://oauth2:${{ env.ACCESS_TOKEN }}@${SERVER_HOST}/${REPO_SLUG}.git"
|
||||
BOOTSTRAP_SCRIPT="/tmp/bootstrap_workspace.sh"
|
||||
BOOTSTRAP_URL="${GITHUB_SERVER_URL}/api/v1/repos/${REPO_SLUG}/media/.gitea/ci/bootstrap_workspace.sh?ref=${GITHUB_SHA}"
|
||||
PREPARED_ENV=$(mktemp)
|
||||
WORKSPACE_DIR="${{ env.WORKSPACE_DIR }}"
|
||||
WORKSPACE_SLOT="${{ env.WORKSPACE_SLOT }}"
|
||||
REPO_DIR="${WORKSPACE_DIR}/${REPO_NAME}/${WORKSPACE_SLOT}"
|
||||
REMOTE_URL="${GITHUB_SERVER_URL}/${REPO_SLUG}.git"
|
||||
REMOTE_REF="refs/remotes/origin/${MAIN_BRANCH}"
|
||||
|
||||
if [ -z "$RUN_ATTEMPT" ]; then
|
||||
RUN_ATTEMPT="1"
|
||||
if [ -z "$MAIN_BRANCH" ]; then
|
||||
echo "❌ 错误: 未配置主分支"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JOB_NAME" ]; then
|
||||
JOB_NAME="job"
|
||||
case "$REMOTE_URL" in
|
||||
https://*) ;;
|
||||
*)
|
||||
echo "❌ 拒绝通过非 HTTPS remote 使用 WORKFLOW token" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if [ -e "$REPO_DIR" ] && [ ! -d "$REPO_DIR/.git" ]; then
|
||||
echo "❌ Slot 已存在但不是 Git 仓库: $REPO_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📁 仓库名称: $REPO_NAME"
|
||||
echo "🪞 Mirror 根目录: ${{ env.MIRROR_ROOT }}"
|
||||
echo "📦 Job 工作区根目录: ${{ env.JOB_WORKSPACE_ROOT }}"
|
||||
echo "📦 工作区根目录: $WORKSPACE_DIR"
|
||||
echo "🎯 Workflow 职责: $WORKSPACE_SLOT"
|
||||
echo "🌐 服务器: ${GITHUB_SERVER_URL}"
|
||||
echo ""
|
||||
|
||||
curl -fsSL \
|
||||
-H "Authorization: token ${{ env.ACCESS_TOKEN }}" \
|
||||
"$BOOTSTRAP_URL" \
|
||||
-o "$BOOTSTRAP_SCRIPT"
|
||||
chmod +x "$BOOTSTRAP_SCRIPT"
|
||||
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||
mkdir -p "$(dirname "$REPO_DIR")"
|
||||
git clone --no-checkout "$REMOTE_URL" "$REPO_DIR"
|
||||
else
|
||||
git -C "$REPO_DIR" remote set-url origin "$REMOTE_URL"
|
||||
fi
|
||||
git -C "$REPO_DIR" fetch \
|
||||
--prune --prune-tags --tags --force origin \
|
||||
'+refs/heads/*:refs/remotes/origin/*'
|
||||
if ! git -C "$REPO_DIR" show-ref --verify --quiet "$REMOTE_REF"; then
|
||||
echo "❌ 配置的远程分支不存在: $MAIN_BRANCH" >&2
|
||||
exit 1
|
||||
fi
|
||||
git -C "$REPO_DIR" checkout --force -B "$MAIN_BRANCH" "$REMOTE_REF"
|
||||
git -C "$REPO_DIR" reset --hard "$REMOTE_REF"
|
||||
git -C "$REPO_DIR" clean -ffdx
|
||||
|
||||
bash "$BOOTSTRAP_SCRIPT" prepare-job-workspace \
|
||||
"$REPO_SLUG" \
|
||||
"$REMOTE_URL" \
|
||||
"${{ env.MIRROR_ROOT }}" \
|
||||
"${{ env.JOB_WORKSPACE_ROOT }}" \
|
||||
"${{ github.run_id }}" \
|
||||
"$RUN_ATTEMPT" \
|
||||
"$JOB_NAME" > "$PREPARED_ENV"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "$PREPARED_ENV"
|
||||
rm -f "$PREPARED_ENV"
|
||||
|
||||
echo "✓ Mirror 路径: $MIRROR_PATH"
|
||||
echo "✓ Job 工作区: $JOB_WORKSPACE"
|
||||
echo "✓ 仓库目录: $REPO_DIR"
|
||||
echo ""
|
||||
|
||||
cd "$REPO_DIR"
|
||||
|
||||
echo ""
|
||||
echo "🔍 验证主分支配置..."
|
||||
|
||||
# 检查是否配置了主分支
|
||||
if [ -z "${{ env.MAIN_BRANCH }}" ]; then
|
||||
echo "❌ 错误: 未配置主分支"
|
||||
echo ""
|
||||
echo "请在 workflow 配置文件的 env 区域设置 MAIN_BRANCH:"
|
||||
echo ""
|
||||
echo "env:"
|
||||
echo " MAIN_BRANCH: \"main\" # 或 \"master\""
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ 使用配置的主分支: $MAIN_BRANCH"
|
||||
|
||||
# 验证分支是否存在
|
||||
if ! git show-ref --verify --quiet refs/remotes/origin/$MAIN_BRANCH; then
|
||||
echo "❌ 错误: 配置的分支 '$MAIN_BRANCH' 不存在"
|
||||
echo ""
|
||||
echo "可用的远程分支:"
|
||||
git branch -r | grep -v HEAD
|
||||
echo ""
|
||||
echo "请在 workflow 配置文件中修改 MAIN_BRANCH 为正确的分支名"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ 分支 '$MAIN_BRANCH' 已验证存在"
|
||||
|
||||
# 切换到主分支
|
||||
echo ""
|
||||
echo "🌿 切换到主分支: $MAIN_BRANCH"
|
||||
git checkout $MAIN_BRANCH
|
||||
git pull origin $MAIN_BRANCH
|
||||
echo "✓ 已切换到主分支并更新到最新"
|
||||
echo "✓ 主分支 '$MAIN_BRANCH' 已准备并清理"
|
||||
|
||||
# 导出到环境变量供后续步骤使用
|
||||
echo "REPO_DIR=$REPO_DIR" >> $GITHUB_ENV
|
||||
echo "REPO_NAME=$REPO_NAME" >> $GITHUB_ENV
|
||||
echo "JOB_WORKSPACE=$JOB_WORKSPACE" >> $GITHUB_ENV
|
||||
echo "MIRROR_PATH=$MIRROR_PATH" >> $GITHUB_ENV
|
||||
echo "MAIN_BRANCH=$MAIN_BRANCH" >> $GITHUB_ENV
|
||||
echo "BOOTSTRAP_SCRIPT=$BOOTSTRAP_SCRIPT" >> $GITHUB_ENV
|
||||
echo "REPO_DIR=$REPO_DIR" >> "$GITHUB_ENV"
|
||||
echo "REPO_NAME=$REPO_NAME" >> "$GITHUB_ENV"
|
||||
echo "WORKSPACE_SLOT=$WORKSPACE_SLOT" >> "$GITHUB_ENV"
|
||||
echo "MAIN_BRANCH=$MAIN_BRANCH" >> "$GITHUB_ENV"
|
||||
|
||||
echo ""
|
||||
echo "✅ 仓库准备完成"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
- name: 🔍 检查 Bot 提交
|
||||
- name: 🤖 检查 Bot 提交
|
||||
id: check_bot
|
||||
run: |
|
||||
echo "======================================"
|
||||
@@ -829,9 +798,7 @@ jobs:
|
||||
git commit -m "${{ env.COMMIT_MSG }}"
|
||||
|
||||
echo "📤 推送到远程 ${{ env.MAIN_BRANCH }} 分支..."
|
||||
git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.MAIN_BRANCH }}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
if git -C "${{ env.REPO_DIR }}" push origin "${{ env.MAIN_BRANCH }}"; then
|
||||
echo "✅ 推送成功"
|
||||
else
|
||||
echo "❌ 推送失败"
|
||||
@@ -853,7 +820,7 @@ jobs:
|
||||
cd ${{ env.REPO_DIR }}
|
||||
|
||||
# 确保使用最新的 CHANGELOG
|
||||
git pull origin ${{ env.MAIN_BRANCH }}
|
||||
git -C "${{ env.REPO_DIR }}" pull --ff-only origin "${{ env.MAIN_BRANCH }}"
|
||||
|
||||
python3 << 'PYSCRIPT'
|
||||
import re
|
||||
@@ -1029,11 +996,11 @@ jobs:
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
- name: 📊 生成 Workflow Summary
|
||||
- name: 📋 生成 Workflow Summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "======================================"
|
||||
echo "📊 生成 Workflow Summary"
|
||||
echo "📋 生成 Workflow Summary"
|
||||
echo "======================================"
|
||||
|
||||
cat >> $GITHUB_STEP_SUMMARY << 'EOFSUMMARY'
|
||||
@@ -1071,7 +1038,6 @@ jobs:
|
||||
- ✅ CHANGELOG.md 已更新
|
||||
- ✅ 更改已推送到主分支 (`${{ env.MAIN_BRANCH }}`)
|
||||
- ✅ Release 已创建
|
||||
- ✅ CHANGELOG.md 已作为附件上传
|
||||
EOFSUCCESS
|
||||
else
|
||||
cat >> $GITHUB_STEP_SUMMARY << 'EOFREBUILD'
|
||||
@@ -1083,7 +1049,6 @@ jobs:
|
||||
|
||||
- ℹ️ CHANGELOG.md 无需更新(内容已存在)
|
||||
- ✅ Release 已创建
|
||||
- ✅ CHANGELOG.md 已作为附件上传
|
||||
|
||||
💡 **说明**: 检测到这是重建已删除的 tag,CHANGELOG 中已包含所有提交内容,因此直接从现有内容创建 Release。
|
||||
EOFREBUILD
|
||||
@@ -1159,11 +1124,9 @@ jobs:
|
||||
echo "✅ 已完成的操作:"
|
||||
echo " - CHANGELOG.md 已更新并推送到 ${{ env.MAIN_BRANCH }} 分支"
|
||||
echo " - Release 已创建"
|
||||
echo " - CHANGELOG.md 已上传为附件"
|
||||
else
|
||||
echo "✅ 已完成的操作:"
|
||||
echo " - Release 已创建(从现有 CHANGELOG 内容)"
|
||||
echo " - CHANGELOG.md 已上传为附件"
|
||||
echo ""
|
||||
echo "💡 说明: 检测到这是重建已删除的 tag,CHANGELOG 中已包含"
|
||||
echo " 所有提交内容,因此直接从现有内容创建 Release。"
|
||||
@@ -1191,8 +1154,4 @@ jobs:
|
||||
run: |
|
||||
echo "🧹 清理临时文件..."
|
||||
rm -rf /tmp/commits.txt /tmp/changelog_updated.txt /tmp/content_changed.txt /tmp/release-body.txt /tmp/payload.json /tmp/release_response.json /tmp/upload_response_*.json
|
||||
if [ -n "${{ env.JOB_WORKSPACE }}" ] && [ "${{ env.JOB_WORKSPACE }}" != "/" ]; then
|
||||
echo "🧹 清理 Job 工作区: ${{ env.JOB_WORKSPACE }}"
|
||||
rm -rf "${{ env.JOB_WORKSPACE }}"
|
||||
fi
|
||||
echo "✅ 清理完成"
|
||||
|
||||
@@ -11,14 +11,14 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: 打印问候
|
||||
- name: 👋 打印问候
|
||||
run: |
|
||||
echo "====================================="
|
||||
echo " Ubuntu System Information Check "
|
||||
echo "====================================="
|
||||
echo ""
|
||||
|
||||
- name: 显示系统信息
|
||||
- name: 🖥️ 显示系统信息
|
||||
run: |
|
||||
echo "===== 系统版本 ====="
|
||||
cat /etc/os-release
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
echo "===== 系统启动时间 ====="
|
||||
uptime
|
||||
|
||||
- name: 显示 CPU 信息
|
||||
- name: 🧮 显示 CPU 信息
|
||||
run: |
|
||||
echo "===== CPU 详细信息 ====="
|
||||
lscpu
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
echo "===== CPU 核心数 ====="
|
||||
nproc
|
||||
|
||||
- name: 显示内存信息
|
||||
- name: 🧠 显示内存信息
|
||||
run: |
|
||||
echo "===== 内存使用情况 ====="
|
||||
free -h
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
echo "===== 内存详细信息 ====="
|
||||
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable'
|
||||
|
||||
- name: 显示磁盘信息
|
||||
- name: 💾 显示磁盘信息
|
||||
run: |
|
||||
echo "===== 磁盘使用情况 ====="
|
||||
df -h
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
echo "===== 磁盘分区信息 ====="
|
||||
lsblk
|
||||
|
||||
- name: 显示网络信息
|
||||
- name: 🌐 显示网络信息
|
||||
run: |
|
||||
echo "===== 网络接口 ====="
|
||||
cat /proc/net/dev
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
echo "===== DNS 配置 ====="
|
||||
cat /etc/resolv.conf
|
||||
|
||||
- name: 显示已安装的软件
|
||||
- name: 📦 显示已安装的软件
|
||||
run: |
|
||||
echo "===== Python 版本 ====="
|
||||
python3 --version
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
echo "===== Git 版本 ====="
|
||||
git --version
|
||||
|
||||
- name: 显示环境变量
|
||||
- name: 🔧 显示环境变量
|
||||
run: |
|
||||
echo "===== 重要环境变量 ====="
|
||||
echo "PATH: $PATH"
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
echo "SHELL: $SHELL"
|
||||
echo "PWD: $PWD"
|
||||
|
||||
- name: 显示当前目录
|
||||
- name: 📂 显示当前目录
|
||||
run: |
|
||||
echo "===== 当前工作目录 ====="
|
||||
pwd
|
||||
|
||||
@@ -5,6 +5,10 @@ on:
|
||||
branches: [main, master]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: stats-${{ github.repository }}
|
||||
cancel-in-progress: false
|
||||
|
||||
# ==========================================
|
||||
# 🔧 配置区域 - 根据你的项目修改
|
||||
# ==========================================
|
||||
@@ -12,12 +16,17 @@ env:
|
||||
# ===== Token 配置 =====
|
||||
# 请在 Settings -> Secrets 中配置 WORKFLOW secret
|
||||
ACCESS_TOKEN: ${{ secrets.WORKFLOW }}
|
||||
GIT_CONFIG_COUNT: "3"
|
||||
GIT_CONFIG_KEY_0: "credential.helper"
|
||||
GIT_CONFIG_VALUE_0: ""
|
||||
GIT_CONFIG_KEY_1: "credential.helper"
|
||||
GIT_CONFIG_VALUE_1: '!f() { test "$1" = get || exit 0; printf "%s\n" username=oauth2; printf "%s\n" "password=${ACCESS_TOKEN}"; }; f'
|
||||
GIT_CONFIG_KEY_2: "credential.interactive"
|
||||
GIT_CONFIG_VALUE_2: "never"
|
||||
|
||||
# ===== 工作区配置 =====
|
||||
# 持久化 mirror 缓存目录
|
||||
MIRROR_ROOT: "/data/git-mirrors"
|
||||
# 每个 job 的独立临时工作目录根路径
|
||||
JOB_WORKSPACE_ROOT: "/home/workspace/jobs"
|
||||
WORKSPACE_DIR: "/data/workspace"
|
||||
WORKSPACE_SLOT: "stats"
|
||||
|
||||
# ===== 分支配置 =====
|
||||
# 徽章数据存储分支(可配置)
|
||||
@@ -74,7 +83,7 @@ jobs:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: 🔍 验证 Token 配置
|
||||
- name: 🔐 验证 Token 配置
|
||||
id: validate_token
|
||||
run: |
|
||||
echo "🔐 验证访问令牌..."
|
||||
@@ -159,66 +168,61 @@ jobs:
|
||||
- name: 📥 准备隔离仓库
|
||||
id: clone_main
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "======================================"
|
||||
echo "🚀 开始准备主仓库"
|
||||
echo "======================================"
|
||||
|
||||
REPO_SLUG="${{ github.repository }}"
|
||||
REPO_NAME="${{ github.event.repository.name }}"
|
||||
RUN_ATTEMPT="${{ github.run_attempt }}"
|
||||
JOB_NAME="${{ github.job }}"
|
||||
SERVER_HOST="${GITHUB_SERVER_URL#http://}"
|
||||
SERVER_HOST="${SERVER_HOST#https://}"
|
||||
REMOTE_URL="https://oauth2:${{ env.ACCESS_TOKEN }}@${SERVER_HOST}/${REPO_SLUG}.git"
|
||||
BOOTSTRAP_SCRIPT="/tmp/bootstrap_workspace.sh"
|
||||
BOOTSTRAP_URL="${GITHUB_SERVER_URL}/api/v1/repos/${REPO_SLUG}/media/.gitea/ci/bootstrap_workspace.sh?ref=${GITHUB_SHA}"
|
||||
PREPARED_ENV=$(mktemp)
|
||||
TARGET_BRANCH="${{ github.ref_name }}"
|
||||
WORKSPACE_DIR="${{ env.WORKSPACE_DIR }}"
|
||||
WORKSPACE_SLOT="${{ env.WORKSPACE_SLOT }}"
|
||||
REPO_DIR="${WORKSPACE_DIR}/${REPO_NAME}/${WORKSPACE_SLOT}"
|
||||
REMOTE_URL="${GITHUB_SERVER_URL}/${REPO_SLUG}.git"
|
||||
REMOTE_REF="refs/remotes/origin/${TARGET_BRANCH}"
|
||||
|
||||
if [ -z "$RUN_ATTEMPT" ]; then
|
||||
RUN_ATTEMPT="1"
|
||||
fi
|
||||
|
||||
if [ -z "$JOB_NAME" ]; then
|
||||
JOB_NAME="job"
|
||||
case "$REMOTE_URL" in
|
||||
https://*) ;;
|
||||
*)
|
||||
echo "❌ 拒绝通过非 HTTPS remote 使用 WORKFLOW token" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if [ -e "$REPO_DIR" ] && [ ! -d "$REPO_DIR/.git" ]; then
|
||||
echo "❌ Slot 已存在但不是 Git 仓库: $REPO_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📁 仓库名称: $REPO_NAME"
|
||||
echo "🪞 Mirror 根目录: ${{ env.MIRROR_ROOT }}"
|
||||
echo "📦 Job 工作区根目录: ${{ env.JOB_WORKSPACE_ROOT }}"
|
||||
echo "📦 工作区根目录: $WORKSPACE_DIR"
|
||||
echo "🎯 Workflow 职责: $WORKSPACE_SLOT"
|
||||
echo "🌐 服务器: ${GITHUB_SERVER_URL}"
|
||||
echo "🌿 分支: ${{ github.ref_name }}"
|
||||
echo "🌿 分支: $TARGET_BRANCH"
|
||||
echo ""
|
||||
|
||||
curl -fsSL \
|
||||
-H "Authorization: token ${{ env.ACCESS_TOKEN }}" \
|
||||
"$BOOTSTRAP_URL" \
|
||||
-o "$BOOTSTRAP_SCRIPT"
|
||||
chmod +x "$BOOTSTRAP_SCRIPT"
|
||||
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||
mkdir -p "$(dirname "$REPO_DIR")"
|
||||
git clone --no-checkout "$REMOTE_URL" "$REPO_DIR"
|
||||
else
|
||||
git -C "$REPO_DIR" remote set-url origin "$REMOTE_URL"
|
||||
fi
|
||||
git -C "$REPO_DIR" fetch \
|
||||
--prune --prune-tags --tags --force origin \
|
||||
'+refs/heads/*:refs/remotes/origin/*'
|
||||
if ! git -C "$REPO_DIR" show-ref --verify --quiet "$REMOTE_REF"; then
|
||||
echo "❌ 触发分支不存在: $TARGET_BRANCH" >&2
|
||||
exit 1
|
||||
fi
|
||||
git -C "$REPO_DIR" checkout --force -B "$TARGET_BRANCH" "$REMOTE_REF"
|
||||
git -C "$REPO_DIR" reset --hard "$REMOTE_REF"
|
||||
git -C "$REPO_DIR" clean -ffdx
|
||||
|
||||
bash "$BOOTSTRAP_SCRIPT" prepare-job-workspace \
|
||||
"$REPO_SLUG" \
|
||||
"$REMOTE_URL" \
|
||||
"${{ env.MIRROR_ROOT }}" \
|
||||
"${{ env.JOB_WORKSPACE_ROOT }}" \
|
||||
"${{ github.run_id }}" \
|
||||
"$RUN_ATTEMPT" \
|
||||
"$JOB_NAME" > "$PREPARED_ENV"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "$PREPARED_ENV"
|
||||
rm -f "$PREPARED_ENV"
|
||||
|
||||
echo "✓ Mirror 路径: $MIRROR_PATH"
|
||||
echo "✓ Job 工作区: $JOB_WORKSPACE"
|
||||
echo "✓ 仓库目录: $REPO_DIR"
|
||||
echo ""
|
||||
|
||||
cd "$REPO_DIR"
|
||||
|
||||
# 切换到目标分支
|
||||
echo "🏷️ 切换到分支: ${{ github.ref_name }}"
|
||||
git checkout -f ${{ github.ref_name }}
|
||||
|
||||
echo "✅ 仓库准备成功"
|
||||
echo ""
|
||||
|
||||
@@ -235,35 +239,35 @@ jobs:
|
||||
echo ""
|
||||
|
||||
# 导出环境变量
|
||||
echo "REPO_DIR=$REPO_DIR" >> $GITHUB_ENV
|
||||
echo "REPO_NAME=$REPO_NAME" >> $GITHUB_ENV
|
||||
echo "JOB_WORKSPACE=$JOB_WORKSPACE" >> $GITHUB_ENV
|
||||
echo "MIRROR_PATH=$MIRROR_PATH" >> $GITHUB_ENV
|
||||
echo "BOOTSTRAP_SCRIPT=$BOOTSTRAP_SCRIPT" >> $GITHUB_ENV
|
||||
echo "REPO_DIR=$REPO_DIR" >> "$GITHUB_ENV"
|
||||
echo "REPO_NAME=$REPO_NAME" >> "$GITHUB_ENV"
|
||||
echo "WORKSPACE_SLOT=$WORKSPACE_SLOT" >> "$GITHUB_ENV"
|
||||
|
||||
echo "✅ 主仓库准备完成"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
- name: ⚙️ 准备统计分支
|
||||
- name: 🌿 准备统计分支
|
||||
id: prepare_stats_branch
|
||||
run: |
|
||||
echo "======================================"
|
||||
echo "🔧 准备统计分支"
|
||||
echo "🌿 准备统计分支"
|
||||
echo "======================================"
|
||||
|
||||
cd "${{ env.REPO_DIR }}"
|
||||
|
||||
# 获取所有远程分支
|
||||
git fetch origin --prune
|
||||
git -C "${{ env.REPO_DIR }}" fetch origin --prune
|
||||
|
||||
# 检查统计分支是否存在
|
||||
if git ls-remote --heads origin ${{ env.BADGE_BRANCH }} | grep -q ${{ env.BADGE_BRANCH }}; then
|
||||
if git -C "${{ env.REPO_DIR }}" ls-remote --heads origin "${{ env.BADGE_BRANCH }}" | \
|
||||
grep -q "refs/heads/${{ env.BADGE_BRANCH }}"; then
|
||||
echo "✅ 统计分支 '${{ env.BADGE_BRANCH }}' 已存在"
|
||||
|
||||
# 检出统计分支
|
||||
git fetch origin ${{ env.BADGE_BRANCH }}:${{ env.BADGE_BRANCH }}
|
||||
git checkout ${{ env.BADGE_BRANCH }}
|
||||
git -C "${{ env.REPO_DIR }}" fetch origin \
|
||||
"+refs/heads/${{ env.BADGE_BRANCH }}:refs/remotes/origin/${{ env.BADGE_BRANCH }}"
|
||||
git checkout --force -B "${{ env.BADGE_BRANCH }}" "refs/remotes/origin/${{ env.BADGE_BRANCH }}"
|
||||
|
||||
echo "📂 当前分支内容:"
|
||||
ls -la
|
||||
@@ -274,6 +278,10 @@ jobs:
|
||||
echo "branch_exists=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "🆕 统计分支 '${{ env.BADGE_BRANCH }}' 不存在,将创建"
|
||||
if git show-ref --verify --quiet "refs/heads/${{ env.BADGE_BRANCH }}"; then
|
||||
echo "🧹 删除上次失败运行遗留的本地统计分支"
|
||||
git branch -D "${{ env.BADGE_BRANCH }}"
|
||||
fi
|
||||
echo "branch_exists=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
@@ -383,7 +391,7 @@ jobs:
|
||||
git commit -m ":bar_chart: chore(stats): 初始化统计分支"
|
||||
|
||||
# 推送到远程
|
||||
git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.BADGE_BRANCH }}
|
||||
git -C "${{ env.REPO_DIR }}" push origin "${{ env.BADGE_BRANCH }}"
|
||||
|
||||
echo "✅ 统计分支创建完成"
|
||||
echo "======================================"
|
||||
@@ -629,9 +637,7 @@ jobs:
|
||||
echo "📤 推送到远程 ${{ env.BADGE_BRANCH }} 分支..."
|
||||
|
||||
# 推送到远程(使用 TOKEN)
|
||||
git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.BADGE_BRANCH }}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
if git -C "${{ env.REPO_DIR }}" push origin "${{ env.BADGE_BRANCH }}"; then
|
||||
echo "✅ 推送成功"
|
||||
echo "changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
@@ -643,7 +649,7 @@ jobs:
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
- name: 📈 生成 Workflow Summary
|
||||
- name: 📋 生成 Workflow Summary
|
||||
if: env.OUTPUT_TO_SUMMARY == 'true' && success()
|
||||
run: |
|
||||
cat >> $GITHUB_STEP_SUMMARY << 'EOFSUMMARY'
|
||||
@@ -764,23 +770,9 @@ jobs:
|
||||
echo " 请检查 LANGUAGE_GROUPS 配置和 MIN_LINES_THRESHOLD 设置"
|
||||
fi
|
||||
|
||||
# 清理工作区(可选)
|
||||
if [ "${{ env.CLEANUP_WORKSPACE }}" == "true" ]; then
|
||||
echo ""
|
||||
echo "🧹 清理工作区..."
|
||||
if [ -n "${{ env.JOB_WORKSPACE }}" ] && [ "${{ env.JOB_WORKSPACE }}" != "/" ]; then
|
||||
rm -rf "${{ env.JOB_WORKSPACE }}"
|
||||
fi
|
||||
echo "✅ 清理完成"
|
||||
fi
|
||||
|
||||
- name: 🧹 清理工作区
|
||||
if: always()
|
||||
run: |
|
||||
echo "🧹 清理临时文件..."
|
||||
rm -rf /tmp/lang_stats /tmp/lang_summary.txt
|
||||
if [ -n "${{ env.JOB_WORKSPACE }}" ] && [ "${{ env.JOB_WORKSPACE }}" != "/" ]; then
|
||||
echo "🧹 清理 Job 工作区: ${{ env.JOB_WORKSPACE }}"
|
||||
rm -rf "${{ env.JOB_WORKSPACE }}"
|
||||
fi
|
||||
echo "✅ 清理完成"
|
||||
|
||||
Reference in New Issue
Block a user