We welcome contributions to nself! This guide will help you understand how to contribute effectively, whether you're fixing bugs, adding features, improving documentation, or helping the community.
Every contribution makes nself better for everyone. Whether it's code, documentation, or community support, your help is valuable and appreciated.
Bug fixes, new features, performance improvements, and code cleanup.
Writing guides, fixing typos, adding examples, and improving clarity.
Finding and reporting bugs, testing new features, platform compatibility.
Helping users in discussions, answering questions, sharing knowledge.
# Fork the repository on GitHub
# Clone your fork
git clone https://github.com/YOUR_USERNAME/nself.git
cd nself
# Set up development environment
make setup
# Install dependencies
go mod download
npm install
# Run tests to ensure everything works
make test
# Create a feature branch
git checkout -b feature/my-new-feature
# Make your changes
# ... code, test, commit ...
# Run tests and linting
make test
make lint
# Push to your fork
git push origin feature/my-new-feature
# Create a pull request on GitHub
// Follow Go conventions and best practices
package main
import (
"context"
"fmt"
"log"
"github.com/acamarata/nself/internal/config"
"github.com/acamarata/nself/pkg/utils"
)
// Use clear, descriptive function names
func ProcessUserData(ctx context.Context, userID string) error {
// Add comprehensive error handling
if userID == "" {
return fmt.Errorf("userID cannot be empty")
}
// Include helpful comments for complex logic
userData, err := fetchUserFromDatabase(ctx, userID)
if err != nil {
return fmt.Errorf("failed to fetch user %s: %w", userID, err)
}
return processData(userData)
}
// Add unit tests for all public functions
func TestProcessUserData(t *testing.T) {
ctx := context.Background()
t.Run("valid user ID", func(t *testing.T) {
err := ProcessUserData(ctx, "user123")
assert.NoError(t, err)
})
t.Run("empty user ID", func(t *testing.T) {
err := ProcessUserData(ctx, "")
assert.Error(t, err)
assert.Contains(t, err.Error(), "cannot be empty")
})
}
// Use TypeScript for type safety
interface UserConfig {
id: string;
name: string;
email: string;
preferences: UserPreferences;
}
// Write clear, self-documenting code
export class ConfigManager {
private config: Map<string, any> = new Map();
/**
* Loads configuration from the specified file
* @param filePath - Path to the configuration file
* @returns Promise that resolves when config is loaded
*/
async loadConfig(filePath: string): Promise<void> {
try {
const configData = await fs.readFile(filePath, 'utf-8');
const parsed = JSON.parse(configData);
this.validateConfig(parsed);
this.config = new Map(Object.entries(parsed));
} catch (error) {
throw new Error(`Failed to load config from ${filePath}: ${error.message}`);
}
}
private validateConfig(config: any): void {
// Configuration validation logic
if (!config || typeof config !== 'object') {
throw new Error('Invalid configuration format');
}
}
}
// Include comprehensive tests
describe('ConfigManager', () => {
let configManager: ConfigManager;
beforeEach(() => {
configManager = new ConfigManager();
});
test('should load valid configuration', async () => {
await expect(configManager.loadConfig('valid-config.json'))
.resolves
.not.toThrow();
});
test('should throw error for invalid configuration', async () => {
await expect(configManager.loadConfig('invalid-config.json'))
.rejects
.toThrow('Invalid configuration format');
});
});
# Use conventional commit format
type(scope): brief description
# Types:
feat: new feature
fix: bug fix
docs: documentation changes
style: formatting, no code change
refactor: code change that neither fixes a bug nor adds a feature
test: adding or modifying tests
chore: maintenance tasks
# Examples:
feat(cli): add database backup command
fix(hasura): resolve connection timeout issue
docs(readme): update installation instructions
test(database): add integration tests for migration system
# Include detailed description for complex changes
feat(cli): add database backup command
- Add 'nself db backup' command with compression
- Support custom backup names and schedules
- Include validation for backup directory permissions
- Add progress indicators for large databases
Closes #123
## Description
Brief description of changes and why they were made
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
- [ ] New tests added (if applicable)
## Related Issues
Closes #123
Related to #456
## Screenshots (if applicable)
Add screenshots for UI changes
## Checklist
- [ ] My code follows the project's coding standards
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or my feature works
- [ ] New and existing unit tests pass locally with my changes
docs/
├── installation/ # Installation guides
├── quick-start/ # Getting started guide
├── configuration/ # Configuration options
├── api-reference/ # API documentation
├── tutorials/ # Step-by-step tutorials
├── examples/ # Code examples
├── troubleshooting/ # Common issues and solutions
├── contributing/ # This guide
└── faq/ # Frequently asked questions
# Page Title
Brief introduction explaining what this page covers and why it's useful.
## Section Heading
Descriptive text explaining the concept or feature.
### Subsection
More detailed information with examples:
```bash
# Command examples with comments
nself init my-project
cd my-project
nself up
```
> **Note**: Important information that users should be aware of.
> **Warning**: Critical information about potential issues or breaking changes.
## Code Examples
Provide complete, working examples:
```typescript
// Complete example with imports
import { ConfigManager } from '@/lib/config';
const config = new ConfigManager();
await config.load('.env.local');
```
## Next Steps
Link to related documentation:
- [Configuration Guide](/docs/configuration)
- [Production Setup](/docs/production)
- [Troubleshooting](/docs/troubleshooting)
nself uses semantic versioning (SemVer):
We are committed to providing a welcoming and inclusive environment for everyone:
Violations of the code of conduct should be reported to conduct@nself.org. All reports will be handled confidentially and fairly.
Regular contributors who demonstrate expertise and commitment may be invited to become maintainers with additional responsibilities:
Look for issues labeled "good first issue" in the GitHub repository. These are specifically chosen to be approachable for new contributors.
Not at all! Contributions at all skill levels are welcome. Even fixing typos or improving documentation is valuable.
We aim to review PRs within 1-2 weeks, but it may take longer for complex changes. Maintainers are volunteers with limited time.
It's best to focus on one issue at a time, especially when starting out. This helps ensure quality and prevents conflicts.
Don't take it personally! Reviewers will provide feedback on why changes are needed. Most PRs require some iteration before being merged.
Whether you fix a typo, answer a question, or implement a major feature, your contributions make nself better for everyone. Thank you for being part of our community!
Ready to contribute? Here's how to get started:
We're excited to have you as part of the nself community. Every contribution, no matter how small, helps make nself better for developers everywhere.