返回 AiToEarn
pr-check.yml
1 name: PR Check
2
3 on:
4 pull_request:
5 types: [opened, synchronize, reopened]
6 env:
7 NX_NO_CLOUD: true
8 NODE_OPTIONS: "--max-old-space-size=4096"
9
10 jobs:
11 lint-and-build:
12 name: Lint & Build
13 runs-on: ubuntu-latest
14
15 steps:
16
17 - name: Check Pull Request title
18 uses: actions/github-script@v7
19 with:
20 github-token: ${{ secrets.GITHUB_TOKEN }}
21 script: |
22 const prNumber = context.payload.pull_request.number;
23 let prBody = context.payload.pull_request.body || '';
24 const prTitle = context.payload.pull_request.title || '';
25
26 const conventionalCommitsPattern = /^(feat|fix|docs|style|refactor|perf|test|chore|ci|build)(\(.+\))?: .+$/;
27 const validTypes = ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'ci', 'build'];
28
29 if (!conventionalCommitsPattern.test(prTitle)) {
30 const errorMessage =
31 '❌ PR title does not follow Conventional Commits format.\n\n' +
32 'Required format: <type>(<scope>): <description>\n\n' +
33 'Valid types:\n' +
34 validTypes.map(t => ` - ${t}`).join('\n') + '\n\n' +
35 'Examples:\n' +
36 ' ✅ feat: add user authentication\n' +
37 ' ✅ fix(web): resolve login button issue\n' +
38 ' ✅ docs: update API documentation\n' +
39 ' ✅ refactor(backend): improve error handling\n' +
40 ' ✅ chore: update dependencies\n\n' +
41 'Common mistakes:\n' +
42 ' ❌ "Add new feature" (missing type and colon)\n' +
43 ' ❌ "feat add feature" (missing colon)\n' +
44 ' ❌ "feat: " (missing description)\n' +
45 ' ❌ "feature: add something" (invalid type)\n\n' +
46 `Current title: "${prTitle}"\n\n` +
47 'Please update your PR title to follow the Conventional Commits specification.';
48
49 core.setFailed(errorMessage);
50 return;
51 }
52
53
54 - name: 检出代码
55 uses: actions/checkout@v4
56 with:
57 fetch-depth: 0
58
59 - name: Install pnpm
60 uses: pnpm/action-setup@v4
61
62 - name: Setup Node.js
63 uses: actions/setup-node@v4
64 with:
65 node-version: 24
66 cache: pnpm
67
68 - name: Cache node_modules
69 id: cache-node-modules
70 uses: actions/cache@v4
71 with:
72 path: |
73 node_modules
74 apps/*/node_modules
75 libs/*/node_modules
76 key: node-modules-${{ hashFiles('pnpm-lock.yaml') }}
77
78 - name: 安装依赖
79 if: steps.cache-node-modules.outputs.cache-hit != 'true'
80 run: pnpm install --frozen-lockfile
81
82 - name: Cache Nx build outputs
83 uses: actions/cache@v4
84 with:
85 path: |
86 .nx/cache
87 .nx/workspace-data
88 key: nx-cache-pr-${{ github.event.pull_request.number }}-${{ github.sha }}
89 restore-keys: |
90 nx-cache-pr-${{ github.event.pull_request.number }}-
91 nx-cache-
92
93 - name: 检测受影响的项目
94 id: detect-changes
95 run: |
96 BASE_REF="origin/${{ github.base_ref }}"
97 echo "📋 检测从 $BASE_REF 到 HEAD 的变更"
98 echo "Base: $BASE_REF"
99 echo "Head: HEAD"
100
101 AFFECTED_PROJECTS=$(pnpm nx show projects --affected --sep="," --base=$BASE_REF --head=HEAD 2>/dev/null || echo "")
102
103 if [ -z "$AFFECTED_PROJECTS" ]; then
104 echo "⚠️ 未检测到受影响的项目"
105 echo "has_changes=false" >> $GITHUB_OUTPUT
106 echo "affected_projects=" >> $GITHUB_OUTPUT
107 else
108 echo "✅ 受影响的项目: $AFFECTED_PROJECTS"
109 echo "has_changes=true" >> $GITHUB_OUTPUT
110 echo "affected_projects=$AFFECTED_PROJECTS" >> $GITHUB_OUTPUT
111
112 echo ""
113 echo "详细信息:"
114 for PROJECT in $(echo "$AFFECTED_PROJECTS" | tr ',' ' '); do
115 echo " - $PROJECT"
116 done
117 fi
118
119 - name: Generate GraphQL types
120 if: steps.detect-changes.outputs.has_changes == 'true'
121 run: pnpm --filter aitoearn-task graphql-codegen
122
123 - name: 运行 ESLint 检查
124 if: steps.detect-changes.outputs.has_changes == 'true'
125 run: |
126 AFFECTED_PROJECTS="${{ steps.detect-changes.outputs.affected_projects }}"
127 echo "🔍 对受影响的项目运行 ESLint 检查"
128 pnpm nx run-many --target=lint --projects="$AFFECTED_PROJECTS" --no-fix --nxBail --outputStyle=static
129
130 - name: 运行构建
131 if: steps.detect-changes.outputs.has_changes == 'true'
132 run: |
133 AFFECTED_PROJECTS="${{ steps.detect-changes.outputs.affected_projects }}"
134 echo "🔨 对受影响的项目运行构建"
135 pnpm nx run-many --target=build --projects="$AFFECTED_PROJECTS" --nxBail --outputStyle=static
136
137 - name: 无变更跳过
138 if: steps.detect-changes.outputs.has_changes == 'false'
139 run: |
140 echo "✅ 未检测到变更,跳过检查"
141 echo "### ✅ 无变更" >> $GITHUB_STEP_SUMMARY
142 echo "未检测到需要检查的项目变更" >> $GITHUB_STEP_SUMMARY
143
143 lines YAML