Skip to content

Commit dd9df61

Browse files
michaelfaithbmish
andauthored
ci: add e2e tests to CI (#546)
* 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. * add cache to node setup and windows to e2e matrix * remove cache option from ci jobs * add newlint to npmpackagejsonlintignore * Make script output more actionable, and add tsdoc * add inline disables * Move e2e test dirs into `fixtures` * Move e2e test dirs into `fixtures` * Format * Update e2e/.npmrc --------- Co-authored-by: Bryan Mishkin <[email protected]>
1 parent 01c526e commit dd9df61

17 files changed

+1517
-2
lines changed

.github/workflows/main.yml

Lines changed: 45 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,47 @@ 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+
- windows-latest
102+
steps:
103+
- uses: actions/checkout@v4
104+
- uses: actions/setup-node@v4
105+
with:
106+
node-version: ${{ matrix.node-version }}
107+
- name: Download build results
108+
uses: actions/download-artifact@v4
109+
with:
110+
name: build_dist
111+
path: dist
112+
- run: npm install
113+
- 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/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock = false
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from 'eslint/config';
2+
3+
import eslintPlugin from 'eslint-plugin-eslint-plugin';
4+
5+
export default defineConfig([
6+
{
7+
linterOptions: {
8+
reportUnusedDisableDirectives: 'error',
9+
},
10+
},
11+
{
12+
extends: [eslintPlugin.configs.all],
13+
files: ['./index.js', './rule.js'],
14+
},
15+
]);
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;
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/fixtures/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+
// eslint-disable-next-line eslint-plugin/require-meta-schema
4+
meta: {
5+
type: 'suggestion',
6+
docs: {
7+
description: 'enforce a test',
8+
recommended: false,
9+
url: 'https://test.org',
10+
},
11+
fixable: undefined, // or "code" or "whitespace"
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;
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/fixtures/all/eslint.config.js

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

e2e/fixtures/all/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',
7+
version: '1.0.0',
8+
},
9+
rules: { 'e2e-test': rule },
10+
configs: {
11+
recommended: {
12+
name: '@e2e/all/recommended',
13+
plugins: {
14+
get ['@e2e/all']() {
15+
return plugin;
16+
},
17+
},
18+
rules: {
19+
'@e2e/all/e2e-test': 'error',
20+
},
21+
},
22+
},
23+
};
24+
25+
export default plugin;

0 commit comments

Comments
 (0)