diff --git a/.github/linters/actionlint.yml b/.github/linters/actionlint.yml index f516136..c7ba559 100644 --- a/.github/linters/actionlint.yml +++ b/.github/linters/actionlint.yml @@ -8,3 +8,4 @@ paths: - '"env" section must be mapping node but got scalar node' - '"ports" section must be sequence node but got scalar node' - '"volumes" section must be sequence node but got scalar node' + - '"runs-on" section is alias node but mapping node is expected' diff --git a/.github/workflows/__test-workflow-continuous-integration.yml b/.github/workflows/__test-workflow-continuous-integration.yml index d26cd59..014f15a 100644 --- a/.github/workflows/__test-workflow-continuous-integration.yml +++ b/.github/workflows/__test-workflow-continuous-integration.yml @@ -11,6 +11,7 @@ jobs: uses: ./.github/workflows/continuous-integration.yml permissions: contents: read + packages: read pull-requests: write security-events: write # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 @@ -41,6 +42,7 @@ jobs: uses: ./.github/workflows/continuous-integration.yml permissions: contents: read + packages: read pull-requests: write security-events: write # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 @@ -82,6 +84,7 @@ jobs: needs: arrange-with-container permissions: contents: read + packages: read pull-requests: write security-events: write # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 @@ -116,6 +119,7 @@ jobs: needs: arrange-with-container permissions: contents: read + packages: read pull-requests: write security-events: write # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 diff --git a/.github/workflows/continuous-integration.md b/.github/workflows/continuous-integration.md index 0fb99cd..1395033 100644 --- a/.github/workflows/continuous-integration.md +++ b/.github/workflows/continuous-integration.md @@ -3,7 +3,7 @@ # GitHub Reusable Workflow: Node.js Continuous Integration
- Node.js Continuous Integration + Node.js Continuous Integration
--- @@ -34,6 +34,7 @@ Workflow to performs continuous integration steps agains a Node.js project: - **`contents`**: `read` - **`id-token`**: `write` +- **`packages`**: `read` - **`pull-requests`**: `write` - **`security-events`**: `write` @@ -52,7 +53,7 @@ on: permissions: {} jobs: continuous-integration: - uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@ce2bb8274a37c1219be2bcae2a1b2528c2c72957 # 0.19.0 + uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@2b8788166256f66b42262e273b4be22a3fc162e8 # copilot/configure-lint-and-test-commands permissions: {} secrets: # Secrets to be used during the build step. @@ -67,6 +68,10 @@ jobs: # Used when the container image is hosted in a private registry. # See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container#defining-credentials-for-a-container-registry. container-password: "" + + # GitHub token to use for authentication. + # Defaults to `GITHUB_TOKEN` if not provided. + github-token: "" with: # JSON array of runner(s) to use. # See https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job. @@ -113,11 +118,16 @@ jobs: # Default: `true` lint: "true" - # Code QL analysis language. See . + # Code QL analysis language. + # See https://github.com/github/codeql-action. + # # Default: `typescript` code-ql: typescript - # Enable dependency review scan. See . + # Enable dependency review scan. + # Works with public repositories and private repositories with a GitHub Advanced Security license. + # See https://github.com/actions/dependency-review-action. + # # Default: `true` dependency-review: true @@ -136,11 +146,13 @@ jobs: # Accepts either a string (container image name) or a JSON object with container options. # # String format (simple): + # # ```yml # container: "node:18" # ``` # # JSON object format (advanced): + # # ```json # { # "image": "node:18", @@ -156,9 +168,16 @@ jobs: # } # ``` # - # Supported properties: image (required), env (object), options (string), ports (array), volumes (array), credentials (object with username). + # Supported properties: # - # See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container + # - `image` (required) + # - `env` (object) + # - `options` (string) + # - `ports` (array) + # - `volumes` (array) + # - `credentials` (object with `username`). + # + # See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container. # # When specified, steps will execute inside this container instead of checking out code. # The container should have the project code and dependencies pre-installed. @@ -191,8 +210,11 @@ jobs: | **`lint`** | Whether to enable linting. | **false** | **string** | `true` | | | Set to `null` or empty to disable. | | | | | | Accepts a JSON object for lint options. See [lint action](../actions/lint/README.md). | | | | -| **`code-ql`** | Code QL analysis language. See . | **false** | **string** | `typescript` | -| **`dependency-review`** | Enable dependency review scan. See . | **false** | **boolean** | `true` | +| **`code-ql`** | Code QL analysis language. | **false** | **string** | `typescript` | +| | See . | | | | +| **`dependency-review`** | Enable dependency review scan. | **false** | **boolean** | `true` | +| | Works with public repositories and private repositories with a GitHub Advanced Security license. | | | | +| | See . | | | | | **`test`** | Whether to enable testing. | **false** | **string** | `true` | | | Set to `null` or empty to disable. | | | | | | Accepts a JSON object for test options. See [test action](../actions/test/README.md). | | | | @@ -201,12 +223,21 @@ jobs: | | Accepts either a string (container image name) or a JSON object with container options. | | | | | | | | | | | | String format (simple): | | | | +| | | | | | | |
container: "node:18"
| | | | | | JSON object format (advanced): | | | | +| | | | | | | |
{
 "image": "node:18",
 "env": {
 "NODE_ENV": "production"
 },
 "options": "--cpus 2",
 "ports": [8080, 3000],
 "volumes": ["/tmp:/tmp", "/cache:/cache"],
 "credentials": {
 "username": "myusername"
 }
}
| | | | -| | Supported properties: image (required), env (object), options (string), ports (array), volumes (array), credentials (object with username). | | | | +| | Supported properties: | | | | +| | | | | | +| | - `image` (required) | | | | +| | - `env` (object) | | | | +| | - `options` (string) | | | | +| | - `ports` (array) | | | | +| | - `volumes` (array) | | | | +| | - `credentials` (object with `username`). | | | | | | | | | | -| | See | | | | +| | See . | | | | | | | | | | | | When specified, steps will execute inside this container instead of checking out code. | | | | | | The container should have the project code and dependencies pre-installed. | | | | @@ -287,6 +318,8 @@ When specified, steps will execute inside this container instead of checking out | **`container-password`** | Password for container registry authentication, if required. | **false** | | | Used when the container image is hosted in a private registry. | | | | See . | | +| **`github-token`** | GitHub token to use for authentication. | **false** | +| | Defaults to `GITHUB_TOKEN` if not provided. | | @@ -317,7 +350,7 @@ on: jobs: continuous-integration: - uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@ce2bb8274a37c1219be2bcae2a1b2528c2c72957 # 0.19.0 + uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@2b8788166256f66b42262e273b4be22a3fc162e8 # copilot/configure-lint-and-test-commands permissions: id-token: write security-events: write @@ -383,7 +416,7 @@ jobs: # Run CI checks inside the Docker container continuous-integration: needs: build-image - uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@ce2bb8274a37c1219be2bcae2a1b2528c2c72957 # 0.19.0 + uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@2b8788166256f66b42262e273b4be22a3fc162e8 # copilot/configure-lint-and-test-commands permissions: id-token: write security-events: write @@ -413,7 +446,7 @@ on: jobs: continuous-integration: - uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@ce2bb8274a37c1219be2bcae2a1b2528c2c72957 # 0.19.0 + uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@2b8788166256f66b42262e273b4be22a3fc162e8 # copilot/configure-lint-and-test-commands permissions: id-token: write security-events: write diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 1c95f75..d1e65d8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -60,12 +60,17 @@ on: required: false default: "true" code-ql: - description: "Code QL analysis language. See ." + description: | + Code QL analysis language. + See https://github.com/github/codeql-action. type: string required: false default: "typescript" dependency-review: - description: "Enable dependency review scan. See ." + description: | + Enable dependency review scan. + Works with public repositories and private repositories with a GitHub Advanced Security license. + See https://github.com/actions/dependency-review-action. type: boolean required: false default: true @@ -88,11 +93,13 @@ on: Accepts either a string (container image name) or a JSON object with container options. String format (simple): + ```yml container: "node:18" ``` JSON object format (advanced): + ```json { "image": "node:18", @@ -108,9 +115,16 @@ on: } ``` - Supported properties: image (required), env (object), options (string), ports (array), volumes (array), credentials (object with username). + Supported properties: - See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container + - `image` (required) + - `env` (object) + - `options` (string) + - `ports` (array) + - `volumes` (array) + - `credentials` (object with `username`). + + See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container. When specified, steps will execute inside this container instead of checking out code. The container should have the project code and dependencies pre-installed. @@ -133,6 +147,11 @@ on: Used when the container image is hosted in a private registry. See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container#defining-credentials-for-a-container-registry. required: false + github-token: + description: | + GitHub token to use for authentication. + Defaults to `GITHUB_TOKEN` if not provided. + required: false outputs: build-artifact-id: description: "ID of the build artifact) uploaded during the build step." @@ -143,7 +162,7 @@ permissions: {} jobs: prepare: name: ๐Ÿ“ฆ Prepare configuration - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} + runs-on: &ci-runner ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} permissions: {} outputs: container-image: ${{ steps.parse.outputs.container-image }} @@ -177,8 +196,8 @@ jobs: try { const parsedContainer = JSON.parse(containerInput); core.debug(`Parsed container input as JSON: ${JSON.stringify(parsedContainer)}`); - container = { - ...container, + container = { + ...container, ...parsedContainer, options: `${container.options} ${parsedContainer.options || ''}`.trim() }; @@ -228,7 +247,7 @@ jobs: if: inputs.checks == true && inputs.code-ql != '' permissions: security-events: write - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} + runs-on: *ci-runner steps: - uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4 @@ -241,32 +260,35 @@ jobs: if: github.event_name == 'pull_request' && inputs.checks == true && inputs.dependency-review permissions: contents: read - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} + runs-on: *ci-runner steps: - uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 setup: name: โš™๏ธ Setup - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} - needs: prepare - container: &container-setup + runs-on: *ci-runner + needs: + - prepare + permissions: + contents: read + packages: read + # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 + id-token: write + container: &ci-container image: ${{ needs.prepare.outputs.container-image || '' }} env: ${{ fromJSON(needs.prepare.outputs.container-env || '{}') }} options: ${{ needs.prepare.outputs.container-options || ' ' }} ports: ${{ fromJSON(needs.prepare.outputs.container-ports || '[]') }} volumes: ${{ fromJSON(needs.prepare.outputs.container-volumes || '[]') }} credentials: ${{ fromJSON(needs.prepare.outputs.container-username && format('{{"username":{0},"password":{1}}}',toJSON(needs.prepare.outputs.container-username),toJSON(secrets.container-password)) || '{}') }} - permissions: - contents: read - # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 - id-token: write outputs: build-env: ${{ steps.build-variables.outputs.env }} build-commands: ${{ steps.build-variables.outputs.commands }} build-artifact: ${{ steps.build-variables.outputs.artifact }} steps: - - if: needs.prepare.outputs.container-image == null + - name: Checkout repository + if: inputs.container == '' uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - id: build-variables @@ -369,21 +391,21 @@ jobs: core.setOutput('env', JSON.stringify(env)); lint: - name: ๐Ÿ‘• Lint if: inputs.checks == true && inputs.lint + name: ๐Ÿ‘• Lint + runs-on: *ci-runner + container: *ci-container needs: - prepare - setup - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} - container: *container-setup - # jscpd:ignore-start permissions: contents: read + packages: read # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 id-token: write steps: - uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - if: needs.prepare.outputs.container-image == null + if: inputs.container == '' - id: oidc uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3 @@ -397,7 +419,7 @@ jobs: - run: | if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi - # jscpd:ignore-end + - id: preparel-lint-options uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: @@ -417,29 +439,35 @@ jobs: } } - - uses: ./self-workflow/actions/lint + core.setOutput('command', lintOptions.command || 'lint:ci'); + core.setOutput('report-file', lintOptions['report-file'] || ''); + + - name: Run lint + uses: ./self-workflow/actions/lint with: working-directory: ${{ inputs.working-directory }} - container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }} + container: ${{ inputs.container != '' && 'true' || 'false' }} + command: ${{ steps.preparel-lint-options.outputs.command }} + report-file: ${{ steps.preparel-lint-options.outputs.report-file }} build: - name: ๐Ÿ—๏ธ Build if: inputs.checks == true - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} - container: *container-setup - # jscpd:ignore-start + name: ๐Ÿ—๏ธ Build + runs-on: *ci-runner + container: *ci-container needs: - prepare - setup permissions: contents: read + packages: read # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 id-token: write outputs: artifact-id: ${{ steps.build.outputs.artifact-id }} steps: - uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - if: needs.setup.outputs.build-commands && needs.prepare.outputs.container-image == null + if: needs.setup.outputs.build-commands && inputs.container == '' # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 - id: oidc @@ -457,23 +485,23 @@ jobs: run: | if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi - # jscpd:ignore-end + - id: build if: needs.setup.outputs.build-commands uses: ./self-workflow/actions/build with: + container: ${{ inputs.container != '' && 'true' || 'false' }} working-directory: ${{ inputs.working-directory }} + build-secrets: ${{ secrets.build-secrets }} build-commands: ${{ needs.setup.outputs.build-commands }} build-env: ${{ needs.setup.outputs.build-env }} - build-secrets: ${{ secrets.build-secrets }} build-artifact: ${{ needs.setup.outputs.build-artifact }} - container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }} test: - name: ๐Ÿงช Test if: inputs.checks == true && inputs.test - runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }} - container: *container-setup + name: ๐Ÿงช Test + runs-on: *ci-runner + container: *ci-container needs: - prepare - setup @@ -481,13 +509,14 @@ jobs: permissions: contents: read pull-requests: write + packages: read # FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659 id-token: write steps: - uses: hoverkraft-tech/ci-github-common/actions/checkout@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 - if: needs.prepare.outputs.container-image == null + if: inputs.container == '' - - if: needs.build.outputs.artifact-id && needs.prepare.outputs.container-image == null + - if: needs.build.outputs.artifact-id && inputs.container == '' uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: artifact-ids: ${{ needs.build.outputs.artifact-id }} @@ -530,13 +559,15 @@ jobs: testOptions.coverage = 'github'; } core.setOutput('coverage', testOptions.coverage ); - core.setOutput('coverage-files', testOptions['coverage-files'] || ''); + core.setOutput('command', testOptions.command || 'test:ci'); - - uses: ./self-workflow/actions/test + - name: Run tests + uses: ./self-workflow/actions/test with: working-directory: ${{ inputs.working-directory }} - container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }} + container: ${{ inputs.container != '' && 'true' || 'false' }} + command: ${{ steps.prepare-test-options.outputs.command }} coverage: ${{ steps.prepare-test-options.outputs.coverage }} coverage-files: ${{ steps.prepare-test-options.outputs.coverage-files }} - github-token: ${{ github.token }} + github-token: ${{ secrets.github-token || github.token }} diff --git a/README.md b/README.md index f071b42..d7c7848 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ _Actions for continuous integration steps: build, lint, and test._ #### - [Test](actions/test/README.md) +#### - [Rewrite Report Paths](actions/rewrite-report-paths/README.md) + ### Dependencies _Actions dedicated to caching and validating Node.js dependencies._ diff --git a/actions/build/action.yml b/actions/build/action.yml index 5b92425..e4c0ebf 100644 --- a/actions/build/action.yml +++ b/actions/build/action.yml @@ -119,12 +119,12 @@ runs: for (const command of commands) { core.info(`Running build command: ${command}`); - + try { const result = await exec.getExecOutput(runScriptCommand, [command], { cwd: require('path').resolve(process.env.GITHUB_WORKSPACE, workingDirectory) }); - + if (result.stdout) { core.info(result.stdout); } diff --git a/actions/get-package-manager/action.yml b/actions/get-package-manager/action.yml index 3165a01..c47d607 100644 --- a/actions/get-package-manager/action.yml +++ b/actions/get-package-manager/action.yml @@ -44,6 +44,7 @@ runs: if (!path.isAbsolute(workingDirectory)) { workingDirectory = path.join(process.env.GITHUB_WORKSPACE, workingDirectory); } + core.debug(`Resolved working directory: ${workingDirectory}`); if (!fs.existsSync(workingDirectory)) { core.setFailed(`The specified working directory does not exist: ${workingDirectory}`); @@ -91,6 +92,8 @@ runs: } let relativeWorkingDirectory = path.relative(process.env.GITHUB_WORKSPACE, workingDirectory) || '.'; + core.debug(`Relative working directory to GITHUB_WORKSPACE (${process.env.GITHUB_WORKSPACE}): ${relativeWorkingDirectory}`); + let cacheDependencyPathPrefix = relativeWorkingDirectory; if (relativeWorkingDirectory.startsWith('../')) { @@ -115,6 +118,8 @@ runs: } } + core.debug(`Cache dependency path prefix: ${cacheDependencyPathPrefix}`); + const packageManagerConfig = { yarn: { cacheDependencyPath: cacheDependencyPathPrefix ? `${cacheDependencyPathPrefix}/**/yarn.lock` : '', diff --git a/actions/lint/README.md b/actions/lint/README.md index 4216595..e1453a1 100644 --- a/actions/lint/README.md +++ b/actions/lint/README.md @@ -42,6 +42,13 @@ Action to lint Node.js projects with support for pull request reporting and anno # Default: `false` container: "false" + # NPM/package manager script command to run for linting. + # This should be a script defined in your package.json. + # The command should generate lint report files in a standard format (ESLint JSON or Checkstyle XML). + # + # Default: `lint:ci` + command: "lint:ci" + # Path to lint report file to process as GitHub annotations. # Supports ESLint JSON and Checkstyle XML formats. # If not specified, auto-detection will be attempted for common paths: @@ -60,6 +67,9 @@ Action to lint Node.js projects with support for pull request reporting and anno | **`working-directory`** | Working directory where lint commands are executed. | **false** | `.` | | | Can be absolute or relative to the repository root. | | | | **`container`** | Whether running in container mode (skips checkout and node setup) | **false** | `false` | +| **`command`** | NPM/package manager script command to run for linting. | **false** | `lint:ci` | +| | This should be a script defined in your package.json. | | | +| | The command should generate lint report files in a standard format. | | | | **`report-file`** | Path to lint report file to process as GitHub annotations. | **false** | - | | | Supports ESLint JSON and Checkstyle XML formats. | | | | | If not specified, auto-detection will be attempted for common paths: | | | diff --git a/actions/lint/action.yml b/actions/lint/action.yml index 6cd4a4e..406524a 100644 --- a/actions/lint/action.yml +++ b/actions/lint/action.yml @@ -16,13 +16,18 @@ inputs: description: "Whether running in container mode (skips checkout and node setup)" required: false default: "false" + command: + description: | + NPM/package manager script command to run for linting. + This should be a script defined in your package.json. + The command should generate lint report files in a standard format (ESLint JSON or Checkstyle XML). + required: false + default: "lint:ci" report-file: description: | - Path to lint report file to process as GitHub annotations. - Supports ESLint JSON and Checkstyle XML formats. - If not specified, auto-detection will be attempted for common paths: - - eslint-report.json, eslint.json - - checkstyle-result.xml, checkstyle.xml + Optional lint report path forwarded to the [parse-ci-reports](https://hoverkraft-tech/ci-github-common/actions/parse-ci-reports) action. + Provide an absolute path or one relative to the working directory. + When omitted, the action falls back to "auto:lint" detection (ESLint JSON / Checkstyle XML). required: false default: "" @@ -53,24 +58,26 @@ runs: env: RUN_LINT_COMMAND: ${{ inputs.container == 'true' && steps.get-package-manager.outputs.run-script-command || steps.setup-node.outputs.run-script-command }} WORKING_DIRECTORY: ${{ inputs.working-directory }} + LINT_COMMAND: ${{ inputs.command }} with: script: | const workingDirectory = process.env.WORKING_DIRECTORY || '.'; const runScriptCommand = process.env.RUN_LINT_COMMAND; + const lintCommand = process.env.LINT_COMMAND || 'lint:ci'; - core.info('๐Ÿ‘• Running lint...'); + core.info(`๐Ÿ‘• Running lint command: ${lintCommand}...`); try { - const result = await exec.getExecOutput(runScriptCommand, ['lint'], { + const result = await exec.getExecOutput(runScriptCommand, [lintCommand], { cwd: require('path').resolve(process.env.GITHUB_WORKSPACE, workingDirectory), ignoreReturnCode: true }); - + if (result.stdout) core.info(result.stdout); if (result.stderr) core.warning(result.stderr); - + core.setOutput('lint-exit-code', result.exitCode); - + if (result.exitCode !== 0) { core.setFailed(`Linting failed with exit code ${result.exitCode}`); } @@ -79,85 +86,13 @@ runs: core.setFailed(`Linting error: ${error.message}`); } - # Auto-detect report file if not specified - - id: detect-report-file + - name: ๐Ÿ“Š Parse lint reports if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - REPORT_FILE: ${{ inputs.report-file }} - WORKING_DIRECTORY: ${{ inputs.working-directory }} - with: - script: | - const path = require('node:path'); - const fs = require('node:fs'); - - const workingDirectory = process.env.WORKING_DIRECTORY || '.'; - const workDir = path.resolve(process.env.GITHUB_WORKSPACE, workingDirectory); - - const autoDetectReportFormat = (filePath) => { - if (filePath.endsWith('.json')) { - return 'eslint'; - } else if (filePath.endsWith('.xml')) { - return 'checkstyle'; - } - return core.setFailed(`Unable to auto-detect report format from file extension: ${filePath}`); - }; - - if (process.env.REPORT_FILE && process.env.REPORT_FILE.trim() !== '') { - const reportFilePath = path.join(workDir, process.env.REPORT_FILE.trim()); - - if (!fs.existsSync(reportFilePath)) { - core.setFailed(`Specified report file does not exist: ${process.env.REPORT_FILE.trim()}`); - return; - } - core.info(`Report file specified: ${reportFilePath}`); - core.setOutput('report-file', reportFilePath); - core.setOutput('report-format', autoDetectReportFormat(reportFilePath)); - - return; - } - - // Common lint report file paths - const commonPaths = [ - 'eslint-report.json', - 'eslint.json', - '.eslint-report.json', - 'checkstyle-result.xml', - 'checkstyle.xml', - 'lint-results.xml', - 'reports/eslint-report.json', - 'reports/checkstyle.xml' - ]; - - for (const filePath of commonPaths) { - const fullPath = path.join(workDir, filePath); - if (fs.existsSync(fullPath)) { - core.info(`Auto-detected lint report file: ${fullPath}`); - core.setOutput('report-file', fullPath); - - // Auto-detect format from extension - core.setOutput('report-format', autoDetectReportFormat(fullPath)); - return; - } - } - - core.info('No lint report file auto-detected'); - - # Process ESLint report - - name: ๐Ÿ“Š Annotate ESLint results - if: always() && steps.detect-report-file.outputs.report-format == 'eslint' - uses: ataylorme/eslint-annotate-action@d57a1193d4c59cbfbf3f86c271f42612f9dbd9e9 # v3.0.0 - with: - report-json: ${{ steps.detect-report-file.outputs.report-file }} - fail-on-error: false - fail-on-warning: false - - # Process Checkstyle report - - name: ๐Ÿ“Š Annotate Checkstyle results - if: always() && steps.detect-report-file.outputs.report-format == 'checkstyle' - uses: lcollins/checkstyle-github-action@658deddef713a1132a9c59b64d754221b66a6f27 # v3.1.0 + uses: hoverkraft-tech/ci-github-common/actions/parse-ci-reports@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 with: - path: ${{ steps.detect-report-file.outputs.report-file }} + report-paths: ${{ inputs.report-file || 'auto:lint' }} + report-name: "Lint Results" + output-format: "annotations,summary" # FIXME: workaround until will be merged: https://github.com/actions/runner/pull/1684 - shell: bash diff --git a/actions/rewrite-report-paths/README.md b/actions/rewrite-report-paths/README.md new file mode 100644 index 0000000..463638f --- /dev/null +++ b/actions/rewrite-report-paths/README.md @@ -0,0 +1,175 @@ + + +# ![Icon](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItZWRpdCIgY29sb3I9ImJsdWUiPjxwYXRoIGQ9Ik0xMSA0SDRhMiAyIDAgMCAwLTIgMnYxNGEyIDIgMCAwIDAgMiAyaDE0YTIgMiAwIDAgMCAyLTJ2LTciPjwvcGF0aD48cGF0aCBkPSJNMTguNSAyLjVhMi4xMjEgMi4xMjEgMCAwIDEgMyAzbC0xMiAxMi0zIDEgMS0zIDEyLTEyeiI+PC9wYXRoPjwvc3ZnPg==) GitHub Action: Rewrite Report Paths + +
+ Rewrite Report Paths +
+ +--- + + + + +[![Marketplace](https://img.shields.io/badge/Marketplace-rewrite--report--paths-blue?logo=github-actions)](https://github.com/marketplace/actions/rewrite-report-paths) +[![Release](https://img.shields.io/github/v/release/hoverkraft-tech/ci-github-nodejs)](https://github.com/hoverkraft-tech/ci-github-nodejs/releases) +[![License](https://img.shields.io/github/license/hoverkraft-tech/ci-github-nodejs)](http://choosealicense.com/licenses/mit/) +[![Stars](https://img.shields.io/github/stars/hoverkraft-tech/ci-github-nodejs?style=social)](https://img.shields.io/github/stars/hoverkraft-tech/ci-github-nodejs?style=social) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/hoverkraft-tech/ci-github-nodejs/blob/main/CONTRIBUTING.md) + + + + +## Overview + +Rewrites file paths in report files to match repository paths when running in containers. + +When running tests or linting in Docker containers, the file paths in generated reports (coverage, lint results, etc.) often reference the container's internal paths (e.g., `/app/src/file.js`). This action rewrites those paths to match the actual repository structure, ensuring that GitHub annotations and coverage reports correctly reference the source files. + + + + +## Usage + +```yaml +- uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main + with: + # Path or glob pattern for report files to process. + # Supports multiple files separated by newlines. + # Common patterns: coverage/**, reports/**, **/*.xml, **/*.json + # + # Required: true + report-files: | + coverage/cobertura-coverage.xml + reports/eslint.json + + # Source root path in the container that should be replaced. + # If not specified, will attempt to auto-detect from file paths. + # Common values: /app, /workspace, /usr/src/app + # + # Default: "" (auto-detect) + source-root: "/app" + + # Target root path in the repository. + # Typically this is the GITHUB_WORKSPACE or a subdirectory. + # + # Default: GITHUB_WORKSPACE + target-root: "" + + # Working directory where report files are located. + # Can be absolute or relative to the repository root. + # + # Default: `.` + working-directory: . +``` + + + + +## Inputs + +| **Input** | **Description** | **Required** | **Default** | +| ----------------------- | ----------------------------------------------------------------------- | ------------ | ----------- | +| **`report-files`** | Path or glob pattern for report files to process. | **true** | - | +| | Supports multiple files separated by newlines. | | | +| | Common patterns: coverage/\*\*, reports/\*\*, \*\*/\*.xml, \*\*/\*.json | | | +| **`source-root`** | Source root path in the container that should be replaced. | **false** | - | +| | If not specified, will attempt to auto-detect from file paths. | | | +| **`target-root`** | Target root path in the repository. | **false** | - | +| | Typically this is the GITHUB_WORKSPACE or a subdirectory. | | | +| **`working-directory`** | Working directory where report files are located. | **false** | `.` | +| | Can be absolute or relative to the repository root. | | | + + + + + + +## Outputs + +| **Output** | **Description** | +| --------------------- | ------------------------------------------ | +| **`files-processed`** | Number of report files that were processed | +| **`paths-replaced`** | Total number of paths that were rewritten | + + + + +## Examples + +### Basic Usage with Auto-Detection + +```yaml +- name: Rewrite coverage paths + uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main + with: + report-files: | + coverage/cobertura-coverage.xml + coverage/lcov.info +``` + +### Explicit Source Root + +```yaml +- name: Rewrite report paths + uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main + with: + report-files: | + coverage/**/*.xml + reports/**/*.json + source-root: "/app" + target-root: ${{ github.workspace }} +``` + +### Multiple Report Types + +```yaml +- name: Rewrite all report paths + uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main + with: + report-files: | + coverage/cobertura-coverage.xml + reports/eslint.json + test-results/junit.xml + source-root: "/workspace" +``` + + + + + + + +## Contributing + +Contributions are welcome! Please see the [contributing guidelines](https://github.com/hoverkraft-tech/ci-github-nodejs/blob/main/CONTRIBUTING.md) for more details. + + + + + + +## License + +This project is licensed under the MIT License. + +SPDX-License-Identifier: MIT + +Copyright ยฉ 2025 hoverkraft + +For more details, see the [license](http://choosealicense.com/licenses/mit/). + + + + +--- + +This documentation was automatically generated by [CI Dokumentor](https://github.com/hoverkraft-tech/ci-dokumentor). + + + + diff --git a/actions/rewrite-report-paths/action.yml b/actions/rewrite-report-paths/action.yml new file mode 100644 index 0000000..064ec36 --- /dev/null +++ b/actions/rewrite-report-paths/action.yml @@ -0,0 +1,151 @@ +name: "Rewrite Report Paths" +description: "Rewrites file paths in report files to match repository paths when running in containers" +author: hoverkraft +branding: + icon: edit + color: blue + +inputs: + report-files: + description: | + Path or glob pattern for report files to process. + Supports multiple files separated by newlines. + Common patterns: coverage/**, reports/**, **/*.xml, **/*.json + required: true + source-root: + description: | + Source root path in the container that should be replaced. + If not specified, will attempt to auto-detect from file paths. + required: false + default: "" + target-root: + description: | + Target root path in the repository. + Typically this is the GITHUB_WORKSPACE or a subdirectory. + required: false + default: "" + working-directory: + description: | + Working directory where report files are located. + Can be absolute or relative to the repository root. + required: false + default: "." + +runs: + using: "composite" + steps: + - id: rewrite-paths + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + REPORT_FILES: ${{ inputs.report-files }} + SOURCE_ROOT: ${{ inputs.source-root }} + TARGET_ROOT: ${{ inputs.target-root }} + WORKING_DIRECTORY: ${{ inputs.working-directory }} + with: + script: | + const fs = require('fs'); + const path = require('path'); + const { glob } = require('glob'); + + const workingDirectory = process.env.WORKING_DIRECTORY || '.'; + const workDir = path.resolve(process.env.GITHUB_WORKSPACE, workingDirectory); + const reportFilesInput = process.env.REPORT_FILES.trim(); + + if (!reportFilesInput) { + core.warning('No report files specified for path rewriting'); + return; + } + + // Parse report files (can be newline separated or comma separated) + const reportPatterns = reportFilesInput + .split(/[\n,]/) + .map(p => p.trim()) + .filter(Boolean); + + core.info(`Looking for report files matching patterns: ${reportPatterns.join(', ')}`); + + // Find all matching files + let reportFiles = []; + for (const pattern of reportPatterns) { + const fullPattern = path.isAbsolute(pattern) ? pattern : path.join(workDir, pattern); + const matches = await glob(fullPattern, { nodir: true }); + reportFiles.push(...matches); + } + + if (reportFiles.length === 0) { + core.warning(`No report files found matching patterns: ${reportPatterns.join(', ')}`); + return; + } + + core.info(`Found ${reportFiles.length} report file(s) to process`); + + // Determine source and target roots + let sourceRoot = process.env.SOURCE_ROOT.trim(); + const targetRoot = process.env.TARGET_ROOT.trim() || process.env.GITHUB_WORKSPACE; + + // Auto-detect source root if not provided + if (!sourceRoot) { + // Common container working directories + const commonRoots = ['/app', '/workspace', '/usr/src/app', '/home/node/app']; + + // Try to detect from the first file + if (reportFiles.length > 0) { + const firstFile = reportFiles[0]; + const content = fs.readFileSync(firstFile, 'utf8'); + + for (const root of commonRoots) { + if (content.includes(root)) { + sourceRoot = root; + core.info(`Auto-detected source root: ${sourceRoot}`); + break; + } + } + } + + if (!sourceRoot) { + core.warning('Could not auto-detect source root. Skipping path rewriting.'); + return; + } + } + + core.info(`Rewriting paths from "${sourceRoot}" to "${targetRoot}"`); + + let filesProcessed = 0; + let pathsReplaced = 0; + + // Process each report file + for (const reportFile of reportFiles) { + try { + let content = fs.readFileSync(reportFile, 'utf8'); + const originalContent = content; + + // Create a regex to match the source root path + // Handle both Unix-style and Windows-style paths + const escapedSource = sourceRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(escapedSource.replace(/\\\//g, '[\\\\/]'), 'g'); + + // Count matches before replacement + const matches = content.match(regex); + const matchCount = matches ? matches.length : 0; + + if (matchCount > 0) { + // Replace source root with target root + content = content.replace(regex, targetRoot.replace(/\\/g, '/')); + + // Write back the modified content + fs.writeFileSync(reportFile, content, 'utf8'); + + core.info(`โœ… Processed ${reportFile}: ${matchCount} path(s) rewritten`); + filesProcessed++; + pathsReplaced += matchCount; + } else { + core.info(`โญ๏ธ Skipped ${reportFile}: no matching paths found`); + } + } catch (error) { + core.warning(`Failed to process ${reportFile}: ${error.message}`); + } + } + + core.info(`\n๐Ÿ“Š Summary: ${filesProcessed} file(s) processed, ${pathsReplaced} path(s) rewritten`); + core.setOutput('files-processed', filesProcessed); + core.setOutput('paths-replaced', pathsReplaced); diff --git a/actions/test/README.md b/actions/test/README.md index 77e597b..fad696d 100644 --- a/actions/test/README.md +++ b/actions/test/README.md @@ -42,6 +42,13 @@ Action to test Node.js projects with support for coverage reporting and pull req # Default: `false` container: "false" + # NPM/package manager script command to run for testing. + # This should be a script defined in your package.json. + # The command should generate coverage report files in a standard format (Cobertura XML, lcov, etc.). + # + # Default: `test:ci` + command: "test:ci" + # Code coverage reporter to use. Supported values: # - `github`: Use ReportGenerator for PR comments with coverage reports # - `codecov`: Upload coverage to Codecov @@ -69,24 +76,27 @@ Action to test Node.js projects with support for coverage reporting and pull req ## Inputs -| **Input** | **Description** | **Required** | **Default** | -| ----------------------- | --------------------------------------------------------------------- | ------------ | ----------- | -| **`working-directory`** | Working directory where test commands are executed. | **false** | `.` | -| | Can be absolute or relative to the repository root. | | | -| **`container`** | Whether running in container mode (skips checkout and node setup) | **false** | `false` | -| **`coverage`** | Code coverage reporter to use. Supported values: | **false** | `github` | -| | - `github`: Use ReportGenerator for PR comments with coverage reports | | | -| | - `codecov`: Upload coverage to Codecov | | | -| | - `""` or `null`: No coverage reporting | | | -| **`coverage-files`** | Path to coverage files for reporting. | **false** | - | -| | Supports multiple formats (Cobertura, OpenCover, lcov, etc.). | | | -| | Can be a single file or multiple files separated by semicolons. | | | -| | If not specified, auto-detection will be attempted for common paths: | | | -| | - coverage/cobertura-coverage.xml, coverage/coverage.xml | | | -| | - coverage/lcov.info | | | -| | - coverage/clover.xml | | | -| **`github-token`** | GitHub token for coverage PR comments. | **false** | - | -| | Required when coverage is set to `github`. | | | +| **Input** | **Description** | **Required** | **Default** | +| ----------------------- | ----------------------------------------------------------------------- | ------------ | ----------- | +| **`working-directory`** | Working directory where test commands are executed. | **false** | `.` | +| | Can be absolute or relative to the repository root. | | | +| **`container`** | Whether running in container mode (skips checkout and node setup) | **false** | `false` | +| **`command`** | NPM/package manager script command to run for testing. | **false** | `test:ci` | +| | This should be a script defined in your package.json. | | | +| | The command should generate coverage report files in a standard format. | | | +| **`coverage`** | Code coverage reporter to use. Supported values: | **false** | `github` | +| | - "GitHub": Use ReportGenerator for PR comments with coverage reports | | | +| | - "Codecov": Upload coverage to Codecov | | | +| | - "": No coverage reporting | | | +| **`coverage-files`** | Path to coverage files for reporting. | **false** | - | +| | Supports multiple formats (Cobertura, OpenCover, lcov, etc.). | | | +| | Can be a single file or multiple files separated by semicolons. | | | +| | If not specified, auto-detection will be attempted for common paths: | | | +| | - coverage/cobertura-coverage.xml, coverage/coverage.xml | | | +| | - coverage/lcov.info | | | +| | - coverage/clover.xml | | | +| **`github-token`** | GitHub token for coverage PR comments. | **false** | - | +| | Required when coverage is set to "GitHub". | | | diff --git a/actions/test/action.yml b/actions/test/action.yml index 3513ba6..7efc7f7 100644 --- a/actions/test/action.yml +++ b/actions/test/action.yml @@ -16,23 +16,28 @@ inputs: description: "Whether running in container mode (skips checkout and node setup)" required: false default: "false" + command: + description: | + NPM/package manager script command to run for testing. + This should be a script defined in your package.json. + The command should generate coverage report files in a standard format (Cobertura XML, lcov, etc.). + required: false + default: "test:ci" coverage: description: | Code coverage reporter to use. Supported values: - - `github`: Use ReportGenerator for PR comments with coverage reports + - `github`: Parse coverage reports via [parse-ci-reports](https://hoverkraft-tech/ci-github-common/actions/parse-ci-reports) action, with GitHub summaries/PR comments - `codecov`: Upload coverage to Codecov - `""` or `null`: No coverage reporting required: false default: "github" coverage-files: description: | - Path to coverage files for reporting. + Optional coverage report paths forwarded to the hoverkraft-tech/ci-github-common/actions/parse-ci-reports action. Supports multiple formats (Cobertura, OpenCover, lcov, etc.). - Can be a single file or multiple files separated by semicolons. - If not specified, auto-detection will be attempted for common paths: - - coverage/cobertura-coverage.xml, coverage/coverage.xml - - coverage/lcov.info - - coverage/clover.xml + Provide absolute paths or paths relative to the working directory. + Multiple entries can be separated by newlines, commas, or semicolons. + When omitted, the action falls back to "auto:test" detection (LCOV / Cobertura / Clover). required: false default: "" github-token: @@ -70,22 +75,27 @@ runs: env: RUN_TEST_COMMAND: ${{ inputs.container == 'true' && steps.get-package-manager.outputs.run-script-command || steps.setup-node.outputs.run-script-command }} WORKING_DIRECTORY: ${{ inputs.working-directory }} + TEST_COMMAND: ${{ inputs.command }} with: script: | const workingDirectory = process.env.WORKING_DIRECTORY || '.'; const runScriptCommand = process.env.RUN_TEST_COMMAND; + const testCommand = process.env.TEST_COMMAND || 'test:ci'; + + core.info(`๐Ÿงช Running test command: ${testCommand}...`); + try { - const result = await exec.getExecOutput(runScriptCommand, ['test:ci'], { + const result = await exec.getExecOutput(runScriptCommand, [testCommand], { cwd: require('path').resolve(process.env.GITHUB_WORKSPACE, workingDirectory), env: { ...process.env, CI: 'true' }, ignoreReturnCode: true }); - + if (result.stdout) core.info(result.stdout); if (result.stderr) core.warning(result.stderr); - + core.setOutput('test-exit-code', result.exitCode); - + if (result.exitCode !== 0) { core.setFailed(`Tests failed with exit code ${result.exitCode}`); } @@ -94,84 +104,21 @@ runs: core.setFailed(`Test execution error: ${error.message}`); } - # Auto-detect coverage files if not specified - - id: detect-coverage-files + - name: ๐Ÿ“Š Parse coverage reports if: always() && inputs.coverage == 'github' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - WORKING_DIRECTORY: ${{ inputs.working-directory }} - COVERAGE_FILES: ${{ inputs.coverage-files }} + id: parse-coverage-reports + uses: hoverkraft-tech/ci-github-common/actions/parse-ci-reports@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 with: - script: | - const path = require('node:path'); - const fs = require('node:fs'); - - const workingDirectory = process.env.WORKING_DIRECTORY || '.'; - const workDir = path.resolve(process.env.GITHUB_WORKSPACE, workingDirectory); - - if (process.env.COVERAGE_FILES && process.env.COVERAGE_FILES.trim() !== '') { - core.info(`Using specified coverage files: ${process.env.COVERAGE_FILES}`); - core.setOutput('coverage-files', process.env.COVERAGE_FILES); - return; - } - - // Common coverage file paths - const commonPaths = [ - 'coverage/cobertura-coverage.xml', - 'coverage/coverage.xml', - 'coverage/lcov.info', - 'coverage/clover.xml', - 'coverage/coverage-final.json', - 'test-results/coverage.xml', - 'test-results/cobertura-coverage.xml' - ]; - - for (const filePath of commonPaths) { - const fullPath = path.join(workDir, filePath); - if (fs.existsSync(fullPath)) { - core.info(`Auto-detected coverage file: ${fullPath}`); - core.setOutput('coverage-files', fullPath); - return; - } - } - - core.warning('No coverage file auto-detected'); - - # ReportGenerator for PR comments with coverage reports - - name: ๐Ÿ“Š Generate coverage report - if: always() && inputs.coverage == 'github' && steps.detect-coverage-files.outputs.coverage-files - uses: danielpalme/ReportGenerator-GitHub-Action@dcdfb6e704e87df6b2ed0cf123a6c9f69e364869 # v5.5.0 - with: - reports: ${{ steps.detect-coverage-files.outputs.coverage-files }} - targetdir: ${{ runner.temp }}/coveragereport-${{ github.run_id }} - reporttypes: MarkdownSummaryGithub - sourcedirs: ${{ inputs.working-directory }} - - - if: always() && inputs.coverage == 'github' - id: get-coverage-report-summary - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - SUMMARY_FILE: ${{ runner.temp }}/coveragereport-${{ github.run_id }}/SummaryGithub.md - with: - script: | - const fs = require('fs'); - const summaryFilePath = process.env.SUMMARY_FILE; - - if (!fs.existsSync(summaryFilePath)) { - return core.setFailed(`Coverage summary file not found: ${summaryFilePath}`); - } - - const summaryContent = fs.readFileSync(summaryFilePath, 'utf8'); - core.summary.addRaw(summaryContent).write(); - - core.setOutput('summary-content', summaryContent); + report-paths: ${{ inputs.coverage-files || 'auto:test' }} + report-name: "Coverage Results" + output-format: "summary,markdown" - name: ๐Ÿ“Š Add coverage PR comment - if: always() && steps.get-coverage-report-summary.outputs.summary-content && github.event_name == 'pull_request' + if: always() && inputs.coverage == 'github' && github.event_name == 'pull_request' && steps.parse-coverage-reports.outputs.markdown uses: hoverkraft-tech/ci-github-common/actions/create-or-update-comment@1127e708e4072515056a4b0d26bcb0653646cedc # 0.30.0 with: title: "Code Coverage Report" - body: ${{ steps.get-coverage-report-summary.outputs.summary-content }} + body: ${{ steps.parse-coverage-reports.outputs.markdown }} # Install dependencies for codecov in container mode - name: Install Codecov dependencies diff --git a/tests/npm/package.json b/tests/npm/package.json index 6e58404..18da720 100644 --- a/tests/npm/package.json +++ b/tests/npm/package.json @@ -3,6 +3,7 @@ "main": "src/index.js", "scripts": { "lint": "echo \"lint test\"", + "lint:ci": "echo \"lint:ci test\"", "build": "mkdir -p dist && echo \"build test\" > dist/test.txt", "test:ci": "jest --coverage" },