Skip to content

Commit

Permalink
Add comment-json for parsing tsconfig (#154)
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
ncalteen authored Feb 21, 2025
2 parents 079a7ed + c6ffd55 commit b202964
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 29 deletions.
1 change: 1 addition & 0 deletions .mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ DISABLE_ERRORS: false
# https://megalinter.io/latest/config-activation/
DISABLE_LINTERS:
- JAVASCRIPT_STANDARD
- JSON_JSONLINT
- JSON_V8R
- MARKDOWN_MARKDOWN_LINK_CHECK
- MARKDOWN_MARKDOWN_TABLE_FORMATTER
Expand Down
2 changes: 2 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/.env.fixture
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ACTIONS_STEP_DEBUG=false
INPUT_MILLISECONDS=2400
17 changes: 17 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: The name of your action here
description: Provide a description here
author: Your name or organization here

inputs:
milliseconds:
description: Your input description here
required: true
default: '1000'

outputs:
time:
description: Your output description here

runs:
using: node20
main: dist/index.js
Empty file.
17 changes: 17 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "typescript-action",
"description": "GitHub Actions TypeScript template",
"version": "0.0.0",
"type": "module",
"engines": {
"node": ">=20"
},
"dependencies": {
"@actions/core": "^1.10.1"
},
"devDependencies": {
"@types/node": "^20.14.7",
"ts-node": "^10.9.2",
"typescript": "^5.5.2"
}
}
3 changes: 3 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { run } from './main.js'

run()
9 changes: 9 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getInput, info, setOutput } from '@actions/core'

export async function run(): Promise<void> {
const myInput: string = getInput('myInput')

setOutput('myOutput', myInput)

info('TypeScript ESM Action Succeeded!')
}
21 changes: 21 additions & 0 deletions __fixtures__/typescript-esm/tsconfig-comments/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
/* Visit https://aka.ms/tsconfig to read more about this file */
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "NodeNext" /* Specify what module code is generated. */,
"rootDir": "./src",
"moduleResolution": "NodeNext" /* Specify how TypeScript looks up a file from a given module specifier. */,
"baseUrl": "./",
"sourceMap": true,
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
"noImplicitAny": true,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
"newLine": "lf"
},
"exclude": ["node_modules"],
"include": ["src"]
}
12 changes: 12 additions & 0 deletions __tests__/commands/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ describe('Command: run', () => {
`Entrypoint ${EnvMeta.entrypoint} does not export a run() function`
)
})

it('TypeScript ESM Action: tsconfig comments', async () => {
EnvMeta.actionFile = `./__fixtures__/typescript-esm/tsconfig-comments/action.yml`
EnvMeta.actionPath = `./__fixtures__/typescript-esm/tsconfig-comments`
EnvMeta.dotenvFile = `./__fixtures__/typescript-esm/tsconfig-comments/.env.fixture`
EnvMeta.entrypoint = `./__fixtures__/typescript-esm/tsconfig-comments/src/main.ts`

await expect(action()).resolves.toBeUndefined()

expect(core.setFailed).not.toHaveBeenCalled()
expect(quibbleEsm).toHaveBeenCalled()
})
})

describe('JavaScript', () => {
Expand Down
46 changes: 43 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@github/local-action",
"description": "Local Debugging for GitHub Actions",
"version": "2.6.2",
"version": "2.6.3",
"type": "module",
"author": "Nick Alteen <ncalteen@github.com>",
"private": false,
Expand Down Expand Up @@ -51,6 +51,7 @@
"archiver": "^7.0.1",
"chalk": "^5.3.0",
"commander": "^13.0.0",
"comment-json": "^4.2.5",
"dotenv": "^16.4.5",
"figlet": "^1.8.0",
"quibble": "^0.9.2",
Expand Down
53 changes: 28 additions & 25 deletions src/bootstrap.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,38 @@
*/
import('fs').then(({ existsSync, readFileSync }) => {
import('tsconfig-paths').then(({ loadConfig, register }) => {
if (
process.env.TARGET_ACTION_PATH &&
process.env.TARGET_ACTION_PATH !== ''
) {
// Check if the action has a `tsconfig.json` file.
if (existsSync(`${process.env.TARGET_ACTION_PATH}/tsconfig.json`)) {
// Load the `tsconfig.json` from the action directory.
const actionTsConfig = JSON.parse(
readFileSync(
`${process.env.TARGET_ACTION_PATH}/tsconfig.json`,
'utf-8'
import('comment-json').then(({ parse }) => {
if (
process.env.TARGET_ACTION_PATH &&
process.env.TARGET_ACTION_PATH !== ''
) {
// Check if the action has a `tsconfig.json` file.
if (existsSync(`${process.env.TARGET_ACTION_PATH}/tsconfig.json`)) {
// Load the `tsconfig.json` from the action directory.
const actionTsConfig = parse(
readFileSync(
`${process.env.TARGET_ACTION_PATH}/tsconfig.json`,
'utf-8'
)
)
)

// Load the current `tsconfig.json` from the root of this directory.
loadConfig(__dirname)
// Load the current `tsconfig.json` from the root of this directory.
loadConfig(__dirname)

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

// Add any path mappings from the imported action. Replace the base URL with
// the target action path.
// @todo Should this take into account the previous `baseUrl` value?
register({
baseUrl: process.env.TARGET_ACTION_PATH,
paths,
addMatchAll: true
})
// Add any path mappings from the imported action. Replace the base URL with
// the target action path.
// @todo Should this take into account the previous `baseUrl` value?
register({
baseUrl: process.env.TARGET_ACTION_PATH,
paths,
addMatchAll: true
})
}
}
}
})
})
})

0 comments on commit b202964

Please # to comment.