466
CONTRIBUTING.md
Archivo normal
466
CONTRIBUTING.md
Archivo normal
@@ -0,0 +1,466 @@
|
||||
# Contributing to My ActivityPub
|
||||
|
||||
Thank you for your interest in contributing to My ActivityPub! This document provides guidelines and instructions for contributing to the project.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Development Setup](#development-setup)
|
||||
- [How to Contribute](#how-to-contribute)
|
||||
- [Coding Standards](#coding-standards)
|
||||
- [Commit Guidelines](#commit-guidelines)
|
||||
- [Pull Request Process](#pull-request-process)
|
||||
- [Testing](#testing)
|
||||
- [Documentation](#documentation)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
### Our Pledge
|
||||
|
||||
We are committed to providing a welcoming and inspiring community for all. Please be respectful and constructive in your interactions.
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
- Use welcoming and inclusive language
|
||||
- Be respectful of differing viewpoints
|
||||
- Accept constructive criticism gracefully
|
||||
- Focus on what is best for the community
|
||||
- Show empathy towards other community members
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before you begin, ensure you have:
|
||||
|
||||
- Android Studio Hedgehog (2023.1.1) or newer
|
||||
- JDK 11 or higher
|
||||
- Git installed and configured
|
||||
- Basic knowledge of Kotlin and Jetpack Compose
|
||||
- Familiarity with the Mastodon API
|
||||
|
||||
### Finding Issues to Work On
|
||||
|
||||
1. Check the [Issues](https://github.com/your-repo/issues) page
|
||||
2. Look for issues labeled `good first issue` or `help wanted`
|
||||
3. Comment on the issue to let others know you're working on it
|
||||
4. Wait for maintainer approval before starting work
|
||||
|
||||
## Development Setup
|
||||
|
||||
### 1. Fork and Clone
|
||||
|
||||
```bash
|
||||
# Fork the repository on GitHub, then clone your fork
|
||||
git clone https://github.com/YOUR_USERNAME/MyActivityPub.git
|
||||
cd MyActivityPub
|
||||
|
||||
# Add the upstream repository
|
||||
git remote add upstream https://github.com/ORIGINAL_OWNER/MyActivityPub.git
|
||||
```
|
||||
|
||||
### 2. Create a Branch
|
||||
|
||||
```bash
|
||||
# Create a new branch for your feature or bugfix
|
||||
git checkout -b feature/your-feature-name
|
||||
|
||||
# Or for a bugfix
|
||||
git checkout -b fix/bug-description
|
||||
```
|
||||
|
||||
### 3. Set Up the Project
|
||||
|
||||
```bash
|
||||
# Sync Gradle files
|
||||
./gradlew build
|
||||
|
||||
# Run the app
|
||||
./gradlew installDebug
|
||||
```
|
||||
|
||||
## How to Contribute
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Before creating a bug report:
|
||||
1. Check if the bug has already been reported
|
||||
2. Verify the bug exists in the latest version
|
||||
3. Collect relevant information (device, Android version, logs)
|
||||
|
||||
**Bug Report Template**:
|
||||
```markdown
|
||||
**Description**
|
||||
A clear description of the bug.
|
||||
|
||||
**Steps to Reproduce**
|
||||
1. Step one
|
||||
2. Step two
|
||||
3. Step three
|
||||
|
||||
**Expected Behavior**
|
||||
What should happen.
|
||||
|
||||
**Actual Behavior**
|
||||
What actually happens.
|
||||
|
||||
**Environment**
|
||||
- Device: [e.g., Pixel 6]
|
||||
- Android Version: [e.g., Android 13]
|
||||
- App Version: [e.g., 1.0.0]
|
||||
|
||||
**Logs**
|
||||
```
|
||||
Paste relevant logs here
|
||||
```
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots.
|
||||
```
|
||||
|
||||
### Suggesting Enhancements
|
||||
|
||||
Enhancement suggestions are welcome! Please provide:
|
||||
1. Clear description of the enhancement
|
||||
2. Use cases and benefits
|
||||
3. Possible implementation approach
|
||||
4. Mockups or examples (if applicable)
|
||||
|
||||
### Contributing Code
|
||||
|
||||
1. **Small Changes**: Typos, bug fixes, small improvements can be submitted directly
|
||||
2. **Large Changes**: Open an issue first to discuss the change
|
||||
3. **New Features**: Must be discussed and approved before implementation
|
||||
|
||||
## Coding Standards
|
||||
|
||||
### Kotlin Style Guide
|
||||
|
||||
Follow the [Official Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html):
|
||||
|
||||
#### Naming
|
||||
|
||||
```kotlin
|
||||
// Classes: PascalCase
|
||||
class StatusCard { }
|
||||
|
||||
// Functions and variables: camelCase
|
||||
fun loadTimeline() { }
|
||||
val statusCount = 10
|
||||
|
||||
// Constants: UPPER_SNAKE_CASE
|
||||
const val MAX_RETRIES = 3
|
||||
|
||||
// Private properties: leading underscore
|
||||
private val _uiState = MutableStateFlow()
|
||||
```
|
||||
|
||||
#### Formatting
|
||||
|
||||
```kotlin
|
||||
// Use 4 spaces for indentation
|
||||
class Example {
|
||||
fun method() {
|
||||
if (condition) {
|
||||
// code here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Line length: max 120 characters
|
||||
// Break long function signatures:
|
||||
fun longFunctionName(
|
||||
parameter1: String,
|
||||
parameter2: Int,
|
||||
parameter3: Boolean
|
||||
): ReturnType {
|
||||
// implementation
|
||||
}
|
||||
```
|
||||
|
||||
#### Comments and Documentation
|
||||
|
||||
```kotlin
|
||||
/**
|
||||
* KDoc for public APIs
|
||||
*
|
||||
* @param userId The user identifier
|
||||
* @return The user's timeline
|
||||
*/
|
||||
suspend fun getUserTimeline(userId: String): Result<List<Status>> {
|
||||
// Implementation comments for complex logic
|
||||
val result = apiService.getTimeline(userId)
|
||||
return parseResult(result)
|
||||
}
|
||||
```
|
||||
|
||||
### Compose Best Practices
|
||||
|
||||
```kotlin
|
||||
// Composable function names: PascalCase
|
||||
@Composable
|
||||
fun StatusCard(status: Status, modifier: Modifier = Modifier) {
|
||||
// Always provide Modifier parameter
|
||||
// Default to Modifier
|
||||
}
|
||||
|
||||
// Extract complex composables
|
||||
@Composable
|
||||
private fun StatusHeader(account: Account) {
|
||||
// Smaller, focused components
|
||||
}
|
||||
|
||||
// Use remember for expensive operations
|
||||
val formattedDate = remember(timestamp) {
|
||||
formatDate(timestamp)
|
||||
}
|
||||
|
||||
// Use derivedStateOf for computed values
|
||||
val isExpanded by remember {
|
||||
derivedStateOf { height > maxHeight }
|
||||
}
|
||||
```
|
||||
|
||||
### Architecture Guidelines
|
||||
|
||||
1. **Separation of Concerns**: Each class has a single responsibility
|
||||
2. **MVVM Pattern**: Follow the established architecture
|
||||
3. **Repository Pattern**: All data access through repositories
|
||||
4. **State Management**: Use StateFlow for UI state
|
||||
5. **Error Handling**: Always handle errors gracefully
|
||||
|
||||
### File Organization
|
||||
|
||||
```
|
||||
app/src/main/java/com/manalejandro/myactivitypub/
|
||||
├── MainActivity.kt # Entry point
|
||||
├── data/
|
||||
│ ├── api/ # API interfaces
|
||||
│ ├── models/ # Data models
|
||||
│ └── repository/ # Repository implementations
|
||||
└── ui/
|
||||
├── components/ # Reusable UI components
|
||||
├── screens/ # Full screen composables
|
||||
├── viewmodel/ # ViewModels
|
||||
└── theme/ # Theme configuration
|
||||
```
|
||||
|
||||
## Commit Guidelines
|
||||
|
||||
### Commit Message Format
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
### Types
|
||||
|
||||
- `feat`: New feature
|
||||
- `fix`: Bug fix
|
||||
- `docs`: Documentation changes
|
||||
- `style`: Code style changes (formatting, missing semicolons, etc.)
|
||||
- `refactor`: Code refactoring
|
||||
- `test`: Adding or updating tests
|
||||
- `chore`: Maintenance tasks
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
feat(timeline): add pull-to-refresh functionality
|
||||
|
||||
Implemented SwipeRefresh composable for the timeline screen.
|
||||
Users can now pull down to refresh the timeline.
|
||||
|
||||
Closes #123
|
||||
|
||||
---
|
||||
|
||||
fix(statuscard): correct avatar image loading
|
||||
|
||||
Fixed issue where avatar images weren't loading correctly
|
||||
due to missing Coil configuration.
|
||||
|
||||
Fixes #456
|
||||
|
||||
---
|
||||
|
||||
docs(readme): update installation instructions
|
||||
|
||||
Added more detailed steps for building the project
|
||||
and troubleshooting common issues.
|
||||
```
|
||||
|
||||
### Guidelines
|
||||
|
||||
- Use present tense ("add feature" not "added feature")
|
||||
- Keep subject line under 50 characters
|
||||
- Capitalize the subject line
|
||||
- Don't end the subject line with a period
|
||||
- Use the body to explain what and why, not how
|
||||
- Reference issues and pull requests in the footer
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
### Before Submitting
|
||||
|
||||
1. **Test your changes**: Ensure the app builds and runs
|
||||
2. **Run lint checks**: `./gradlew lint`
|
||||
3. **Update documentation**: If you changed APIs or features
|
||||
4. **Add tests**: For new features or bug fixes
|
||||
5. **Update CHANGELOG**: Add your changes to the unreleased section
|
||||
|
||||
### Submitting a Pull Request
|
||||
|
||||
1. **Push your branch**:
|
||||
```bash
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
2. **Create Pull Request** on GitHub with:
|
||||
- Clear title describing the change
|
||||
- Detailed description of what and why
|
||||
- Link to related issues
|
||||
- Screenshots/recordings for UI changes
|
||||
- Test instructions
|
||||
|
||||
3. **PR Template**:
|
||||
```markdown
|
||||
## Description
|
||||
Brief description of changes.
|
||||
|
||||
## Type of Change
|
||||
- [ ] Bug fix
|
||||
- [ ] New feature
|
||||
- [ ] Breaking change
|
||||
- [ ] Documentation update
|
||||
|
||||
## Related Issues
|
||||
Closes #123
|
||||
|
||||
## Testing
|
||||
- [ ] Tested on physical device
|
||||
- [ ] Tested on emulator
|
||||
- [ ] Added unit tests
|
||||
- [ ] Added UI tests
|
||||
|
||||
## Screenshots
|
||||
[Add screenshots if applicable]
|
||||
|
||||
## Checklist
|
||||
- [ ] Code follows style guidelines
|
||||
- [ ] Self-reviewed the code
|
||||
- [ ] Commented complex code
|
||||
- [ ] Updated documentation
|
||||
- [ ] No new warnings
|
||||
- [ ] Added tests
|
||||
- [ ] All tests pass
|
||||
```
|
||||
|
||||
### Review Process
|
||||
|
||||
1. Maintainer will review your PR
|
||||
2. Address any requested changes
|
||||
3. Once approved, your PR will be merged
|
||||
4. Delete your branch after merge
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
./gradlew test
|
||||
|
||||
# Run unit tests
|
||||
./gradlew testDebugUnitTest
|
||||
|
||||
# Run instrumented tests
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
|
||||
### Writing Tests
|
||||
|
||||
#### Unit Tests
|
||||
|
||||
```kotlin
|
||||
class TimelineViewModelTest {
|
||||
@Test
|
||||
fun `loadTimeline updates state to Success on successful fetch`() = runTest {
|
||||
// Arrange
|
||||
val mockRepository = mock<MastodonRepository>()
|
||||
val testStatuses = listOf(/* test data */)
|
||||
whenever(mockRepository.getPublicTimeline())
|
||||
.thenReturn(Result.success(testStatuses))
|
||||
|
||||
val viewModel = TimelineViewModel(mockRepository)
|
||||
|
||||
// Act
|
||||
viewModel.loadTimeline()
|
||||
|
||||
// Assert
|
||||
val state = viewModel.uiState.value
|
||||
assertTrue(state is TimelineUiState.Success)
|
||||
assertEquals(testStatuses, (state as TimelineUiState.Success).statuses)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Compose UI Tests
|
||||
|
||||
```kotlin
|
||||
class StatusCardTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun statusCard_displays_username() {
|
||||
val testStatus = Status(/* test data */)
|
||||
|
||||
composeTestRule.setContent {
|
||||
StatusCard(status = testStatus)
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(testStatus.account.username)
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
### Code Documentation
|
||||
|
||||
- Add KDoc comments for all public APIs
|
||||
- Comment complex algorithms
|
||||
- Use meaningful variable and function names
|
||||
- Update README.md for user-facing changes
|
||||
|
||||
### Documentation Files
|
||||
|
||||
- **README.md**: User documentation, setup, features
|
||||
- **ARCHITECTURE.md**: Architecture and design decisions
|
||||
- **API.md**: API integration details
|
||||
- **CONTRIBUTING.md**: This file
|
||||
|
||||
## Questions?
|
||||
|
||||
If you have questions:
|
||||
1. Check existing documentation
|
||||
2. Search closed issues
|
||||
3. Ask in discussions
|
||||
4. Open a new issue with the `question` label
|
||||
|
||||
## Recognition
|
||||
|
||||
Contributors will be recognized in:
|
||||
- CONTRIBUTORS.md file
|
||||
- Release notes
|
||||
- Project README
|
||||
|
||||
Thank you for contributing to My ActivityPub! 🎉
|
||||
Referencia en una nueva incidencia
Block a user