flutter
Flutter는 wger용 피트니스·운동 앱입니다
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Roller Derby Jam Timer
README 전체를 불러오는 중입니다.
README 전문 보기 ↗JamReady is a Flutter app for managing a Roller Derby jam timer. It supports both standalone (offline) mode and remote mode, where it connects to a CRG Derby Scoreboard instance over WebSocket and acts as a remote control.
Verify your environment:
flutter doctor
flutter pub get --enforce-lockfile
List connected devices:
flutter devices
Run on a device:
flutter run -d <device-id>
make unit # unit and widget tests (no device required)
make integration # offline integration test (requires a connected device or emulator)
make test # both of the above
The scoreboard tests connect to a real CRG scoreboard over WebSocket and verify compatibility across multiple versions. They require Docker and git (the scoreboard build runs entirely inside Docker — no local JDK or Ant needed).
Build the scoreboard images once before running either suite. You can build every supported version or select specific versions:
make build-scoreboards
./scripts/build-scoreboard-images.sh --versions v2025.9,v2025.8
The source for each scoreboard version is cloned and compiled inside a multi-stage Docker build (scripts/scoreboard.Dockerfile).
Run both suites and create one version-first Allure report:
./scripts/test-scoreboards.sh --jobs 4 --emulator-jobs 2
--jobs controls headless remote-engine workers. --emulator-jobs is independently capped at the number of running Android emulators, so it cannot overcommit devices. The coordinator runs the headless suite first, then the emulator suite, and writes one report to test-results/scoreboards-<timestamp>-<pid>/allure-report/index.html.
The fast suite exercises RemoteGameEngine and ScoreboardState directly, without building the app or launching an emulator. Local runs can fan out versions across independent Flutter workers; each worker uses an isolated copy of the current checkout, so uncommitted changes are included and concurrent Flutter builds do not share build/ or .dart_tool/.
./scripts/test-remote-engine-scoreboards.sh
./scripts/test-remote-engine-scoreboards.sh --versions v2025.9,v2025.8
./scripts/test-remote-engine-scoreboards.sh --jobs 2
Useful options:
--versions Comma-separated list of versions to test
--host Host address the tests connect to (default: 127.0.0.1)
--port First Docker host port to try (default: 8001)
--jobs Versions to run concurrently locally (default: 1)
--results-dir Parent directory for local reports (default: test-results)
--no-html Leave raw Allure result files without generating HTML
The runner finds an available Docker port for each worker, including a retry if Docker loses a port-binding race. A local run writes logs and raw Allure results to test-results/remote-engine-<timestamp>-<pid>/, plus a self-contained report at allure-report/index.html that can be opened directly from Finder. Report generation uses npx -y allure@3, so it requires Node.js 20+; use --no-html to skip it.
Arguments after -- are passed to flutter test. GitHub Actions continues to emit its existing per-version JSON files for the GitHub test reporter.
The UI-driven suite builds and controls the Flutter app on Android emulators. When several emulators are already running, it fans versions out across them; each concurrent worker uses an isolated copy of the current checkout, an independent Docker port, and a distinct Docker container. If no emulator is running, the script starts one and runs sequentially.
make test-scoreboards
./scripts/test-all-scoreboards.sh --versions v2025.9,v2025.8
./scripts/test-all-scoreboards.sh --jobs 2
Useful options:
--versions Comma-separated list of versions to test
--avd AVD name (default: first from `emulator -list-avds`)
--host Host address the tests connect to (default: 10.0.2.2)
--port First Docker host port to try (default: 8001)
--jobs Maximum emulator workers to use (default: all running emulators)
--results-dir Parent directory for local reports (default: test-results)
--no-html Leave raw Allure result files without generating HTML
--jobs is capped at the number of available emulators (and test versions), so asking for more never starts extra emulators. The runner selects an available Docker port for each worker and retries after a binding race. It writes logs and raw Allure results to test-results/scoreboard-integration-<timestamp>-<pid>/, plus a self-contained report at allure-report/index.html when Node.js 20+ is available.
Arguments after -- are passed to flutter test.
The main CI workflow runs static analysis and unit/widget tests on pushes and pull requests to main. Test results are uploaded as JSON artifacts and published as a GitHub Check. Pull requests also run the headless remote-engine suite as a matrix across the supported CRG scoreboard versions, with a separate artifact and check for each version.
The release script handles versioning, changelog generation, and tagging. It requires the claude CLI to generate the changelog.
./scripts/release.sh
It will ask whether this is a stable or pre-release, which version component to bump, and (for pre-releases) a suffix like rc1 or beta1. It then generates a changelog from commits since the last release using Claude, shows it for confirmation, commits the version bump to pubspec.yaml, creates an annotated git tag, and offers to push. Pushing the tag triggers the GitHub Actions release workflow, which publishes a GitHub release with the changelog as the release notes.
The GitHub release contains release notes only — store builds must be created and uploaded manually using make release, which runs all tests (including scoreboard compatibility tests) and then builds both artifacts:
make release
This requires:
android/key.properties pointing to your upload keystore (not checked in) for the Android build:
storeFile=/path/to/upload-keystore.jks
storePassword=...
keyAlias=upload
keyPassword=...
Once built, upload the artifacts via their respective consoles:
build/app/outputs/bundle/release/app-release.aab → Play Consolebuild/ios/ipa/*.ipa → Xcode Organizer or xcrun altoolflutter analyze
lib/ app source (screens, widgets, models, services)
test/ unit and widget tests
integration_test/ integration tests (run separately)
remote_engine_test/ headless CRG scoreboard compatibility tests
assets/ app assets
scripts/ build and test utilities