Files
gh-jezweb-claude-skills-ski…/assets/bad-pr-example.md
2025-11-30 08:25:07 +08:00

13 KiB

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

## 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!)

# 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!)

# 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:

// 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!):

// 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:

## 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:

## 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!