Contributing
Thank you for considering contributing to Grithub! This guide will help you get started.
Code of Conduct
Be respectful and constructive in all interactions. We aim to create a welcoming environment for contributors of all backgrounds.
How to Contribute
There are many ways to contribute:
Report Bugs
Found a bug? Open an issue with:
- Clear title and description
- Steps to reproduce
- Expected vs actual behavior
- Your environment (OS, Node version, etc.)
- Screenshots if applicable
Example:
**Bug:** Issues command fails with authentication error
**Steps to reproduce:**
1. Run `grithub login`
2. Run `grithub issues`
3. See error: "Authentication failed"
**Expected:** Should show list of issues
**Environment:**
- OS: macOS 14.2
- Node: 18.19.0
- Grithub: 0.1.6Suggest Features
Have an idea? Open a feature request with:
- Clear use case
- Proposed solution
- Alternative approaches considered
- Willingness to implement
Example:
**Feature:** Add support for GitHub Discussions
**Use case:** Teams using Discussions want CLI management
**Proposed solution:**
- Add `grithub discussions` command
- Support CRUD operations
- Enable bulk operations
**Alternatives:**
- Use GitHub CLI (lacks bulk operations)
- Manual API calls (not user-friendly)
**Implementation:** I can implement this if approvedImprove Documentation
Documentation is crucial! You can:
- Fix typos or unclear explanations
- Add examples or use cases
- Improve code samples
- Translate to other languages
Documentation lives in docs/:
# Start docs server
pnpm docs:dev
# Edit markdown files
vi docs/guide/getting-started.md
# Preview changes at http://localhost:5173Write Code
Ready to code? Follow this workflow:
Development Workflow
1. Fork Repository
Click "Fork" on GitHub
2. Clone Your Fork
git clone https://github.com/YOUR_USERNAME/grithub.git
cd grithub3. Add Upstream Remote
git remote add upstream https://github.com/toneflix/grithub.git4. Create Branch
git checkout -b feature/my-featureBranch naming:
feature/- New featuresfix/- Bug fixesdocs/- Documentationrefactor/- Code refactoringtest/- Test additions/fixes
5. Install Dependencies
pnpm install6. Make Changes
Edit files in src/:
// Example: src/Commands/MyCommand.ts
import { Command } from '@h3ravel/musket';
export class MyCommand extends Command {
protected signature = 'my-command';
protected description = 'My new command';
async handle() {
this.info('Hello, Grithub!');
}
}7. Test Changes
# Run in development
pnpm runner my-command
# Run tests
pnpm test
# Lint code
pnpm lint8. Commit Changes
Use Conventional Commits:
git add .
git commit -m "feat: add my-command"Commit types:
feat:- New featurefix:- Bug fixdocs:- Documentationstyle:- Formattingrefactor:- Code refactoringtest:- Testschore:- Maintenance
Examples:
git commit -m "feat: add bulk delete for pull requests"
git commit -m "fix: resolve authentication timeout issue"
git commit -m "docs: update installation instructions"
git commit -m "refactor: simplify issue parsing logic"9. Push Changes
git push origin feature/my-feature10. Create Pull Request
Go to GitHub and click "Compare & pull request"
PR Template:
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
How was this tested?
## Checklist
- [ ] Code follows project style
- [ ] Tests pass
- [ ] Documentation updated
- [ ] No breaking changes (or documented)Development Guidelines
Code Style
TypeScript
Use strict typing:
// Good
function getIssue(number: number): Promise<IIssue> {
return octokit.rest.issues.get({ number });
}
// Avoid
function getIssue(number: any): any {
return octokit.rest.issues.get({ number });
}Naming Conventions
// Classes: PascalCase
class IssuesCommand extends Command {}
// Functions/Variables: camelCase
function parseIssue(data: any) {}
const issueNumber = 42;
// Constants: UPPER_SNAKE_CASE
const MAX_RETRIES = 3;
// Interfaces: PascalCase with I prefix
interface IUser {
name: string;
email: string;
}File Structure
// Imports first
import { Command } from '@h3ravel/musket';
import { useOctokit } from '../hooks';
import type { IIssue } from '../Contracts/Interfaces';
// Class/function definition
export class MyCommand extends Command {
// Class implementation
}
// No default export for classes
// Use named exportsError Handling
Always handle errors gracefully:
import { promiseWrapper } from '../helpers';
const [err, result] = await promiseWrapper(
octokit.rest.issues.create({
/* ... */
}),
);
if (err) {
this.error(`Failed to create issue: ${err.message}`);
return;
}
this.success(`Issue #${result.data.number} created`);User Feedback
Provide clear feedback:
// Use spinners for operations
const spinner = this.spinner('Creating issue...').start();
try {
await createIssue();
spinner.succeed('Issue created successfully');
} catch (error) {
spinner.fail('Failed to create issue');
this.error(error.message);
}
// Use appropriate log levels
this.info('Information message');
this.success('Success message');
this.warn('Warning message');
this.error('Error message');Testing
Write tests for new features:
// tests/my-feature.spec.ts
import { describe, it, expect } from 'vitest';
import { myFunction } from '../src/my-feature';
describe('myFunction', () => {
it('should return expected result', () => {
const result = myFunction('input');
expect(result).toBe('expected');
});
it('should handle edge cases', () => {
expect(myFunction('')).toBe('');
expect(myFunction(null)).toBeUndefined();
});
});Documentation
Document all public APIs:
/**
* Creates an issue in the specified repository.
*
* @param owner - Repository owner
* @param repo - Repository name
* @param title - Issue title
* @param body - Issue description
* @returns Created issue object
* @throws {Error} If authentication fails
*/
async function createIssue(
owner: string,
repo: string,
title: string,
body?: string,
): Promise<IIssue> {
// Implementation
}Pull Request Guidelines
Before Submitting
Checklist:
- [ ] Code follows style guidelines
- [ ] All tests pass:
pnpm test - [ ] Lint passes:
pnpm lint - [ ] Build succeeds:
pnpm build - [ ] Documentation updated
- [ ] Commit messages follow conventions
- [ ] Branch is up to date with main
PR Description
Include:
- What - What does this PR do?
- Why - Why is this change needed?
- How - How does it work?
- Testing - How was it tested?
- Screenshots - If UI changes
Review Process
- Automated Checks - CI runs tests and linting
- Code Review - Maintainer reviews code
- Feedback - Address review comments
- Approval - PR approved for merge
- Merge - Squash and merge to main
After Merge
Your contribution will be:
- Included in next release
- Listed in changelog
- Credited in release notes
First Time Contributors
New to open source? Look for issues labeled:
good first issue- Easy entry pointshelp wanted- Contributions welcomedocumentation- Docs improvements
Don't hesitate to ask questions!
Getting Help
Questions
- Open a Discussion
- Ask in Issues
Stuck?
- Review Development Guide
- Check existing Pull Requests
- Read GitHub Docs
License
By contributing, you agree that your contributions will be licensed under the ISC License.
Recognition
Contributors are recognized:
- In release notes
- In changelog
- On GitHub contributors page
Thank you for contributing to Grithub! 🎉
Next Steps
- Development Guide - Set up development environment
- Commands - Learn command structure
- GitHub Issues - Find issues to work on
