Skip to content

feat: reusable Flutter CI, release and Pages workflows - #1

Closed
ThePhaseless wants to merge 1 commit into
mainfrom
initial
Closed

ThePhaseless wants to merge 1 commit into
mainfrom
initial

Conversation

@ThePhaseless

@ThePhaseless ThePhaseless commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

The CI, release and Pages workflows of SilverTimetable2, moved here so every Flutter app of the organization calls them instead of keeping its own copy. SilverTimetable2's master already calls this branch's head commit.

What

  • flutter-ci.yml: mise run check, an optional check that generated code is committed, release APKs and the web build, and an optional unsigned iOS build on macOS.
  • flutter-release.yml: one GitHub release in, every platform out.
    • The tag is the version: X.Y.Z for a release and X.Y.Z-beta.N for a pre-release, with or without v. The jobs write version: X.Y.Z+B into pubspec.yaml before building. The build number B = X·1000000 + Y·10000 + Z·100 + N, with N = 99 for a release, so it grows with every tag and a promoted beta keeps its own. Malformed tags, and a pre-release tick that doesn't match the tag, fail before anything is built.
    • Pre-release = public beta: signed APKs, an App Bundle and the web build are attached to the release. The bundle goes to Google Play's open testing track. The iOS build goes to TestFlight: it is added to an external group with a public link (created if missing), testers are notified automatically, and it is sent to Beta App Review. The release description becomes "What to Test", and empty test information is filled from the App Store listing. The web build is served under /beta/ on Pages.
    • Release = production; unticking "pre-release" promotes the same Play build, TestFlight build and web build without rebuilding.
    • Store jobs turn on per app: android-package turns on Google Play and bundle-id turns on iOS, both only once the store's variables are set, so org-wide variables don't switch a store on for every app. A half-done setup fails in the first job, before any macOS minute.
    • Defaults:
      • artifact-prefix defaults to the repository name.
      • The push notification check follows the app's Runner.entitlements.
      • Pages deploys once Pages is enabled.
    • Security: Google Play uses Workload Identity Federation (no stored Google key). App Store Connect uses cloud signing (no stored certificate). The store scripts are checked out at the exact commit the caller pinned (job.workflow_sha). An optional environment input adds a reviewer gate.
  • flutter-pages.yml: the newest release at the site root, and the newest build of any kind (usually the beta) under /beta/.
  • README: usage, every input, the task contract the apps provide, and the store setup.

Tests

  • Store scripts: tests/ runs both scripts against local mock APIs.
    • The App Store Connect mock checks every request against a trimmed copy of Apple's OpenAPI 4.5 description. The Google Play mock checks track updates against Google's Track schema.
    • The scenarios cover the public TestFlight beta, test information that is filled without overwriting, re-runs, reused build numbers, promotions, staged rollouts, compliance answers, API retries and resumed submissions.
    • Breaking a script on purpose fails the tests.
  • Workflows:
    • CI lints them with actionlint (with shellcheck), zizmor, taplo, rumdl and gitleaks.
    • The tag-to-version step was run against 31 tag and event combinations, and the settings check against every missing-setting case.
  • App: SilverTimetable2 was built locally with the version step applied for 4.3.0-beta.1. All APKs and the App Bundle report versionCode 4030001 / versionName 4.3.0, and the web build's version.json matches.
  • Earlier end-to-end run: an earlier revision ran these workflows on a sample app, including the iOS archive on macOS.
  • Not testable here: the real store uploads. The first beta is the real test.

Decisions to check

  • License: MIT, so any repository can reuse the workflows; the apps stay GPL-3.0.
  • After merging: any merge method works, since SilverTimetable2 pins this branch's head commit by SHA. Optionally tag v1.0.0. Once Renovate is installed, it moves the apps' pins forward (README, "Renovate", has the app config: config:recommended with non-major updates merged after CI).

🤖 Generated with Claude Code

@ThePhaseless
ThePhaseless force-pushed the initial branch 5 times, most recently from 98cc17b to 7828001 Compare October 5, 2026 15:00
Moves the GitHub Actions setup of SilverTimetable2 here so that every
Flutter app of the organization can call it instead of keeping a copy.

- flutter-ci.yml: lint and test (`mise run check`), optional generated-code
  check, release APKs and web build, optional unsigned iOS build.
- flutter-release.yml: one GitHub release in, every platform out. The tag
  is the version (X.Y.Z or X.Y.Z-beta.N, optional "v"); the build number is
  derived from it. A pre-release becomes a public beta (Play open testing,
  a TestFlight public link after Beta App Review, Pages /beta/); a release
  goes to production; unticking "pre-release" promotes the same builds
  without rebuilding. Store jobs turn on per app (android-package,
  bundle-id) once the store variables are set, and a half-done setup fails
  before anything is built. Google Play uses Workload Identity Federation,
  App Store Connect cloud signing; the store scripts are checked out at
  the commit the caller pinned (job.workflow_sha).
- flutter-pages.yml: newest release at the site root, newest build of any
  kind under /beta/.
- tests/: the store scripts against local mocks that check their requests
  against trimmed copies of the official API descriptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ThePhaseless

Copy link
Copy Markdown
Contributor Author

Superseded by SilverNETGroupSGGW/Infra#1, which merged this branch with its history into the Infra repository.

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