Flutter Package
This workflow runs helpful checks on a Flutter package according to the steps below. As with any workflow, it can be customized.
Steps
The Flutter package workflow consists of the following steps:
- Setup Flutter
- Set SSH Key (if provided)
- Set Pub Tokens (if provided)
- Install dependencies
- Run Setup (if provided)
- Format
- Analyze
- Bloc Lint (if enabled)
- Cognitive Complexity (if enabled)
- Run tests (includes coverage collection and enforcement)
- Upload artifacts (if configured)
Inputs
analyze_directories
Optional A space-separated list of folders that should be analyzed.
Default "lib test"
format_directories
Optional A space-separated list of folders that should be formatted.
Default "lib test"
concurrency
Optional The number of concurrent test suites run.
Default 4
coverage_excludes
Optional Space-separated list of globs to exclude files from the coverage report (e.g. '**/*.g.dart **/gen/*.dart').
Default ""
dart_define
Optional Space-separated list of key-value pairs passed to the tests as --dart-define (e.g. dart.vm.product=true FLAVOR=staging). Each pair is forwarded as a separate --dart-define flag.
Default ""
flutter_channel
Optional The Flutter release channel to use (e.g. stable).
Default "stable"
flutter_version
Optional The Flutter SDK version to use (e.g. 3.24.0).
Default ""
flutter_version_file
Optional Path to a file that holds the Flutter version to use, such as pubspec.yaml or .fvmrc, resolved from the repository root rather than working_directory. This lets you keep a single source of truth for the Flutter version.
flutter_version_file and flutter_version are mutually exclusive. Setting both fails the job with Cannot specify both a version and a version file.
Files other than .fvmrc and fvm_config.json (such as pubspec.yaml) are parsed with yq, which Windows runners don't provide. On Windows, use .fvmrc or fvm_config.json.
Default ""
format_line_length
Optional The preferred line length preferred for running the dart format command. Be aware that this does not change the behavior of the analysis step and longer lines could still make the workflow fail if the rule lines_longer_than_80_chars is used.
min_coverage
Optional The minimum coverage percentage allowed.
Default 100
setup
Optional A command that should be executed immediately after dependencies are installed.
Default ""
working_directory
Optional The path to the root of the Flutter package.
Default "."
test_optimization
Optional Enable the test optimization.
Default true
Note: Since the optimization process groups tests into a single file, golden tests will not work properly. Consider disabling optimizations if you are using golden tests.
test_recursion
Optional Whether to recursively run tests in nested directories.
Default false
runs_on
Optional The operating system on which to run the workflow.
Default "ubuntu-latest"
timeout_minutes
Optional The maximum number of minutes to let the job run before GitHub automatically cancels it.
Default 360
package_get_excludes
Optional List of paths to exclude from packages get. Supports globs to describe file patterns.
Default "!*"
platform
Optional The platform to run tests on (e.g., chrome, android, ios).
Default ""
report_on
Optional A comma-separated list of folders that should be checked in code coverage.
Default "lib"
run_bloc_lint
Optional Whether to run bloc lint on the package.
Default false
run_cognitive_complexity
Optional Whether to run the cognitive_complexity audit on the package. See Cognitive complexity.
Default false
cognitive_complexity_targets
Optional Space-separated list of directories or files to scan for cognitive complexity.
Like artifact_paths, these paths are resolved from the repository root, not from working_directory. For a package nested in a monorepo, write the prefix out in full (e.g. packages/my_package/lib).
Default "lib"
cognitive_complexity_fail_threshold
Optional The maximum cognitive complexity score a function may reach before the job fails.
Default 15
cognitive_complexity_fail_on_increase
Optional Whether to fail the job when cognitive complexity increases relative to cognitive_complexity_diff_base. The action resolves the diff base on its own.
Default false
cognitive_complexity_diff_base
Optional Git reference to compare against when computing complexity changes (e.g. origin/main). An empty value lets the action auto-detect the base.
Default ""
run_skipped
Optional Run skipped tests instead of skipping them.
Default false
show_uncovered
Optional Whether to show uncovered lines when coverage is below 100%. Implicitly enables coverage collection when used alone.
Default true
collect_coverage_from
Optional Whether to collect coverage from imported files only or all files. Counting untested files against coverage (all) results in stricter enforcement.
Allowed values imports, all
Default "imports"
artifact_paths
Optional A newline-separated list of globs to upload as a workflow artifact once the tests finish. Runs on both passing and failing test runs, so it captures golden test failures as well as reports produced by a green run. An empty value disables the upload entirely.
Default ""
Note: Unlike the other path inputs, these globs are resolved from the repository root, not from working_directory. This is a constraint of actions/upload-artifact, which has no working directory setting. See Uploading artifacts.
artifact_name
Optional The name given to the uploaded artifact. Must be unique across every job in the same workflow run, otherwise the upload fails with a conflict. Only relevant when artifact_paths is set.
Default "artifacts"
Secrets
ssh_key
Optional An SSH key used to access private repositories when installing dependencies.
pub_tokens
Optional Authentication tokens for custom package repositories, used to resolve dependencies hosted somewhere other than pub.dev. Provide one entry per line in the form <hosted-url> <token>. Each entry is registered with dart pub token add before dependencies are installed, so several repositories can be authenticated at once. The token is read through the recommended --env-var flag rather than being written to a configuration file. Lines that do not contain a space fail the workflow. See Custom package repositories.
Custom package repositories
When a package depends on a custom (private) package repository, pass the credentials through the pub_tokens secret. Store the tokens in a repository or organization secret with one <hosted-url> <token> pair per line:
https://dart-packages.example.com TOKEN_VALUE
https://another-repo.example.com ANOTHER_TOKEN_VALUE
Then forward that secret to the workflow:
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v2
secrets:
pub_tokens: ${{secrets.PUB_TOKENS}}
The step only runs when the secret is provided, so packages that depend solely on pub.dev need no extra configuration.
Uploading artifacts
Set artifact_paths to keep files produced by the run. The step executes whether the tests pass or fail, and quietly does nothing when no file matches.
The main use case is golden tests. When matchesGoldenFile fails, Flutter writes the expected and actual images, plus pixel diffs when the two share the same dimensions, into a failures directory next to the test. That directory normally disappears along with the runner:
with:
test_optimization: false
artifact_paths: '**/failures/**'
Both settings are needed here. As noted under test_optimization, the optimization step groups tests into a single file and breaks golden tests, so it has to be off before there are any failures worth uploading.
Globs are resolved from the repository root rather than from working_directory, so **/failures/** matches every package in a monorepo. To scope the upload to one package, write the prefix out in full:
with:
working_directory: packages/my_package
artifact_paths: 'packages/my_package/**/failures/**'
Pass several globs on separate lines, and use artifact_name to keep names unique when more than one job uploads in the same run:
with:
artifact_paths: |
**/failures/**
coverage/lcov.info
artifact_name: 'artifacts-${{matrix.package}}'
Exclusions and the rest of the pattern syntax work as described in the actions/upload-artifact documentation.
Cognitive complexity
Enable run_cognitive_complexity to audit the package with package:cognitive_complexity. The step fails when any function's score exceeds cognitive_complexity_fail_threshold, and can additionally block increases relative to a base ref via cognitive_complexity_fail_on_increase and cognitive_complexity_diff_base.
with:
run_cognitive_complexity: true
cognitive_complexity_targets: 'lib'
cognitive_complexity_fail_threshold: 15
When enabled, the workflow checks out the full git history so the action can resolve a merge base against the diff base. No extra configuration is required.
To post the complexity report as a pull request comment, grant the caller workflow pull-requests: write permission:
jobs:
build:
permissions:
contents: read
pull-requests: write
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v2
with:
run_cognitive_complexity: true
Example Usage
name: My Flutter Workflow
on: pull_request
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v2
with:
coverage_excludes: '**/*.g.dart'
dart_define: 'dart.vm.product=true FLAVOR=staging'
flutter_channel: 'stable'
flutter_version: '3.35.0'
timeout_minutes: 10
working_directory: 'examples/my_flutter_package'
test_recursion: true
secrets:
ssh_key: ${{secrets.EXAMPLE_KEY}}