Skip to content

Commit 570869e

Browse files
committed
docs: add user guide and update README with PR guidelines
Change-Id: I4c648e944313a85e4da1c10fdc8d477288a10e4c
1 parent 834cbfd commit 570869e

9 files changed

Lines changed: 2426 additions & 152 deletions

File tree

.github/PR_GUIDE.md

Lines changed: 494 additions & 0 deletions
Large diffs are not rendered by default.

.github/PR_GUIDE_zh.md

Lines changed: 496 additions & 0 deletions
Large diffs are not rendered by default.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!--
2+
Thank you for contributing to Himarket! 🎉
3+
4+
Please follow these guidelines:
5+
1. Title format: type: description (e.g., feat: add new feature)
6+
2. Fill in the Description section (required)
7+
3. Check "Code has been formatted" in Checklist (required)
8+
4. Link related issues if applicable (optional)
9+
10+
For detailed guidelines, see:
11+
- English: .github/PR_GUIDE.md
12+
- 中文: .github/PR_GUIDE_zh.md
13+
-->
14+
15+
## Description
16+
17+
<!-- Describe your changes in detail -->
18+
<!-- You can use bullet points for clarity -->
19+
<!--
20+
Example:
21+
- Refactored the user authentication module to improve performance
22+
- Added caching mechanism for frequently accessed data
23+
- Fixed a bug where session timeout was not properly handled
24+
-->
25+
26+
27+
28+
## Related Issues
29+
30+
<!-- Link related issues using keywords like "Fix", "Close", or "Resolve" -->
31+
<!--
32+
Examples:
33+
- Fix #123
34+
- Close #456, Resolve #789
35+
- Related to #100
36+
-->
37+
38+
39+
40+
## Checklist
41+
42+
<!-- Please check the items that apply to your PR -->
43+
<!-- You can check items by changing [ ] to [x], or click the checkboxes after creating the PR -->
44+
45+
- [ ] Code has been formatted with `mvn spotless:apply`
46+
- [ ] Code is self-reviewed
47+
- [ ] Tests added/updated (if applicable)
48+
- [ ] Documentation updated (if applicable)
49+
- [ ] No breaking changes (or migration guide provided)
50+
51+

.github/workflows/pr-check.yml

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
name: PR Check
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize, reopened]
6+
7+
jobs:
8+
pr-title-check:
9+
name: PR Title Check
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Check PR Title
13+
uses: amannn/action-semantic-pull-request@v5
14+
env:
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
with:
17+
# Allowed types
18+
types: |
19+
feat
20+
fix
21+
docs
22+
style
23+
refactor
24+
perf
25+
test
26+
build
27+
ci
28+
chore
29+
revert
30+
# Scope is optional
31+
requireScope: false
32+
# Subject must start with lowercase letter
33+
subjectPattern: ^(?![A-Z]).+$
34+
subjectPatternError: |
35+
PR title format is incorrect!
36+
37+
❌ Wrong examples:
38+
- feat: Add new feature (first letter should be lowercase)
39+
- add new feature (missing type prefix)
40+
- featadd new feature (missing colon and space)
41+
42+
✅ Correct format:
43+
type: brief description
44+
or
45+
type(scope): brief description
46+
47+
Allowed types:
48+
- feat: new feature
49+
- fix: bug fix
50+
- docs: documentation update
51+
- style: code formatting
52+
- refactor: code refactoring
53+
- perf: performance improvement
54+
- test: testing
55+
- build: build system
56+
- ci: CI/CD
57+
- chore: other changes
58+
- revert: revert previous commit
59+
60+
Examples:
61+
✅ feat: add product feature configuration
62+
✅ fix: fix product list pagination
63+
✅ feat(product): add feature configuration
64+
✅ docs: update README deployment guide
65+
66+
pr-content-check:
67+
name: PR Content Check
68+
runs-on: ubuntu-latest
69+
steps:
70+
- name: Checkout
71+
uses: actions/checkout@v3
72+
73+
- name: Check PR Description
74+
uses: actions/github-script@v7
75+
with:
76+
script: |
77+
const pr = context.payload.pull_request;
78+
const body = pr.body || '';
79+
80+
console.log('PR Body:', body);
81+
82+
// Required checks
83+
const checks = {
84+
hasDescription: {
85+
test: () => {
86+
const descSection = body.match(/##\s*Description\s*([\s\S]*?)(?=##|$)/i);
87+
if (!descSection) return false;
88+
const content = descSection[1].replace(/<!--[\s\S]*?-->/g, '').trim();
89+
return content.length > 10;
90+
},
91+
message: '❌ Missing description or too short (at least 10 characters required)'
92+
},
93+
hasCodeFormatted: {
94+
test: () => {
95+
const checklistSection = body.match(/##\s*Checklist\s*([\s\S]*?)(?=##|$)/i);
96+
if (!checklistSection) return false;
97+
// Check if "Code has been formatted" is checked
98+
return /- \[x\].*mvn spotless:apply/i.test(checklistSection[1]);
99+
},
100+
message: '❌ Please confirm code has been formatted with `mvn spotless:apply`'
101+
}
102+
};
103+
104+
// Execute checks
105+
const errors = [];
106+
const warnings = [];
107+
108+
for (const [key, check] of Object.entries(checks)) {
109+
if (!check.test()) {
110+
errors.push(check.message);
111+
}
112+
}
113+
114+
// Optional checks (warnings only)
115+
const hasIssueLink = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#\d+/i.test(body);
116+
if (!hasIssueLink) {
117+
warnings.push('⚠️ Consider linking related issues (e.g., `Fix #123` or `Close #456`)');
118+
}
119+
120+
if (body.length < 50) {
121+
warnings.push('⚠️ PR description is short. Consider adding more details.');
122+
}
123+
124+
// Generate report
125+
let comment = '## PR Content Check Report\n\n';
126+
127+
if (errors.length === 0) {
128+
comment += '### ✅ All required checks passed\n\n';
129+
} else {
130+
comment += '### ❌ Required items need to be completed\n\n';
131+
errors.forEach(error => {
132+
comment += `${error}\n`;
133+
});
134+
comment += '\n';
135+
}
136+
137+
if (warnings.length > 0) {
138+
comment += '### 💡 Suggestions\n\n';
139+
warnings.forEach(warning => {
140+
comment += `${warning}\n`;
141+
});
142+
comment += '\n';
143+
}
144+
145+
comment += '---\n\n';
146+
comment += '**PR Content Requirements:**\n\n';
147+
comment += '**Required:**\n';
148+
comment += '- **Description**: Clear explanation of changes (minimum 10 characters)\n';
149+
comment += '- **Code Formatting**: Check the box in Checklist (Note: Code format is automatically verified by CI)\n\n';
150+
comment += '**Optional but recommended:**\n';
151+
comment += '- **Related Issues**: Link issues using `Fix #123`, `Close #456`, or `Resolve #789`\n';
152+
comment += '- **Other Checklist Items**: Self-review, tests, documentation, etc.\n\n';
153+
comment += 'Example format:\n';
154+
comment += '```markdown\n';
155+
comment += '## Description\n\n';
156+
comment += '- Refactor client initialization method\n';
157+
comment += '- Optimize parameter handling\n\n';
158+
comment += '## Related Issues\n\n';
159+
comment += 'Fix #123\n\n';
160+
comment += '## Checklist\n\n';
161+
comment += '- [x] Code has been formatted with `mvn spotless:apply`\n';
162+
comment += '- [x] Code is self-reviewed\n';
163+
comment += '```\n';
164+
165+
// Find and delete previous check comments
166+
const { data: comments } = await github.rest.issues.listComments({
167+
owner: context.repo.owner,
168+
repo: context.repo.repo,
169+
issue_number: pr.number,
170+
});
171+
172+
const botComment = comments.find(comment =>
173+
comment.user.type === 'Bot' &&
174+
comment.body.includes('PR Content Check Report')
175+
);
176+
177+
if (botComment) {
178+
await github.rest.issues.deleteComment({
179+
owner: context.repo.owner,
180+
repo: context.repo.repo,
181+
comment_id: botComment.id,
182+
});
183+
}
184+
185+
// Post new comment
186+
await github.rest.issues.createComment({
187+
owner: context.repo.owner,
188+
repo: context.repo.repo,
189+
issue_number: pr.number,
190+
body: comment
191+
});
192+
193+
// Fail if there are errors
194+
if (errors.length > 0) {
195+
core.setFailed(`PR content check failed: ${errors.length} required item(s) incomplete`);
196+
}
197+
198+

0 commit comments

Comments
 (0)