Skip to content

ci: run the Dart test suite on pull_request - #8930

Merged
myleshorton merged 1 commit into
mainfrom
fisk/ci-flutter-test
Jul 26, 2026
Merged

ci: run the Dart test suite on pull_request#8930
myleshorton merged 1 commit into
mainfrom
fisk/ci-flutter-test

Conversation

@myleshorton

@myleshorton myleshorton commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

The gap

Nothing in CI ran flutter test test/. Every pre-existing flutter test call in the repo, in full:

$ grep -rn 'flutter test' .github/
build-linux.yml:250    flutter test integration_test/vpn/linux_connect_smoke_test.dart
build-linux.yml:288    flutter test integration_test/auth/auth_smoke_test.dart
build-windows.yml:321  flutter test integration_test/auth/auth_smoke_test.dart
scripts/linux_config_url_smoke.sh:24,26
                       flutter test integration_test/vpn/linux_config_url_*.dart

All five target integration_test/, never test/. build-linux.yml and build-windows.yml are workflow_call-only; the script is reached from those same jobs.

And the workflows that do trigger on pull_request are only go.yml, android-compile-check.yml, and update-issue-status.yml — Go tests, a Kotlin compile gate, and issue-board bookkeeping. No Dart tests. (app-smoke-tests.yml is workflow_dispatch-only.)

So the 114-test unit suite has never executed on a PR. Tests could rot, or pin a regression that CI would happily let through.

Why now

This is the second half of #8929. lantern-box v0.0.101 changed the JSON shape of user_failures, which broke AvailableServers.fromJson for every user carrying a recorded failure — and cost them their entire server list. It shipped in v9.1.16-beta and v9.1.17-beta.

#8929 added seven tests, five of which fail without the fix. Without this workflow those five are inert: a future change that reintroduced the break would go green.

What this runs

flutter test runs on the Dart VM and builds no platform artifact, so this needs no Go toolchain, no Android SDK, no Java — just checkout, Flutter, make pubget && make gen, and the suite. Six steps.

Two details worth calling out:

  • touch app.envapp.env is a gitignored declared pubspec asset, normally decoded from a secret by the release workflow. Asset bundling runs before any test does and hard-fails without it (No file or variants found for asset: app.envFailed to build asset bundle). Same empty-placeholder treatment, and same comment, as android-compile-check.yml.
  • make gen — generated sources are committed, so this isn't strictly required to get a green run. It's here so the suite tests the PR's own source rather than whatever .g.dart happened to be checked in; a model change with a forgotten make gen would otherwise pass against stale generated code. It costs ~20s.

No --reporter flag: the Dart test runner already defaults to its github reporter under Actions, which annotates failures inline on the PR.

Path filter is lib/**, test/**, pubspec.{yaml,lock}, .github/flutter-version.yaml, plus the usual self-trigger — so this PR exercises its own workflow.

Deleting test/widget_test.dart

This had to go first, or the new job could never be green. It is the stock flutter create counter template, and the load-bearing line is commented out:

testWidgets('Counter increments smoke test', (WidgetTester tester) async {
  // Build our app and trigger a frame.
  // await tester.pumpWidget(const MyApp());

  // Verify that our counter starts at 0.
  expect(find.text('0'), findsOneWidget);   // <-- against an empty tree

It asserts against an empty widget tree, so it fails unconditionally — verified on origin/main at 444c1397, which reported +107 -1 with this as the only failure (widget_test.dart:17). It was never adapted to this app and there is no MyApp to pump; this repo's root widget is LanternApp. Nothing else references it.

Verification

Locally, at the exact commands the workflow runs:

commit result
444c13971 (main before #8929) +107 -1 — only widget_test.dart fails
6fc4c9705 (main after #8929) + this PR +114 All tests passed!

114 = 107 baseline + the 7 new user_failures deserialization tests from #8929. Confirmed those seven ran, rather than being silently skipped.

Noticed, not fixed here

make gen on a cold cache rewrites lib/features/home/provider/home_notifier.g.dart — the committed riverpod content hash is stale relative to home_notifier.dart:

-String _$homeNotifierHash() => r'dce2899ed14b142ae662b13a1e02b2525e826d60';
+String _$homeNotifierHash() => r'5c0613e6e2059cf9ff59edaba2f7cb1fce865485';

Harmless — it's a hot-reload guard, and the suite passes either way. But it means a git diff --exit-code "generated files are current" assertion would fail on main today. That'd be a reasonable follow-up gate; it's a separate policy call and out of scope here.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added automated Flutter test checks for pull requests and manual runs.
    • Test runs now validate generated sources and execute the full Flutter test suite.
    • Removed the outdated counter widget smoke test.

Nothing ran `flutter test test/` on a PR. The only two references to
`flutter test` live in build-linux.yml and build-windows.yml, both
workflow_call-only and both scoped to integration_test/ — so the unit
suite never executed in CI at all.

That is part of why the user_failures deserialization break (#8929)
reached three releases: a unit test would have caught it, and a unit
test now pins it, but on `pull_request` nothing would have run it.

flutter test needs no Go toolchain, Android SDK, or Java, so this gate
is just checkout + flutter + pubget/gen + test.

Deletes test/widget_test.dart, which had to go first: it is the stock
`flutter create` counter template with `pumpWidget` commented out, so it
asserts against an empty widget tree and fails unconditionally. It was
never adapted to this app and tests nothing.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 25, 2026 17:52
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a path-filtered GitHub Actions workflow for Flutter tests, including dependency caching, Flutter setup, source generation, environment preparation, and test execution. The existing counter widget smoke test is removed.

Changes

Flutter test CI

Layer / File(s) Summary
Workflow triggers and scheduling
.github/workflows/flutter-test.yml
Adds manual and Dart-related pull request triggers, plus concurrency cancellation for superseded runs.
Flutter test execution
.github/workflows/flutter-test.yml, test/widget_test.dart
Runs dependency setup, code generation, environment preparation, and flutter test; removes the previous counter widget smoke test.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding CI to run the Dart test suite on pull requests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fisk/ci-flutter-test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a PR-triggered GitHub Actions workflow to run the Flutter/Dart unit + widget test suite under test/, closing a CI gap where only integration_test/ was exercised (and not on pull_request). It also removes the default flutter create template widget test that fails unconditionally so the new CI gate can be green.

Changes:

  • Add .github/workflows/flutter-test.yml to run make pubget, make gen, then flutter test on relevant PR path changes.
  • Create a placeholder app.env in CI to satisfy Flutter asset bundling during tests.
  • Delete test/widget_test.dart (the unused template test that fails against an empty widget tree).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
test/widget_test.dart Removes a default template widget test that fails unconditionally, preventing CI from going green.
.github/workflows/flutter-test.yml Introduces a PR-triggered workflow that runs the Dart/Flutter test/ suite with minimal setup (Flutter + pubget + codegen + tests).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/flutter-test.yml (1)

42-58: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid caching ~/.pub-cache twice.

The explicit cache step and subosito/flutter-action@v2.22.0 with cache: true both cache pub dependencies, causing redundant restore/save work. Keep the Flutter action’s cache and remove the explicit cache step, or intentionally disable one layer. (raw.githubusercontent.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/flutter-test.yml around lines 42 - 58, Remove the explicit
“Cache Flutter dependencies” actions/cache step from the workflow and retain
cache: true on the “Install Flutter” subosito/flutter-action step, ensuring
~/.pub-cache is managed by only one caching mechanism.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/flutter-test.yml:
- Around line 39-40: Update the actions/checkout@v4 step in the workflow to
disable credential persistence by setting persist-credentials to false before
the PR-controlled make pubget, make gen, and flutter test steps; do not add
authenticated Git access unless explicitly required.

---

Nitpick comments:
In @.github/workflows/flutter-test.yml:
- Around line 42-58: Remove the explicit “Cache Flutter dependencies”
actions/cache step from the workflow and retain cache: true on the “Install
Flutter” subosito/flutter-action step, ensuring ~/.pub-cache is managed by only
one caching mechanism.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 87e28a25-4d8a-4388-b523-5578aa7f5a45

📥 Commits

Reviewing files that changed from the base of the PR and between 6fc4c97 and 0abeb92.

📒 Files selected for processing (2)
  • .github/workflows/flutter-test.yml
  • test/widget_test.dart
💤 Files with no reviewable changes (1)
  • test/widget_test.dart

Comment on lines +39 to +40
- name: Checkout code
uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/flutter-test.yml ]; then
  nl -ba .github/workflows/flutter-test.yml | sed -n '1,120p'
else
  echo "missing .github/workflows/flutter-test.yml"
fi

echo
echo "== actions checkout usages with persist-credentials =="
rg -n "actions/checkout|persist-credentials" .github/workflows || true

echo
echo "== read commands after checkout that are likely PR-controlled =="
python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/flutter-test.yml')
if not p.exists():
    raise SystemExit
lines = p.read_text().splitlines()
for i,l in enumerate(lines,1):
    if i <= 45: continue
    if any(s in l for s in ['shell:', 'run:', '- ', '&&', ';']):
        print(f"{i}: {l}")
PY

Repository: getlantern/lantern

Length of output: 219


🏁 Script executed:

#!/bin/sh
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/flutter-test.yml ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/flutter-test.yml | sed -n '1,140p'
else
  echo "missing .github/workflows/flutter-test.yml"
fi

echo
echo "== actions checkout usages with persist-credentials =="
grep -Rn "actions/checkout\|persist-credentials" .github/workflows || true

echo
echo "== commands after checkout that are likely PR-controlled =="
python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/flutter-test.yml')
if not p.exists():
    raise SystemExit
lines = p.read_text().splitlines()
in_run = False
for i,l in enumerate(lines, 1):
    stripped = l.strip()
    if stripped.startswith('run:'):
        in_run = True
    elif l.startswith('      - ') or l.startswith('    - '):
        in_run = False
    if i <= 45:
        continue
    if in_run or stripped.startswith('make ') or stripped.startswith('flutter ') or stripped.startswith('//'):
        print(f"{i}: {l}")
PY

Repository: getlantern/lantern

Length of output: 6010


🌐 Web query:

actions/checkout v4 persist-credentials default true README

💡 Result:

In actions/checkout version 4, the persist-credentials input defaults to true [1][2]. When this setting is enabled (the default), the authentication token or SSH key used by the action is persisted in the local git configuration [3][4]. This allows subsequent steps in your workflow to execute authenticated git commands [3][4]. The action automatically removes this token during the post-job cleanup phase [3][4]. If you wish to prevent the action from configuring your credentials in the local git config, you can explicitly set persist-credentials to false in your workflow file [3][4].

Citations:


Disable checkout credential persistence before running PR-controlled code.

actions/checkout@v4 persists GITHUB_TOKEN credentials by default, and this pull_request job later runs PR-controlled make pubget, make gen, and flutter test. Set persist-credentials: false unless this workflow needs authenticated Git access.

Proposed fix
       - name: Checkout code
         uses: actions/checkout@v4
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout code
uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 39-40: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/flutter-test.yml around lines 39 - 40, Update the
actions/checkout@v4 step in the workflow to disable credential persistence by
setting persist-credentials to false before the PR-controlled make pubget, make
gen, and flutter test steps; do not add authenticated Git access unless
explicitly required.

Source: Linters/SAST tools

@myleshorton
myleshorton merged commit 7aaf93b into main Jul 26, 2026
11 checks passed
@myleshorton
myleshorton deleted the fisk/ci-flutter-test branch July 26, 2026 13:56
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.

2 participants