Files
MyActivityPub/CONTRIBUTING.md
2026-01-24 17:45:29 +01:00

467 líneas
10 KiB
Markdown

# 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! 🎉