-
Notifications
You must be signed in to change notification settings - Fork 4k
118 lines (106 loc) · 5.82 KB
/
Copy pathlint.yml
File metadata and controls
118 lines (106 loc) · 5.82 KB
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
name: ESLint check
on:
workflow_call:
pull_request:
types: [opened, synchronize]
branches-ignore: [staging, production]
paths:
['**.js', '**.ts', '**.tsx', '**.json', '**.mjs', '**.cjs', 'config/.editorconfig', 'config/eslint/**', 'scripts/lint.sh', 'scripts/lintChanged.sh', '.watchmanconfig', '.imgbotconfig']
concurrency:
group: ${{ github.ref == 'refs/heads/main' && format('{0}-{1}', github.ref, github.sha) || github.ref }}-lint
cancel-in-progress: true
jobs:
lint:
name: ESLint check
if: ${{ github.event.head_commit.author.name != 'OSBotify' || github.event_name == 'push' }}
# A cold-cache run lints the whole repo with type-aware rules, which loads the full TypeScript
# program in every worker (~12GB of heap each, regardless of how files are split between workers).
# 2 workers with a 14GB heap cap need ~30GB of memory, so this requires the 32GB (8vcpu) runner.
runs-on: blacksmith-8vcpu-ubuntu-2404
steps:
- name: Checkout
uses: useblacksmith/checkout@1c9394c220d293645707b625ba9d79685f093a8f # v1
with:
# Only use the elevated OSBotify token on the post-merge `workflow_call` run
# (so the auto-commit step below can push to the protected `main` branch).
# PR runs use the default GITHUB_TOKEN so PR code can't borrow push-to-main
# access via the persisted checkout credentials.
token: ${{ github.event_name == 'push' && secrets.OS_BOTIFY_COMMIT_TOKEN || github.token }}
- name: Setup Node
uses: ./.github/actions/composite/setupNode
# Extract only the lint-affecting dependencies: eslint packages, the parser chain
# (espree/acorn) whose bumps can silently change parse results, plus
# typescript/ts-api-utils since a TS bump can change type-aware lint results.
# The cache key hashes this slice so a cold full re-lint happens only when
# the lint config or a lint dependency changes -- not on every dep bump.
- name: Extract lint-related deps from package-lock.json
shell: bash
run: |
jq '{packages: (.packages | to_entries | map(select(.key | test("eslint|espree|acorn|^node_modules/(typescript|ts-api-utils)$"))) | from_entries)}' package-lock.json > lint-deps-lock.json
# The setupNode sticky disk persists all of node_modules between runs, including
# node_modules/.cache/eslint. Clear it so the restore step below is the only cache
# source -- a restore miss doesn't delete pre-existing files, so without this a
# config change would silently reuse the stale cache carried over by the disk.
- name: Clear ESLint cache carried over by the node_modules sticky disk
shell: bash
run: rm -rf node_modules/.cache/eslint
- name: Restore ESLint cache
# v5.0.1
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: node_modules/.cache/eslint
key: ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.mjs', 'config/eslint/**', 'lint-deps-lock.json') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-eslint-${{ hashFiles('eslint.config.mjs', 'config/eslint/**', 'lint-deps-lock.json') }}-
# ESLint's cache doesn't track cross-file TypeScript dependencies, which can cause stale errors.
# If lint fails, we clear the cache and retry to rule out false positives.
# See: https://typescript-eslint.io/troubleshooting/faqs/eslint/#can-i-use-eslints---cache-with-typescript-eslint
- name: Lint JavaScript and Typescript with ESLint
env:
# See the runs-on comment: each worker needs ~12GB of heap on a cold cache, so run
# 2 workers with a 14GB cap instead of ESLint's defaults (4 workers, 8GB cap).
ESLINT_CONCURRENCY: 2
NODE_OPTIONS: --max_old_space_size=14336
run: |
if ! npm run lint; then
echo "Lint failed, clearing cache and retrying..."
rm -rf node_modules/.cache/eslint
npm run lint
fi
- name: Save ESLint cache
# v5.0.1
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb
if: always()
with:
path: node_modules/.cache/eslint
key: ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.mjs', 'config/eslint/**', 'lint-deps-lock.json') }}-${{ github.sha }}
# If lint tightened the seatbelt baseline (i.e. fewer baselined errors than last time),
# commit the updated TSV back to `main` as OSBotify. Only runs under `workflow_call`
# (i.e. invoked from preDeploy.yml, which only triggers on push to main).
- name: Check for tightened eslint-seatbelt baseline
id: seatbelt_diff
if: github.event_name == 'push'
run: |
if git diff --quiet config/eslint/eslint.seatbelt.tsv; then
echo "tightened=false" >> "$GITHUB_OUTPUT"
echo "::notice::eslint.seatbelt.tsv unchanged; skipping auto-commit."
else
echo "tightened=true" >> "$GITHUB_OUTPUT"
fi
- name: Setup git for OSBotify
if: steps.seatbelt_diff.outputs.tightened == 'true'
uses: Expensify/GitHub-Actions/setupGitForOSBotify@main
with:
OP_VAULT: ${{ vars.OP_VAULT }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
SETUP_AS_APP: false
# If the push races with another commit to `main`, let this step fail.
# The next `push: main` lint run will re-tighten the baseline and try
# again; no need to retry here.
- name: Auto-commit tightened eslint-seatbelt baseline
if: steps.seatbelt_diff.outputs.tightened == 'true'
continue-on-error: true
run: |
git add config/eslint/eslint.seatbelt.tsv
git commit -m "Auto-tighten eslint-seatbelt baseline"
git push origin main