Thank you for your interest in contributing to AFRAMP! This guide will help you get started.
- Getting Started
- Development Workflow
- Code Standards
- Testing
- Submitting Changes
- CI/CD Pipeline
- Troubleshooting
- Node.js ≥20.0.0
- npm ≥10.0.0
- Git
- GitHub account
-
Fork the repository
# On GitHub, click "Fork" -
Clone your fork
git clone https://github.com/YOUR_USERNAME/aframp.git cd aframp -
Add upstream remote
git remote add upstream https://github.com/aframp/aframp.git
-
Install dependencies
npm install
-
Create a feature branch
git checkout -b feature/your-feature-name
# Update main branch
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/descriptive-nameBranch naming conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentationrefactor/- Code refactoringtest/- Test additionschore/- Maintenance tasks
# Edit files
# Run tests frequently
npm run test:watch
# Check code quality
npm run lint
npm run format:check
npm run type-check# Stage changes
git add .
# Commit with conventional commit format
git commit -m "feat: add new payment method"Commit message format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat- New featurefix- Bug fixdocs- Documentationstyle- Code style (formatting)refactor- Code refactoringtest- Test additionschore- Maintenance
Example:
feat(kyc): add document verification
Add support for document verification in KYC flow.
Implements OCR-based validation for ID documents.
Closes #123
git push origin feature/your-feature-name- Go to GitHub
- Click "New Pull Request"
- Select your branch
- Fill in PR template
- Submit for review
- Use strict mode (enabled by default)
- Add explicit return types to functions
- Avoid
anytype (useunknownif needed) - Use interfaces for object shapes
// ✅ Good
interface User {
id: string
name: string
email: string
}
function getUser(id: string): Promise<User> {
// ...
}
// ❌ Avoid
function getUser(id: any): any {
// ...
}- Use functional components with hooks
- Keep components focused and reusable
- Add prop types/interfaces
- Use meaningful component names
// ✅ Good
interface ButtonProps {
label: string
onClick: () => void
disabled?: boolean
}
export function Button({ label, onClick, disabled }: ButtonProps) {
return (
<button onClick={onClick} disabled={disabled}>
{label}
</button>
)
}
// ❌ Avoid
export function Btn(props: any) {
return <button {...props} />
}- Use Tailwind CSS classes
- Avoid inline styles
- Use CSS modules for complex styles
- Follow mobile-first approach
// ✅ Good
<div className="flex flex-col gap-4 md:flex-row">
<button className="px-4 py-2 bg-blue-500 text-white rounded">
Click me
</button>
</div>
// ❌ Avoid
<div style={{ display: 'flex', flexDirection: 'column' }}>
<button style={{ padding: '8px 16px', backgroundColor: 'blue' }}>
Click me
</button>
</div>components/
├── common/ # Reusable components
│ ├── Button.tsx
│ └── Modal.tsx
├── kyc/ # Feature-specific
│ ├── KycForm.tsx
│ └── KycStatus.tsx
└── __tests__/ # Tests
└── Button.test.tsx
// components/__tests__/Button.test.tsx
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Button } from '../Button'
describe('Button', () => {
it('renders with label', () => {
render(<Button label="Click me" onClick={() => {}} />)
expect(screen.getByText('Click me')).toBeInTheDocument()
})
it('calls onClick when clicked', async () => {
const onClick = jest.fn()
render(<Button label="Click me" onClick={onClick} />)
await userEvent.click(screen.getByText('Click me'))
expect(onClick).toHaveBeenCalled()
})
})# Run all tests
npm run test
# Watch mode (re-run on changes)
npm run test:watch
# Coverage report
npm run test:coverage- Minimum: 70% across all metrics
- Target: 80%+ for new code
- Metrics: Lines, Statements, Functions, Branches
-
Run local CI checks
./test-ci-local.sh
-
Verify all checks pass
- ✅ ESLint
- ✅ Prettier
- ✅ TypeScript
- ✅ Tests
- ✅ Build
-
Update documentation
- Add/update comments
- Update README if needed
- Document breaking changes
- Branch created from
developormain - Commits follow conventional format
- Tests added/updated
- Coverage maintained (≥70%)
- Code follows style guide
- Documentation updated
- No console errors/warnings
- Local CI checks pass
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Related Issues
Closes #123
## Testing
Describe testing performed
## Screenshots (if applicable)
Add screenshots for UI changes
## Checklist
- [ ] Tests pass
- [ ] Coverage maintained
- [ ] Documentation updatedWhen you push or create a PR, GitHub Actions automatically runs:
-
Code Quality (2-3 min)
- ESLint
- Prettier
- TypeScript
-
Tests (3-5 min)
- Jest tests
- Coverage report
- Codecov upload
-
Build (4-6 min)
- Next.js production build
- Artifact upload
- ✅ All checks pass → Ready to merge
- ❌ Any check fails → Fix issues and push again
- ⏳ Checks running → Wait for completion
- Go to PR
- Scroll to "Checks" section
- Click on failed check to see logs
- Fix issues locally
- Push again
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install
# Run tests
npm run test:coverage# Auto-fix formatting
npm run format
# Check remaining issues
npm run lint# Check TypeScript
npm run type-check
# Try clean build
rm -rf .next
npm run build# Update branch with latest main
git fetch upstream
git rebase upstream/main
# Force push (use carefully!)
git push origin feature/name --force-with-lease- ✅ Code follows style guide
- ✅ Tests are comprehensive
- ✅ No breaking changes
- ✅ Documentation is clear
- ✅ Performance is acceptable
- ✅ Security best practices followed
- Read feedback carefully
- Ask questions if unclear
- Make requested changes
- Push updates
- Mark conversations as resolved
- CI/CD Setup Guide
- GitHub Actions Workflows
- TypeScript Handbook
- React Documentation
- Next.js Documentation
- Tailwind CSS
- Check existing issues/discussions
- Ask in PR comments
- Contact team lead
- Review documentation
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Thank you for contributing to AFRAMP! 🚀