Skip to content

Commit 1279df5

Browse files
Copilotneilime
andcommitted
Add configurable lint/test commands and path rewrite action
Co-authored-by: neilime <[email protected]>
1 parent 29d543f commit 1279df5

File tree

9 files changed

+464
-17
lines changed

9 files changed

+464
-17
lines changed

.github/workflows/continuous-integration.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ jobs:
104104
# Set to `null` or empty to disable.
105105
# Accepts a JSON object for lint options. See [lint action](../actions/lint/README.md).
106106
#
107+
# Supported options:
108+
# - command: NPM script to run (default: "lint:ci"). The command should generate lint report files.
109+
# - report-file: Path to lint report file for annotations.
110+
#
111+
# Example:
112+
# lint: |
113+
# {
114+
# "command": "lint:ci",
115+
# "report-file": "reports/eslint.json"
116+
# }
117+
#
107118
# Default: `true`
108119
lint: "true"
109120

@@ -119,6 +130,19 @@ jobs:
119130
# Set to `null` or empty to disable.
120131
# Accepts a JSON object for test options. See [test action](../actions/test/README.md).
121132
#
133+
# Supported options:
134+
# - command: NPM script to run (default: "test:ci"). The command should generate coverage report files.
135+
# - coverage: Coverage reporter ("github", "codecov", or "" for none).
136+
# - coverage-files: Path to coverage files for reporting.
137+
#
138+
# Example:
139+
# test: |
140+
# {
141+
# "command": "test:ci",
142+
# "coverage": "github",
143+
# "coverage-files": "coverage/cobertura-coverage.xml"
144+
# }
145+
#
122146
# Default: `true`
123147
test: "true"
124148

.github/workflows/continuous-integration.yml

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ on:
5656
Whether to enable linting.
5757
Set to `null` or empty to disable.
5858
Accepts a JSON object for lint options. See [lint action](../actions/lint/README.md).
59+
60+
Supported options:
61+
- `command`: NPM script to run (default: "lint:ci"). The command should generate lint report files.
62+
- `report-file`: Path to lint report file for annotations.
63+
64+
Example:
65+
```json
66+
{
67+
"command": "lint:ci",
68+
"report-file": "reports/eslint.json"
69+
}
70+
```
5971
type: string
6072
required: false
6173
default: "true"
@@ -74,6 +86,20 @@ on:
7486
Whether to enable testing.
7587
Set to `null` or empty to disable.
7688
Accepts a JSON object for test options. See [test action](../actions/test/README.md).
89+
90+
Supported options:
91+
- `command`: NPM script to run (default: "test:ci"). The command should generate coverage report files.
92+
- `coverage`: Coverage reporter ("github", "codecov", or "" for none).
93+
- `coverage-files`: Path to coverage files for reporting.
94+
95+
Example:
96+
```json
97+
{
98+
"command": "test:ci",
99+
"coverage": "github",
100+
"coverage-files": "coverage/cobertura-coverage.xml"
101+
}
102+
```
77103
type: string
78104
required: false
79105
default: "true"
@@ -417,10 +443,26 @@ jobs:
417443
}
418444
}
419445
446+
core.setOutput('command', lintOptions.command || 'lint:ci');
447+
core.setOutput('report-file', lintOptions['report-file'] || '');
448+
420449
- uses: ./self-workflow/actions/lint
421450
with:
422451
working-directory: ${{ inputs.working-directory }}
423452
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
453+
command: ${{ steps.preparel-lint-options.outputs.command }}
454+
report-file: ${{ steps.preparel-lint-options.outputs.report-file }}
455+
456+
- name: 🔄 Rewrite lint report paths (container mode)
457+
if: always() && needs.prepare.outputs.container-image
458+
uses: ./self-workflow/actions/rewrite-report-paths
459+
with:
460+
working-directory: ${{ inputs.working-directory }}
461+
report-files: |
462+
**/*eslint*.json
463+
**/*checkstyle*.xml
464+
reports/**/*.json
465+
reports/**/*.xml
424466
425467
build:
426468
name: 🏗️ Build
@@ -530,13 +572,25 @@ jobs:
530572
testOptions.coverage = 'github';
531573
}
532574
core.setOutput('coverage', testOptions.coverage );
533-
534575
core.setOutput('coverage-files', testOptions['coverage-files'] || '');
576+
core.setOutput('command', testOptions.command || 'test:ci');
535577
536578
- uses: ./self-workflow/actions/test
537579
with:
538580
working-directory: ${{ inputs.working-directory }}
539581
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
582+
command: ${{ steps.prepare-test-options.outputs.command }}
540583
coverage: ${{ steps.prepare-test-options.outputs.coverage }}
541584
coverage-files: ${{ steps.prepare-test-options.outputs.coverage-files }}
542585
github-token: ${{ github.token }}
586+
587+
- name: 🔄 Rewrite coverage report paths (container mode)
588+
if: always() && needs.prepare.outputs.container-image
589+
uses: ./self-workflow/actions/rewrite-report-paths
590+
with:
591+
working-directory: ${{ inputs.working-directory }}
592+
report-files: |
593+
coverage/**/*.xml
594+
coverage/**/*.info
595+
coverage/**/*.json
596+
test-results/**/*.xml

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ _Actions for continuous integration steps: build, lint, and test._
2828

2929
#### - [Test](actions/test/README.md)
3030

31+
#### - [Rewrite Report Paths](actions/rewrite-report-paths/README.md)
32+
3133
### Dependencies
3234

3335
_Actions dedicated to caching and validating Node.js dependencies._

actions/lint/README.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ Action to lint Node.js projects with support for pull request reporting and anno
4242
# Default: `false`
4343
container: "false"
4444

45+
# NPM/package manager script command to run for linting.
46+
# This should be a script defined in your package.json.
47+
# The command should generate lint report files in a standard format (ESLint JSON or Checkstyle XML).
48+
#
49+
# Default: `lint:ci`
50+
command: "lint:ci"
51+
4552
# Path to lint report file to process as GitHub annotations.
4653
# Supports ESLint JSON and Checkstyle XML formats.
4754
# If not specified, auto-detection will be attempted for common paths:
@@ -55,16 +62,19 @@ Action to lint Node.js projects with support for pull request reporting and anno
5562
5663
## Inputs
5764
58-
| **Input** | **Description** | **Required** | **Default** |
59-
| ----------------------- | -------------------------------------------------------------------- | ------------ | ----------- |
60-
| **`working-directory`** | Working directory where lint commands are executed. | **false** | `.` |
61-
| | Can be absolute or relative to the repository root. | | |
62-
| **`container`** | Whether running in container mode (skips checkout and node setup) | **false** | `false` |
63-
| **`report-file`** | Path to lint report file to process as GitHub annotations. | **false** | - |
64-
| | Supports ESLint JSON and Checkstyle XML formats. | | |
65-
| | If not specified, auto-detection will be attempted for common paths: | | |
66-
| | - eslint-report.json, eslint.json | | |
67-
| | - checkstyle-result.xml, checkstyle.xml | | |
65+
| **Input** | **Description** | **Required** | **Default** |
66+
| ----------------------- | ---------------------------------------------------------------- | ------------ | ----------- |
67+
| **`working-directory`** | Working directory where lint commands are executed. | **false** | `.` |
68+
| | Can be absolute or relative to the repository root. | | |
69+
| **`container`** | Whether running in container mode (skips checkout and node setup)| **false** | `false` |
70+
| **`command`** | NPM/package manager script command to run for linting. | **false** | `lint:ci` |
71+
| | This should be a script defined in your package.json. | | |
72+
| | The command should generate lint report files in a standard format.| | |
73+
| **`report-file`** | Path to lint report file to process as GitHub annotations. | **false** | - |
74+
| | Supports ESLint JSON and Checkstyle XML formats. | | |
75+
| | If not specified, auto-detection will be attempted for common paths:| | |
76+
| | - eslint-report.json, eslint.json | | |
77+
| | - checkstyle-result.xml, checkstyle.xml | | |
6878

6979
<!-- inputs:end -->
7080
<!-- secrets:start -->

actions/lint/action.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ inputs:
1616
description: "Whether running in container mode (skips checkout and node setup)"
1717
required: false
1818
default: "false"
19+
command:
20+
description: |
21+
NPM/package manager script command to run for linting.
22+
This should be a script defined in your package.json.
23+
The command should generate lint report files in a standard format (ESLint JSON or Checkstyle XML).
24+
required: false
25+
default: "lint:ci"
1926
report-file:
2027
description: |
2128
Path to lint report file to process as GitHub annotations.
@@ -53,15 +60,17 @@ runs:
5360
env:
5461
RUN_LINT_COMMAND: ${{ inputs.container == 'true' && steps.get-package-manager.outputs.run-script-command || steps.setup-node.outputs.run-script-command }}
5562
WORKING_DIRECTORY: ${{ inputs.working-directory }}
63+
LINT_COMMAND: ${{ inputs.command }}
5664
with:
5765
script: |
5866
const workingDirectory = process.env.WORKING_DIRECTORY || '.';
5967
const runScriptCommand = process.env.RUN_LINT_COMMAND;
68+
const lintCommand = process.env.LINT_COMMAND || 'lint:ci';
6069
61-
core.info('👕 Running lint...');
70+
core.info(`👕 Running lint command: ${lintCommand}...`);
6271
6372
try {
64-
const result = await exec.getExecOutput(runScriptCommand, ['lint'], {
73+
const result = await exec.getExecOutput(runScriptCommand, [lintCommand], {
6574
cwd: require('path').resolve(process.env.GITHUB_WORKSPACE, workingDirectory),
6675
ignoreReturnCode: true
6776
});
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<!-- header:start -->
2+
3+
# ![Icon](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItZWRpdCIgY29sb3I9ImJsdWUiPjxwYXRoIGQ9Ik0xMSA0SDRhMiAyIDAgMCAwLTIgMnYxNGEyIDIgMCAwIDAgMiAyaDE0YTIgMiAwIDAgMCAyLTJ2LTciPjwvcGF0aD48cGF0aCBkPSJNMTguNSAyLjVhMi4xMjEgMi4xMjEgMCAwIDEgMyAzbC0xMiAxMi0zIDEgMS0zIDEyLTEyeiI+PC9wYXRoPjwvc3ZnPg==) GitHub Action: Rewrite Report Paths
4+
5+
<div align="center">
6+
<img src="https://opengraph.githubassets.com/50237226ce5d3230f19bbf31d04efd98f21cb2150e9ae4acd09a498440ecde82/hoverkraft-tech/ci-github-nodejs" width="60px" align="center" alt="Rewrite Report Paths" />
7+
</div>
8+
9+
---
10+
11+
<!-- header:end -->
12+
<!-- badges:start -->
13+
14+
[![Marketplace](https://img.shields.io/badge/Marketplace-rewrite--report--paths-blue?logo=github-actions)](https://github.com/marketplace/actions/rewrite-report-paths)
15+
[![Release](https://img.shields.io/github/v/release/hoverkraft-tech/ci-github-nodejs)](https://github.com/hoverkraft-tech/ci-github-nodejs/releases)
16+
[![License](https://img.shields.io/github/license/hoverkraft-tech/ci-github-nodejs)](http://choosealicense.com/licenses/mit/)
17+
[![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)
18+
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/hoverkraft-tech/ci-github-nodejs/blob/main/CONTRIBUTING.md)
19+
20+
<!-- badges:end -->
21+
<!-- overview:start -->
22+
23+
## Overview
24+
25+
Rewrites file paths in report files to match repository paths when running in containers.
26+
27+
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.
28+
29+
<!-- overview:end -->
30+
<!-- usage:start -->
31+
32+
## Usage
33+
34+
```yaml
35+
- uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main
36+
with:
37+
# Path or glob pattern for report files to process.
38+
# Supports multiple files separated by newlines.
39+
# Common patterns: coverage/**, reports/**, **/*.xml, **/*.json
40+
#
41+
# Required: true
42+
report-files: |
43+
coverage/cobertura-coverage.xml
44+
reports/eslint.json
45+
46+
# Source root path in the container that should be replaced.
47+
# If not specified, will attempt to auto-detect from file paths.
48+
# Common values: /app, /workspace, /usr/src/app
49+
#
50+
# Default: "" (auto-detect)
51+
source-root: "/app"
52+
53+
# Target root path in the repository.
54+
# Typically this is the GITHUB_WORKSPACE or a subdirectory.
55+
#
56+
# Default: GITHUB_WORKSPACE
57+
target-root: ""
58+
59+
# Working directory where report files are located.
60+
# Can be absolute or relative to the repository root.
61+
#
62+
# Default: `.`
63+
working-directory: .
64+
```
65+
66+
<!-- usage:end -->
67+
<!-- inputs:start -->
68+
69+
## Inputs
70+
71+
| **Input** | **Description** | **Required** | **Default** |
72+
| ----------------------- | ---------------------------------------------------------------- | ------------ | ----------- |
73+
| **`report-files`** | Path or glob pattern for report files to process. | **true** | - |
74+
| | Supports multiple files separated by newlines. | | |
75+
| | Common patterns: coverage/\*\*, reports/\*\*, \*\*/\*.xml, \*\*/\*.json | | |
76+
| **`source-root`** | Source root path in the container that should be replaced. | **false** | - |
77+
| | If not specified, will attempt to auto-detect from file paths. | | |
78+
| **`target-root`** | Target root path in the repository. | **false** | - |
79+
| | Typically this is the GITHUB_WORKSPACE or a subdirectory. | | |
80+
| **`working-directory`** | Working directory where report files are located. | **false** | `.` |
81+
| | Can be absolute or relative to the repository root. | | |
82+
83+
<!-- inputs:end -->
84+
<!-- secrets:start -->
85+
<!-- secrets:end -->
86+
<!-- outputs:start -->
87+
88+
## Outputs
89+
90+
| **Output** | **Description** |
91+
| --------------------- | ------------------------------------------------- |
92+
| **`files-processed`** | Number of report files that were processed |
93+
| **`paths-replaced`** | Total number of paths that were rewritten |
94+
95+
<!-- outputs:end -->
96+
<!-- examples:start -->
97+
98+
## Examples
99+
100+
### Basic Usage with Auto-Detection
101+
102+
```yaml
103+
- name: Rewrite coverage paths
104+
uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main
105+
with:
106+
report-files: |
107+
coverage/cobertura-coverage.xml
108+
coverage/lcov.info
109+
```
110+
111+
### Explicit Source Root
112+
113+
```yaml
114+
- name: Rewrite report paths
115+
uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main
116+
with:
117+
report-files: |
118+
coverage/**/*.xml
119+
reports/**/*.json
120+
source-root: "/app"
121+
target-root: ${{ github.workspace }}
122+
```
123+
124+
### Multiple Report Types
125+
126+
```yaml
127+
- name: Rewrite all report paths
128+
uses: hoverkraft-tech/ci-github-nodejs/actions/rewrite-report-paths@main
129+
with:
130+
report-files: |
131+
coverage/cobertura-coverage.xml
132+
reports/eslint.json
133+
test-results/junit.xml
134+
source-root: "/workspace"
135+
```
136+
137+
<!-- examples:end -->
138+
139+
<!--
140+
// jscpd:ignore-start
141+
-->
142+
143+
<!-- contributing:start -->
144+
145+
## Contributing
146+
147+
Contributions are welcome! Please see the [contributing guidelines](https://github.com/hoverkraft-tech/ci-github-nodejs/blob/main/CONTRIBUTING.md) for more details.
148+
149+
<!-- contributing:end -->
150+
<!-- security:start -->
151+
<!-- security:end -->
152+
<!-- license:start -->
153+
154+
## License
155+
156+
This project is licensed under the MIT License.
157+
158+
SPDX-License-Identifier: MIT
159+
160+
Copyright © 2025 hoverkraft
161+
162+
For more details, see the [license](http://choosealicense.com/licenses/mit/).
163+
164+
<!-- license:end -->
165+
<!-- generated:start -->
166+
167+
---
168+
169+
This documentation was automatically generated by [CI Dokumentor](https://github.com/hoverkraft-tech/ci-dokumentor).
170+
171+
<!-- generated:end -->
172+
173+
<!--
174+
// jscpd:ignore-end
175+
-->

0 commit comments

Comments
 (0)