Contributing
Overview
Panduan untuk berkontribusi ke Centralize Management System.
Branch Strategy
main ─────────────────────────────────▶ Production
│
├── develop ─────────────────────────────────▶ Development
│ │
│ ├── feature/xxx ──────────────────────▶ Feature branch
│ │
│ └── bugfix/xxx ───────────────────────▶ Bugfix branch
│
└── release/x.x.x ──────────────────────────▶ Release branch
Branch Naming
| Type | Pattern | Example |
|---|---|---|
| Feature | feature/description | feature/add-alerting |
| Bugfix | bugfix/description | bugfix/fix-login |
| Hotfix | hotfix/description | hotfix/security-patch |
| Release | release/x.x.x | release/1.0.0 |
Commit Messages
Format
<type>(<scope>): <subject>
<body>
<footer>
Types
| Type | Description |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation |
style | Formatting |
refactor | Code refactoring |
test | Tests |
chore | Maintenance |
Examples
feat(alerting): add Telegram notification
- Add Telegram bot integration
- Add verification code flow
- Add broadcast webhook
Closes #123
fix(backend): fix JWT token validation
- Fix JWKS caching issue
- Add token expiration check
Fixes #456
Pull Request Process
1. Create Feature Branch
git checkout -b feature/my-feature develop
2. Make Changes
# Make changes
git add .
git commit -m "feat(scope): description"
3. Push to Remote
git push origin feature/my-feature
4. Create Pull Request
- Title:
<type>(<scope>): <description> - Description: What, Why, How
- Link to issue
5. Code Review
- At least 1 approval required
- All CI checks must pass
- No merge conflicts
6. Merge
git checkout develop
git merge --no-ff feature/my-feature
git push origin develop
Code Standards
Go Backend
// Good
func HandleLogin(w http.ResponseWriter, r *http.Request) {
var req loginRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, "invalid json body")
return
}
// ...
}
// Bad
func handlelogin(w http.ResponseWriter, r *http.Request) {
var req loginRequest
json.NewDecoder(r.Body).Decode(&req)
// ...
}
TypeScript Frontend
// Good
interface LogEntry {
id: string;
message: string;
level: string;
timestamp: string;
}
function LogItem({ log }: { log: LogEntry }) {
return <div>{log.message}</div>;
}
// Bad
function logItem(props: any) {
return <div>{props.log.message}</div>
}
Testing
Backend Tests
func TestHandleLogin(t *testing.T) {
// Arrange
req := loginRequest{
Username: "admin",
Password: "Admin123!",
}
// Act
resp, err := login(req)
// Assert
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if resp.Token.AccessToken == "" {
t.Error("expected access token")
}
}
Frontend Tests
describe('LogItem', () => {
it('renders message', () => {
const log = { id: '1', message: 'Test log', level: 'info' };
render(<LogItem log={log} />);
expect(screen.getByText('Test log')).toBeInTheDocument();
});
});
Documentation
- Update README if needed
- Add/update API documentation
- Add/update inline comments
- Update CHANGELOG
Code Review Checklist
- Code follows style guidelines
- Tests are included
- Documentation is updated
- No breaking changes
- Security considerations
- Performance implications
Next Steps
- Local Setup - Development setup
- API Reference - API documentation