@sun-asterisk/sunlint 1.3.19 → 1.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,421 @@
1
+ # GitHub Actions Integration
2
+
3
+ Hướng dẫn tích hợp SunLint với GitHub Actions để tự động review Pull Requests.
4
+
5
+ ## Tính năng mới: Auto GitHub Annotation
6
+
7
+ SunLint giờ đây có thể tự động tạo review comments trên Pull Requests mà **không cần chỉ định `--output` và `--format=json`**.
8
+
9
+ ### 3 Annotation Modes
10
+
11
+ `--github-annotate` hỗ trợ 3 modes:
12
+
13
+ #### 1. **`annotate`** - Inline Comments Only
14
+ Tạo review comments trực tiếp trên code (inline comments)
15
+ ```bash
16
+ sunlint --all --input=src --github-annotate=annotate
17
+ ```
18
+ - ✅ Comment trên từng dòng code có lỗi
19
+ - ✅ Duplicate detection
20
+ - ✅ Batch processing (30 comments/review)
21
+
22
+ #### 2. **`summary`** - Summary Comment Only
23
+ Tạo 1 comment tổng hợp (như GitHub Actions summary)
24
+ ```bash
25
+ sunlint --all --input=src --github-annotate=summary
26
+ ```
27
+ - ✅ Thống kê tổng quan (errors, warnings, files)
28
+ - ✅ Top 10 files có nhiều lỗi nhất
29
+ - ✅ Auto update comment cũ (không spam)
30
+
31
+ #### 3. **`all`** - Both (Default)
32
+ Tạo cả inline comments và summary comment
33
+ ```bash
34
+ sunlint --all --input=src --github-annotate # default
35
+ sunlint --all --input=src --github-annotate=all # explicit
36
+ ```
37
+ - ✅ Full experience: inline + summary
38
+ - ✅ Resilient: nếu 1 task fail, task kia vẫn chạy
39
+
40
+ ### Cách hoạt động
41
+
42
+ Khi sử dụng flag `--github-annotate`:
43
+
44
+ 1. ✅ **Tự động phát hiện PR event** - Chỉ chạy khi event là `pull_request`
45
+ 2. ✅ **Tự động tạo JSON report** - Không cần `--output` và `--format=json`
46
+ 3. ✅ **Tự động cleanup** - Xóa temp file sau khi annotate
47
+ 4. ✅ **Intelligent error handling** - Báo lỗi chi tiết và gợi ý fix
48
+ 5. ✅ **Duplicate detection** - Tránh spam comments trùng lặp
49
+ 6. ✅ **3 flexible modes** - Chọn mode phù hợp với workflow
50
+
51
+ ## Quick Start
52
+
53
+ ### Workflow đơn giản nhất
54
+
55
+ ```yaml
56
+ name: SunLint PR Review
57
+ on:
58
+ pull_request:
59
+ branches: [main, develop]
60
+
61
+ jobs:
62
+ sunlint:
63
+ runs-on: ubuntu-latest
64
+ permissions:
65
+ pull-requests: write
66
+ contents: read
67
+
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+
71
+ - name: Setup Node.js
72
+ uses: actions/setup-node@v4
73
+ with:
74
+ node-version: '18'
75
+
76
+ - name: Install SunLint
77
+ run: npm install -g sunlint
78
+
79
+ - name: Run SunLint with Auto Annotation
80
+ run: sunlint --all --input=src --github-annotate
81
+ env:
82
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83
+ ```
84
+
85
+ **Đó là tất cả!** SunLint sẽ tự động:
86
+ - Phân tích code
87
+ - Tạo JSON report (tạm thời)
88
+ - Comment lên PR
89
+ - Xóa file tạm
90
+
91
+ ## Advanced Usage
92
+
93
+ ### 1. Analyze only changed files
94
+
95
+ ```yaml
96
+ - name: Run SunLint on Changed Files
97
+ run: sunlint --all --changed-files --github-annotate
98
+ env:
99
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
100
+ ```
101
+
102
+ ### 2. Save report file + annotate
103
+
104
+ ```yaml
105
+ - name: Run SunLint
106
+ run: sunlint --all --input=src --output=sunlint-report.json --github-annotate
107
+ env:
108
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
109
+
110
+ - name: Upload Report
111
+ uses: actions/upload-artifact@v4
112
+ if: always()
113
+ with:
114
+ name: sunlint-report
115
+ path: sunlint-report.json
116
+ ```
117
+
118
+ ### 3. Run specific rules
119
+
120
+ ```yaml
121
+ - name: Run Security Rules Only
122
+ run: sunlint --security --input=src --github-annotate
123
+ env:
124
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
125
+ ```
126
+
127
+ ### 4. Multiple languages
128
+
129
+ ```yaml
130
+ - name: Run SunLint on TypeScript and Kotlin
131
+ run: sunlint --all --languages=typescript,kotlin --input=. --github-annotate
132
+ env:
133
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134
+ ```
135
+
136
+ ### 5. Với verbose logging
137
+
138
+ ```yaml
139
+ - name: Run SunLint (Verbose)
140
+ run: sunlint --all --input=src --github-annotate --verbose
141
+ env:
142
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143
+ ```
144
+
145
+ ## Complete Example Workflow
146
+
147
+ ```yaml
148
+ name: Code Quality Check
149
+ on:
150
+ pull_request:
151
+ branches: [main, develop, 'release/**']
152
+ paths:
153
+ - '**.ts'
154
+ - '**.tsx'
155
+ - '**.js'
156
+ - '**.jsx'
157
+ - '**.kt'
158
+ - '**.dart'
159
+
160
+ jobs:
161
+ sunlint:
162
+ name: SunLint Analysis
163
+ runs-on: ubuntu-latest
164
+
165
+ permissions:
166
+ contents: read
167
+ pull-requests: write
168
+
169
+ steps:
170
+ - name: Checkout code
171
+ uses: actions/checkout@v4
172
+ with:
173
+ fetch-depth: 0 # For git diff
174
+
175
+ - name: Setup Node.js
176
+ uses: actions/setup-node@v4
177
+ with:
178
+ node-version: '18'
179
+ cache: 'npm'
180
+
181
+ - name: Install dependencies
182
+ run: npm ci
183
+
184
+ - name: Install SunLint
185
+ run: npm install -g sunlint
186
+
187
+ - name: Run SunLint on Changed Files
188
+ id: sunlint
189
+ continue-on-error: true # Don't fail the workflow
190
+ run: |
191
+ sunlint --all \
192
+ --changed-files \
193
+ --diff-base=origin/${{ github.base_ref }} \
194
+ --github-annotate \
195
+ --output=sunlint-report.json \
196
+ --verbose
197
+ env:
198
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
199
+
200
+ - name: Upload Report
201
+ uses: actions/upload-artifact@v4
202
+ if: always()
203
+ with:
204
+ name: sunlint-report-${{ github.event.pull_request.number }}
205
+ path: sunlint-report.json
206
+ retention-days: 30
207
+
208
+ - name: Comment Summary
209
+ if: always()
210
+ uses: actions/github-script@v7
211
+ with:
212
+ script: |
213
+ const fs = require('fs');
214
+ if (!fs.existsSync('sunlint-report.json')) return;
215
+
216
+ const report = JSON.parse(fs.readFileSync('sunlint-report.json', 'utf8'));
217
+ let violations = 0;
218
+ let errors = 0;
219
+ let warnings = 0;
220
+
221
+ for (const file of report) {
222
+ violations += file.messages.length;
223
+ errors += file.errorCount;
224
+ warnings += file.warningCount;
225
+ }
226
+
227
+ const body = `## SunLint Report
228
+
229
+ 📊 **Summary:**
230
+ - Total violations: ${violations}
231
+ - Errors: ${errors}
232
+ - Warnings: ${warnings}
233
+
234
+ ${violations === 0 ? '✅ No issues found!' : '⚠️ Please check the PR comments for details.'}
235
+ `;
236
+
237
+ github.rest.issues.createComment({
238
+ issue_number: context.issue.number,
239
+ owner: context.repo.owner,
240
+ repo: context.repo.repo,
241
+ body: body
242
+ });
243
+ ```
244
+
245
+ ## Environment Variables
246
+
247
+ SunLint tự động đọc các biến môi trường từ GitHub Actions:
248
+
249
+ | Variable | Description | Required |
250
+ |----------|-------------|----------|
251
+ | `GITHUB_TOKEN` | GitHub token for API access | ✅ Yes |
252
+ | `GITHUB_REPOSITORY` | Repository (owner/repo) | Auto |
253
+ | `GITHUB_EVENT_NAME` | Event type (pull_request) | Auto |
254
+ | `GITHUB_EVENT_PATH` | Path to event payload | Auto |
255
+ | `RUNNER_TEMP` | Temp directory | Auto |
256
+
257
+ ## Permissions Required
258
+
259
+ ```yaml
260
+ permissions:
261
+ contents: read # To checkout code
262
+ pull-requests: write # To create review comments
263
+ ```
264
+
265
+ ## Troubleshooting
266
+
267
+ ### 1. "GitHub annotation only works on pull_request events"
268
+
269
+ **Nguyên nhân:** Workflow chạy trên `push` event thay vì `pull_request`
270
+
271
+ **Giải pháp:**
272
+ ```yaml
273
+ on:
274
+ pull_request: # Thay vì push
275
+ branches: [main]
276
+ ```
277
+
278
+ ### 2. "Missing GITHUB_TOKEN"
279
+
280
+ **Nguyên nhân:** Thiếu GITHUB_TOKEN trong env
281
+
282
+ **Giải pháp:**
283
+ ```yaml
284
+ env:
285
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
286
+ ```
287
+
288
+ ### 3. "Permission denied"
289
+
290
+ **Nguyên nhân:** Token không có quyền `pull-requests: write`
291
+
292
+ **Giải pháp:**
293
+ ```yaml
294
+ permissions:
295
+ pull-requests: write
296
+ ```
297
+
298
+ ### 4. Annotations không hiển thị
299
+
300
+ **Nguyên nhân:** File paths không đúng format
301
+
302
+ **Giải pháp:** Đảm bảo paths là relative từ repo root:
303
+ ```yaml
304
+ - uses: actions/checkout@v4 # Checkout đúng branch
305
+ ```
306
+
307
+ ### 5. Fork PRs không annotate được
308
+
309
+ **Nguyên nhân:** `pull_request` event từ fork có quyền hạn chế
310
+
311
+ **Giải pháp:** Dùng `pull_request_target` (cẩn thận về security!)
312
+ ```yaml
313
+ on:
314
+ pull_request_target: # Cho fork PRs
315
+ ```
316
+
317
+ ## Best Practices
318
+
319
+ ### 1. Fail on errors, warn on warnings
320
+
321
+ ```yaml
322
+ - name: Run SunLint
323
+ run: sunlint --all --input=src --github-annotate
324
+ continue-on-error: false # Fail if errors found
325
+ ```
326
+
327
+ ### 2. Cache SunLint installation
328
+
329
+ ```yaml
330
+ - name: Cache SunLint
331
+ uses: actions/cache@v3
332
+ with:
333
+ path: ~/.npm
334
+ key: ${{ runner.os }}-sunlint-${{ hashFiles('**/package-lock.json') }}
335
+ ```
336
+
337
+ ### 3. Run only on specific files
338
+
339
+ ```yaml
340
+ on:
341
+ pull_request:
342
+ paths:
343
+ - 'src/**'
344
+ - '!src/**/*.test.ts'
345
+ ```
346
+
347
+ ### 4. Matrix strategy for multiple projects
348
+
349
+ ```yaml
350
+ jobs:
351
+ sunlint:
352
+ strategy:
353
+ matrix:
354
+ project: [frontend, backend, mobile]
355
+ steps:
356
+ - run: sunlint --all --input=${{ matrix.project }} --github-annotate
357
+ ```
358
+
359
+ ### 5. Skip on draft PRs
360
+
361
+ ```yaml
362
+ jobs:
363
+ sunlint:
364
+ if: github.event.pull_request.draft == false
365
+ steps:
366
+ - run: sunlint --all --github-annotate
367
+ ```
368
+
369
+ ## Migration Guide
370
+
371
+ ### From old style (with --output)
372
+
373
+ **Before:**
374
+ ```yaml
375
+ - name: Run SunLint
376
+ run: sunlint --all --input=src --output=report.json --format=json
377
+
378
+ - name: Annotate PR
379
+ run: node annotate-script.js
380
+ env:
381
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
382
+ ```
383
+
384
+ **After:**
385
+ ```yaml
386
+ - name: Run SunLint with Auto Annotation
387
+ run: sunlint --all --input=src --github-annotate
388
+ env:
389
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
390
+ ```
391
+
392
+ ## FAQ
393
+
394
+ **Q: Có thể dùng cho push events không?**
395
+ A: Không. `--github-annotate` chỉ hoạt động cho `pull_request` events. Dùng `--output` để save report cho push events.
396
+
397
+ **Q: Có bị rate limit không?**
398
+ A: SunLint có retry mechanism và batch processing để tránh rate limit. Maximum 30 comments/review, tự động chia batches nếu nhiều hơn.
399
+
400
+ **Q: Có thể customize comment format không?**
401
+ A: Hiện tại format là `[rule-id] message`. Customize format đang được phát triển.
402
+
403
+ **Q: Có delete được comments cũ không?**
404
+ A: SunLint có duplicate detection để tránh spam. Comments cũ được giữ lại cho lịch sử.
405
+
406
+ **Q: Performance với large PRs?**
407
+ A: SunLint optimize cho large PRs với:
408
+ - Batch processing
409
+ - Only comment on changed files
410
+ - Async operations
411
+ - Retry mechanism
412
+
413
+ ## Examples Repository
414
+
415
+ Xem thêm examples tại: [examples/github-actions/](../examples/github-actions/)
416
+
417
+ ## Support
418
+
419
+ - Issues: [GitHub Issues](https://github.com/sun-asterisk/engineer-excellence/issues)
420
+ - Docs: [Documentation](../README.md)
421
+ - Community: [Discussions](https://github.com/sun-asterisk/engineer-excellence/discussions)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sunlint",
3
- "version": "1.3.19",
3
+ "version": "1.3.21",
4
4
  "description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -139,4 +139,4 @@
139
139
  "url": "https://github.com/sun-asterisk/engineer-excellence/issues"
140
140
  },
141
141
  "homepage": "https://github.com/sun-asterisk/engineer-excellence/tree/main/coding-quality/extensions/sunlint#readme"
142
- }
142
+ }