diff --git a/.github/workflows/dart_package.yml b/.github/workflows/dart_package.yml index d00ca63..7eaee46 100644 --- a/.github/workflows/dart_package.yml +++ b/.github/workflows/dart_package.yml @@ -17,6 +17,26 @@ on: type: string default: "" description: "Newline-separated list of globs to upload as a workflow artifact, relative to the repository root (e.g. 'coverage/lcov.info'). Empty disables the upload." + cognitive_complexity_diff_base: + required: false + type: string + default: "" + description: "Git reference to compare against when computing complexity changes (e.g. 'origin/main'). Empty lets the action auto-detect the base." + cognitive_complexity_fail_on_increase: + required: false + type: boolean + default: false + description: "Whether to fail the job when cognitive complexity increases relative to cognitive_complexity_diff_base." + cognitive_complexity_fail_threshold: + required: false + type: number + default: 15 + description: "The maximum cognitive complexity score a function may reach before the job fails." + cognitive_complexity_targets: + required: false + type: string + default: "lib" + description: "Space-separated list of directories or files to scan for cognitive complexity. Resolved from the repository root, not working_directory." collect_coverage_from: required: false type: string @@ -67,6 +87,10 @@ on: required: false type: boolean default: true + run_cognitive_complexity: + required: false + type: boolean + default: false run_skipped: required: false type: boolean @@ -156,6 +180,15 @@ jobs: dart pub global activate bloc_tools bloc lint . + - name: 🧠 Cognitive Complexity + if: ${{inputs.run_cognitive_complexity}} + uses: kevmoo/analytica.dart/packages/cognitive_complexity@main + with: + targets: ${{inputs.cognitive_complexity_targets}} + fail-threshold: ${{inputs.cognitive_complexity_fail_threshold}} + fail-on-increase: ${{inputs.cognitive_complexity_fail_on_increase}} + diff-base: ${{inputs.cognitive_complexity_diff_base}} + - name: 🧪 Run Tests run: >- very_good dart test diff --git a/.github/workflows/flutter_package.yml b/.github/workflows/flutter_package.yml index 4072eba..320fe64 100644 --- a/.github/workflows/flutter_package.yml +++ b/.github/workflows/flutter_package.yml @@ -17,6 +17,26 @@ on: type: string default: "" description: "Newline-separated list of globs to upload as a workflow artifact, relative to the repository root (e.g. '**/failures/**'). Empty disables the upload." + cognitive_complexity_diff_base: + required: false + type: string + default: "" + description: "Git reference to compare against when computing complexity changes (e.g. 'origin/main'). Empty lets the action auto-detect the base." + cognitive_complexity_fail_on_increase: + required: false + type: boolean + default: false + description: "Whether to fail the job when cognitive complexity increases relative to cognitive_complexity_diff_base." + cognitive_complexity_fail_threshold: + required: false + type: number + default: 15 + description: "The maximum cognitive complexity score a function may reach before the job fails." + cognitive_complexity_targets: + required: false + type: string + default: "lib" + description: "Space-separated list of directories or files to scan for cognitive complexity. Resolved from the repository root, not working_directory." collect_coverage_from: required: false type: string @@ -77,6 +97,10 @@ on: required: false type: boolean default: true + run_cognitive_complexity: + required: false + type: boolean + default: false run_skipped: required: false type: boolean @@ -173,6 +197,15 @@ jobs: flutter pub global activate bloc_tools bloc lint . + - name: 🧠 Cognitive Complexity + if: ${{inputs.run_cognitive_complexity}} + uses: kevmoo/analytica.dart/packages/cognitive_complexity@main + with: + targets: ${{inputs.cognitive_complexity_targets}} + fail-threshold: ${{inputs.cognitive_complexity_fail_threshold}} + fail-on-increase: ${{inputs.cognitive_complexity_fail_on_increase}} + diff-base: ${{inputs.cognitive_complexity_diff_base}} + # Built in a bash step so the test command below stays shell-agnostic # (Windows runners default to pwsh, which cannot parse bash loops). - name: 🎯 Resolve Dart Defines diff --git a/site/docs/workflows/dart_package.md b/site/docs/workflows/dart_package.md index 004561f..72555b7 100644 --- a/site/docs/workflows/dart_package.md +++ b/site/docs/workflows/dart_package.md @@ -18,8 +18,9 @@ The Dart package workflow consists of the following steps: 6. Format 7. Analyze 8. Bloc Lint (if enabled) -9. Run tests (includes coverage collection and enforcement) -10. Upload artifacts (if configured) +9. Cognitive Complexity (if enabled) +10. Run tests (includes coverage collection and enforcement) +11. Upload artifacts (if configured) ## Inputs @@ -144,6 +145,40 @@ The Dart package workflow consists of the following steps: **Default** `true` +### `run_cognitive_complexity` + +**Optional** Whether to run the [cognitive_complexity](https://pub.dev/packages/cognitive_complexity) audit on the package. See [Cognitive complexity](#cognitive-complexity). + +**Default** `false` + +### `cognitive_complexity_targets` + +**Optional** Space-separated list of directories or files to scan for cognitive complexity. + +:::note +Like [`artifact_paths`](#artifact_paths), these paths are resolved from the **repository root**, not from [`working_directory`](#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`](#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** `""` + ### `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 output from a failed run as well as reports produced by a green one. An empty value disables the upload entirely. @@ -218,6 +253,30 @@ with: Exclusions and the rest of the pattern syntax work as described in the [`actions/upload-artifact` documentation](https://github.com/actions/upload-artifact#upload-using-multiple-paths-and-exclusions). +## Cognitive complexity + +Enable [`run_cognitive_complexity`](#run_cognitive_complexity) to audit the package with [`package:cognitive_complexity`](https://pub.dev/packages/cognitive_complexity). The step fails when any function's score exceeds [`cognitive_complexity_fail_threshold`](#cognitive_complexity_fail_threshold), and can additionally block increases relative to a base ref via [`cognitive_complexity_fail_on_increase`](#cognitive_complexity_fail_on_increase) and [`cognitive_complexity_diff_base`](#cognitive_complexity_diff_base). + +```yaml +with: + run_cognitive_complexity: true + cognitive_complexity_targets: 'lib' + cognitive_complexity_fail_threshold: 15 +``` + +To post the complexity report as a pull request comment, grant the caller workflow `pull-requests: write` permission: + +```yaml +jobs: + build: + permissions: + contents: read + pull-requests: write + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1 + with: + run_cognitive_complexity: true +``` + ## Providing environment variables Tests sometimes read values from the environment via [`Platform.environment`](https://api.dart.dev/dart-io/Platform/environment.html), for example: diff --git a/site/docs/workflows/flutter_package.md b/site/docs/workflows/flutter_package.md index 36bbcf1..4b3788b 100644 --- a/site/docs/workflows/flutter_package.md +++ b/site/docs/workflows/flutter_package.md @@ -18,8 +18,9 @@ The Flutter package workflow consists of the following steps: 6. Format 7. Analyze 8. Bloc Lint (if enabled) -9. Run tests (includes coverage collection and enforcement) -10. Upload artifacts (if configured) +9. Cognitive Complexity (if enabled) +10. Run tests (includes coverage collection and enforcement) +11. Upload artifacts (if configured) ## Inputs @@ -149,6 +150,40 @@ Files other than `.fvmrc` and `fvm_config.json` (such as `pubspec.yaml`) are par **Default** `true` +### `run_cognitive_complexity` + +**Optional** Whether to run the [cognitive_complexity](https://pub.dev/packages/cognitive_complexity) audit on the package. See [Cognitive complexity](#cognitive-complexity). + +**Default** `false` + +### `cognitive_complexity_targets` + +**Optional** Space-separated list of directories or files to scan for cognitive complexity. + +:::note +Like [`artifact_paths`](#artifact_paths), these paths are resolved from the **repository root**, not from [`working_directory`](#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`](#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. @@ -248,6 +283,30 @@ with: Exclusions and the rest of the pattern syntax work as described in the [`actions/upload-artifact` documentation](https://github.com/actions/upload-artifact#upload-using-multiple-paths-and-exclusions). +## Cognitive complexity + +Enable [`run_cognitive_complexity`](#run_cognitive_complexity) to audit the package with [`package:cognitive_complexity`](https://pub.dev/packages/cognitive_complexity). The step fails when any function's score exceeds [`cognitive_complexity_fail_threshold`](#cognitive_complexity_fail_threshold), and can additionally block increases relative to a base ref via [`cognitive_complexity_fail_on_increase`](#cognitive_complexity_fail_on_increase) and [`cognitive_complexity_diff_base`](#cognitive_complexity_diff_base). + +```yaml +with: + run_cognitive_complexity: true + cognitive_complexity_targets: 'lib' + cognitive_complexity_fail_threshold: 15 +``` + +To post the complexity report as a pull request comment, grant the caller workflow `pull-requests: write` permission: + +```yaml +jobs: + build: + permissions: + contents: read + pull-requests: write + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + run_cognitive_complexity: true +``` + ## Example Usage ```yaml diff --git a/test/package-lock.json b/test/package-lock.json index 20d4924..00aca88 100644 --- a/test/package-lock.json +++ b/test/package-lock.json @@ -1503,9 +1503,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1527,9 +1524,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1551,9 +1545,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1575,9 +1566,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1599,9 +1587,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1623,9 +1608,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2137,9 +2119,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2154,9 +2133,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2171,9 +2147,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2188,9 +2161,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2205,9 +2175,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2222,9 +2189,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2239,9 +2203,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2256,9 +2217,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2273,9 +2231,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2290,9 +2245,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [