Skip to content

Commit 363ace4

Browse files
committed
ci: add e2e tests to CI
This change adds a new end-to-end test capability. There are two new jobs in the main CI workflow. One job to build the package (which also good to have outside of the need to run e2e tests), executed with the latest LTS node. The build artifact is uploaded for the downstream `e2e` job to use. The `e2e` job, downloads the artifact, run `npm install` and then `npm run e2e`, which executes a custom node script to loop through subdirectories of `/e2e`, which each contain a project fixture with different setups. Both projects have the same simple plugin source code, and each has this plugin (referenced from the root of the repo (aka the result of the build)) and `eslint` installed as `devDependencies`. Each also has a `lint` package.json script that runs `eslint` on the simple plugin. \## `/e2e/all` This fixture has a regular js config and runs our `all` config on the project. \## `/e2e/all-typed-config` This fixture has `typescript` installed and uses a ts-based config and runs our `all` config on the project. It also executes `tsc` as part of the `lint` command, to ensure everything's typed property.
1 parent 01c526e commit 363ace4

File tree

16 files changed

+281
-2
lines changed

16 files changed

+281
-2
lines changed

.github/workflows/main.yml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66

77
jobs:
88
test:
9-
name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
9+
name: Test / Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
1010
runs-on: ${{ matrix.os }}
1111
strategy:
1212
fail-fast: false
@@ -67,3 +67,46 @@ jobs:
6767
node-version: 'lts/*'
6868
- run: npm install
6969
- run: npm run typecheck
70+
71+
build:
72+
runs-on: ubuntu-latest
73+
steps:
74+
- uses: actions/checkout@v4
75+
- uses: actions/setup-node@v4
76+
with:
77+
node-version: 'lts/*'
78+
- run: npm install
79+
- run: npm run build
80+
- name: Upload build results
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: build_dist
84+
path: dist
85+
e2e:
86+
name: E2E / Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
87+
needs: build
88+
runs-on: ${{ matrix.os }}
89+
strategy:
90+
fail-fast: false
91+
matrix:
92+
node-version:
93+
- '24.0.0' # minimum supported v24
94+
- 24
95+
- '22.13.1' # minimum supported v22
96+
- 22
97+
- '20.19.0' #minimum supported v20
98+
- 20
99+
os:
100+
- ubuntu-latest
101+
steps:
102+
- uses: actions/checkout@v4
103+
- uses: actions/setup-node@v4
104+
with:
105+
node-version: ${{ matrix.node-version }}
106+
- name: Download build results
107+
uses: actions/download-artifact@v4
108+
with:
109+
name: build_dist
110+
path: dist
111+
- run: npm install
112+
- run: npm run e2e

.npmpackagejsonlintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
e2e/

e2e/all-typed-config/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock = false

e2e/all-typed-config/eslint.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineConfig } from 'eslint/config';
2+
3+
import eslintPlugin from 'eslint-plugin-eslint-plugin';
4+
5+
export default defineConfig([
6+
{
7+
extends: [eslintPlugin.configs.all],
8+
files: ['./index.js', './rule.js'],
9+
},
10+
]);

e2e/all-typed-config/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import rule from './rule.js';
2+
3+
/** @type {import('eslint').ESLint.Plugin} */
4+
const plugin = {
5+
meta: {
6+
name: '@e2e/all-typed-config',
7+
version: '1.0.0',
8+
},
9+
rules: { 'e2e-test': rule },
10+
configs: {
11+
recommended: {
12+
name: '@e2e/all-typed-config/recommended',
13+
plugins: {
14+
get ['@e2e/all-typed-config']() {
15+
return plugin;
16+
},
17+
},
18+
rules: {
19+
'@e2e/all-typed-config/e2e-test': 'error',
20+
},
21+
},
22+
},
23+
};
24+
25+
export default plugin;

e2e/all-typed-config/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "@e2e/all-typed-config",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"lint": "tsc && eslint"
7+
},
8+
"main": "./index.js",
9+
"devDependencies": {
10+
"eslint": "^9.33.0",
11+
"eslint-plugin-eslint-plugin": "file:../..",
12+
"jiti": "^2.5.1",
13+
"typescript": "^5.9.2"
14+
}
15+
}

e2e/all-typed-config/rule.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
const rule = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'enforce a test',
7+
recommended: false,
8+
url: 'https://test.org',
9+
},
10+
fixable: undefined, // or "code" or "whitespace"
11+
schema: [],
12+
messages: {
13+
missingOutput: 'This is a test',
14+
},
15+
},
16+
17+
create(context) {
18+
return {
19+
Program(ast) {
20+
const sourceCode = context.sourceCode;
21+
if (false) {
22+
context.report({
23+
node: ast,
24+
messageId: 'missingOutput',
25+
});
26+
}
27+
},
28+
};
29+
},
30+
};
31+
32+
export default rule;

e2e/all-typed-config/tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"rootDir": ".",
4+
"module": "nodenext",
5+
"moduleResolution": "nodenext",
6+
"noEmit": true,
7+
"skipLibCheck": true,
8+
"strict": true,
9+
"target": "ES2024",
10+
"verbatimModuleSyntax": true,
11+
"erasableSyntaxOnly": true,
12+
"types": []
13+
},
14+
"include": ["eslint.config.ts"]
15+
}

e2e/all/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock = false

e2e/all/eslint.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineConfig } from 'eslint/config';
2+
3+
import eslintPlugin from 'eslint-plugin-eslint-plugin';
4+
5+
export default defineConfig([
6+
{
7+
extends: [eslintPlugin.configs.all],
8+
files: ['./index.js', './rule.js'],
9+
},
10+
]);

0 commit comments

Comments
 (0)