Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:25:07 +08:00
commit f613de7a1a
13 changed files with 4333 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "open-source-contributions",
"description": "Create maintainer-friendly pull requests for open source projects with clean code submissions and professional communication. Prevents 16 common mistakes that cause PR rejection. Use when: contributing to public repositories, submitting PRs to community projects, migrating from contributor to maintainer workflows, or troubleshooting PR rejection, working on main branch errors, failing CI checks, or personal artifacts in commits.",
"version": "1.0.0",
"author": {
"name": "Jeremy Dawes",
"email": "jeremy@jezweb.net"
},
"skills": [
"./"
]
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Jeremy Dawes - Jezweb
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# open-source-contributions
Create maintainer-friendly pull requests for open source projects with clean code submissions and professional communication. Prevents 16 common mistakes that cause PR rejection. Use when: contributing to public repositories, submitting PRs to community projects, migrating from contributor to maintainer workflows, or troubleshooting PR rejection, working on main branch errors, failing CI checks, or personal artifacts in commits.

1233
SKILL.md Normal file

File diff suppressed because it is too large Load Diff

552
assets/bad-pr-example.md Normal file
View File

@@ -0,0 +1,552 @@
# Bad PR Example
This example demonstrates common mistakes that annoy maintainers and lead to PR rejection or delays. Learn what NOT to do!
---
## Example: Adding OAuth2 Authentication (Done Wrong)
### PR Title ❌
```
Updated code
```
**Why it's bad:**
- ❌ Too vague
- ❌ Doesn't describe what changed
- ❌ No type prefix (feat/fix/docs)
- ❌ Wrong tense (past instead of imperative)
- ❌ Lowercase (should capitalize)
**Should be:**
```
feat(auth): add OAuth2 support for Google and GitHub providers
```
---
### PR Description ❌
```markdown
## Changes
Added OAuth
## Testing
Works for me
```
**Why it's bad:**
- ❌ No explanation of WHAT was added
- ❌ No explanation of WHY it's needed
- ❌ No explanation of HOW it works
- ❌ No testing instructions for reviewers
- ❌ No issue links
- ❌ No screenshots
- ❌ "Works for me" is not helpful
**Result:** Maintainer has to ask multiple questions before even starting review.
---
### Files Changed (Messy!) ❌
```
.env # ❌ SECRETS COMMITTED!
.vscode/settings.json # ❌ Personal IDE config
SESSION.md # ❌ Personal development notes
planning/oauth-implementation.md # ❌ Planning documents
screenshots/debug-oauth-1.png # ❌ Debug screenshots
screenshots/debug-oauth-2.png # ❌ Debug screenshots
screenshots/test-local.png # ❌ Personal testing screenshots
test-manual.js # ❌ Temporary test file
NOTES.md # ❌ Personal notes
TODO.md # ❌ Personal todo list
node_modules/ # ❌ Dependencies (should be in .gitignore!)
package-lock.json # ❌ Lock file changes (not needed)
src/routes/auth.js # ✅ Actual feature code
src/routes/users.js # ❌ Unrelated changes
src/routes/posts.js # ❌ Unrelated changes
src/components/Header.js # ❌ Unrelated changes
src/utils/formatting.js # ❌ Unrelated refactoring
README.md # ✅ Documentation update
docs/authentication.md # ✅ OAuth documentation
```
**Problems:**
-**28 files changed** (way too many!)
-**Secrets committed** (.env file with API keys)
-**Personal artifacts** (SESSION.md, NOTES.md, planning/)
-**Unrelated changes** (users.js, posts.js, Header.js)
-**Mixed concerns** (feature + refactoring + bug fixes)
**Should be:** 5-8 files, only those directly related to OAuth feature.
---
### Commit History (Terrible!) ❌
```
WIP
fixed stuff
asdf
more changes
fix
actually working now
Final commit
Actually final
OK this one is final
oops forgot something
```
**Why it's bad:**
- ❌ 10 commits for one feature (should squash)
- ❌ Meaningless commit messages
- ❌ "WIP" commits (not production-ready)
- ❌ No explanation of what changed
- ❌ No issue links
- ❌ Commit history shows trial-and-error (should clean up)
**Should be:** 1-2 clean commits with proper messages.
---
### SESSION.md Content (Should Never Be Committed!) ❌
```markdown
# OAuth Implementation Session
## 2025-11-04
Started working on OAuth. Not sure if I should use passport or just implement it myself. Going to try passport first.
## 2025-11-05
Passport is confusing. Spent 3 hours debugging. Finally got it working but the code is messy.
TODO:
- Clean up the callback logic
- Add tests (maybe)
- Figure out how to handle errors
- Ask @maintainer about rate limiting?
NOTES:
- Google OAuth app ID: 123456789-abcdefgh.apps.googleusercontent.com
- Redirect URI: http://localhost:3000/auth/google/callback
- Remember to add to staging: https://staging.myapp.com/auth/google/callback
BUGS FOUND:
- Header component has alignment issue on mobile
- Post creation form doesn't validate correctly
- User profile page crashes when avatar is null
```
**Why this should NEVER be in a PR:**
- ❌ Personal development journal
- ❌ Reveals your confusion/struggle
- ❌ Contains unfinished TODOs
- ❌ Mentions unrelated bugs
- ❌ Unprofessional appearance
- ❌ Pollutes the project
---
### NOTES.md Content (Should Never Be Committed!) ❌
```markdown
# Development Notes
## OAuth Research
Looked at how GitHub and GitLab do OAuth. Their implementations are pretty complex. Mine is simpler.
## Design Decisions
- Using passport because it's easier
- Not implementing token refresh yet (can do later)
- Rate limiting - should probably add this but skipping for now
- Testing - added some tests but not complete coverage
## Things I'm Not Sure About
- Is the error handling good enough?
- Should I use sessions or JWT?
- Do I need to validate the email from OAuth providers?
## Known Issues
- Doesn't work in Safari (CORS issue)
- Memory leak in callback handler (need to fix)
- Missing rate limiting (security risk?)
```
**Why this hurts your PR:**
- ❌ Shows incomplete work
- ❌ Admits to known issues not mentioned in PR
- ❌ Reveals security concerns not addressed
- ❌ Makes maintainer lose confidence
- ❌ Creates more work for maintainer
---
### Communication During Review ❌
**Initial Comment:**
```
Here's my OAuth implementation. Let me know what you think.
```
**Why it's bad:**
- ❌ No context
- ❌ No explanation
- ❌ No testing instructions
- ❌ Sounds careless
---
**Response to Feedback (Poor):**
**Maintainer:** "Could you add tests for the error cases?"
**Bad Response:**
```
Tests are boring. The code works fine without them.
```
**Why it's bad:**
- ❌ Dismissive
- ❌ Unprofessional
- ❌ Doesn't follow project standards
- ❌ Shows lack of respect
---
**Maintainer:** "This PR is too large. Could you split it into smaller PRs?"
**Bad Response:**
```
It's all related though. I don't want to spend time splitting it up.
```
**Why it's bad:**
- ❌ Refuses reasonable request
- ❌ Doesn't consider reviewer's time
- ❌ Makes review harder
- ❌ Likely to be closed
---
**No Response for 2 Weeks**
**Maintainer:** "The tests are failing. Can you fix them?"
**Your response:** [Silence for 2 weeks]
**Why it's bad:**
- ❌ Wastes maintainer's time
- ❌ PR goes stale
- ❌ Likely to be closed
- ❌ Damages your reputation
---
### PR Metrics ❌
**Size:**
- Lines changed: 847
- Files changed: 28
- Commits: 10
**Problems:**
- ❌ Way too large (should be <200 lines)
- ❌ Too many files (includes unrelated changes)
- ❌ Messy commit history
**Timeline:**
- Submitted: Day 1
- Maintainer requests changes: Day 2
- No response: Days 3-16
- PR closed as stale: Day 17
---
## Specific Mistakes Breakdown
### 1. Committed Secrets ❌
**.env file contents:**
```
GOOGLE_CLIENT_ID=123456789-abcdefgh.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-abc123def456 # ❌ SECRET!
GITHUB_CLIENT_ID=Iv1.1234567890abcdef
GITHUB_CLIENT_SECRET=1234567890abcdef1234567890abcdef12345678 # ❌ SECRET!
DATABASE_URL=postgresql://admin:SuperSecret123@localhost/myapp # ❌ PASSWORD!
```
**Impact:**
- 🚨 Security breach!
- 🚨 Must rotate all secrets immediately
- 🚨 Potentially compromises production
- 🚨 Even if removed later, it's in git history
**What you should have done:**
- ✅ Only commit .env.example with placeholder values
- ✅ Add .env to .gitignore
- ✅ Never commit actual secrets
---
### 2. Including Unrelated Changes ❌
**src/routes/users.js:**
```javascript
// OAuth PR includes this "drive-by fix"
exports.getUser = async (req, res) => {
const user = await User.findById(req.params.id);
// Fixed bug where avatar URL was broken
if (user.avatar) {
user.avatar = user.avatar.replace('http://', 'https://');
}
res.json(user);
};
```
**Why it's bad:**
- ❌ Not related to OAuth feature
- ❌ Makes PR harder to review
- ❌ Mixed concerns
- ❌ If PR is reverted, this fix goes too
**What you should have done:**
- ✅ Create separate PR for bug fix
- ✅ Keep OAuth PR focused on OAuth only
---
### 3. Massive PR with No Breakdown ❌
**Includes all at once:**
- OAuth implementation (200 lines)
- Refactoring of existing auth (300 lines)
- Bug fixes in unrelated files (150 lines)
- UI updates (100 lines)
- Test updates (97 lines)
**Total: 847 lines in 28 files**
**Why it's bad:**
- ❌ Takes hours to review
- ❌ Hard to find bugs
- ❌ Difficult to discuss
- ❌ Can't merge incrementally
**What you should have done:**
- ✅ PR #1: Refactor existing auth (300 lines)
- ✅ PR #2: Add OAuth backend (200 lines)
- ✅ PR #3: Add OAuth UI (100 lines)
- ✅ PR #4: Fix related bugs (150 lines)
---
### 4. Poor Testing ❌
**test-manual.js (Committed by mistake!):**
```javascript
// Quick test script - DELETE BEFORE COMMIT!
const axios = require('axios');
async function testOAuth() {
// This only works on my machine
const response = await axios.get('http://localhost:3000/auth/google');
console.log('Works!');
}
testOAuth();
```
**Why it's bad:**
- ❌ Not a proper test
- ❌ Hardcoded localhost
- ❌ No assertions
- ❌ Comment says "DELETE BEFORE COMMIT"
- ❌ Clutters project
**What you should have done:**
- ✅ Delete this file
- ✅ Write proper tests in tests/auth/oauth.test.js
- ✅ Use project's testing framework
- ✅ Include assertions and edge cases
---
### 5. Missing Documentation ❌
**README.md changes:**
```markdown
## Authentication
We now have OAuth.
```
**Why it's bad:**
- ❌ No setup instructions
- ❌ No explanation of how it works
- ❌ No examples
- ❌ Unhelpful to users
**Should be:**
```markdown
## Authentication
### OAuth 2.0 Social Login
Users can sign in with Google or GitHub accounts.
#### Setup
1. Create OAuth apps:
- Google: https://console.cloud.google.com/apis/credentials
- GitHub: https://github.com/settings/developers
2. Add credentials to `.env`:
```
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
```
3. Restart server
#### Usage
Users will see "Sign in with Google" and "Sign in with GitHub" buttons on the login page.
For detailed implementation, see [docs/authentication.md](docs/authentication.md).
```
---
### 6. Ignoring CI Failures ❌
**CI Status:**
```
❌ Tests: 5 failing
❌ Lint: 23 errors
❌ Build: Failed
```
**Your response:** Submit PR anyway, hope maintainer doesn't notice
**Why it's bad:**
- ❌ Shows you didn't test
- ❌ Wastes CI resources
- ❌ Can't merge with failing CI
- ❌ Unprofessional
**What you should have done:**
- ✅ Fix all CI issues before submitting
- ✅ Run tests locally first: `npm test`
- ✅ Run lint locally: `npm run lint`
- ✅ Only submit when all checks pass
---
## The Result
**Maintainer's Response:**
```
Thanks for the PR, but there are several issues:
1. You've committed secrets in the .env file - this is a security issue
2. The PR includes unrelated changes (users.js, posts.js, Header.js)
3. Personal development files (SESSION.md, NOTES.md, planning/) shouldn't be here
4. The PR is too large - 847 lines across 28 files
5. Tests are failing
6. Missing proper documentation
7. test-manual.js is committed
Please:
- Remove all secrets and rotate them
- Create separate PRs for unrelated changes
- Remove personal development artifacts
- Fix the failing tests
- Add proper documentation
- Keep the PR focused on OAuth only
I'm closing this for now. Please feel free to submit a new PR addressing these issues.
```
**Status:** ❌ PR Closed
---
## Key Lessons
### What Went Wrong
1. **Security**: Committed secrets (.env file)
2. **Scope**: Too large, too many unrelated changes
3. **Artifacts**: Personal files committed (SESSION.md, NOTES.md)
4. **Testing**: Poor testing, CI failures
5. **Documentation**: Inadequate documentation
6. **Communication**: Poor responses to feedback
7. **Quality**: Messy commits, no code review
8. **Professionalism**: Dismissive attitude
### How to Fix It
1. **Security**
- Never commit secrets
- Use .env.example with placeholders
- Run pre-PR check script
2. **Scope**
- Keep PRs small (<200 lines)
- One feature per PR
- No unrelated changes
3. **Artifacts**
- Remove SESSION.md, NOTES.md, TODO.md
- Remove planning/ directory
- Remove debug screenshots
- Use clean-branch script
4. **Testing**
- Write proper tests
- Fix CI before submitting
- Test locally first
5. **Documentation**
- Update README
- Add setup instructions
- Include examples
6. **Communication**
- Be responsive
- Be respectful
- Accept feedback gracefully
7. **Quality**
- Clean commit history
- Proper commit messages
- Review your own code
8. **Professionalism**
- Respect maintainer's time
- Follow project conventions
- Be patient and courteous
---
## Comparison: Bad vs Good
| Aspect | Bad PR ❌ | Good PR ✅ |
|--------|-----------|-----------|
| **Title** | "Updated code" | "feat(auth): add OAuth2 support" |
| **Size** | 847 lines, 28 files | 180 lines, 9 files |
| **Commits** | 10 messy commits | 1 clean commit |
| **Files** | Includes SESSION.md, .env | Only relevant files |
| **Testing** | test-manual.js, CI failing | Proper tests, CI passing |
| **Docs** | "We now have OAuth" | Complete setup guide |
| **Secrets** | Committed .env | Only .env.example |
| **Scope** | OAuth + bugs + refactor | OAuth only |
| **Communication** | Dismissive | Professional |
| **Result** | Closed | Merged in 3 days |
---
**Remember:** Every mistake in this example is based on real PRs that have been rejected. Learn from these errors and follow the good PR example instead!

308
assets/good-pr-example.md Normal file
View File

@@ -0,0 +1,308 @@
# Good PR Example
This example demonstrates a well-structured pull request that follows best practices for open source contributions.
---
## Example: Adding OAuth2 Authentication
### PR Title
```
feat(auth): add OAuth2 support for Google and GitHub providers
```
**Why it's good:**
- ✅ Uses Conventional Commits format (feat)
- ✅ Includes scope (auth)
- ✅ Clear, specific description
- ✅ Under 50 characters
- ✅ Imperative mood
---
### PR Description
```markdown
## What?
Add OAuth2 authentication support for Google and GitHub providers, allowing users to sign in with their social accounts.
## Why?
Multiple users have requested social login to reduce friction during signup (issues #234, #156). This addresses a key pain point: 40% of attempted signups are abandoned at the password creation step according to our analytics.
This implements Key Result 2 of Q4 OKR1: "Reduce signup friction by 30%"
## How?
- Implemented OAuth2 flow using passport.js strategy pattern
- Added provider configuration via environment variables (no hardcoded secrets)
- Created callback routes for each provider:
- `/auth/google/callback`
- `/auth/github/callback`
- Updated user model to link social accounts with existing email-based accounts
- Added middleware to automatically merge accounts if user already exists with same email
- Implemented proper error handling for failed OAuth attempts
## Testing
### Setup
1. Create OAuth apps in developer consoles:
- Google: https://console.cloud.google.com/apis/credentials
- GitHub: https://github.com/settings/developers
2. Add credentials to `.env` file (see `.env.example` for required variables)
3. Run `npm install` to ensure passport dependencies are installed
### Manual Testing Steps
1. Start server: `npm start`
2. Navigate to `http://localhost:3000/login`
3. Click "Login with Google" button
4. Verify OAuth flow redirects to Google consent screen
5. Grant permissions
6. Verify redirect back to app with user logged in
7. Check user profile shows data from Google (name, email, avatar)
8. Repeat steps 3-7 for GitHub provider
### Test Cases Covered
- ✅ New user signup via OAuth
- ✅ Existing user login via OAuth
- ✅ Account merging (same email, different provider)
- ✅ Error handling (user denies permissions)
- ✅ Error handling (OAuth provider timeout)
- ✅ Security: CSRF token validation
### Automated Tests
```bash
npm test -- tests/auth/oauth.test.js
```
All 15 test cases pass, including edge cases.
## Checklist
- [x] Tests added/updated (tests/auth/oauth.test.js)
- [x] Documentation updated:
- [x] README.md (setup instructions)
- [x] docs/authentication.md (OAuth flow documentation)
- [x] .env.example (required environment variables)
- [x] CI passing (all checks green)
- [x] No breaking changes
- [x] Follows existing code style
- [x] Security review completed (no secrets committed)
## Related Issues
Closes #234
Relates to #156 (social login epic)
## Screenshots
### Login Page with OAuth Buttons
![OAuth Login Buttons](./screenshots/oauth-buttons.png)
*New social login buttons integrated into existing login page*
### OAuth Consent Screen (Google)
![Google Consent](./screenshots/google-consent.png)
*User experience during Google OAuth flow*
## Breaking Changes
None - this is additive functionality that doesn't affect existing authentication methods.
## Security Considerations
- OAuth tokens are stored securely using bcrypt hashing
- CSRF protection implemented for all OAuth routes
- State parameter used to prevent CSRF attacks
- No secrets committed to repository (all in .env)
- Rate limiting applied to OAuth endpoints
## Additional Notes
### Design Decisions
- **Chose passport.js** over custom implementation for security, maintenance, and community support
- **Used strategy pattern** to make adding new OAuth providers easier in future
- **Account merging** happens automatically based on email address (primary key)
- **No email verification required** for OAuth signups (providers already verify emails)
### Future Improvements
Consider in follow-up PRs:
- Add more providers (Twitter, LinkedIn, Microsoft)
- Implement OAuth token refresh logic
- Add rate limiting for OAuth endpoints
- Add admin dashboard for managing OAuth apps
### Migration Notes
No migration needed - existing users can continue using password authentication. OAuth is an additional option.
### Dependencies Added
- passport v0.6.0
- passport-google-oauth20 v2.0.0
- passport-github2 v0.1.12
All dependencies are actively maintained and have good security track records.
```
---
### Files Changed (Clean!)
```
.env.example # Environment variable examples (no secrets!)
README.md # Updated setup instructions
docs/authentication.md # OAuth documentation
package.json # Added passport dependencies
src/routes/auth.js # OAuth routes
src/middleware/authenticate.js # OAuth middleware
src/models/user.js # Updated user model
tests/auth/oauth.test.js # OAuth tests
tests/fixtures/users.json # Test fixtures
```
**What's NOT included:**
- ❌ No SESSION.md or notes files
- ❌ No planning/ directory
- ❌ No debug screenshots (only feature demos)
- ❌ No temporary test files
- ❌ No .env file (only .env.example)
- ❌ No personal artifacts
---
### Commit History (Clean!)
```
feat(auth): add OAuth2 support for Google and GitHub
Implemented OAuth2 authentication flow using passport.js.
Users can now sign in with Google or GitHub accounts.
Accounts are automatically merged if email matches existing user.
- Added OAuth routes and callbacks
- Updated user model to support social accounts
- Added comprehensive tests for OAuth flow
- Documented setup and usage
Closes #234
```
**Why it's good:**
- ✅ Single, focused commit
- ✅ Clear commit message
- ✅ Explains what and why
- ✅ Links issue
- ✅ Follows Conventional Commits
---
### Communication During Review
**Initial Comment (When Submitting):**
```
Hi @maintainer! 👋
I've implemented OAuth2 support as discussed in #234. I went with passport.js over a custom implementation because:
1. Battle-tested security
2. Well-maintained by the community
3. Easy to add more providers in future
I've tested this locally for the past week and also deployed to staging for integration testing. All existing auth flows remain unchanged - this is purely additive.
Ready for review when you have time! Happy to make any changes you'd like.
```
**Response to Feedback:**
```
> Could you add rate limiting to these endpoints?
Good idea! I've added rate limiting in commit abc1234:
- Max 5 OAuth attempts per IP per minute
- Returns 429 with Retry-After header
- Uses existing rate limiting middleware
Let me know if you'd prefer different limits!
```
**After Changes:**
```
@maintainer I've addressed all your feedback:
- ✅ Added rate limiting (commit abc1234)
- ✅ Updated docs with security considerations (commit def5678)
- ✅ Refactored callback logic as suggested (commit ghi9012)
Marked all conversations as resolved. Ready for re-review!
Thanks for the thorough feedback - the rate limiting suggestion was spot-on.
```
---
### PR Metrics
**Size:**
- Lines changed: 180
- Files changed: 9
- Commits: 1
**Result:**
- ✅ Ideal size for review
- ✅ Focused on one feature
- ✅ Easy to understand
- ✅ Quick to review
**Timeline:**
- Submitted: Day 1
- First review: Day 2
- Changes made: Day 2
- Approved: Day 3
- Merged: Day 3
**Why it was quick:**
- Clean, focused PR
- Comprehensive testing
- Good documentation
- Responsive to feedback
- No surprises or issues
---
## Key Takeaways
This PR demonstrates:
1. **Clear Communication**
- What/Why/How structure
- Testing instructions
- Design decisions explained
- Security considerations noted
2. **Proper Scope**
- One feature
- ~180 lines changed
- No unrelated changes
- Easy to review
3. **Complete Documentation**
- Updated README
- Added OAuth docs
- Included .env.example
- Comprehensive inline comments
4. **Thorough Testing**
- Automated tests
- Manual test steps
- Edge cases covered
- Deployed to staging first
5. **Professional Artifacts**
- No personal files
- No secrets
- Clean commit history
- Proper branch naming
6. **Excellent Communication**
- Polite and respectful
- Responsive to feedback
- Explains decisions
- Thanks reviewers
7. **Security Conscious**
- No secrets committed
- CSRF protection
- Rate limiting
- Security considerations documented
This is the standard to aim for in your pull requests!

81
plugin.lock.json Normal file
View File

@@ -0,0 +1,81 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:jezweb/claude-skills:skills/open-source-contributions",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "7ae82902e2041f78650cf6c998468d6077cb54b2",
"treeHash": "a5ed0be3adad9b9e436d1b851f17d92f37cda3323b14344a4902f39c4d4d26c2",
"generatedAt": "2025-11-28T10:19:05.922861Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "open-source-contributions",
"description": "Create maintainer-friendly pull requests for open source projects with clean code submissions and professional communication. Prevents 16 common mistakes that cause PR rejection. Use when: contributing to public repositories, submitting PRs to community projects, migrating from contributor to maintainer workflows, or troubleshooting PR rejection, working on main branch errors, failing CI checks, or personal artifacts in commits.",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "LICENSE",
"sha256": "b76f0805c81dad30acd0fa7aca893e4f834986e168549201c42a92e810956072"
},
{
"path": "README.md",
"sha256": "bc84341ca3867a7d42dd9d89d8eaa0326b6f9a76de91fb6a31d50895f53885b1"
},
{
"path": "SKILL.md",
"sha256": "1d6898ec2795b969f4768a253e4ac5780193f69ac34a291ae479531276698ede"
},
{
"path": "references/commit-message-guide.md",
"sha256": "99de91dcfbc148f82c1c31bd2d115a13863a113e287249abe4c1de93cddf0fea"
},
{
"path": "references/files-to-exclude.md",
"sha256": "296fd9310d53d57c48654e1e13876b8fe0e2c5d11da8d5bf51cc8f923e8bc82a"
},
{
"path": "references/pr-template.md",
"sha256": "cb077517e050d9610bf6fe83a7bb00767513be46d218f223d3beaee5a7b7b4a4"
},
{
"path": "references/pr-checklist.md",
"sha256": "69ba9e481e6e6209fc4d17fea8588886eb0634f8978daaa76fc3b59b3c542b42"
},
{
"path": "scripts/pre-pr-check.sh",
"sha256": "6e21d0c55651921b270f166f7cbbea244f0578506d78f984663c0c83497b4587"
},
{
"path": "scripts/clean-branch.sh",
"sha256": "0183418de9c4414aa40006a7a26f9c6ee04cade92de5eefe1bc5b5d1110e372c"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "0a0aa15f64627b970f0ca3b0bbf86390474a0994d963971ff72c438714d61434"
},
{
"path": "assets/good-pr-example.md",
"sha256": "11cf4e7376469c5bc334b54936fb794ecaffe5b09d9deaa857b832fb54a51d5c"
},
{
"path": "assets/bad-pr-example.md",
"sha256": "29cdd1bc4f676062dacf397342b366c08eb61f8637fb06ac08641436b4be3ab0"
}
],
"dirSha256": "a5ed0be3adad9b9e436d1b851f17d92f37cda3323b14344a4902f39c4d4d26c2"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,534 @@
# Commit Message Guide
A comprehensive guide to writing clear, consistent, and maintainable commit messages using the Conventional Commits format.
---
## Why Good Commit Messages Matter
- **Documentation**: Git history becomes a changelog
- **Code Review**: Easier to understand what changed and why
- **Debugging**: Quickly find when bugs were introduced
- **Automation**: Enables automatic changelog generation and versioning
- **Professionalism**: Shows attention to detail and respect for maintainers
---
## Conventional Commits Format
```
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]
```
### Components
**Type** (required): Category of change
**Scope** (optional): What section of codebase is affected
**Subject** (required): Brief description of change
**Body** (optional): Detailed explanation
**Footer** (optional): Issue references, breaking changes
---
## Types
### Primary Types
**feat**: New feature for the user
```
feat(auth): add OAuth2 support for Google and GitHub
```
**fix**: Bug fix for the user
```
fix(api): resolve memory leak in worker shutdown
```
**docs**: Documentation changes only
```
docs(readme): update installation instructions for v2.0
```
**style**: Code style changes (formatting, missing semicolons, etc.)
```
style(components): format code with Prettier
```
**refactor**: Code change that neither fixes bug nor adds feature
```
refactor(auth): extract middleware to separate module
```
**perf**: Performance improvement
```
perf(database): add index to user_id column
```
**test**: Adding or updating tests
```
test(auth): add OAuth flow integration tests
```
### Supporting Types
**build**: Changes to build system or dependencies
```
build(deps): upgrade React to v18.2.0
```
**ci**: CI configuration changes
```
ci(github): add automated release workflow
```
**chore**: Other changes that don't modify src or test files
```
chore(deps): update dev dependencies
```
**revert**: Revert a previous commit
```
revert: feat(auth): add OAuth2 support
This reverts commit abc123def456.
```
---
## Subject Line Rules
### The 7 Rules
1. **Limit to 50 characters** (hard limit: 72)
2. **Use imperative mood** ("Add" not "Added" or "Adds")
3. **Capitalize first word** after the colon
4. **Don't end with punctuation**
5. **Focus on WHAT changed** (body explains WHY)
6. **Be specific** but concise
7. **Start with type** (if using Conventional Commits)
### Examples
**Good:**
```
feat(api): add user authentication endpoint
fix(ui): resolve button alignment on mobile
docs(contributing): clarify PR submission process
refactor(utils): simplify date formatting logic
```
**Bad:**
```
Fixed stuff # Too vague
Added new feature to the authentication system that allows users to login with OAuth # Too long
updated code # Not specific, wrong tense
feat(api): add user authentication. # Don't end with period
Feat(api): add auth # Don't capitalize type
```
---
## Optional Scope
The scope provides context about what part of the codebase changed.
### Common Scopes
```
feat(auth): ... # Authentication
feat(api): ... # API layer
feat(ui): ... # User interface
feat(database): ... # Database
feat(docs): ... # Documentation
feat(tests): ... # Tests
fix(deps): ... # Dependencies
build(webpack): ... # Build tooling
```
### Project-Specific Scopes
Check the project's recent commits for conventions:
```bash
git log --oneline -20
```
### When to Omit Scope
Scope is optional. Omit when:
- Change affects multiple areas
- Project doesn't use scopes
- Scope would be too generic
```
feat: add dark mode support
docs: update README
```
---
## Body (Optional)
The body provides detailed explanation of WHAT and WHY (code shows HOW).
### Rules
- Separate from subject with blank line
- Wrap at 72 characters per line
- Explain motivation and context
- Contrast with previous behavior
- Use bullet points for multiple points
### Example
```
feat(api): add rate limiting to authentication endpoints
Users can now make up to 100 authentication attempts per hour
per IP address. This prevents brute force attacks while allowing
legitimate users to retry failed login attempts.
Implementation details:
- Uses Redis for distributed rate limiting
- Configurable via RATE_LIMIT_MAX environment variable
- Returns 429 status with Retry-After header when exceeded
- Resets hourly at top of the hour
Previous behavior allowed unlimited attempts, which was identified
as a security vulnerability in audit #456.
```
### When to Include Body
Include a body when:
- Change is complex or non-obvious
- Design decisions need explanation
- Previous behavior needs context
- Multiple related changes in one commit
- Security or performance implications
### When to Skip Body
Skip the body when:
- Change is self-explanatory
- Subject line tells the complete story
- Trivial changes (typos, formatting)
---
## Footer (Optional)
Footers provide metadata about the commit.
### Breaking Changes
Use `BREAKING CHANGE:` footer for breaking changes:
```
feat(api)!: change authentication endpoint path
BREAKING CHANGE: The authentication endpoint has moved from
/api/auth to /api/v2/auth. Update your API calls accordingly.
Migration guide available at docs/migration/v2.md
```
Note the `!` after the type indicates a breaking change.
### Issue References
Link issues using keywords for automatic closing:
```
fix(ui): resolve mobile layout issues
Fixes #123
Closes #456, #789
Relates to #234
```
**Closing Keywords:**
- `Closes #123`
- `Fixes #123`
- `Resolves #123`
- Also: close, fix, resolve (case insensitive)
### Co-authored-by
Credit co-authors:
```
feat(api): add GraphQL support
Co-authored-by: Jane Doe <jane@example.com>
Co-authored-by: John Smith <john@example.com>
```
### Other Footers
```
Reviewed-by: Name <email>
Signed-off-by: Name <email>
Acked-by: Name <email>
See-also: #123
```
---
## Complete Examples
### Example 1: Simple Feature
```
feat(ui): add dark mode toggle
Adds a toggle button in settings to switch between light and dark
themes. User preference is saved to localStorage and persists
across sessions.
Closes #234
```
### Example 2: Bug Fix
```
fix(api): prevent race condition in cache invalidation
The cache invalidation logic wasn't thread-safe, causing occasional
race conditions when multiple workers tried to invalidate the same
key simultaneously.
Solution:
- Added mutex locks around the critical section
- Implemented timeout for lock acquisition (5s)
- Added retry logic with exponential backoff
- Updated tests to verify thread-safety
Fixes #456
```
### Example 3: Breaking Change
```
feat(api)!: migrate to TypeScript and update endpoint contracts
BREAKING CHANGE: All API endpoints now return ISO 8601 date
strings instead of Unix timestamps. Update client code to parse
dates accordingly.
Additionally, authentication now requires JWT tokens in the
Authorization header instead of session cookies.
Migration guide: docs/migration/v3.md
Closes #567
```
### Example 4: Refactoring
```
refactor(auth): extract middleware to separate module
No functional changes, but auth logic is now easier to test and
maintain. Consolidated duplicate code from 5 route handlers into
reusable middleware functions.
Files affected:
- New: middleware/authenticate.js
- Updated: routes/*.js (5 files)
- Tests: tests/middleware/auth.test.js
Relates to #301 (technical debt epic)
```
### Example 5: Documentation
```
docs(api): add examples for authentication flows
Added code examples for:
- Basic authentication with username/password
- OAuth2 flow with Google
- API key authentication
- JWT token refresh
Examples include curl commands and JavaScript fetch() snippets.
Closes #678
```
### Example 6: Multiple Related Changes
```
fix(auth): resolve multiple OAuth edge cases
- Handle expired refresh tokens gracefully
- Prevent account linking when email doesn't match
- Add rate limiting to token refresh endpoint
- Log failed OAuth attempts for security monitoring
Each issue was related to OAuth implementation and fixing them
separately would have caused merge conflicts.
Fixes #123, #456, #789
```
---
## Tips for Writing Good Commit Messages
### Do:
✅ Write in imperative mood ("Add" not "Added")
```
feat: add user profile page
```
✅ Be specific about what changed
```
fix(api): resolve timeout in user search endpoint
```
✅ Explain WHY in the body
```
refactor(db): switch to connection pooling
The previous approach created a new connection for each request,
which caused performance issues under load. Connection pooling
reduces overhead and improves response times by 40%.
```
✅ Use the body for complex changes
✅ Reference issues and PRs
✅ Follow project conventions
### Don't:
❌ Use past tense
```
feat: added user profile page ❌
```
❌ Be vague
```
fix: bug fix ❌
update: changes ❌
```
❌ Write novels in the subject line
```
feat(api): add new user authentication endpoint with OAuth2 support for Google and GitHub that also includes rate limiting ❌
```
❌ Skip the type (if project uses Conventional Commits)
```
Add user profile page ❌
```
❌ Use abbreviations or jargon unnecessarily
```
fix(db): rm dup recs via opt idx ❌
```
❌ Combine unrelated changes in one commit
```
feat: add dark mode, fix typo in README, update dependencies ❌
```
---
## Real-World Examples from Popular Projects
### React
```
feat(react-dom): Add support for CSS Layers
Implements support for @layer, enabling better CSS encapsulation.
Fixes #24556
```
### Node.js
```
doc: add missing types to request and response
Added TypeScript type definitions for several Request and Response
methods that were previously missing from the declarations.
Fixes: #12345
Refs: #67890
```
### Kubernetes
```
fix: prevent pod creation with invalid security context
Adds validation to reject pods with both `runAsUser: 0` and
`allowPrivilegeEscalation: false`, which is an invalid combination.
Closes #12345
```
---
## Commit Message Checklist
Before committing, verify:
- [ ] Type is correct (feat, fix, docs, etc.)
- [ ] Subject line under 50 characters (max 72)
- [ ] Imperative mood ("Add" not "Added")
- [ ] First word capitalized
- [ ] No period at end
- [ ] Body explains WHY (if needed)
- [ ] Body wrapped at 72 characters
- [ ] Blank line between subject and body
- [ ] Issues referenced in footer
- [ ] Breaking changes noted with BREAKING CHANGE:
- [ ] Follows project conventions
---
## Tools & Automation
### Commitizen
Interactive tool for writing commits:
```bash
npm install -g commitizen
git cz
```
### Commitlint
Lint commit messages:
```bash
npm install --save-dev @commitlint/cli @commitlint/config-conventional
```
### Husky
Git hooks to enforce commit message format:
```bash
npm install --save-dev husky
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
```
---
## Resources
**Specifications:**
- Conventional Commits: https://www.conventionalcommits.org/
- Git Commit Guidelines: https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project
**Tools:**
- Commitizen: https://github.com/commitizen/cz-cli
- Commitlint: https://commitlint.js.org/
**Further Reading:**
- "How to Write a Git Commit Message": https://chris.beams.io/posts/git-commit/
- Angular Commit Guidelines: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit

View File

@@ -0,0 +1,533 @@
# Files to Exclude from Pull Requests
A comprehensive reference of files that should NEVER be included in open source pull requests, organized by category.
---
## Personal Development Artifacts
### Session & Notes Files
```
❌ SESSION.md # Session tracking
❌ NOTES.md # Development notes
❌ TODO.md # Personal todo lists
❌ SCRATCH.md # Scratch notes
❌ DEBUGGING.md # Debugging notes
❌ TESTING.md # Testing notes
❌ JOURNAL.md # Development journal
❌ IDEAS.md # Personal ideas
❌ THOUGHTS.md # Random thoughts
❌ WIP.md # Work in progress notes
```
### Planning Documents
```
❌ planning/ # Entire planning directory
❌ IMPLEMENTATION_PHASES.md # Phase-based planning
❌ DATABASE_SCHEMA.md # Database planning (unless adding to project)
❌ ARCHITECTURE.md # Architecture planning (unless adding to project)
❌ API_ENDPOINTS.md # API planning (unless adding to project)
❌ UI_COMPONENTS.md # UI planning (unless adding to project)
❌ PROJECT_SPEC.md # Project specifications
❌ ROADMAP.md # Personal roadmap
❌ MILESTONES.md # Personal milestones
```
### Research & Reference
```
❌ research-logs/ # Research directory
❌ references/ # Personal references (skill-specific)
❌ research-*.md # Research documents
❌ analysis-*.md # Analysis documents
❌ comparison-*.md # Comparison documents
❌ evaluation-*.md # Evaluation documents
```
---
## Screenshots & Visual Assets
### Debug & Development Screenshots
```
❌ screenshots/debug-*.png # Debugging screenshots
❌ screenshots/test-*.png # Testing screenshots
❌ screenshots/scratch-*.png # Scratch screenshots
❌ screenshot-*.png # Ad-hoc screenshots
❌ screen-recording-*.mp4 # Screen recordings
❌ before-after-local.png # Local comparisons
❌ demo-local.* # Local demos
❌ temp-visual.* # Temporary visuals
```
### When Screenshots ARE Okay
```
✅ docs/assets/ui-example.png # Documentation assets
✅ screenshots/feature-demo.png # Demonstrating feature in PR description
✅ docs/images/architecture.png # Architecture diagrams for project docs
```
**Rule of Thumb**: Only include screenshots if they:
1. Demonstrate a feature for the PR description
2. Are part of documentation updates
3. Would be useful to all users/developers
---
## Test Files (Situational)
### Temporary Test Files (NEVER Include)
```
❌ test-manual.js # Manual testing scripts
❌ test-debug.ts # Debugging tests
❌ test-quick.py # Quick validation tests
❌ scratch-test.sh # Scratch test scripts
❌ example-local.json # Local test data
❌ quick-test.* # Quick test files
❌ debug-test.* # Debug test files
❌ temp-test.* # Temporary tests
❌ playground.* # Playground files
❌ experiment.* # Experimental files
```
### Proper Test Files (Include These)
```
✅ tests/feature.test.js # Proper test suite
✅ tests/fixtures/data.json # Required test fixtures
✅ __tests__/component.tsx # Component tests
✅ spec/feature_spec.rb # RSpec tests
✅ test_feature.py # Python tests
```
**Rule**: Only include tests that:
1. Are part of the project's test suite structure
2. Follow project's testing conventions
3. Will be run by CI/other developers
4. Test the specific feature/fix in the PR
---
## Build Artifacts & Dependencies
### Build Output
```
❌ dist/ # Build output
❌ build/ # Build directory
❌ out/ # Output directory
❌ target/ # Rust/Java build directory
❌ bin/ # Binary output (usually)
❌ lib/ # Library output (usually)
❌ *.exe, *.dll, *.so # Compiled binaries
❌ *.o, *.obj # Object files
❌ *.pyc, *.pyo # Python compiled files
❌ __pycache__/ # Python cache
❌ .next/ # Next.js build
❌ .nuxt/ # Nuxt build
❌ .output/ # Nitro build
```
### Dependencies
```
❌ node_modules/ # Node dependencies
❌ vendor/ # Ruby/PHP dependencies
❌ venv/ # Python virtual environment
❌ .venv/ # Python virtual environment
❌ env/ # Environment directory
❌ Cargo.lock # Rust dependencies (situational)
❌ package-lock.json # NPM lock (situational)
❌ yarn.lock # Yarn lock (situational)
❌ pnpm-lock.yaml # PNPM lock (situational)
```
**Lock File Rule**: Only include lock files if:
- Project explicitly requires them (check CONTRIBUTING.md)
- You're adding/updating dependencies
- Project uses lock files (check existing files in repo)
### Cache & Temporary Build Files
```
❌ .cache/ # Cache directory
❌ .tmp/ # Temporary files
❌ .temp/ # Temporary files
❌ tmp/ # Temporary directory
❌ temp/ # Temporary directory
❌ *.cache # Cache files
❌ .eslintcache # ESLint cache
❌ .parcel-cache/ # Parcel cache
❌ .turbo/ # Turborepo cache
```
---
## IDE & Editor Files
### VS Code
```
❌ .vscode/ # VS Code settings (use global gitignore)
❌ *.code-workspace # Workspace files
```
### JetBrains (IntelliJ, WebStorm, etc.)
```
❌ .idea/ # IntelliJ settings
❌ *.iml # Module files
❌ *.ipr # Project files
❌ *.iws # Workspace files
```
### Vim
```
❌ *.swp # Swap files
❌ *.swo # Swap files
❌ *~ # Backup files
❌ .*.sw? # Swap files pattern
```
### Emacs
```
❌ *~ # Backup files
❌ \#*\# # Auto-save files
❌ .\#* # Lock files
```
### Sublime Text
```
❌ *.sublime-project # Project files
❌ *.sublime-workspace # Workspace files
```
**Exception**: If the project provides official IDE configurations (like .vscode/settings.json in the repo), you may update those if needed for the feature.
---
## Operating System Files
### macOS
```
❌ .DS_Store # Finder metadata
❌ .AppleDouble # Resource forks
❌ .LSOverride # Icon metadata
❌ ._* # Resource forks
```
### Windows
```
❌ Thumbs.db # Thumbnail cache
❌ ehthumbs.db # Thumbnail cache
❌ Desktop.ini # Folder settings
❌ $RECYCLE.BIN/ # Recycle bin
```
### Linux
```
❌ .directory # KDE directory settings
❌ .Trash-*/ # Trash directory
```
---
## Secrets & Credentials (CRITICAL!)
### Environment Files
```
❌ .env # Environment variables (NEVER!)
❌ .env.local # Local environment
❌ .env.development # Development environment
❌ .env.production # Production environment (NEVER!)
❌ .env.*.local # Any local env files
❌ config/local.json # Local configuration
❌ config/secrets.json # Secrets configuration
```
### Credentials
```
❌ credentials.json # Credentials file
❌ secrets.json # Secrets file
❌ auth.json # Authentication file
❌ token.txt # Token files
❌ api-keys.json # API keys
❌ service-account.json # Service account credentials
```
### Keys & Certificates
```
❌ *.key # Private keys
❌ *.pem # PEM certificates
❌ *.p12 # PKCS#12 certificates
❌ *.pfx # PFX certificates
❌ id_rsa # SSH private key
❌ id_dsa # SSH private key
❌ *.crt (sometimes) # Certificates
```
### Password & Secret Patterns
Look for these in file contents:
```
❌ password=
❌ api_key=
❌ api-key=
❌ apiKey=
❌ secret=
❌ token=
❌ access_token=
❌ private_key=
```
**CRITICAL**: Even if deleted later, secrets in git history are compromised. Use `git filter-branch` or BFG Repo-Cleaner if secrets are committed.
---
## Logs & Debugging
### Log Files
```
❌ *.log # Log files
❌ logs/ # Logs directory
❌ debug.log # Debug logs
❌ error.log # Error logs
❌ npm-debug.log # NPM debug logs
❌ yarn-debug.log # Yarn debug logs
❌ yarn-error.log # Yarn error logs
❌ lerna-debug.log # Lerna debug logs
```
### Debug Files
```
❌ debug-*.js # Debug scripts
❌ debug-*.py # Debug scripts
❌ trace-*.txt # Trace files
❌ profile-*.json # Profiling output
❌ *.prof # Profiling files
❌ *.trace # Trace files
```
### Crash Dumps
```
❌ core # Core dumps
❌ core.* # Core dumps
❌ *.dmp # Dump files
❌ crash-*.log # Crash logs
```
---
## Database & Data Files
### Database Files (Local Development)
```
❌ *.db # SQLite databases (local)
❌ *.sqlite # SQLite databases (local)
❌ *.sqlite3 # SQLite databases (local)
❌ dump.sql # Database dumps
❌ backup.sql # Database backups
❌ *.mdb # Access databases
```
### Data Files (Local/Personal)
```
❌ data/local/ # Local data directory
❌ data/personal/ # Personal data
❌ data/test-data.json # Test data (unless fixtures)
❌ sample-data-local.json # Local sample data
```
**Exception**: Include database files if:
- They're part of the project's test fixtures
- They're example/seed data for the project
- Project explicitly includes them (check existing repo)
---
## Coverage & Reports
### Test Coverage
```
❌ coverage/ # Coverage reports
❌ .coverage # Coverage data
❌ htmlcov/ # HTML coverage
❌ .nyc_output/ # NYC coverage
❌ lcov.info # LCOV coverage
```
### Reports
```
❌ reports/ # Generated reports
❌ test-results/ # Test results
❌ junit.xml # JUnit reports
❌ cypress/videos/ # Cypress videos
❌ cypress/screenshots/ # Cypress screenshots (unless demonstrating bug)
```
---
## Version Control (Other Than Git)
### SVN
```
❌ .svn/ # SVN metadata
```
### Mercurial
```
❌ .hg/ # Mercurial metadata
❌ .hgignore # Mercurial ignore
```
### CVS
```
❌ CVS/ # CVS metadata
❌ .cvsignore # CVS ignore
```
---
## What SHOULD Be Included
For reference, these ARE okay to include:
### Source Code
```
✅ src/ # Source code
✅ lib/ # Library code (if source, not compiled)
✅ app/ # Application code
✅ components/ # Component files
✅ utils/ # Utility functions
```
### Tests
```
✅ tests/ # Test directory
✅ __tests__/ # Jest tests
✅ spec/ # RSpec tests
✅ test_*.py # Python tests
```
### Documentation
```
✅ README.md # Project readme
✅ CHANGELOG.md # Changelog
✅ CONTRIBUTING.md # Contributing guide
✅ LICENSE # License file
✅ docs/ # Documentation directory
```
### Configuration (Project-level)
```
✅ .gitignore # Git ignore rules
✅ .eslintrc # ESLint config (if updating)
✅ .prettierrc # Prettier config (if updating)
✅ tsconfig.json # TypeScript config (if updating)
✅ package.json # NPM package file (if updating)
✅ Cargo.toml # Rust config (if updating)
✅ pyproject.toml # Python config (if updating)
```
### CI/CD (if part of feature)
```
✅ .github/workflows/ # GitHub Actions
✅ .gitlab-ci.yml # GitLab CI
✅ .travis.yml # Travis CI
✅ Jenkinsfile # Jenkins
```
### Migrations & Schema (if part of feature)
```
✅ migrations/ # Database migrations
✅ schema.sql # Database schema (if adding to project)
✅ seeds/ # Seed data (if part of project)
```
---
## How to Prevent Including These Files
### 1. Project .gitignore
Add patterns that benefit ALL developers:
```gitignore
# Build
dist/
build/
*.pyc
# Dependencies
node_modules/
vendor/
# Logs
*.log
# Secrets
.env
.env.local
*.key
*.pem
```
### 2. Global .gitignore (Recommended)
Add personal/OS-specific patterns:
```bash
# Configure global gitignore
git config --global core.excludesfile ~/.gitignore_global
# Add your patterns
echo ".DS_Store" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global
```
### 3. Local Exclusions (.git/info/exclude)
For patterns specific to YOUR workflow only:
```bash
echo "SESSION.md" >> .git/info/exclude
echo "NOTES.md" >> .git/info/exclude
echo "planning/" >> .git/info/exclude
echo "screenshots/debug-*" >> .git/info/exclude
```
**Difference**:
- `.gitignore` → Committed, affects everyone
- `~/.gitignore_global` → Your global settings, affects all your repos
- `.git/info/exclude` → This repo only, not committed
---
## Quick Check Commands
### List all tracked files:
```bash
git ls-files
```
### Check for specific patterns:
```bash
git ls-files | grep -E "SESSION|NOTES|TODO|planning"
```
### Find large files:
```bash
git ls-files | while read file; do
[ -f "$file" ] && stat -f%z "$file" "$file"
done | sort -rn | head -20
```
### Search for secrets in staged files:
```bash
git diff --cached | grep -iE "password|secret|api[_-]?key|token"
```
### Use the pre-PR check script:
```bash
./scripts/pre-pr-check.sh
```
---
## Resources
- **Pre-PR Check Script**: Automated scanning for these patterns
- **Clean Branch Script**: Remove common artifacts safely
- **GitHub's gitignore templates**: https://github.com/github/gitignore
---
**Remember**: When in doubt, DON'T include it. You can always add files later if needed, but removing them from git history is much harder.

351
references/pr-checklist.md Normal file
View File

@@ -0,0 +1,351 @@
# Pull Request Submission Checklist
A comprehensive checklist to ensure your PR is ready for review and meets open source contribution standards.
---
## Pre-Contribution Phase
**Before starting any work:**
- [ ] **Read CONTRIBUTING.md** - Found in root, .github/, or docs/
- [ ] **Read CODE_OF_CONDUCT.md** - Understand community expectations
- [ ] **Check if issue exists** - Search existing issues for your topic
- [ ] **Create issue first (if needed)** - For significant changes, discuss before coding
- [ ] **Comment on issue to claim work** - Prevents duplicate effort
```
"Hi! I'd like to work on this. My approach would be to [brief outline]."
```
- [ ] **Wait for acknowledgment** - Especially for large changes
- [ ] **Fork the repository** - If you don't have write access
- [ ] **Set up upstream remote**
```bash
git remote add upstream https://github.com/ORIGINAL/repo.git
```
- [ ] **Create feature branch** - NEVER work on main/master
```bash
git checkout -b feature/descriptive-name
```
- [ ] **Understand testing requirements** - Check what tests are expected
- [ ] **Identify code style tools** - Look for .eslintrc, .prettierrc, etc.
---
## Development Phase
**While coding:**
- [ ] **Follow project style guidelines** - Match existing code patterns
- [ ] **Write tests for new functionality** - Most projects require this
- [ ] **Update tests for changed behavior** - Keep tests in sync with code
- [ ] **Add/update documentation** - README, API docs, inline comments
- [ ] **Keep commits atomic** - One logical change per commit
- [ ] **Write good commit messages** - Follow Conventional Commits format
```
feat(scope): brief description
Longer explanation if needed
Fixes #123
```
- [ ] **Run linters and formatters** - Fix style issues during development
```bash
npm run lint
npm run format
```
- [ ] **Test locally frequently** - Don't wait until the end
- [ ] **Keep PR scope focused** - One feature/fix per PR
- [ ] **Sync with upstream regularly** - Avoid merge conflicts
```bash
git fetch upstream
git rebase upstream/main
```
---
## Pre-Submission Phase
### Code Quality
- [ ] **All tests pass locally**
```bash
npm test
# or
pytest
# or
cargo test
# or project's test command
```
- [ ] **Code builds successfully**
```bash
npm run build
```
- [ ] **Linter passes**
```bash
npm run lint
```
- [ ] **Formatter applied**
```bash
npm run format
```
- [ ] **Code coverage maintained** - If project has minimum thresholds
- [ ] **No compiler warnings** - Clean build output
- [ ] **Manual testing completed** - Test the actual functionality
### Code Review (Self)
- [ ] **Review your own diff**
```bash
git diff origin/main
```
- [ ] **No debugging code** - Remove console.logs, debugger statements
- [ ] **No commented-out code** - Remove dead code
- [ ] **No TODO comments** - Complete work or create follow-up issues
- [ ] **Consistent naming** - Variables, functions, files match conventions
- [ ] **Proper error handling** - Don't swallow errors silently
- [ ] **Edge cases considered** - Null checks, empty arrays, etc.
### Cleanup (Critical!)
Run the pre-PR check script:
```bash
./scripts/pre-pr-check.sh
```
- [ ] **Remove SESSION.md** - Personal session tracking
- [ ] **Remove NOTES.md** - Development notes
- [ ] **Remove TODO.md** - Personal todo lists
- [ ] **Remove planning/* directory** - Project planning documents
- [ ] **Remove debug screenshots** - Screenshots used during debugging
- Keep only screenshots demonstrating features for PR description
- [ ] **Remove temporary test files**
- test-manual.js, test-debug.ts, quick-test.py
- [ ] **Remove personal workflow files**
- scratch.*, temp.*, debug.*
- [ ] **No IDE/editor files**
- .vscode/, .idea/, *.swp
- Should be in global .gitignore, not committed
- [ ] **No OS-specific files**
- .DS_Store, Thumbs.db, desktop.ini
- [ ] **No build artifacts**
- dist/, build/, node_modules/, __pycache__/
- [ ] **No secrets or credentials**
- .env, credentials.json, *.key, *.pem
- Double-check with: `git diff | grep -i "password\|secret\|key"`
- [ ] **No large binary files** - Unless necessary for the PR
- [ ] **No unrelated changes** - Only changes relevant to this PR
### Git Hygiene
- [ ] **Commits are clean** - No "WIP" or "fix typo" commits
- Consider squashing if needed
- [ ] **Commit messages follow conventions** - Conventional Commits format
- [ ] **No merge conflicts** - Rebase on latest upstream/main
```bash
git fetch upstream
git rebase upstream/main
```
- [ ] **Branch is up to date** - Latest changes from main included
- [ ] **On feature branch** - Not on main/master
---
## PR Creation Phase
### PR Description
- [ ] **Title follows conventions** - Conventional Commits format
```
feat(auth): add OAuth2 support
fix(api): resolve memory leak
docs(readme): update installation
```
- [ ] **Uses What/Why/How structure**
- What: Brief description of changes
- Why: Reasoning and context
- How: Implementation approach
- [ ] **Testing instructions included** - Step-by-step how to test
- [ ] **Screenshots for visual changes** - Before/after if applicable
- [ ] **Breaking changes noted** - If any
- [ ] **Links to related issues** - Use closing keywords
```
Closes #123
Fixes #456
Relates to #789
```
- [ ] **Checklist included** - Tests, docs, CI status
- [ ] **Description is clear** - Reviewer can understand without asking questions
### PR Quality
- [ ] **PR is reasonably sized**
- Ideal: < 50 lines
- Good: < 200 lines
- Max: < 400 lines
- If larger, explain why or split into multiple PRs
- [ ] **PR is focused** - One feature/fix/refactor, not multiple unrelated changes
- [ ] **No unrelated changes** - No "drive-by fixes" in unrelated files
- [ ] **All changed files are intentional** - Review git status
### GitHub Settings
- [ ] **Pushed to feature branch on fork**
```bash
git push origin feature/my-feature
```
- [ ] **PR targets correct branch** - Usually main or develop
- [ ] **Assigned labels** - If you have permission
- [ ] **Requested reviewers** - If known and appropriate
- [ ] **Linked to project/milestone** - If applicable
- [ ] **Set as draft** - If not ready for full review yet
```bash
gh pr create --draft
```
---
## Post-Submission Phase
### Monitor CI/Checks
- [ ] **CI is running** - Green checkmarks appearing
- [ ] **All checks pass** - No failures
- [ ] **Fix failures immediately** - Don't wait for review if CI fails
- [ ] **Watch for build notifications** - Email/GitHub notifications
### Communication
- [ ] **Responsive to feedback** - Reply within 24-48 hours
- [ ] **Address all review comments** - Even if just "Acknowledged"
- [ ] **Mark conversations resolved** - After addressing feedback
- [ ] **Request re-review** - After making changes
```bash
gh pr ready # if was draft
```
- [ ] **Thank reviewers** - Shows appreciation for their time
- [ ] **Professional tone** - Courteous and respectful
- [ ] **Ask for clarification** - If feedback is unclear
- [ ] **Be patient** - Reviewers are often volunteers
### Updates
- [ ] **Keep PR updated** - Rebase if main moves forward
```bash
git fetch upstream
git rebase upstream/main
git push origin feature/my-feature --force-with-lease
```
- [ ] **Fix requested changes** - Implement feedback
- [ ] **Update documentation** - If requirements change
- [ ] **Squash commits** - If maintainer requests
---
## Ready to Submit?
**Final verification:**
```bash
# 1. Run pre-PR check
./scripts/pre-pr-check.sh
# 2. Review changes
git status
git diff origin/main --stat
# 3. Verify tests pass
npm test
# 4. Verify build succeeds
npm run build
# 5. Check commit messages
git log --oneline -5
# 6. Push to your fork
git push origin feature/my-feature
# 7. Create PR
gh pr create --fill
# or
gh pr create --title "feat: ..." --body "$(cat pr-description.md)"
```
---
## Common Mistakes Checklist
Avoid these common errors:
- [ ] ❌ Not reading CONTRIBUTING.md
- [ ] ❌ Including personal artifacts (SESSION.md, planning/*)
- [ ] ❌ Submitting massive PR (>400 lines)
- [ ] ❌ Not testing before submission
- [ ] ❌ Working on already assigned issue
- [ ] ❌ Not discussing large changes first
- [ ] ❌ Being impatient or unresponsive
- [ ] ❌ Not updating documentation
- [ ] ❌ Ignoring code style
- [ ] ❌ Ignoring CI failures
- [ ] ❌ Including unrelated changes
- [ ] ❌ Not linking issues properly
- [ ] ❌ Committing secrets
- [ ] ❌ Force-pushing without warning
- [ ] ❌ Working on main/master branch
---
## Project-Specific Checklist
Add project-specific items here based on CONTRIBUTING.md:
- [ ] _[Project-specific requirement 1]_
- [ ] _[Project-specific requirement 2]_
- [ ] _[Project-specific requirement 3]_
---
## Quick Reference: Essential Commands
```bash
# Setup
git clone https://github.com/YOUR-USERNAME/repo.git
git remote add upstream https://github.com/ORIGINAL/repo.git
git checkout -b feature/my-feature
# Development
npm run lint
npm test
npm run build
git add .
git commit -m "feat(scope): description"
# Pre-submission
./scripts/pre-pr-check.sh
git status
git diff origin/main
# Submission
git push origin feature/my-feature
gh pr create --fill
# After feedback
git fetch upstream
git rebase upstream/main
# make changes
git push origin feature/my-feature --force-with-lease
```
---
## Resources
- **Pre-PR Check Script**: `./scripts/pre-pr-check.sh`
- **Clean Branch Script**: `./scripts/clean-branch.sh`
- **PR Template**: `./references/pr-template.md`
- **Commit Message Guide**: `./references/commit-message-guide.md`
- **Files to Exclude**: `./references/files-to-exclude.md`
---
**Remember**: The goal is to make the maintainer's job as easy as possible. A well-prepared PR shows respect for their time and increases the likelihood of quick acceptance.

266
references/pr-template.md Normal file
View File

@@ -0,0 +1,266 @@
# Pull Request Template
Use this template when creating pull requests to open source projects. Adapt as needed based on the project's CONTRIBUTING.md guidelines.
---
## Standard PR Template (What/Why/How)
```markdown
## What?
[Brief, clear description of what this PR does - 1-2 sentences]
## Why?
[Explain the reasoning, problem being solved, or business value - 2-3 sentences]
## How?
[Describe the implementation approach and key decisions - bullet points work well]
- Key change 1
- Key change 2
- Key change 3
## Testing
[Step-by-step instructions for reviewers to test the changes]
1. Step 1
2. Step 2
3. Expected result
## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] CI passing
- [ ] Breaking changes documented (if any)
- [ ] Follows project code style
## Related Issues
Closes #[issue number]
Relates to #[issue number]
## Screenshots (if applicable)
[Add screenshots for visual changes, UI updates, or bug fixes]
## Additional Notes
[Any other context, concerns, or questions for reviewers]
```
---
## Example: Feature Addition
```markdown
## What?
Add OAuth2 authentication support for Google and GitHub providers
## Why?
Users have requested social login to reduce friction during signup. This implements Key Result 2 of Q4 OKR1 and addresses multiple user requests from issue #234.
## How?
- Implemented OAuth2 flow using passport.js strategy pattern
- Added provider configuration via environment variables
- Created callback routes for each provider (/auth/google/callback, /auth/github/callback)
- Updated user model to link social accounts with existing email-based accounts
- Added middleware to merge accounts if user already exists
## Testing
1. Set up OAuth apps in Google and GitHub developer consoles
2. Add credentials to `.env` file (see `.env.example` for required variables)
3. Run `npm install` to ensure passport dependencies are installed
4. Start server: `npm start`
5. Navigate to `/login`
6. Click "Login with Google" button
7. Verify OAuth flow redirects correctly
8. Verify user profile data merges correctly with existing account (if applicable)
9. Test GitHub provider following same steps
## Checklist
- [x] Tests added for OAuth flow (see tests/auth/oauth.test.js)
- [x] Documentation updated (see docs/authentication.md)
- [x] CI passing
- [x] No breaking changes
- [x] Follows existing code style
- [x] Environment variables documented in .env.example
## Related Issues
Closes #234
Relates to #156 (social login epic)
## Screenshots
![OAuth Login Buttons](./screenshots/oauth-buttons.png)
*New social login buttons on login page*
## Additional Notes
- Chose passport.js over custom implementation for security and maintenance
- Used strategy pattern to make adding new providers easier in future
- Account merging happens automatically based on email address
- Consider adding rate limiting for OAuth endpoints in future PR
```
---
## Example: Bug Fix
```markdown
## What?
Fix memory leak in worker process shutdown
## Why?
The worker pool wasn't properly cleaning up connections when shutting down gracefully, leading to memory leaks over time. This was causing production issues on long-running instances and reported in #456.
## How?
- Added connection cleanup in worker shutdown handler
- Implemented timeout for graceful shutdown (30s default)
- Added mutex locks to prevent race conditions during cleanup
- Updated tests to verify proper cleanup
## Testing
1. Run load test: `npm run test:load`
2. Monitor memory usage: `npm run monitor:memory`
3. Trigger graceful shutdown: `kill -SIGTERM <pid>`
4. Verify memory is released (check monitor output)
5. Run for 24 hours to verify no gradual memory increase
Manual testing:
- Tested on staging for 48 hours with production load
- Memory usage remained stable at ~120MB
- Previous behavior showed gradual increase to 2GB+ over 24h
## Checklist
- [x] Tests added for shutdown cleanup
- [x] Documentation updated (shutdown behavior in README)
- [x] CI passing
- [x] No breaking changes
- [x] Tested on staging environment
## Related Issues
Fixes #456
## Additional Notes
- Considered force-killing workers after timeout, but went with graceful degradation
- Mutex implementation follows existing pattern in connection-pool.js
- Backward compatible with existing shutdown handlers
```
---
## Example: Refactoring
```markdown
## What?
Refactor authentication middleware to improve testability and reduce duplication
## Why?
The authentication logic was duplicated across 5 different route handlers, making it difficult to test and maintain. This refactoring consolidates the logic into reusable middleware.
## How?
- Extracted auth logic into `middleware/authenticate.js`
- Created composable middleware functions:
- `requireAuth()` - Basic authentication check
- `requireRole(role)` - Role-based access control
- `optionalAuth()` - Sets user if authenticated, continues if not
- Updated all routes to use new middleware
- Maintained backward compatibility with existing behavior
## Testing
1. Run full test suite: `npm test`
2. Verify authentication still works:
- Try accessing protected route without token (should get 401)
- Access with valid token (should succeed)
- Access with invalid token (should get 401)
3. Verify role-based access:
- User role trying admin endpoint (should get 403)
- Admin role trying admin endpoint (should succeed)
All existing tests pass without modification, demonstrating backward compatibility.
## Checklist
- [x] All existing tests pass
- [x] Added tests for new middleware functions
- [x] Documentation updated
- [x] CI passing
- [x] No breaking changes
- [x] Code coverage maintained
## Related Issues
Relates to #301 (technical debt epic)
## Additional Notes
- No changes to API contracts - purely internal refactoring
- Reduces code duplication from ~200 lines to ~50 lines
- Future PRs can add new auth strategies more easily
- All 5 route handlers tested individually to verify behavior unchanged
```
---
## Example: Documentation Update
```markdown
## What?
Update installation instructions for v2.0 and add troubleshooting section
## Why?
Users have reported confusion about new installation requirements in v2.0. Multiple support requests (#567, #589, #601) asking about the same issues.
## How?
- Updated README.md with new installation steps
- Added prerequisites section (Node.js 18+, npm 9+)
- Created troubleshooting guide for common issues
- Added examples for different deployment scenarios
- Fixed typos and outdated links
## Testing
- Followed installation steps on fresh Ubuntu 22.04 VM
- Tested on macOS Ventura
- Verified all links work
- Asked non-technical user to follow guide (successfully completed)
## Checklist
- [x] All links verified working
- [x] Code examples tested
- [x] Markdown formatting validated
- [x] Screenshots updated to v2.0 UI
- [x] Spelling and grammar checked
## Related Issues
Closes #567, #589, #601
## Screenshots
N/A (documentation only)
## Additional Notes
- Kept v1.0 migration guide in separate file (MIGRATION.md)
- Added FAQ section based on common support questions
- Consider adding video walkthrough in future
```
---
## Tips for Writing Good PR Descriptions
### Do:
✅ Be specific and clear
✅ Explain WHY, not just WHAT
✅ Provide testing instructions
✅ Link related issues
✅ Include screenshots for visual changes
✅ Note breaking changes prominently
✅ Keep it concise but complete
### Don't:
❌ Just repeat the commit message
❌ Leave sections empty ("TODO", "TBD")
❌ Assume reviewers know the context
❌ Include implementation details better suited for code comments
❌ Write a novel (keep it scannable)
❌ Skip testing instructions
---
## Project-Specific Variations
Some projects have specific PR template requirements. Check for:
- `.github/PULL_REQUEST_TEMPLATE.md` in the repository
- Instructions in CONTRIBUTING.md
- Examples in recently merged PRs
**Always adapt this template to match project expectations.**

190
scripts/clean-branch.sh Executable file
View File

@@ -0,0 +1,190 @@
#!/bin/bash
# Clean Branch Script
# Safely removes common personal development artifacts before PR submission
# Part of the open-source-contributions skill
set -e
# Colors for output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}====================================${NC}"
echo -e "${BLUE} Clean Branch for PR${NC}"
echo -e "${BLUE}====================================${NC}"
echo ""
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}✗ Not in a git repository${NC}"
exit 1
fi
# Interactive mode flag
INTERACTIVE=true
if [ "$1" = "--non-interactive" ] || [ "$1" = "-y" ]; then
INTERACTIVE=false
fi
# Files to potentially remove
PERSONAL_FILES=(
"SESSION.md"
"NOTES.md"
"TODO.md"
"SCRATCH.md"
"DEBUGGING.md"
"TESTING.md"
)
FOUND_FILES=()
echo -e "${BLUE}Scanning for personal development artifacts...${NC}"
echo ""
# Check for personal files
for file in "${PERSONAL_FILES[@]}"; do
if git ls-files --error-unmatch "$file" > /dev/null 2>&1; then
FOUND_FILES+=("$file")
echo -e "${YELLOW} Found: $file${NC}"
fi
done
# Check for planning directory
if git ls-files | grep -q "^planning/"; then
FOUND_FILES+=("planning/")
echo -e "${YELLOW} Found: planning/* directory${NC}"
git ls-files | grep "^planning/" | head -5 | sed 's/^/ - /'
PLANNING_COUNT=$(git ls-files | grep "^planning/" | wc -l)
if [ "$PLANNING_COUNT" -gt 5 ]; then
echo -e "${YELLOW} ... and $((PLANNING_COUNT - 5)) more files${NC}"
fi
fi
# Check for debug screenshots
DEBUG_SCREENSHOTS=$(git ls-files | grep -E "(debug|test|scratch).*\.(png|jpg|jpeg|gif)" || true)
if [ -n "$DEBUG_SCREENSHOTS" ]; then
echo -e "${YELLOW} Found: debug/test screenshots${NC}"
echo "$DEBUG_SCREENSHOTS" | sed 's/^/ - /'
FOUND_FILES+=("screenshots-debug")
fi
# Check for temporary test files
TEMP_TESTS=$(git ls-files | grep -iE "(test-manual|test-debug|quick-test|scratch-test|example-local)" || true)
if [ -n "$TEMP_TESTS" ]; then
echo -e "${YELLOW} Found: temporary test files${NC}"
echo "$TEMP_TESTS" | sed 's/^/ - /'
FOUND_FILES+=("temp-tests")
fi
echo ""
# If nothing found, exit
if [ ${#FOUND_FILES[@]} -eq 0 ]; then
echo -e "${GREEN}✓ No personal artifacts found!${NC}"
echo -e "${GREEN}Your branch is clean.${NC}"
exit 0
fi
# Confirm removal
if [ "$INTERACTIVE" = true ]; then
echo -e "${YELLOW}These files should not be included in your PR.${NC}"
echo -e "${BLUE}Would you like to remove them? (y/n)${NC}"
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Cancelled. No files removed.${NC}"
exit 0
fi
fi
echo ""
echo -e "${BLUE}Removing files...${NC}"
REMOVED_COUNT=0
# Remove personal files
for file in "${PERSONAL_FILES[@]}"; do
if git ls-files --error-unmatch "$file" > /dev/null 2>&1; then
git rm --cached "$file" 2>/dev/null || git rm "$file" 2>/dev/null || true
echo -e "${GREEN} ✓ Removed: $file${NC}"
((REMOVED_COUNT++))
fi
done
# Remove planning directory
if git ls-files | grep -q "^planning/"; then
git rm --cached -r "planning/" 2>/dev/null || git rm -r "planning/" 2>/dev/null || true
echo -e "${GREEN} ✓ Removed: planning/* directory${NC}"
((REMOVED_COUNT++))
fi
# Remove debug screenshots (interactive)
if [ -n "$DEBUG_SCREENSHOTS" ]; then
if [ "$INTERACTIVE" = true ]; then
echo ""
echo -e "${YELLOW}Found debug screenshots. Remove these too? (y/n)${NC}"
echo "$DEBUG_SCREENSHOTS" | sed 's/^/ - /'
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "$DEBUG_SCREENSHOTS" | while read -r file; do
git rm --cached "$file" 2>/dev/null || git rm "$file" 2>/dev/null || true
echo -e "${GREEN} ✓ Removed: $file${NC}"
done
((REMOVED_COUNT++))
fi
else
echo "$DEBUG_SCREENSHOTS" | while read -r file; do
git rm --cached "$file" 2>/dev/null || git rm "$file" 2>/dev/null || true
done
echo -e "${GREEN} ✓ Removed: debug screenshots${NC}"
((REMOVED_COUNT++))
fi
fi
# Remove temporary test files (interactive)
if [ -n "$TEMP_TESTS" ]; then
if [ "$INTERACTIVE" = true ]; then
echo ""
echo -e "${YELLOW}Found temporary test files. Remove these too? (y/n)${NC}"
echo "$TEMP_TESTS" | sed 's/^/ - /'
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "$TEMP_TESTS" | while read -r file; do
git rm --cached "$file" 2>/dev/null || git rm "$file" 2>/dev/null || true
echo -e "${GREEN} ✓ Removed: $file${NC}"
done
((REMOVED_COUNT++))
fi
else
echo "$TEMP_TESTS" | while read -r file; do
git rm --cached "$file" 2>/dev/null || git rm "$file" 2>/dev/null || true
done
echo -e "${GREEN} ✓ Removed: temporary test files${NC}"
((REMOVED_COUNT++))
fi
fi
echo ""
echo -e "${BLUE}====================================${NC}"
if [ $REMOVED_COUNT -gt 0 ]; then
echo -e "${GREEN}✓ Cleaned $REMOVED_COUNT artifact(s)${NC}"
echo ""
echo -e "${BLUE}Next steps:${NC}"
echo -e " 1. Review changes: ${YELLOW}git status${NC}"
echo -e " 2. Commit removal: ${YELLOW}git commit -m 'chore: remove personal development artifacts'${NC}"
echo -e " 3. Re-run check: ${YELLOW}./scripts/pre-pr-check.sh${NC}"
echo -e " 4. Push changes: ${YELLOW}git push${NC}"
else
echo -e "${GREEN}✓ No files removed${NC}"
fi
echo ""
echo -e "${YELLOW}Note:${NC} Files are removed from git tracking but still exist locally."
echo -e "Add them to .git/info/exclude to prevent re-adding:"
echo ""
echo -e "${BLUE}echo 'SESSION.md' >> .git/info/exclude${NC}"
echo -e "${BLUE}echo 'planning/' >> .git/info/exclude${NC}"

249
scripts/pre-pr-check.sh Executable file
View File

@@ -0,0 +1,249 @@
#!/bin/bash
# Pre-PR Check Script
# Scans for common personal development artifacts before PR submission
# Part of the open-source-contributions skill
set -e
# Colors for output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}====================================${NC}"
echo -e "${BLUE} Pre-PR Validation Check${NC}"
echo -e "${BLUE}====================================${NC}"
echo ""
ERRORS=0
WARNINGS=0
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}✗ Not in a git repository${NC}"
exit 1
fi
# Get current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo -e "${BLUE}Current branch:${NC} $CURRENT_BRANCH"
echo ""
# Check 1: Personal Development Artifacts
echo -e "${BLUE}[1/8] Checking for personal development artifacts...${NC}"
PERSONAL_FILES=(
"SESSION.md"
"NOTES.md"
"TODO.md"
"SCRATCH.md"
"DEBUGGING.md"
"TESTING.md"
)
for file in "${PERSONAL_FILES[@]}"; do
if git ls-files --error-unmatch "$file" > /dev/null 2>&1; then
echo -e "${RED} ✗ Found: $file (should not be in PR)${NC}"
((ERRORS++))
fi
done
# Check planning directory
if git ls-files | grep -q "^planning/"; then
echo -e "${RED} ✗ Found: planning/* directory (should not be in PR)${NC}"
git ls-files | grep "^planning/" | head -5 | sed 's/^/ - /'
((ERRORS++))
fi
if [ $ERRORS -eq 0 ]; then
echo -e "${GREEN} ✓ No personal development artifacts found${NC}"
fi
echo ""
# Check 2: Screenshots and Visual Assets
echo -e "${BLUE}[2/8] Checking for debug screenshots...${NC}"
DEBUG_SCREENSHOTS=$(git ls-files | grep -E "screenshot.*\.(png|jpg|jpeg|gif|mp4|mov)" || true)
if [ -n "$DEBUG_SCREENSHOTS" ]; then
echo -e "${YELLOW} ⚠ Found screenshots:${NC}"
echo "$DEBUG_SCREENSHOTS" | sed 's/^/ - /'
echo -e "${YELLOW} → Ensure these are needed for PR description (demonstrating feature)${NC}"
echo -e "${YELLOW} → Remove if they're just debugging artifacts${NC}"
((WARNINGS++))
else
echo -e "${GREEN} ✓ No screenshot files found${NC}"
fi
echo ""
# Check 3: Temporary Test Files
echo -e "${BLUE}[3/8] Checking for temporary test files...${NC}"
TEMP_TEST_PATTERNS=(
"test-manual"
"test-debug"
"quick-test"
"scratch-test"
"example-local"
"debug-"
"temp-"
"tmp-"
)
TEMP_TESTS_FOUND=0
for pattern in "${TEMP_TEST_PATTERNS[@]}"; do
MATCHES=$(git ls-files | grep -i "$pattern" || true)
if [ -n "$MATCHES" ]; then
echo -e "${RED} ✗ Found temporary test files matching '$pattern':${NC}"
echo "$MATCHES" | sed 's/^/ - /'
((ERRORS++))
TEMP_TESTS_FOUND=1
fi
done
if [ $TEMP_TESTS_FOUND -eq 0 ]; then
echo -e "${GREEN} ✓ No temporary test files found${NC}"
fi
echo ""
# Check 4: Large Files
echo -e "${BLUE}[4/8] Checking for large files (>1MB)...${NC}"
LARGE_FILES=$(git ls-files | while read file; do
if [ -f "$file" ]; then
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
if [ "$size" -gt 1048576 ]; then
echo "$file ($(numfmt --to=iec-i --suffix=B $size 2>/dev/null || echo "$((size / 1024))KB"))"
fi
fi
done)
if [ -n "$LARGE_FILES" ]; then
echo -e "${YELLOW} ⚠ Found large files:${NC}"
echo "$LARGE_FILES" | sed 's/^/ - /'
echo -e "${YELLOW} → Ensure these are necessary for the PR${NC}"
((WARNINGS++))
else
echo -e "${GREEN} ✓ No large files found${NC}"
fi
echo ""
# Check 5: Potential Secrets
echo -e "${BLUE}[5/8] Checking for potential secrets...${NC}"
SECRET_PATTERNS=(
"\.env$"
"\.env\.local$"
"credentials\.json$"
"\.key$"
"\.pem$"
"secret"
"password"
"api[_-]?key"
"access[_-]?token"
)
SECRETS_FOUND=0
for pattern in "${SECRET_PATTERNS[@]}"; do
MATCHES=$(git ls-files | grep -iE "$pattern" || true)
if [ -n "$MATCHES" ]; then
echo -e "${RED} ✗ Found potential secrets matching '$pattern':${NC}"
echo "$MATCHES" | sed 's/^/ - /'
((ERRORS++))
SECRETS_FOUND=1
fi
done
if [ $SECRETS_FOUND -eq 0 ]; then
echo -e "${GREEN} ✓ No potential secrets found in file names${NC}"
fi
echo ""
# Check 6: PR Size
echo -e "${BLUE}[6/8] Checking PR size...${NC}"
# Get default branch (usually main or master)
DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
if [ -z "$DEFAULT_BRANCH" ]; then
DEFAULT_BRANCH="main"
fi
# Count lines changed
if git rev-parse --verify "origin/$DEFAULT_BRANCH" > /dev/null 2>&1; then
LINES_CHANGED=$(git diff --shortstat "origin/$DEFAULT_BRANCH" | grep -oE '[0-9]+ insertion|[0-9]+ deletion' | grep -oE '[0-9]+' | paste -sd+ | bc || echo "0")
FILES_CHANGED=$(git diff --name-only "origin/$DEFAULT_BRANCH" | wc -l)
echo -e "${BLUE} Lines changed:${NC} $LINES_CHANGED"
echo -e "${BLUE} Files changed:${NC} $FILES_CHANGED"
if [ "$LINES_CHANGED" -lt 50 ]; then
echo -e "${GREEN} ✓ Small PR (< 50 lines) - Ideal!${NC}"
elif [ "$LINES_CHANGED" -lt 200 ]; then
echo -e "${GREEN} ✓ Good PR size (< 200 lines)${NC}"
elif [ "$LINES_CHANGED" -lt 400 ]; then
echo -e "${YELLOW} ⚠ Large PR (< 400 lines) - Consider splitting if possible${NC}"
((WARNINGS++))
else
echo -e "${RED} ✗ Very large PR (>= 400 lines) - Strongly consider splitting${NC}"
((ERRORS++))
fi
else
echo -e "${YELLOW} ⚠ Cannot compare with origin/$DEFAULT_BRANCH${NC}"
((WARNINGS++))
fi
echo ""
# Check 7: Uncommitted Changes
echo -e "${BLUE}[7/8] Checking for uncommitted changes...${NC}"
if ! git diff-index --quiet HEAD --; then
echo -e "${YELLOW} ⚠ You have uncommitted changes${NC}"
git status --short | sed 's/^/ /'
echo -e "${YELLOW} → Commit or stash these before creating PR${NC}"
((WARNINGS++))
else
echo -e "${GREEN} ✓ No uncommitted changes${NC}"
fi
echo ""
# Check 8: Branch Name
echo -e "${BLUE}[8/8] Checking branch name...${NC}"
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then
echo -e "${RED} ✗ You're on $CURRENT_BRANCH branch!${NC}"
echo -e "${RED} → Never create PRs from main/master${NC}"
echo -e "${RED} → Create a feature branch instead${NC}"
((ERRORS++))
else
echo -e "${GREEN} ✓ On feature branch: $CURRENT_BRANCH${NC}"
fi
echo ""
# Summary
echo -e "${BLUE}====================================${NC}"
echo -e "${BLUE} Summary${NC}"
echo -e "${BLUE}====================================${NC}"
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e "${GREEN}✓ All checks passed!${NC}"
echo -e "${GREEN}Your branch is ready for PR submission.${NC}"
exit 0
elif [ $ERRORS -eq 0 ]; then
echo -e "${YELLOW}$WARNINGS warning(s) found${NC}"
echo -e "${YELLOW}Review warnings above and address if needed.${NC}"
exit 0
else
echo -e "${RED}$ERRORS error(s) found${NC}"
if [ $WARNINGS -gt 0 ]; then
echo -e "${YELLOW}$WARNINGS warning(s) found${NC}"
fi
echo -e "${RED}Fix errors above before submitting PR.${NC}"
echo ""
echo -e "${BLUE}Next steps:${NC}"
echo -e " 1. Remove personal artifacts: ${YELLOW}git rm --cached <file>${NC}"
echo -e " 2. Clean branch: ${YELLOW}./scripts/clean-branch.sh${NC}"
echo -e " 3. Re-run this check: ${YELLOW}./scripts/pre-pr-check.sh${NC}"
exit 1
fi