Skip to content

Project initializer (melos run init) + Flutter 3.47.5, Melos 8, native upgrades - #122

Merged
amaury901130 merged 6 commits into
mainfrom
chore/project-init-and-toolchain-upgrade
Sep 23, 2026
Merged

amaury901130 merged 6 commits into
mainfrom
chore/project-init-and-toolchain-upgrade

Conversation

@amaury901130

@amaury901130 amaury901130 commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Adds a template → project lifecycle, and upgrades the toolchain and native projects. This is easiest to review commit by commit:

  1. Flutter 3.41.3 → 3.47.5 (Dart 3.11.1 → 3.13.4) and dependencies.

    • Every direct dependency is at its latest version: get_it 9, go_router 18, permission_handler 13, package_info_plus 10, app_links 7, firebase_core 4, flutter_dotenv 6, flutter_lints 6.
    • Code migrations:
      • testLoad → loadFromString (flutter_dotenv 6).
      • A new transformTimeout case (dio). This was an analyzer error on main.
      • Getter types required by lints 6.
      • The cross-platform url_strategy.dart import. The web-only import doesn't compile for mobile on 3.47.
    • The codebase is reformatted in the 3.13 "tall" style.
  2. Native projects.

    • Android: Gradle 9.3.1, AGP 9.1, Kotlin 2.4 and Java 17. compileSdk is 37, which permission_handler 13 requires; targetSdk stays 36.
    • iOS: deployment target 15.0. CocoaPods is replaced by Swift Package Manager (every plugin supports it), and the Flutter tool performed the UIScene migration.
    • Project identity now lives in two files: android/build.properties and ios/Flutter/AppIdentity.xcconfig.
  3. Project initializer and Melos 8.

    • flutter_base.json records the state (template | initialized).
    • tool/project_init is a pure-Dart initializer: melos run init (prompts), or dart tool/project_init/bin/init.dart --name … --package-name … --bundle-id ….
      • It validates all input and plans every edit before writing anything.
      • It applies the edits atomically, with rollback.
      • It refuses to run twice.
    • Its tests initialize a copy of this repo, so template drift fails CI.
    • The Melos scripts move to Melos 8 conventions (exec, dependsOn, verify, gen:l10n).
    • CI:
      • New ci.yml: format, analyze, test and an Android build, in the template and in projects.
      • SonarQube becomes project-only. A gate job reads flutter_base.json, so it's skipped in the template and turns on after init.
  4. Docs.

    • New docs/development/project-initialization.md: lifecycle, parameters, what init changes, manual steps, toolchain.
    • CLAUDE.md, README and the guides are updated.
  5. Initializer fix: indirect dependency names.

    • Package names of indirect dependencies (such as bloc, reached through flutter_bloc, or meta) used to pass validation. melos bootstrap then failed, and the initializer refused to run again.
    • They are now rejected before anything is written. The names are listed in tool/project_init/lib/src/resolved_packages.dart, and a test fails when pubspec.lock gains a package the list is missing.
  6. README rewrite.

    • It now covers requirements, project setup, environments, running each flavor, everyday commands, release builds, CI and contributing to the template.
    • It drops features that don't exist (the Gemini chat, RS-GPT-Review, Bitrise).

Issue

N/A

Preview

N/A (tooling / native)

Validation (local: macOS, Xcode 27, JDK 17)

  • Baseline on main (Flutter 3.41.3): analyze failed, format failed (a test file from fix(common): make ResultType.mapError invoke its callback #118), and all native builds failed. The causes were Kotlin 1.8.22, iOS deployment targets below 15, and a broken include path in qa.xcconfig.
  • This branch, template state:
    • melos run verify passes: format, analyze across 5 packages, 27 tests.
    • These builds pass: APK debug and release; iOS simulator; iOS release (no codesign); the dev and qa flavors; web.
  • Initialized sample project ("Acme Field Notes" / acme_field_notes / com.acme.fieldnotes), in a fresh copy:
    • init ran before bootstrap, through the interactive prompts, the flags, and melos run.
    • Bootstrap and verify pass, and all builds pass.
    • The binaries report com.acme.fieldnotes(.debug/.qa) and the new name.
    • Regenerating l10n gives zero diff.
    • A re-run is refused (exit 3) and leaves the tree unchanged.
  • The branch is committed in the template state.
  • Not verified: the GitHub Actions workflows haven't run yet (this PR is their first run), the app wasn't launched on a device, the initializer wasn't tested on Windows, and nothing was signed.

Behavior changes to review

  • The iOS Debug bundle ID was com.rs.base.debug.debug (.debug applied twice). It's now com.rs.base.debug.
  • iOS no longer hardcodes version 2.0.0. The pubspec version: is the single source.
  • The template display name is now "RS Base" everywhere: the Android label, the web title and the l10n appName. Before, these were flutter_base_rootstrap / "Flutter Target".
  • Release APKs without key.properties are signed with the debug key instead of failing.
  • run:web uses the dev entrypoint.
  • The Sonar host URL comes from the SONAR_URL secret. sonar.tests lists only directories that exist.
  • CI and developer machines need Android platform 37: sdkmanager "platforms;android-37.0". ci.yml installs it.
  • New findings are recorded in docs/architecture/known-issues.md (Define Arch #17–Define PR template for base project. #21). Among them: firebase_core pulls the entire Firebase iOS SDK while Firebase is never initialized, and lock files aren't committed.

🤖 Generated with Claude Code

amaury901130 and others added 6 commits September 22, 2026 18:11
- .fvmrc 3.41.3 -> 3.47.5; packages require sdk ^3.13.0, flutter >=3.47.0
- Major bumps: get_it 9, go_router 18, permission_handler 13, package_info_plus 10,
  app_links 7, firebase_core 4, flutter_dotenv 6, equatable 3, flutter_lints 6
- flutter_dotenv 6: testLoad -> loadFromString in the EnvConfig tests
- dio 5.9+: map DioExceptionType.transformTimeout (analyzer error on main)
- lints 6 (strict_top_level_inference): add the missing getter types
- flutter_web_plugins: import url_strategy.dart, the cross-platform entry point;
  the web-only library no longer compiles for mobile
- Flutter 3.47's analysis_options migration: exclude build/platform dirs, and
  generated l10n code
- dart format with the 3.13 language version (tall style)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…andards

Android
- Gradle 9.3.1, AGP 9.1.0, Kotlin 2.4.0, Java 17, AGP 9 compatibility flags
  (as generated by the Flutter 3.47 template); layout.buildDirectory
- Fixes the build on main (Kotlin 1.8.22 was too old for the plugins)
- compileSdk 37 (required by permission_handler 13), target 36, min 24
- Identity (applicationId, namespace, launcher label) now lives only in
  build.properties; the manifest label uses an appLabel placeholder
- Release builds fall back to debug signing when key.properties is absent
- Removed the deprecated manifest package attributes

iOS
- Deployment target 15.0 (Xcode 27 rejects 12/13, which broke every build)
- CocoaPods removed (pod deintegrate): every plugin supports Swift Package
  Manager, Flutter's default; Flutter added its SPM integration
- UIScene lifecycle migration performed by the Flutter tool
- Identity in Flutter/AppIdentity.xcconfig (APP_BUNDLE_ID, APP_DISPLAY_NAME);
  every configuration derives bundle ID and display name from it
- Fixed the flavor xcconfigs: wrong Generated.xcconfig include path, release
  Pods include in debug configs, Debug bundle ID applied .debug twice
- PRODUCT_NAME is Runner again; version comes from pubspec only
- Removed the stray root ios/Podfile

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- flutter_base.json records the repository state (template | initialized)
  and the identity currently written into the repository
- tool/project_init: pure-Dart initializer (runs before melos bootstrap).
  Validates all input, plans every edit in memory, applies atomically with
  rollback, refuses to run twice (exit 3), supports --dry-run and prompts
- Tests initialize a copy of the repository and fail on template drift
- Melos 7 -> 8.9: exec scripts, dependsOn (test, verify, lint:all), noSelect,
  gen:l10n, pub:runner limited to build_runner users, run:web on dev flavor
- CI: new ci.yml (format, analyze, test, Android build) for template and
  projects; SonarQube becomes project-only, gated on flutter_base.json
- Template identity normalized to "RS Base" (web, l10n appName)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- docs/development/project-initialization.md: lifecycle, state detection,
  parameters, what init changes, manual steps, verification, toolchain
- CLAUDE.md, README, module/testing/customization guides and known issues
  updated for Melos 8, Flutter 3.47, SPM and the initializer

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The package-name check only knew the dependencies listed in the workspace
pubspecs, so names such as `bloc` (reached through flutter_bloc) or `meta`
passed validation. Init then rewrote the project and marked it initialized,
`melos bootstrap` failed version solving, and a re-run was refused.

The initializer runs before bootstrap, when there is no pubspec.lock, so the
resolved dependency graph is listed in resolved_packages.dart. A test fails
when the lock gains a package the list is missing, and a lock that exists
is read as well.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The README now covers the requirements, setting up a project (init,
bootstrap, verify, manual steps), environments, running each flavor on
iOS, Android and web, everyday Melos commands, release builds, CI and
contributing to the template. It drops features that don't exist (the
Gemini chat, RS-GPT-Review, Bitrise) and the stale compileSdk note, and
known-issues #15 is updated to match.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@amaury901130
amaury901130 merged commit a6a5954 into main Sep 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant