Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Bug report
description: Report a reproducible problem with Roller Coasters
title: "[Bug]: "
labels:
- Bug
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What happened, and what did you expect instead?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Reproduction steps
description: List the smallest set of steps needed to reproduce the issue.
placeholder: |
1. Clone the repository
2. Run ...
3. See ...
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Include Android Studio, JDK, Gradle, device/emulator, and OS details when relevant.
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional context
description: Add logs, screenshots, or links that help explain the problem.
validations:
required: false
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: true
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Feature request
description: Suggest an improvement for Roller Coasters
title: "[Feature]: "
labels:
- Enhancement
body:
- type: textarea
id: motivation
attributes:
label: Motivation
description: What problem would this solve for the app or codebase?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposal
description: Describe the change you would like to see.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: List any simpler or more focused alternatives you considered.
validations:
required: false
- type: textarea
id: scope
attributes:
label: Scope notes
description: Call out any maintenance, architecture, or migration trade-offs.
validations:
required: false
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Summary

- Briefly describe the change.

## Verification

- [ ] Ran relevant local checks
- [ ] Added or updated tests where needed
- [ ] Updated screenshots or snapshots for intentional UI changes

## Notes

- Add any follow-up context, screenshots, or trade-offs here.
116 changes: 73 additions & 43 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,92 @@
name: CI
name: Android CI

on:
push:
branches: [ "develop" ]
pull_request:
workflow_dispatch:
schedule:
- cron: "0 3 * * *"

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build
name: Build & Validate
runs-on: ubuntu-latest
timeout-minutes: 60

steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v3
- uses: actions/setup-java@v4
- name: Checkout code
uses: actions/checkout@v4
with:
distribution: 'temurin'
java-version: '17'
- uses: gradle/actions/setup-gradle@v3
- name: Cache Gradle
uses: actions/cache@v4
fetch-depth: 0

- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v3

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-
distribution: temurin
java-version: "21"

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Make gradlew executable
run: chmod +x gradlew

- name: Setup local.properties with Maps API Key
run: |
echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties
echo "MAPS_API_KEY=${{ secrets.MAPS_API_KEY }}" >> local.properties
- name: Assemble Debug
run: ./gradlew assembleDebug --stacktrace --no-daemon

jvm-tests:
name: JVM Tests
runs-on: ubuntu-latest
needs: build
- name: Check Module Boundaries
run: ./gradlew --no-daemon --stacktrace checkModuleDependencyBoundaries

steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v3
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- uses: gradle/actions/setup-gradle@v3
- name: Cache Gradle
uses: actions/cache@v4
- name: Run Static Analysis
run: ./gradlew --no-daemon --stacktrace detekt lintDebug

- name: Run Unit Tests
run: ./gradlew --no-daemon --stacktrace test -PexcludeSnapshotTests=true

- name: Verify Paparazzi Snapshots
run: ./gradlew --no-daemon --stacktrace --no-parallel verifyPaparazziDebug

- name: Generate Kover Coverage
run: ./gradlew --no-daemon --stacktrace koverXmlReport koverVerify -PexcludeSnapshotTests=true

- name: Build Debug APK
run: ./gradlew --no-daemon --stacktrace assembleDebug

- name: Upload Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: android-ci-reports
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-
- name: Setup local.properties with Maps API Key
run: |
echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties
echo "MAPS_API_KEY=${{ secrets.MAPS_API_KEY }}" >> local.properties
- name: Run JVM Tests
run: ./gradlew testDebugUnitTest --stacktrace --no-daemon
**/build/reports/**
**/build/test-results/**
if-no-files-found: ignore

- name: Job Summary
if: always()
uses: actions/github-script@v7
with:
script: |
await core.summary
.addHeading("Android CI Summary")
.addList([
"Static analysis: detekt + lintDebug",
"Unit tests: test",
"Snapshot tests: verifyPaparazziDebug",
"Coverage: koverXmlReport + koverVerify",
"Build: assembleDebug",
])
.write();
1 change: 1 addition & 0 deletions .java-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
21
29 changes: 29 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Code of Conduct

## Our Pledge

We want this project to be a welcoming, respectful place for everyone who wants
to learn from or improve Roller Coasters.

## Expected Behavior

- Be respectful and constructive.
- Assume good intent, especially when discussing architecture preferences.
- Keep feedback focused on the code, documentation, and project goals.
- Make room for maintainers to prioritize work according to the project's scope.

## Unacceptable Behavior

- Harassment, insults, or discriminatory language.
- Personal attacks or repeated unwelcome attention.
- Publishing private information without permission.
- Derailing issues or pull requests with unrelated arguments.

## Enforcement

Maintainers may edit, hide, or remove comments, issues, pull requests, or other
contributions that do not follow this code of conduct. Repeated or severe
violations may result in being blocked from participating in the project.

Report concerns by opening a private security advisory or contacting the
maintainer through the public profile links.
39 changes: 39 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Contributing

Thanks for helping improve Roller Coasters.

## Workflow

1. Fork the repository.
2. Create a focused branch from `dev`.
3. Keep changes small enough to review.
4. Run the relevant checks before opening a pull request.
5. Open a pull request using the template and describe the behavior change.

## Local Checks

Run the narrowest check that covers your change. Use JDK 21 or newer. For broad changes, run:

```bash
./gradlew checkModuleDependencyBoundaries detekt lintDebug test \
-PexcludeSnapshotTests=true \
verifyPaparazziDebug koverXmlReport koverVerify assembleDebug
```

Run Paparazzi with `--no-parallel` if a local Gradle configuration enables parallel execution:

```bash
./gradlew --no-parallel verifyPaparazziDebug
```

## Pull Requests

Pull requests should include:

- What changed.
- Why the change is needed.
- How it was verified.
- Screenshots or recordings for visible UI changes.

Please keep unrelated formatting, generated files, and IDE metadata out of the
pull request unless they are required for the change.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Pablo Costa Tirado

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading