-
Notifications
You must be signed in to change notification settings - Fork 1.5k
164 lines (147 loc) · 6.26 KB
/
hardhat-ci.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
name: hardhat CI
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true
jobs:
packages:
name: Find packages to test
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.packages.outputs.result }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch files modified in push event
if: github.event_name == 'push'
env:
BEFORE: ${{ github.event.before }}
AFTER: ${{ github.event.after }}
run: git diff --name-only $BEFORE $AFTER | tee files.txt
- name: Parse pnpm lock file
run: yq -p yaml -o json pnpm-lock.yaml | tee pnpm-lock.json
- uses: actions/github-script@v7
name: Find packages to test
id: packages
env:
EXCLUDED_PACKAGES: |
.
packages/hardhat-core
packages/common
packages/eslint-plugin-hardhat-internal-rules
packages/eslint-plugin-slow-imports
COMMON_DEPENDENCIES: |
packages/common
config
WORKFLOW_FILE: .github/workflows/hardhat-ci.yml
with:
script: |
const fs = require('fs');
const excludedPackages = process.env.EXCLUDED_PACKAGES.split('\n').filter(p => p);
const commonDependencies = process.env.COMMON_DEPENDENCIES.split('\n').filter(p => p);
const workflowFile = process.env.WORKFLOW_FILE;
const event = context.eventName;
const modifiedFiles = [];
if (event === 'pull_request') {
core.info('This is a pull request event')
const pullNumber = context.issue.number;
core.info(`Fetching files for pull request #${pullNumber}`);
const files = await github.paginate(github.rest.pulls.listFiles, {
...context.issue,
pull_number: pullNumber
});
modifiedFiles.push(...files.map(file => file.filename));
core.info(`Modified files: ${JSON.stringify(modifiedFiles)}`);
} else if (event === 'push') {
core.info('This is a push event')
core.info(`Fetching files modified between ${context.payload.before} and ${context.payload.after}`)
const files = fs.readFileSync('files.txt', 'utf8').split('\n').filter(f => f);
modifiedFiles.push(...files);
core.info(`Modified files: ${JSON.stringify(modifiedFiles)}`);
}
core.info('Checking if workflow file was modified')
const isWorkflowFileModified = modifiedFiles.includes(workflowFile);
core.info(`Workflow file was modified: ${isWorkflowFileModified}`)
core.info('Reading pnpm lock file')
const lock = JSON.parse(fs.readFileSync('pnpm-lock.json', 'utf8'));
const packagesToTest = [];
core.info('Finding packages to test')
for (const [package, dependencies] of Object.entries(lock.importers)) {
core.info(`Checking package ${package}`)
if (excludedPackages.includes(package)) {
core.info(`Package ${package} is excluded, skipping`)
continue;
}
if (event === 'workflow_dispatch' || isWorkflowFileModified) {
core.info(`Workflow was dispatched or workflow file was modified, testing package ${package}`)
packagesToTest.push(package);
continue;
}
core.info(`Finding internal dependencies for package ${package} (only direct; not transitive)`)
const internalDependencies = Object.values(dependencies)
.flatMap(d => Object.values(d))
.map(d => d.version)
.filter(dependency => dependency.startsWith('link:../'))
.map(dependency => dependency.replace('link:../', 'packages/'));
core.info(`Internal dependencies for package ${package}: ${JSON.stringify(internalDependencies)}`)
core.info(`Checking if package ${package} or its internal dependencies were modified`)
const prefixes = [
package,
...internalDependencies,
...commonDependencies,
].map(p => `${p}/`);
const isPackageModified = prefixes.some(p => modifiedFiles.some(f => f.startsWith(p)));
core.info(`Package ${package} or its internal dependencies were modified: ${isPackageModified}`)
if (isPackageModified) {
core.info(`Package ${package} or its internal dependencies were modified, testing package ${package}`)
packagesToTest.push(package);
}
}
core.info(`Packages to test: ${JSON.stringify(packagesToTest)}`)
return packagesToTest.map(p => p.replace('packages/', ''));
test:
needs: [packages]
name: Test ${{ matrix.package }} on ${{ matrix.runner }} with Node ${{ matrix.node_version }}
runs-on: ${{ matrix.runner }}
if: needs.packages.outputs.packages != '[]'
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.packages.outputs.packages) }}
runner: [windows-latest, macos-latest, ubuntu-latest]
node_version: [18, 20, 22]
exclude:
- package: hardhat-vyper
runner: windows-latest
- package: hardhat-vyper
runner: macos-latest
- runner: windows-latest
node_version: 20
- runner: macos-latest
node_version: 20
- runner: windows-latest
node_version: 22
- runner: macos-latest
node_version: 22
defaults:
run:
working-directory: packages/${{ matrix.package }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-env
with:
node-version: ${{ matrix.node_version }}
- name: Install
run: pnpm install --frozen-lockfile --prefer-offline
- name: Build
run: pnpm build
- name: Run tests
env:
FORCE_COLOR: 3
run: pnpm ${{ matrix.package == 'hardhat-chai-matchers' && 'test:ci' || 'test' }}