Skip to content

Commit b202964

Browse files
authored
Add comment-json for parsing tsconfig (#154)
When generating new TypeScript projects, the TSConfig.json file will often contain comments. This was causing an error with the default JSON parser. This PR switches to `comments-json` to parse the TSConfig file in `bootstrap.mts`.
2 parents 079a7ed + c6ffd55 commit b202964

File tree

12 files changed

+155
-29
lines changed

12 files changed

+155
-29
lines changed

.mega-linter.yml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ DISABLE_ERRORS: false
2121
# https://megalinter.io/latest/config-activation/
2222
DISABLE_LINTERS:
2323
- JAVASCRIPT_STANDARD
24+
- JSON_JSONLINT
2425
- JSON_V8R
2526
- MARKDOWN_MARKDOWN_LINK_CHECK
2627
- MARKDOWN_MARKDOWN_TABLE_FORMATTER
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ACTIONS_STEP_DEBUG=false
2+
INPUT_MILLISECONDS=2400
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: The name of your action here
2+
description: Provide a description here
3+
author: Your name or organization here
4+
5+
inputs:
6+
milliseconds:
7+
description: Your input description here
8+
required: true
9+
default: '1000'
10+
11+
outputs:
12+
time:
13+
description: Your output description here
14+
15+
runs:
16+
using: node20
17+
main: dist/index.js

__fixtures__/typescript-esm/tsconfig-comments/node_modules/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "typescript-action",
3+
"description": "GitHub Actions TypeScript template",
4+
"version": "0.0.0",
5+
"type": "module",
6+
"engines": {
7+
"node": ">=20"
8+
},
9+
"dependencies": {
10+
"@actions/core": "^1.10.1"
11+
},
12+
"devDependencies": {
13+
"@types/node": "^20.14.7",
14+
"ts-node": "^10.9.2",
15+
"typescript": "^5.5.2"
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { run } from './main.js'
2+
3+
run()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { getInput, info, setOutput } from '@actions/core'
2+
3+
export async function run(): Promise<void> {
4+
const myInput: string = getInput('myInput')
5+
6+
setOutput('myOutput', myInput)
7+
8+
info('TypeScript ESM Action Succeeded!')
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
/* Visit https://aka.ms/tsconfig to read more about this file */
3+
"$schema": "https://json.schemastore.org/tsconfig",
4+
"compilerOptions": {
5+
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
6+
"module": "NodeNext" /* Specify what module code is generated. */,
7+
"rootDir": "./src",
8+
"moduleResolution": "NodeNext" /* Specify how TypeScript looks up a file from a given module specifier. */,
9+
"baseUrl": "./",
10+
"sourceMap": true,
11+
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
12+
"noImplicitAny": true,
13+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
14+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
15+
"strict": true /* Enable all strict type-checking options. */,
16+
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
17+
"newLine": "lf"
18+
},
19+
"exclude": ["node_modules"],
20+
"include": ["src"]
21+
}

__tests__/commands/run.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ describe('Command: run', () => {
7373
`Entrypoint ${EnvMeta.entrypoint} does not export a run() function`
7474
)
7575
})
76+
77+
it('TypeScript ESM Action: tsconfig comments', async () => {
78+
EnvMeta.actionFile = `./__fixtures__/typescript-esm/tsconfig-comments/action.yml`
79+
EnvMeta.actionPath = `./__fixtures__/typescript-esm/tsconfig-comments`
80+
EnvMeta.dotenvFile = `./__fixtures__/typescript-esm/tsconfig-comments/.env.fixture`
81+
EnvMeta.entrypoint = `./__fixtures__/typescript-esm/tsconfig-comments/src/main.ts`
82+
83+
await expect(action()).resolves.toBeUndefined()
84+
85+
expect(core.setFailed).not.toHaveBeenCalled()
86+
expect(quibbleEsm).toHaveBeenCalled()
87+
})
7688
})
7789

7890
describe('JavaScript', () => {

package-lock.json

+43-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@github/local-action",
33
"description": "Local Debugging for GitHub Actions",
4-
"version": "2.6.2",
4+
"version": "2.6.3",
55
"type": "module",
66
"author": "Nick Alteen <[email protected]>",
77
"private": false,
@@ -51,6 +51,7 @@
5151
"archiver": "^7.0.1",
5252
"chalk": "^5.3.0",
5353
"commander": "^13.0.0",
54+
"comment-json": "^4.2.5",
5455
"dotenv": "^16.4.5",
5556
"figlet": "^1.8.0",
5657
"quibble": "^0.9.2",

src/bootstrap.mts

+28-25
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,38 @@
88
*/
99
import('fs').then(({ existsSync, readFileSync }) => {
1010
import('tsconfig-paths').then(({ loadConfig, register }) => {
11-
if (
12-
process.env.TARGET_ACTION_PATH &&
13-
process.env.TARGET_ACTION_PATH !== ''
14-
) {
15-
// Check if the action has a `tsconfig.json` file.
16-
if (existsSync(`${process.env.TARGET_ACTION_PATH}/tsconfig.json`)) {
17-
// Load the `tsconfig.json` from the action directory.
18-
const actionTsConfig = JSON.parse(
19-
readFileSync(
20-
`${process.env.TARGET_ACTION_PATH}/tsconfig.json`,
21-
'utf-8'
11+
import('comment-json').then(({ parse }) => {
12+
if (
13+
process.env.TARGET_ACTION_PATH &&
14+
process.env.TARGET_ACTION_PATH !== ''
15+
) {
16+
// Check if the action has a `tsconfig.json` file.
17+
if (existsSync(`${process.env.TARGET_ACTION_PATH}/tsconfig.json`)) {
18+
// Load the `tsconfig.json` from the action directory.
19+
const actionTsConfig = parse(
20+
readFileSync(
21+
`${process.env.TARGET_ACTION_PATH}/tsconfig.json`,
22+
'utf-8'
23+
)
2224
)
23-
)
2425

25-
// Load the current `tsconfig.json` from the root of this directory.
26-
loadConfig(__dirname)
26+
// Load the current `tsconfig.json` from the root of this directory.
27+
loadConfig(__dirname)
2728

28-
// Get the paths from the action's `tsconfig.json`, if any.
29-
const paths = actionTsConfig.compilerOptions.paths ?? {}
29+
// Get the paths from the action's `tsconfig.json`, if any.
30+
// @ts-expect-error The `compilerOptions` property is not typed.
31+
const paths = actionTsConfig.compilerOptions?.paths ?? {}
3032

31-
// Add any path mappings from the imported action. Replace the base URL with
32-
// the target action path.
33-
// @todo Should this take into account the previous `baseUrl` value?
34-
register({
35-
baseUrl: process.env.TARGET_ACTION_PATH,
36-
paths,
37-
addMatchAll: true
38-
})
33+
// Add any path mappings from the imported action. Replace the base URL with
34+
// the target action path.
35+
// @todo Should this take into account the previous `baseUrl` value?
36+
register({
37+
baseUrl: process.env.TARGET_ACTION_PATH,
38+
paths,
39+
addMatchAll: true
40+
})
41+
}
3942
}
40-
}
43+
})
4144
})
4245
})

0 commit comments

Comments
 (0)