195 lines
7.3 KiB
YAML
195 lines
7.3 KiB
YAML
name: Plugin Library CI (Incremental)
|
||
|
||
on:
|
||
push:
|
||
branches: [master, main]
|
||
workflow_dispatch:
|
||
inputs:
|
||
force_publish:
|
||
description: '强制全量发布 (忽略变更检测)'
|
||
default: 'false'
|
||
required: true
|
||
type: choice
|
||
options:
|
||
- 'false'
|
||
- 'true'
|
||
|
||
env:
|
||
SERVER_HOST: ${{ vars.SERVER_HOST }}
|
||
AuthToken: ${{ vars.AUTH_TOKEN }}
|
||
|
||
jobs:
|
||
# 第一步:检测变更的模块
|
||
detect-changes:
|
||
runs-on: dev
|
||
container: node:18-alpine
|
||
outputs:
|
||
matrix: ${{ steps.detect.outputs.matrix }}
|
||
has_changes: ${{ steps.detect.outputs.has_changes }}
|
||
changed_count: ${{ steps.detect.outputs.changed_count }}
|
||
steps:
|
||
- name: Install Git & jq
|
||
run: apk add --no-cache git jq
|
||
|
||
- name: Checkout
|
||
uses: http://106.52.62.106:3000/unity-registry/checkout@v4
|
||
with:
|
||
fetch-depth: 2 # 关键:需要上次提交来对比差异
|
||
|
||
- name: Detect Changed Modules
|
||
id: detect
|
||
run: |
|
||
# 如果是强制全量发布
|
||
if [ "${{ github.event.inputs.force_publish }}" = "true" ]; then
|
||
echo "强制执行全量发布..."
|
||
ALL_MODULES='["00.StaryEvo","00.StaryEvoTools","00.BuildOriginality","00.ARMazTools","01.HybridCLR","02.InformationSave","03.YooAsset","04.AudioCore","05.TableTextConversion","06.UIFarme","07.RKTools","08.UniTask","09.CodeChecker","10.StoryEditor","10.XNode","11.PointCloudTools"]'
|
||
echo "matrix={\"module\":$ALL_MODULES}" >> $GITHUB_OUTPUT
|
||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||
echo "changed_count=15" >> $GITHUB_OUTPUT
|
||
exit 0
|
||
fi
|
||
|
||
# 获取变更文件列表(对比 HEAD~1 和 HEAD)
|
||
# 处理首次提交的情况(没有 HEAD~1)
|
||
if git rev-parse HEAD~1 >/dev/null 2>&1; then
|
||
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD)
|
||
echo "变更文件列表:"
|
||
echo "$CHANGED_FILES"
|
||
else
|
||
echo "首次提交,全量发布所有模块..."
|
||
CHANGED_FILES=$(find Assets -type f 2>/dev/null)
|
||
fi
|
||
|
||
# 定义所有候选模块
|
||
ALL_MODULES=(
|
||
"00.StaryEvo"
|
||
"00.StaryEvoTools"
|
||
"00.BuildOriginality"
|
||
"00.ARMazTools"
|
||
"01.HybridCLR"
|
||
"02.InformationSave"
|
||
"03.YooAsset"
|
||
"04.AudioCore"
|
||
"05.TableTextConversion"
|
||
"06.UIFarme"
|
||
"07.RKTools"
|
||
"08.UniTask"
|
||
"09.CodeChecker"
|
||
"10.StoryEditor"
|
||
"10.XNode"
|
||
"11.PointCloudTools"
|
||
)
|
||
|
||
# 检测哪些模块目录下有文件变更
|
||
CHANGED_MODULES=()
|
||
for module in "${ALL_MODULES[@]}"; do
|
||
MODULE_PATH="Assets/${module}"
|
||
|
||
# 检查是否有文件属于这个模块
|
||
if echo "$CHANGED_FILES" | grep -q "^${MODULE_PATH}/"; then
|
||
# 检查是否有 package.json(确保是有效的 npm 包)
|
||
if [ -f "${MODULE_PATH}/package.json" ]; then
|
||
CHANGED_MODULES+=("$module")
|
||
echo "✅ 检测到变更: $module"
|
||
else
|
||
echo "⚠️ $module 有文件变更但缺少 package.json,跳过"
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# 构建 JSON 矩阵输出
|
||
if [ ${#CHANGED_MODULES[@]} -gt 0 ]; then
|
||
MATRIX_JSON=$(printf '%s\n' "${CHANGED_MODULES[@]}" | jq -R . | jq -s -c .)
|
||
echo "matrix={\"module\":$MATRIX_JSON}" >> $GITHUB_OUTPUT
|
||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||
echo "changed_count=${#CHANGED_MODULES[@]}" >> $GITHUB_OUTPUT
|
||
echo "总结: 本次将发布 ${#CHANGED_MODULES[@]} 个模块"
|
||
else
|
||
echo "没有检测到模块变更,跳过发布"
|
||
echo "matrix={\"module\":[]}" >> $GITHUB_OUTPUT
|
||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||
echo "changed_count=0" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Show Detection Result
|
||
run: |
|
||
echo "变更检测结果:"
|
||
echo "Has Changes: ${{ steps.detect.outputs.has_changes }}"
|
||
echo "Changed Count: ${{ steps.detect.outputs.changed_count }}"
|
||
echo "Matrix: ${{ steps.detect.outputs.matrix }}"
|
||
|
||
# 第二步:只对变更的模块执行发布
|
||
publish:
|
||
needs: detect-changes
|
||
if: needs.detect-changes.outputs.has_changes == 'true'
|
||
runs-on: dev
|
||
container:
|
||
image: node:18-alpine
|
||
# 可选:挂载 npm 缓存(需在 runner 宿主机创建 /cache/npm)
|
||
volumes:
|
||
- /cache/npm:/root/.npm:rw
|
||
strategy:
|
||
fail-fast: false
|
||
# 根据变更数量动态调整并发(变更少时串行,多时并行)
|
||
max-parallel: ${{ fromJSON(needs.detect-changes.outputs.changed_count) > 4 && 4 || 1 }}
|
||
matrix: ${{ fromJSON(needs.detect-changes.outputs.matrix) }}
|
||
|
||
steps:
|
||
- name: Setup Node.js
|
||
run: |
|
||
# 如果使用了挂载缓存,先确保链接存在
|
||
ln -sf /srv/18-alpine/bin/node /usr/bin/node 2>/dev/null || true
|
||
ln -sf /srv/18-alpine/bin/npm /usr/bin/npm 2>/dev/null || true
|
||
node -v
|
||
|
||
- name: Configure npm
|
||
run: |
|
||
npm config set registry "http://${SERVER_HOST}/npm"
|
||
npm config set "//${SERVER_HOST}/:_authToken" "${AuthToken}"
|
||
|
||
- name: Sparse Checkout (仅检出目标模块)
|
||
uses: http://106.52.62.106:3000/unity-registry/checkout@v4
|
||
with:
|
||
fetch-depth: 1
|
||
sparse-checkout: Assets/${{ matrix.module }}
|
||
# 不检出历史,极大减少大仓库的 IO 时间
|
||
|
||
- name: Publish ${{ matrix.module }}
|
||
working-directory: Assets/${{ matrix.module }}
|
||
run: |
|
||
echo "========================================"
|
||
echo "开始发布: ${{ matrix.module }}"
|
||
|
||
# 获取版本号
|
||
CURRENT_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
|
||
echo "当前版本: $CURRENT_VERSION"
|
||
|
||
# 尝试发布
|
||
if npm publish --registry=http://${SERVER_HOST}/npm 2>&1; then
|
||
echo "✅ ${{ matrix.module }}@$CURRENT_VERSION 发布成功"
|
||
else
|
||
PUBLISH_EXIT=$?
|
||
# 检查是否因为版本已存在而失败(不算真失败)
|
||
if npm view . --registry=http://${SERVER_HOST}/npm 2>/dev/null | grep -q "$CURRENT_VERSION"; then
|
||
echo "⚠️ 版本 $CURRENT_VERSION 已存在,跳过"
|
||
else
|
||
echo "❌ 发布失败 (exit $PUBLISH_EXIT)"
|
||
exit 1 # 真正的失败,终止 workflow
|
||
fi
|
||
fi
|
||
|
||
- name: Complete
|
||
if: always()
|
||
run: echo "====== ${{ matrix.module }} 处理完成 ======"
|
||
|
||
# 第三步:汇总通知(可选)
|
||
summary:
|
||
needs: [detect-changes, publish]
|
||
if: always() && needs.detect-changes.outputs.has_changes == 'true'
|
||
runs-on: dev
|
||
steps:
|
||
- name: Publish Summary
|
||
run: |
|
||
echo "## 发布汇总" >> $GITHUB_STEP_SUMMARY
|
||
echo "- **变更模块数**: ${{ needs.detect-changes.outputs.changed_count }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "- **执行结果**: ${{ needs.publish.result }}" >> $GITHUB_STEP_SUMMARY |