Skip to content

Commit a1b6525

Browse files
SleeplessByteiHiD
andauthored
Optimize GitHub actions (#875)
This aims to make it easier to run much more actions on PRs without it slowing down the entire CI. - Split out configlet to a single action that runs once - Split out running tests (3 node versions, LTS, previous and next) from linting/stub-checking/etc (LTS only) - Design new ci scripts pr and pr-check which only run on exercises that have changed. - Use the babel-node cli, so that the scripts themselves can be written in ES6. - This PR does not sync/update all exercises here in order to keep it a bit more clean. Commits: * Add GitHub Actions * Rename node.js.yml to ci.js.yml * Use exercism/github-actions for configlet * Extract configlet workflow to reduce how often it is ran * Simplify when configlet runs * Add PR script that runs only exercises that are important * Actually use babel-node * Update call comment, and align package.json with this change * Fix PR workflow * Update dependencies * Split out node version agnostic steps from running tests * Make PR binaries executable on UNIX based systems * Update action names * Fix single exercise run for sync * Test new workflows by syncing two-fer * Use correct script in pr.precheck * Add conditional to step everywhere, because its easier to grasp than top-level on * Split out CI precheck from CI * Make executable * Sync grep (because its tests changed) * Apply code review * Rename actions to make them shorter * Move step name into build configuration * Merge workflow files * Update badges * Fix CI workflow link * Add missing hashbang * Apply suggestions from code review Co-authored-by: Jeremy Walker <jez.walker@gmail.com>
1 parent 2ba7ddb commit a1b6525

23 files changed

Lines changed: 3126 additions & 1744 deletions

.github/workflows/ci.js.yml

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,45 @@
1-
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
1+
# This workflow will do a clean install of node dependencies and run tests across different versions of node
22
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
33

4-
name: exercism/javascript ci
4+
name: javascript / master
55

66
on:
77
push:
8-
branches: [ master ]
9-
pull_request:
10-
branches: [ master ]
8+
branches: [master]
119

1210
jobs:
13-
build:
11+
precheck:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Use Node.js LTS
17+
uses: actions/setup-node@v1
18+
with:
19+
node-version: 12.x
20+
21+
- name: Install project dependencies
22+
run: npm ci
1423

24+
- name: Run exercism/javascript ci precheck (checks config, lint code, and runs tests) for all exercises
25+
run: npx babel-node scripts/ci-check
26+
27+
ci:
1528
runs-on: ubuntu-latest
1629

1730
strategy:
1831
matrix:
1932
node-version: [10.x, 12.x, 14.x]
2033

2134
steps:
22-
- uses: actions/checkout@v2
23-
- name: Use Node.js ${{ matrix.node-version }}
24-
uses: actions/setup-node@v1
25-
with:
26-
node-version: ${{ matrix.node-version }}
27-
28-
- name: Install project dependencies
29-
run: npm ci
30-
31-
- name: Fetch configlet
32-
uses: exercism/github-actions/configlet-ci@master
35+
- uses: actions/checkout@v2
36+
- name: Use Node.js ${{ matrix.node-version }}
37+
uses: actions/setup-node@v1
38+
with:
39+
node-version: ${{ matrix.node-version }}
3340

34-
- name: Run exercism/configlet linter
35-
run: configlet lint .
41+
- name: Install project dependencies
42+
run: npm ci
3643

37-
- name: Run exercism/javascript ci (checks config, lint code, and runs tests)
38-
run: npx @babel/node scripts/ci
44+
- name: Run exercism/javascript ci (checks config, lint code, and runs tests) for all exercises
45+
run: npx babel-node scripts/ci

.github/workflows/configlet.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# This workflow will do a fetch the latest configlet binary and lint this repository.
2+
3+
name: configlet
4+
5+
on: [push, pull_request]
6+
7+
jobs:
8+
lint:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v2
13+
14+
- name: Fetch configlet
15+
uses: exercism/github-actions/configlet-ci@master
16+
17+
- name: Configlet Linter
18+
run: configlet lint .

.github/workflows/pr.ci.js.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# This workflow will do a clean install of node dependencies and run tests across different versions of node
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3+
4+
name: javascript / pr
5+
6+
on: pull_request
7+
8+
jobs:
9+
precheck:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout PR
14+
uses: actions/checkout@v2
15+
16+
- name: Use Node.js LTS (12.x)
17+
uses: actions/setup-node@v1
18+
with:
19+
node-version: 12.x
20+
21+
- name: Install project dependencies
22+
run: npm ci
23+
24+
- name: Run exercism/javascript ci precheck (stub files, config integrity) for changed exercises
25+
run: |
26+
PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH")
27+
curl --url $"${PULL_REQUEST_URL}/files" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \
28+
jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|md|json)$")) | .filename' | \
29+
xargs -r npx babel-node scripts/pr-check
30+
31+
ci:
32+
runs-on: ubuntu-latest
33+
34+
strategy:
35+
matrix:
36+
node-version: [10.x, 12.x, 14.x]
37+
38+
steps:
39+
- name: Checkout PR
40+
uses: actions/checkout@v2
41+
42+
- name: Use Node.js ${{ matrix.node-version }}
43+
uses: actions/setup-node@v1
44+
with:
45+
node-version: ${{ matrix.node-version }}
46+
47+
- name: Install project dependencies
48+
run: npm ci
49+
50+
- name: Run exercism/javascript ci (runs tests) for changed/added exercises
51+
run: |
52+
PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH")
53+
curl --url $"${PULL_REQUEST_URL}/files" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \
54+
jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|md|json)$")) | .filename' | \
55+
xargs -r npx babel-node scripts/pr

CONTRIBUTING.md

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ This is the JavaScript track, one of the many tracks on [exercism][web-exercism]
44
It holds all the _exercises_ that are currently implemented and available for students
55
to complete. The track consists of various **core** exercises, the ones a student _must_
66
complete, and each **core** exercise may unlock various _side_ exercises. You can find
7-
this in the [`config.json`][file-config]. It's not uncommon that people discover
7+
this in the [`config.json`][file-config]. It's not uncommon that people discover
88
incorrect implementations of certain tests, have a suggestion for a track specific hint
99
to aid the student on the _JavaScript specifics_, see optimisations in terms of the
10-
configurations of `jest`, `eslint` or other dependencies, report missing edge cases,
10+
configurations of `jest`, `eslint` or other dependencies, report missing edge cases,
1111
factual errors, logical errors, and, implement exercises or develop new exercises.
1212

1313
We welcome contributions of all sorts and sizes, from reporting issues to
@@ -45,27 +45,29 @@ There are two ways to implement new exercises.
4545

4646
Let's say you want to implement a new exercise, from the list of exercises, because
4747
you've noticed that this track could benefit from this exercise, really liked it in
48-
another track, or just because you find this interesting; the first step is to
49-
[check for an open issue][issue-new-exercise]. If it's there, make sure no one is
50-
working on it, and most of all that there is not an open Pull Request towards this
48+
another track, or just because you find this interesting; the first step is to
49+
[check for an open issue][issue-new-exercise]. If it's there, make sure no one is
50+
working on it, and most of all that there is not an open Pull Request towards this
5151
exercise.
5252

5353
If there is no such issue, you may open one. The baseline of work is as follows:
5454

5555
1. Open a new issue, we'll label it with `new exercise ✨`
5656
1. We'll assign the issue to you, so you get to work on this exercise
5757
1. Create a new folder in `/exercises`
58-
1. You'll need to sync this folder with the matching config files. You can use
59-
`scripts/sync` to do this: `ASSIGNMENT=slug npx @babel/node scripts/sync`.
58+
1. You'll need to sync this folder with the matching config files. You can use
59+
`scripts/sync` to do this: `ASSIGNMENT=slug npx babel-node scripts/sync`.
6060
1. Create a `<slug>.js` stub file.
61-
1. Create a `<slug>.spec.js` test file. Here add the tests, per canonical data if
61+
1. Create a `<slug>.spec.js` test file. Here add the tests, per canonical data if
6262
possible.
63-
1. Create a `example.js` file. Place a working implementation, assuming it's renamed
63+
1. Create a `example.js` file. Place a working implementation, assuming it's renamed
6464
to `<slug>.js`
65-
1. Run the tests locally, using `scripts/test`:
66-
`ASSIGNMENT=slug npx @babel/node scripts/test`.
65+
1. Run the tests locally, using `scripts/test`:
66+
`ASSIGNMENT=slug npx babel-node scripts/test`.
67+
1. Run the linter locally, using `scripts/lint`:
68+
`ASSIGNMENT=slug npx babel-node scripts/lint`.
6769

68-
The final step is opening a Pull Request, with these items all checked off. Make
70+
The final step is opening a Pull Request, with these items all checked off. Make
6971
sure the tests run and the linter is happy. It will run automatically on your PR.
7072

7173
#### Creating a track-specific exercise
@@ -75,15 +77,15 @@ established, existing exercise. The differences are:
7577

7678
- You'll have to write a README.md and test-suite from scratch
7779
- You'll have to come up with a unique _slug_.
78-
- We need to require an icon for it.
80+
- We need to require an icon for it.
7981
- Generate a UUID, for example using [configlet][configlet].
8082

81-
Open a new issue with your proposal, and we'll make sure all these steps are
83+
Open a new issue with your proposal, and we'll make sure all these steps are
8284
correctly taken. Don't worry! You're not alone in this.
8385

8486
### Existing exercises
8587

86-
There are always improvements possible on existing exercises.
88+
There are always improvements possible on existing exercises.
8789

8890
#### Improving the README.md
8991

@@ -103,13 +105,13 @@ no `README.md` explanation should _give away_ a certain implementation. The
103105
#### Syncing the exercise
104106

105107
Syncing an exercise with _canonical data_: There is a [problem-specifications][problem-specifications]
106-
repository that holds test data in a standardised format. These tests are
108+
repository that holds test data in a standardised format. These tests are
107109
occasionally fixed, improved, added, removed or otherwise changed. Each change also
108110
changes the _version_ of that canonical data. Syncing an exercise consists of:
109111

110-
- updating or adding the `"version"` key in the `package.json` file,
112+
- updating or adding the `"version"` key in the `package.json` file,
111113
- updating the `<slug>.spec.js` file,
112-
- match the `example.js` file to still work with the new tests, and
114+
- match the `example.js` file to still work with the new tests, and
113115
- [regenerate the `README.md`][doc-readme], should there be any changes.
114116

115117
#### Improving or adding mentor notes
@@ -121,13 +123,13 @@ the `website-copy` repository. Find their [contributing guidelines][contributing
121123
#### Improving or adding automated test analyzers
122124

123125
Some exercises already have automated mentoring support. These automations
124-
don't live in this repository, but instead in the `javascript-analyzer` repository.
126+
don't live in this repository, but instead in the `javascript-analyzer` repository.
125127
Find their [contributing guidelines][contributing-javascript-analyzer] [here][contributing-javascript-analyzer].
126128

127129
## Documentation
128130

129-
There is quite a bit of student-facing documentation, which can be found in the
130-
[`docs`][file-docs] folder. You may improve these files by making the required
131+
There is quite a bit of student-facing documentation, which can be found in the
132+
[`docs`][file-docs] folder. You may improve these files by making the required
131133
changes and opening a new Pull Request.
132134

133135
## Tools
@@ -144,19 +146,19 @@ as listed below. We use the following dependencies:
144146
### Fetch configlet
145147

146148
If you'd like to download [configlet][configlet], you can use the [`fetch-configlet`][bin-fetch-configlet]
147-
binary. It will run on Linux, Mac OSX and Windows, and download `configlet` to your
149+
binary. It will run on Linux, Mac OSX and Windows, and download `configlet` to your
148150
local drive. Find more information about [configlet][configlet] [here][configlet].
149151

150152
### Scripts
151153

152-
We have various `scripts` for you in order to aid with maintaining and contributing
154+
We have various `scripts` for you in order to aid with maintaining and contributing
153155
to this repository.
154156

155157
#### `lint`
156158

157159
```js
158160
/*
159-
* Run this script (from root directory): npx @babel/node scripts/lint
161+
* Run this script (from root directory): npx babel/node scripts/lint
160162
*
161163
* This runs `eslint` on all sample solutions (and test) files
162164
*/
@@ -167,32 +169,32 @@ example, if you only want to lint `two-fer`, you may, depending on your environm
167169
use:
168170

169171
```shell
170-
ASSIGNMENT=two-fer npx @babel/node scripts/lint
172+
ASSIGNMENT=two-fer npx babel/node scripts/lint
171173
```
172174

173175
#### `test`
174176

175177
```js
176178
/**
177-
* Run this script (from root directory): npx @babel/node scripts/test
179+
* Run this script (from root directory): npx babel/node scripts/test
178180
*
179181
* This runs `jest` tests for all sample solutions
180182
*/
181183
```
182184

183185
If the `ASSIGNMENT` environment variable is set, only _that_ exercise is tested. For
184-
example, if you only want to test the `example.js` for `two-fer`, you may, depending
186+
example, if you only want to test the `example.js` for `two-fer`, you may, depending
185187
on your environment, use:
186188

187189
```shell
188-
ASSIGNMENT=two-fer npx @babel/node scripts/test
190+
ASSIGNMENT=two-fer npx babel/node scripts/test
189191
```
190192

191193
#### `sync`
192194

193195
```js
194196
/**
195-
* Run this script (from root directory): npx @babel/node scripts/sync
197+
* Run this script (from root directory): npx babel/node scripts/sync
196198
*
197199
* This script is used to propagate any change to root package.json to
198200
* all exercises and keep them in sync.
@@ -202,18 +204,18 @@ ASSIGNMENT=two-fer npx @babel/node scripts/test
202204
```
203205

204206
If the `ASSIGNMENT` environment variable is set, only _that_ exercise is tested. For
205-
example, if you only want to sync the files for `two-fer`, you may, depending on
207+
example, if you only want to sync the files for `two-fer`, you may, depending on
206208
your environment, use:
207209

208210
```shell
209-
ASSIGNMENT=two-fer npx @babel/node scripts/sync
211+
ASSIGNMENT=two-fer npx babel/node scripts/sync
210212
```
211213

212214
#### `checksum`
213215

214216
```js
215217
/*
216-
* Run this script (from root directory): npx @babel/node scripts/checksum
218+
* Run this script (from root directory): npx babel/node scripts/checksum
217219
*
218220
* This will check root `package.json` matches each exercise's `package.json`.
219221
* But the catch is there are some dependencies used for build but not served to end users
@@ -222,19 +224,37 @@ ASSIGNMENT=two-fer npx @babel/node scripts/sync
222224
*/
223225
```
224226

225-
#### `ci`
227+
#### `ci-check`
226228

227229
```js
228230
/**
229-
* Run this script (from root directory): npx @babel/node scripts/ci
231+
* Run this script (from root directory): npx babel-node scripts/ci-check
230232
*
231233
* This will run following checks:
234+
*
232235
* 1. Check config in all exercises matches
233-
* 2. Run eslint to check code-style
234-
* 3. Run tests against sample solutions
236+
* 2. Checks stubs exist
237+
* 3. Run eslint to check code-style
238+
*/
239+
```
240+
241+
Run this script to check stubs, configuration integrity and lint the code.
242+
243+
#### `ci`
244+
245+
```js
246+
/**
247+
* Run this script (from root directory): npx babel/node scripts/ci
248+
*
249+
* This will run following checks:
250+
*
251+
* 1. Find the exercises
252+
* 2. Run tests against sample solutions
235253
*/
236254
```
237255

256+
Run this script to test all exercises.
257+
238258
[configlet]: https://github.com/exercism/docs/blob/master/language-tracks/configuration/configlet.md
239259
[bin-fetch-configlet]: https://github.com/exercism/javascript/blob/master/bin/fetch-configlet
240260
[web-exercism]: https://exercism.io

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# JavaScript
2-
[![javascript/ci](https://github.com/exercism/javascript/workflows/exercism/javascript%20ci/badge.svg)](https://github.com/exercism/javascript/actions?query=workflow%3A%22exercism%2Fjavascript+ci%22)
2+
3+
[![configlet](https://github.com/exercism/javascript/workflows/configlet/badge.svg)](https://github.com/exercism/javascript/actions?query=workflow%3Aconfiglet) [![javascript / ci](https://github.com/exercism/javascript/workflows/javascript%20/%20ci/badge.svg)](https://github.com/exercism/javascript/actions?query=workflow%3A%22javascript+%2F+ci%22) [![codeql](https://github.com/exercism/javascript/workflows/codql/badge.svg)](https://github.com/exercism/javascript/actions?query=workflow%3Acodeql)
34

45
**Exercism exercises in JavaScript**
56

6-
This is the JavaScript track, one of the many tracks on [exercism][web-exercism]. It holds all the _exercises_ that are currently implemented and available for students to complete. The track consists of various **core** exercises - the ones a student _must_ complete - and each **core** exercise may unlock various _side_ exercises. You can find this in the [`config.json`][file-config].
7+
This is the JavaScript track, one of the many tracks on [Exercism][web-exercism]. It holds all the _exercises_ that are currently implemented and available for students to complete. The track consists of various **core** exercises - the ones a student _must_ complete - and each **core** exercise may unlock various _side_ exercises. You can find this in the [`config.json`][file-config].
78

8-
> In version 3 of exercism, the above no longer holds. See the [`exercism/v3`][git-v3] repository for more information.
9+
> In version 3 of Exercism, the above no longer holds. See the [`exercism/v3`][git-v3] repository for more information.
910
1011
## Tools
1112

0 commit comments

Comments
 (0)