Thank you for your interest in contributing to InterlockSim! This guide will help you understand our development process, CI/CD workflows, and quality standards.
- Getting Started
- Development Workflow
- Testing Requirements
- CI/CD Pipeline
- Code Quality Standards
- Pull Request Process
- Documentation
- Java 21 LTS or later
- Gradle (wrapper included)
- Git
- Docker (optional, for containerized builds)
# Clone repository
git clone https://github.com/bedaHovorka/interlockSim.git
cd interlockSim
# Build and test
./gradlew clean build
# Run simulation
./gradlew runSimFor detailed setup instructions, see README.md and CLAUDE.md.
Use descriptive branch names following these patterns:
feature/short-description- New featuresfix/short-description- Bug fixesrefactor/short-description- Code refactoringdocs/short-description- Documentation updatescopilot/short-description- GitHub Copilot agent changesclaude/short-description- Claude AI agent changes
Write clear, descriptive commit messages:
Short summary (50 chars or less)
More detailed explanation if needed. Wrap at 72 characters.
Explain what changed and why, not how.
Fixes #123
Relates to #456
Minimum Requirements:
- Overall coverage: ≥ 51% (current baseline)
- New code coverage: ≥ 70% (aim for 80%+)
- Critical paths: 100% coverage (simulation physics, train safety)
# Unit tests only (excludes integration tests)
./gradlew test
# Integration tests only
./gradlew integrationTest
# All tests
./gradlew test integrationTest
# Generate coverage report
./gradlew test jacocoTestReport
# View coverage report
open build/reports/jacoco/test/html/index.html # macOS
xdg-open build/reports/jacoco/test/html/index.html # Linux- Unit Tests - Fast, isolated tests (default with
./gradlew test) - Integration Tests - End-to-end scenarios (tagged with
@Tag("integration-test"))
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
@Test
@Tag("integration-test")
fun myIntegrationTest() {
// Integration test code
}After running tests, review the JaCoCo coverage report:
Location: build/reports/jacoco/test/html/index.html
Key Metrics:
- Instructions: Bytecode instruction coverage
- Branches: Conditional branch coverage
- Lines: Source line coverage
- Methods: Method coverage
Target Coverage by Package:
objects.tracks/- 85% (safety-critical)xml/- 85% (data integrity)util/- 75%objects.cells/- 72%context/- 70%objects.paths/- 52%sim/- 33% (limited by jDisco framework)
Our CI/CD pipeline includes three main workflows:
File: .github/workflows/gradle-java21.yml
Triggers: Push and PR to main, develop, feature/**, fix/**, copilot/**, claude/**
Steps:
- Compile Kotlin and Java sources
- Run unit tests
- Run integration tests
- Verify Koin DI configuration
- Create JAR artifacts (shadowJar)
- Upload JAR artifact (90-day retention)
- Upload test results
- Generate test report summary
- Run smoke test (shunting loop, 300 simulated seconds)
Duration: ~10-15 minutes
Artifacts Produced:
interlockSim-jar-{sha}- Compiled JAR (90 days)test-results-{sha}- Test results XML (30 days)
File: .github/workflows/sonarqube.yml
Triggers: Push and PR to main, develop, feature/**, fix/**, copilot/**, claude/**
Steps:
- Build and test with coverage
- Generate JaCoCo coverage report
- Upload coverage report artifact
- Generate coverage report summary
- Run SonarCloud scan (if configured)
- Display quality gate status
Duration: ~15-20 minutes
Artifacts Produced:
jacoco-coverage-report-{sha}- Coverage report HTML (30 days)
SonarCloud:
- Requires
SONAR_TOKENandSONAR_ORGANIZATIONsecrets - Skips gracefully if not configured
- View results at: https://sonarcloud.io/project/overview?id=bedaHovorka_interlockSim
Before merging a PR, ensure all CI checks pass:
- Navigate to: https://github.com/bedaHovorka/interlockSim/actions
- Find your branch/PR workflow runs
- Verify all workflows show green checkmarks ✓
- Open your PR on GitHub
- Scroll to the bottom to see status checks
- Wait for all checks to complete
- Verify all checks pass before merging
# View workflow runs for current branch
gh run list --branch $(git branch --show-current)
# View specific workflow run
gh run view {run-id}
# Watch workflow run in real-time
gh run watch# List artifacts for a PR
gh run list --branch your-branch-name
# Download specific artifact
gh run download {run-id} -n interlockSim-jar-{sha}
# Download all artifacts
gh run download {run-id}Or download via GitHub web UI:
- Go to Actions tab
- Click on workflow run
- Scroll to "Artifacts" section
- Click artifact name to download
After CI completes:
-
Download Coverage Report:
- Go to Actions → Workflow Run → Artifacts
- Download
jacoco-coverage-report-{sha}.zip - Extract and open
index.html
-
Verify Coverage Metrics:
- Overall coverage ≥ 51% (baseline)
- No coverage decrease in modified packages
- New code has adequate coverage (≥70%)
-
Review Package-Level Coverage:
- Check coverage for packages you modified
- Ensure critical paths have high coverage
- Add tests for any uncovered branches
The project uses a dual-level approach for Kotlin code quality:
1. Legacy Code (Java→Kotlin converted):
- Configuration:
detekt.yml - Permissive rules (allows
var, higher complexity) - Run:
./gradlew detekt
2. New Kotlin Code:
- Configuration:
detekt-strict.yml - Strict rules (enforces
val, immutability, Kotlin idioms) - Place code in:
src/main/kotlin/cz/vutbr/fit/interlockSim/new/ - Run:
./gradlew detektStrict
Code Formatting:
# Check formatting
./gradlew ktlintCheck
# Auto-format
./gradlew ktlintFormatStyle Rules:
- Indentation: Tabs (width 4) - NOT spaces
- Max line length: 120 characters
- Encoding: UTF-8
- Line endings: LF
Follow .editorconfig configuration:
- Tabs for indentation (width 4)
- Max line length: 120
- UTF-8 encoding, LF line endings
# Full quality check
./gradlew clean build detekt ktlintCheck test integrationTest jacocoTestReport-
Sync with upstream:
git checkout develop git pull origin develop git checkout your-feature-branch git merge develop
-
Run all checks locally:
./gradlew clean build test integrationTest ./gradlew detekt ktlintCheck ./gradlew jacocoTestReport -
Verify smoke test:
java -jar build/libs/interlockSim.jar example shuntingLoop 300
-
Review coverage report:
open build/reports/jacoco/test/html/index.html
-
Push your branch:
git push origin your-feature-branch
-
Open PR on GitHub:
- Use the PR template as a guide
- Fill out all required sections
- Link related issues
-
Complete PR Description:
- Summary: Clear description of changes
- Test Coverage: Before/after metrics, new tests added
- CI/CD Status: Verify all checks pass
- Coverage Validation: Review JaCoCo report
- Documentation: Update relevant docs
-
Monitor CI Status:
- Ensure all checks remain green
- Address any CI failures promptly
- Re-run failed checks if needed
-
Respond to Feedback:
- Address reviewer comments
- Make requested changes
- Re-run tests after changes
-
Keep PR Updated:
- Merge
developregularly if PR is long-lived - Resolve merge conflicts promptly
- Merge
Final Checklist:
- All CI checks passing (Gradle Build, SonarQube, Code Review)
- Test coverage maintained or improved
- JaCoCo report reviewed and validates improvements
- No merge conflicts with target branch
- All review comments addressed
- Documentation updated
- CHANGELOG.md updated (for user-visible changes)
Update documentation when you:
- Add new features → Update README.md
- Change architecture → Update relevant docs in
docs/ - Modify developer workflows → Update CLAUDE.md
- Add public APIs → Add JavaDoc/KDoc comments
- README.md - User-facing documentation (quick start, features)
- CLAUDE.md - Comprehensive developer guide (architecture, build, test)
- CONTRIBUTING.md - This file (contribution guidelines)
- docs/ - Detailed architecture and design docs
- CHANGELOG.md - Notable changes and releases
- Use clear, concise language
- Include code examples
- Add diagrams for complex concepts
- Keep documentation up-to-date with code
- Follow existing documentation style
- Issues: https://github.com/bedaHovorka/interlockSim/issues
- Discussions: https://github.com/bedaHovorka/interlockSim/discussions
- Documentation: See CLAUDE.md for comprehensive development guide
By contributing to InterlockSim, you agree that your contributions will be licensed under the same terms as the project.
Thank you for contributing to Railway Interlocking Simulator! 🚂