{"id":37227809,"url":"https://github.com/bcgov/action-test-and-analyse","last_synced_at":"2026-01-15T03:24:11.515Z","repository":{"id":63142434,"uuid":"565000336","full_name":"bcgov/action-test-and-analyse","owner":"bcgov","description":"GitHub Action to change run node unit tests and analyse with SonarCloud.","archived":false,"fork":false,"pushed_at":"2026-01-10T19:33:30.000Z","size":101,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-11T01:03:52.551Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bcgov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/codeowners","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-11-12T02:59:41.000Z","updated_at":"2026-01-10T19:31:49.000Z","dependencies_parsed_at":"2023-09-27T22:44:30.242Z","dependency_job_id":"6d69cbe2-6cfa-4e2c-84cd-be24093f2450","html_url":"https://github.com/bcgov/action-test-and-analyse","commit_stats":{"total_commits":15,"total_committers":2,"mean_commits":7.5,"dds":0.06666666666666665,"last_synced_commit":"c100844973819a7d20e24a238d7627a07a336cc9"},"previous_names":["bcgov/action-test-and-analyse","bcgov-nr/action-test-and-analyse"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/bcgov/action-test-and-analyse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcgov%2Faction-test-and-analyse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcgov%2Faction-test-and-analyse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcgov%2Faction-test-and-analyse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcgov%2Faction-test-and-analyse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bcgov","download_url":"https://codeload.github.com/bcgov/action-test-and-analyse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcgov%2Faction-test-and-analyse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28442270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"online","status_checked_at":"2026-01-15T02:00:08.019Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-15T03:24:10.881Z","updated_at":"2026-01-15T03:24:11.507Z","avatar_url":"https://github.com/bcgov.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\n**BREAKING CHANGES in v1.0:**\n* **node_version is now required (previously defaulted to 16)**\n* **sonar_comment_token has been removed (ignored by SonarCloud)**\n* **sonar_project_token has been renamed sonar_token**\n\n\u003c!-- Badges --\u003e\n[![Issues](https://img.shields.io/github/issues/bcgov/action-test-and-analyse)](/../../issues)\n[![Pull Requests](https://img.shields.io/github/issues-pr/bcgov/action-test-and-analyse)](/../../pulls)\n[![MIT License](https://img.shields.io/github/license/bcgov/action-test-and-analyse.svg)](/LICENSE)\n[![Lifecycle](https://img.shields.io/badge/Lifecycle-Experimental-339999)](https://github.com/bcgov/repomountie/blob/master/doc/lifecycle-badges.md)\n\n\u003c!-- Reference-Style link --\u003e\n[SonarCloud]: https://sonarcloud.io\n[Issues]: https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue\n[Pull Requests]: https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/working-with-your-remote-repository-on-github-or-github-enterprise/creating-an-issue-or-pull-request\n\n# Test and Analyze with Triggers, SonarCloud, Supply Chain Scanning and Dependency/Export Analysis\n\nThis action runs tests, dependent on triggers, optionally sending results and coverage to [SonarCloud](https://sonarcloud.io).  Test and SonarCloud can be configured to comment on pull requests or stop failing workflows.  Optional supply chain attack detection can be enabled to scan packages before installation.  Optional Knip analysis can be enabled to detect unused dependencies and exports in JavaScript/TypeScript projects.\n\nConditional triggers are used to determine whether tests need to be run.  If triggers are matched, then the appropriate code has changed and should be tested.  Tests always run if no triggers are provided.  Untriggered runs do little other than report a success.\n\nOnly nodejs (JavaScript, TypeScript) is supported by this action.  Please see our [Java action](https://github.com/bcgov/action-test-and-analyse-java) or upcoming Python action as required.\n\n# Usage\n\n```yaml\n- uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    ### Required\n\n    # Commands to run tests\n    # Please configure your app to generate coverage (coverage/lcov.info)\n    commands: |\n      npm ci\n      npm run test:cov\n\n    # Project/app directory\n    dir: frontend\n\n    # Node.js version\n    # BREAKING CHANGE: previously defaulted to 16 (LTS)\n    node_version: \"20\"\n\n    ### Typical / recommended\n\n    # Sonar arguments\n    # https://docs.sonarcloud.io/advanced-setup/analysis-parameters/\n    sonar_args: |\n        -Dsonar.exclusions=**/coverage/**,**/node_modules/**\n        -Dsonar.organization=bcgov-sonarcloud\n        -Dsonar.projectKey=bcgov_${{ github.repository }}\n\n    # Sonar token\n    # Available from sonarcloud.io or your organization administrator\n    # BCGov uses https://github.com/BCDevOps/devops-requests/issues/new/choose\n    # Provide an unpopulated token for pre-setup, section will be skipped\n    sonar_token: ${{ secrets.SONAR_TOKEN }}\n\n    # Bash array to diff for build triggering\n    # Optional, defaults to nothing, which forces a build\n    triggers: ('frontend/')\n\n    # Enable supply chain attack detection using @aikidosec/safe-chain\n    # Optional, defaults to true (enabled by default for security)\n    # Detects and blocks malicious packages during npm ci\n    # Set to false to disable\n    supply_scan: true\n\n    # Enable dependency and export analysis using Knip\n    # Optional, defaults to warn (runs but doesn't fail)\n    # Options: off (skip), warn (run but don't fail), error (run and fail on issues)\n    # Analyzes JS/TS projects for unused dependencies and exports\n    dep_scan: warn\n\n    ### Usually a bad idea / not recommended\n\n    # Overrides the default branch to diff against\n    # Defaults to the default branch, usually `main`\n    diff_branch: ${{ github.event.repository.default_branch }}\n\n    # Repository to clone and process\n    # Useful for consuming other repos, like in testing\n    # Defaults to the current one\n    repository: ${{ github.repository }}\n\n    # Branch to clone and process\n    # Useful for consuming non-default branches, like in testing\n    # Defants to empty, cloning the default branch\n    branch: \"\"\n```\n\n# Example, Single Directory with SonarCloud Analysis, Supply Chain Scanning, and Dependency/Export Analysis\n\nRun tests and provide results to SonarCloud.  This is a full workflow that runs on pull requests, merge to main and workflow_dispatch.  Use a GitHub Action secret to provide ${{ secrets.SONAR_TOKEN }}.\n\nThe specified triggers will be used to decide whether this job runs tests and analysis or just exits successfully.\n\nThis example demonstrates the default behavior with supply chain scanning enabled (scans packages before installation) and Knip analysis set to error mode (detects unused dependencies and exports).\n\nCreate or modify a GitHub workflow, like below.  E.g. `./github/workflows/tests.yml`\n\nNote: Provide an unpopulated SONAR_TOKEN until one is provisioned.  SonarCloud will only run once populated, allowing for pre-setup.\n\n```yaml\nname: Test and Analyze\n\non:\n  pull_request:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      - \".github/**\"\n      - \"**.md\"\n  workflow_dispatch:\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  tests:\n    name: Test and Analyze\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: bcgov/action-test-and-analyse@x.y.z\n        with:\n          commands: |\n            npm ci\n            npm run test:cov\n          dir: frontend\n          node_version: \"20\"\n          sonar_args: |\n            -Dsonar.exclusions=**/coverage/**,**/node_modules/**\n            -Dsonar.organization=bcgov-nr\n            -Dsonar.projectKey=bcgov-nr_action-test-and-analyse_frontend\n          sonar_token: ${{ secrets.SONAR_TOKEN }}\n          dep_scan: error\n          # supply_scan defaults to true, so no need to specify\n          triggers: ('frontend/' 'charts/frontend')\n```\n\n# Example, Only Running Tests (No SonarCloud, Supply Chain Scanning Disabled, No Dependency/Export Analysis), No Triggers\n\nNo triggers are provided so tests will always run.  SonarCloud is skipped, supply chain scanning is disabled, and dependency/export analysis is skipped.\n\n```yaml\njobs:\n  tests:\n    name: Test and Analyze\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: bcgov/action-test-and-analyse@x.y.z\n        with:\n          commands: |\n            npm ci\n            npm run test:cov\n          dir: frontend\n          node_version: \"20\"\n          supply_scan: false  # Disable supply chain scanning\n          dep_scan: off  # Disable dependency analysis\n```\n\n# Example, Matrix / Multiple Directories with Sonar Cloud and Triggers\n\nTest and analyze projects in multiple directories in parallel.  This time `repository` and `branch` are provided.  Please note how secrets must be passed in to composite Actions using the secrets[matrix.variable] syntax.\n\n```yaml\njobs:\n  tests:\n    name: Test and Analyze\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        dir: [backend, frontend]\n        include:\n          - dir: backend\n            token: SONAR_TOKEN_BACKEND\n            triggers: ('frontend/' 'charts/frontend')\n          - dir: frontend\n            token: SONAR_TOKEN_FRONTEND\n            triggers: ('backend/' 'charts/backend')\n    steps:\n      - uses: actions/checkout@v5\n      - uses: bcgov/action-test-and-analyse@x.y.z\n        with:\n          commands: |\n            npm ci\n            npm run test:cov\n          dir: ${{ matrix.dir }}\n          node_version: \"20\"\n          sonar_args: |\n            -Dsonar.exclusions=**/coverage/**,**/node_modules/**\n            -Dsonar.organization=bcgov-nr\n            -Dsonar.projectKey=bcgov-nr_action-test-and-analyse_${{ matrix.dir }}\n          sonar_token: ${{ secrets[matrix.token] }}\n          triggers: ${{ matrix.triggers }}\n          repository: bcgov/quickstart-openshift\n          branch: main\n```\n\n# Outputs\n\n| Output    | Description                                |\n| --------- | ------------------------------------------ |\n| triggered | Whether the action was triggered based on path changes (true/false) |\n\nHas the action been triggered by path changes? \\[true|false\\]\n\n```yaml\n- id: test\n  uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    commands: |\n      npm ci\n      npm run test:cov\n    dir: frontend\n    node_version: \"20\"\n    triggers: ('frontend/')\n\n- if: steps.test.outputs.triggered == 'true'\n  run: echo \"✅ Tests were triggered by path changes\"\n\n- if: steps.test.outputs.triggered == 'false'\n  run: echo \"ℹ️ Tests were not triggered (no matching path changes)\"\n```\n\n# Sonar Project Token\n\nSonarCloud project tokens are free, available from [SonarCloud] or your organization's aministrators.\n\nFor BC Government projects, please create an [issue for our platform team](https://github.com/BCDevOps/devops-requests/issues/new/choose).\n\nAfter sign up, a token should be available from your project on the [SonarCloud] site.  Multirepo projects (e.g. backend, frontend) will have multiple projects.  Click `Administration \u003e Analysis Method \u003e GitHub Actions (tutorial)` to find yours.\n\nE.g. https://sonarcloud.io/project/configuration?id={\u003cPROJECT\u003e}\u0026analysisMode=GitHubActions\n\n# Supply Chain Scanning\n\nThis action supports supply chain attack detection using [@aikidosec/safe-chain](https://www.npmjs.com/package/@aikidosec/safe-chain). Supply chain scanning is **enabled by default** (default: `true`) because catching supply chain problems is critical security. When enabled, safe-chain wraps npm commands to scan packages before installation, protecting against malicious code, typosquats, and suspicious scripts.\n\n## Default Behavior\n\nSupply chain scanning is enabled by default. No configuration is required - it will automatically scan packages during `npm ci` and other package manager commands.\n\n## How to Disable\n\nIf you need to disable supply chain scanning, set `supply_scan: false` in your workflow:\n\n```yaml\n- uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    commands: |\n      npm ci\n      npm run test:cov\n    dir: frontend\n    node_version: \"20\"\n    supply_scan: false  # Disable supply chain scanning\n```\n\nWhen enabled, safe-chain will:\n- Scan packages against Aikido's threat intelligence database\n- Block known malicious packages and supply chain attacks (installation will fail if threats are detected)\n- Protect against typosquatting and suspicious install scripts\n\nNo additional configuration or API tokens are required. The scanning happens automatically during `npm ci` and other package manager commands.\n\n# Knip - Dependency and Export Analysis\n\nThis action supports dependency and export analysis using [Knip](https://knip.dev/). When enabled, Knip scans JavaScript/TypeScript projects to identify unused dependencies, devDependencies, and exports, helping keep your codebase clean and maintainable.\n\n**Default behavior**: Runs in `warn` mode (shows issues without failing) to encourage adoption without blocking builds. You can disable with `dep_scan: off` or enforce with `dep_scan: error`.\n\n## How to Use\n\nThe `dep_scan` parameter supports three modes:\n\n- **`off`** - Skip Knip analysis entirely\n- **`warn`** - Run Knip and show issues, but don't fail the workflow (default)\n- **`error`** - Run Knip and fail the workflow if issues are found\n\n### Example: Warn Mode (Default)\n\n```yaml\n- uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    commands: |\n      npm ci\n      npm run test:cov\n    dir: frontend\n    node_version: \"20\"\n    dep_scan: warn\n```\n\n### Example: Error Mode (Enforce Cleanup)\n\n```yaml\n- uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    commands: |\n      npm ci\n      npm run test:cov\n    dir: frontend\n    node_version: \"20\"\n    dep_scan: error\n```\n\nWhen enabled, Knip will:\n- Analyze your project for unused dependencies and devDependencies\n- Detect unused exports that can be removed\n- In `error` mode: Fail the workflow if unused dependencies or exports are found, encouraging cleanup\n- In `warn` mode: Show issues without failing, allowing teams to see problems without blocking builds\n\nThis helps maintain a lean dependency footprint and reduces security surface area by removing unnecessary packages.\n\n## Default Configuration\n\nThe action provides a default `.knip.json` configuration with common exceptions to reduce false positives. When no `knip_config` is provided, this default configuration is written to `.knip.json` in the project directory and will overwrite any existing `.knip.json`.\n\n### Why These Packages Are Excluded\n\nThe default configuration excludes the following packages that are commonly flagged as unused but are actually needed:\n\n- **`swagger-ui-express`** - Peer dependency for NestJS's `SwaggerModule.setup()`. NestJS dynamically requires this package at runtime, so Knip doesn't detect it as used. This is a common pattern with peer dependencies that are loaded dynamically.\n\n- **`rimraf`** - Build tool commonly used in npm scripts (e.g., `\"clean\": \"rimraf dist\"`). Knip may flag it as unused because it's referenced in `package.json` scripts rather than imported in code. It's also listed in `ignoreBinaries` since it's used as a command-line tool.\n\n- **`@types/node`** - TypeScript type definitions for Node.js. These are used by the TypeScript compiler for type checking but aren't directly imported in source code, so Knip may flag them as unused.\n\n- **`@types/react`** and **`@types/react-dom`** - TypeScript type definitions for React. Similar to `@types/node`, these are used by the TypeScript compiler but may not appear as direct imports in your codebase.\n\n## Custom Configuration\n\nWhen `knip_config` is not provided, the action uses its default configuration. If you need a custom configuration, specify it using the `knip_config` parameter:\n\n```yaml\n- uses: bcgov/action-test-and-analyse@x.y.z\n  with:\n    dep_scan: error\n    knip_config: \"configs/custom.knip.json\"  # Path is relative to the GitHub workspace root, not to the `dir` input\n```\n\n**Note:** The `knip_config` path is resolved relative to the GitHub workspace root (`github.workspace`), not relative to the `dir` input parameter. If you do not provide `knip_config`, the action will use its default configuration.\n\nEven better, tell us when you encounter false positives!  Your contributions are greatly appreciated, so please send suggestions by writing an issue or sending a PR.\n\n### Common Exclusion Options\n\nKnip provides several ways to exclude packages and files from analysis:\n\n- **`ignoreDependencies`** - Exclude specific packages from dependency analysis (supports regular expressions)\n  ```json\n  {\n    \"ignoreDependencies\": [\"hidden-package\", \"@org/.+\"]\n  }\n  ```\n\n- **`ignoreBinaries`** - Exclude binaries that aren't provided by dependencies\n  ```json\n  {\n    \"ignoreBinaries\": [\"zip\", \"docker-compose\"]\n  }\n  ```\n\n- **`ignore`** - Suppress all issue types for matching files/patterns\n  ```json\n  {\n    \"ignore\": [\"**/*.d.ts\", \"**/fixtures\"]\n  }\n  ```\n\n- **`ignoreWorkspaces`** - Exclude workspaces in monorepos\n  ```json\n  {\n    \"ignoreWorkspaces\": [\"packages/go-server\"]\n  }\n  ```\n\n- **`ignoreExports`** - Ignore specific exports from analysis\n\nFor complete configuration options, see the [Knip documentation](https://knip.dev/reference/configuration).\n\n## Requirements\n\n- JavaScript or TypeScript projects only\n- Project must have a `package.json` file\n- Works best with projects that have clear entry points defined in configuration\n\nKnip supports many JavaScript/TypeScript tools and frameworks out of the box. For advanced configuration beyond exclusions, you can also use `knip.json` or `knip.ts` configuration files. See [Knip documentation](https://knip.dev/) for all available options.\n\n# Feedback\n\nPlease contribute your ideas!  [Issues] and [pull requests] are appreciated.\n\n\u003c!-- # Acknowledgements\n\nThis Action is provided courtesty of the Forestry Suite of Applications, part of the Government of British Columbia. --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcgov%2Faction-test-and-analyse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcgov%2Faction-test-and-analyse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcgov%2Faction-test-and-analyse/lists"}