Update dependencies, CI workflows and require Node.js 20 / 22 / 24

* Remove support for Node.js 18 and 21

* Upgrade XO

* Update dev dependencies

* Break out AVA and c8 config into their own files

* Upgrade execa

* Update CI workflow

* Pin node and npm versions using Volta

* Automate releases
This commit is contained in:
Mark Wubben 2025-06-17 21:25:20 +02:00 committed by GitHub
parent 87afe23ce9
commit b84e7b7168
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 164 additions and 38 deletions

9
.c8rc.json Normal file
View file

@ -0,0 +1,9 @@
{
"all": true,
"include": "index.js",
"reporter": [
"html",
"lcov",
"text"
]
}

View file

@ -3,9 +3,14 @@ on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
paths-ignore:
- '*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
nodejs:
name: Node.js
@ -13,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [^18.18, ^20.8, ^21, ^22, ^24]
node-version: [^20.8, ^22, ^24]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
@ -26,3 +31,4 @@ jobs:
with:
files: coverage/lcov.info
name: ${{ matrix.os }}/${{ matrix.node-version }}
token: ${{ secrets.CODECOV_TOKEN }}

89
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,89 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g., v1.2.3)'
required: true
type: string
skip_ci_check:
description: 'Skip CI status check'
required: false
type: boolean
default: false
permissions:
contents: write
id-token: write
jobs:
release:
name: Release
runs-on: ubuntu-latest
environment: npm
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}
fetch-depth: 0
- name: Verify tag matches package.json version
run: |
jq --raw-output --exit-status --arg tag "$RELEASE_TAG" '
if (.version == ($tag | ltrimstr("v"))) then
"Package version (\(.version)) matches tag version (\($tag | ltrimstr("v")))"
else
"Package version (\(.version)) does not match tag version (\($tag | ltrimstr("v")))" | halt_error(1)
end' package.json
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
- name: Verify commit is in main branch
run: |
# Check if the tagged commit is included in the main branch
if git merge-base --is-ancestor ${{ github.sha }} origin/main; then
echo "Tagged commit is properly included in main branch"
else
echo "Tagged commit is not included in the main branch"
echo "Please push the commit to main before releasing"
exit 1
fi
- name: Check CI status
if: ${{ !inputs.skip_ci_check }}
run: |
# Check if CI has completed successfully for this commit
gh run list --commit ${{ github.sha }} --status success --json workflowName | jq --raw-output --exit-status '
if any(.[]; .workflowName == "Install and test @ava/typescript") then
"All CI checks have passed!"
else
"CI has not completed successfully for this commit" | halt_error(1)
end'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: package.json
cache: npm
registry-url: https://registry.npmjs.org
- name: Publish to npm with provenance
run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub Release
run: |
gh release create "$RELEASE_TAG" \
--title "$RELEASE_TAG" \
--draft \
--generate-notes
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

14
ava.config.js Normal file
View file

@ -0,0 +1,14 @@
const avaConfig = {
files: [
'!test/broken-fixtures/**',
],
watchMode: {
ignoreChanges: [
'test/fixtures/**',
'test/broken-fixtures/**',
],
},
timeout: '60s',
};
export default avaConfig;

View file

@ -37,7 +37,7 @@ function validate(target, properties) {
}
async function compileTypeScript(projectDirectory) {
return execa('tsc', ['--incremental'], {preferLocal: true, cwd: projectDirectory});
return execa({preferLocal: true, cwd: projectDirectory})`tsc --incremental`;
}
const configProperties = {

View file

@ -3,7 +3,7 @@
"version": "5.0.0",
"description": "TypeScript provider for AVA",
"engines": {
"node": "^18.18 || ^20.8 || ^21 || ^22 || >=24"
"node": "^20.8 || ^22 || >=24"
},
"files": [
"index.js"
@ -24,38 +24,17 @@
},
"dependencies": {
"escape-string-regexp": "^5.0.0",
"execa": "^8.0.1"
"execa": "^9.6.0"
},
"devDependencies": {
"ava": "^6.1.2",
"c8": "^9.1.0",
"del": "^7.1.0",
"typescript": "^5.4.5",
"xo": "^0.58.0"
"ava": "^6.4.0",
"c8": "^10.1.3",
"del": "^8.0.0",
"typescript": "^5.8.3",
"xo": "^1.1.0"
},
"c8": {
"reporter": [
"html",
"lcov",
"text"
]
},
"ava": {
"files": [
"!test/broken-fixtures/**"
],
"watcher": {
"ignoreChanges": [
"test/fixtures/**",
"test/broken-fixtures/**"
]
},
"timeout": "60s"
},
"xo": {
"ignores": [
"test/broken-fixtures",
"test/fixtures/**/compiled/**"
]
"volta": {
"node": "22.16.0",
"npm": "11.4.2"
}
}

View file

@ -1,6 +1,9 @@
{
"compilerOptions": {
"outDir": "typescript/compiled"
"outDir": "typescript/compiled",
"lib": [
"es2022"
]
},
"include": [
"typescript"

View file

@ -1,7 +1,7 @@
{
"compilerOptions": {
"strictNullChecks": true,
"module": "Node16",
"module": "node18",
"outDir": "compiled"
},
"include": [

View file

@ -1,6 +1,10 @@
{
"compilerOptions": {
"strictNullChecks": true,
"lib": [
"es2022",
"dom"
],
"outDir": "typescript/compiled"
},
"include": [

View file

@ -121,17 +121,27 @@ test('main() resolvePossibleOutOfBandCompilationSources() .js but .ts not config
test('main() resolvePossibleOutOfBandCompilationSources() .cjs and .cjs and .cts configured', withProvider, (t, provider) => {
const main = provider.main({config: {extensions: ['cjs', 'cts'], rewritePaths: {'src/': 'build/'}, compile: false}});
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.cjs')), [path.join(projectDirectory, 'src/foo.cjs'), path.join(projectDirectory, 'src/foo.cts')]);
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.cjs')), [
path.join(projectDirectory, 'src/foo.cjs'),
path.join(projectDirectory, 'src/foo.cts'),
]);
});
test('main() resolvePossibleOutOfBandCompilationSources() .mjs and .mjs and .mts configured', withProvider, (t, provider) => {
const main = provider.main({config: {extensions: ['mjs', 'mts'], rewritePaths: {'src/': 'build/'}, compile: false}});
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.mjs')), [path.join(projectDirectory, 'src/foo.mjs'), path.join(projectDirectory, 'src/foo.mts')]);
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.mjs')), [
path.join(projectDirectory, 'src/foo.mjs'),
path.join(projectDirectory, 'src/foo.mts'),
]);
});
test('main() resolvePossibleOutOfBandCompilationSources() .js and .js, .ts and .tsx configured', withProvider, (t, provider) => {
const main = provider.main({config: {extensions: ['js', 'ts', 'tsx'], rewritePaths: {'src/': 'build/'}, compile: false}});
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.js')), [path.join(projectDirectory, 'src/foo.js'), path.join(projectDirectory, 'src/foo.ts'), path.join(projectDirectory, 'src/foo.tsx')]);
t.deepEqual(main.resolvePossibleOutOfBandCompilationSources(path.join(projectDirectory, 'build/foo.js')), [
path.join(projectDirectory, 'src/foo.js'),
path.join(projectDirectory, 'src/foo.ts'),
path.join(projectDirectory, 'src/foo.tsx'),
]);
});
test('main() resolvePossibleOutOfBandCompilationSources() returns the first possible path that exists', withProvider, (t, provider) => {

View file

@ -21,4 +21,5 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
`Command failed with exit code 2: tsc --incremental␊
␊
typescript/typescript.ts(1,1): error TS2304: Cannot find name 'a'.`

Binary file not shown.

11
xo.config.js Normal file
View file

@ -0,0 +1,11 @@
/** @type {import('xo').FlatXoConfig} */
const xoConfig = [
{
ignores: [
'test/broken-fixtures',
'test/fixtures/**/compiled/**',
],
},
];
export default xoConfig;