Skip to content

CI / release

GitHub Actions checks: install reproducibility, toolchain version drift, and release-pipeline correctness (tests/analysis before publish, no debug/dev artifacts). Secrets are never resolved and are redacted in evidence.

13 checks.

ci-cache-key-missing-lockfile

Severity: Low

A cache key not derived from the lockfile can serve a stale dependency cache after the lockfile changes, masking version drift or breaking the build.

How to fix: Include the lockfile in the cache key, e.g. key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }}.


ci-flutter-version-drift

Severity: Low

Different Flutter versions across CI jobs build/test against different toolchains, so a green check on one job does not guarantee the others.

How to fix: Pin one Flutter version across all workflows (shared env var, matrix include, or version file).


ci-java-version-drift

Severity: Low

Different Java versions across CI jobs can produce class-version mismatches and inconsistent builds.

How to fix: Pin one Java version across all workflows.


ci-release-builds-debug-artifact

Severity: Medium

A debug artifact is unoptimized, larger, and may expose debuggable internals — it must never be what gets published.

How to fix: Build the release configuration on the release path (assembleRelease / bundleRelease, flutter build --release, -configuration Release).


ci-release-gate-order-drift

Severity: Low

If the gate runs after the publish step, a broken artifact is already shipped by the time the check fails.

How to fix: Reorder steps so tests/lint run and pass before the publish/upload step.


ci-release-uses-development-config

Severity: Low

Shipping a release built with a dev/staging flavor can point the app at non-production backends or enable debug behavior in production.

How to fix: Use the production flavor/configuration on the release path; gate dev/staging builds to non-release workflows.


ci-release-without-static-analysis

Severity: Low

Static analysis catches a class of defects before release; skipping it on the release path lets analyzer-detectable issues ship.

How to fix: Add a lint/analyze step (flutter analyze, ktlint/detekt, swiftlint, eslint) to the release path.


ci-release-without-tests

Severity: Medium

Shipping without a test gate means a regression goes straight to users — the release pipeline should fail before publishing, not after.

How to fix: Run the test suite before the publish step, or make the release job depend on a test job via needs.


ci-toolchain-version-unpinned

Severity: Low

An unpinned toolchain means the build silently moves to a new Node/Java/Flutter version when the runner image updates — a classic source of surprise breakages.

How to fix: Pin an explicit version (node-version / java-version / flutter-version), ideally via a version file checked into the repo.


ci-unlocked-cocoapods-install

Severity: Low

pod update in CI ignores the committed Podfile.lock, producing non-reproducible pod versions.

How to fix: Use pod install (honors Podfile.lock) in CI; run pod update deliberately and commit the updated lock.


ci-unlocked-flutter-install

Severity: Low

pub upgrade in CI defeats the lockfile, so each run can pull different dependency versions.

How to fix: Use flutter pub get (honors pubspec.lock) in CI; run pub upgrade deliberately and commit the updated lock.


ci-unlocked-node-install

Severity: Medium

Installing without a frozen lockfile lets transitive versions drift between CI runs and from local — builds become non-reproducible and "works on my machine" bugs slip through.

How to fix: Use npm ci, yarn install --frozen-lockfile, or pnpm install --frozen-lockfile in CI, and commit the lockfile.


ci-xcode-version-drift

Severity: Low

Different Xcode versions across CI jobs build against different SDKs, so results are not comparable and releases can differ from what was tested.

How to fix: Pin one Xcode version across all workflows.