Skip to content

Commit 8965c3d

Browse files
authored
Merge pull request #7786 from plotly/cam/7785/check-regl-ci
ci: Add CI step to check if precompiled regl shaders need to be updated
2 parents c201dd1 + c089676 commit 8965c3d

7 files changed

Lines changed: 176 additions & 79 deletions

File tree

.github/workflows/ci.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
outputs:
2424
stackgl_modules: ${{ steps.check.outputs.stackgl_modules }}
2525
topojson: ${{ steps.check.outputs.topojson }}
26+
regl_codegen: ${{ steps.check.outputs.regl_codegen }}
2627
steps:
2728
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2829
with:
@@ -42,6 +43,12 @@ jobs:
4243
if git diff --name-only "$BASE"...HEAD -- stackgl_modules/ | grep -q .; then
4344
echo "stackgl_modules=true" >> "$GITHUB_OUTPUT"
4445
fi
46+
# If any of the directories listed below have changed, we need to re-run the regl-codegen step
47+
# stackgl_modules/ is listed here too because the regl-* shader libs live there;
48+
# changes can alter shader output and require regenerating the precompiled shaders.
49+
if git diff --name-only "$BASE"...HEAD -- src/traces/scattergl/ src/traces/scatterpolargl/ src/traces/splom/ src/traces/parcoords/ src/lib/prepare_regl.js stackgl_modules/ devtools/regl_codegen/ | grep -q .; then
50+
echo "regl_codegen=true" >> "$GITHUB_OUTPUT"
51+
fi
4552
4653
# ============================================================
4754
# Root build job - all dependent jobs fan out from here
@@ -636,3 +643,54 @@ jobs:
636643
name: topojson-dist
637644
retention-days: 7
638645
path: topojson/dist/
646+
647+
check-regl-codegen:
648+
needs: [detect-changes, install-and-cibuild]
649+
if: >-
650+
(github.event_name == 'push' && github.ref_name == github.event.repository.default_branch) ||
651+
needs.detect-changes.outputs.regl_codegen == 'true'
652+
runs-on: ubuntu-latest
653+
timeout-minutes: 10
654+
steps:
655+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
656+
- uses: ./.github/actions/setup-workspace
657+
- uses: ./.github/actions/setup-chrome
658+
659+
- name: Run regl codegen
660+
run: |
661+
# Wipe the codegen output dir so orphaned shader files surface as deletions in the diff below.
662+
rm -rf src/generated/regl-codegen/*
663+
node devtools/regl_codegen/server.mjs &
664+
SERVER_PID=$!
665+
until curl -sf -o /dev/null http://localhost:3000/build/regl_codegen-bundle.js 2>/dev/null; do
666+
sleep 1
667+
done
668+
$CHROME_BIN --headless=new --no-sandbox --enable-unsafe-swiftshader --ignore-gpu-blocklist http://localhost:3000/devtools/regl_codegen/index.html &
669+
wait $SERVER_PID
670+
671+
- name: Check regl precompiled shaders are up to date
672+
run: |
673+
# git add -N so newly-generated (untracked) shader files show up in git diff
674+
git add -N src/generated/regl-codegen/
675+
if ! git diff --exit-code \
676+
src/generated/regl-codegen/ \
677+
src/traces/scattergl/regl_precompiled.js \
678+
src/traces/scatterpolargl/regl_precompiled.js \
679+
src/traces/splom/regl_precompiled.js \
680+
src/traces/parcoords/regl_precompiled.js; then
681+
echo "::error::Regl precompiled shaders are out of date. Download the 'regl-codegen' artifact from this workflow run, extract it into src/, and commit the updated files to this pull request."
682+
exit 1
683+
fi
684+
685+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
686+
name: Upload updated regl codegen files
687+
if: failure()
688+
with:
689+
name: regl-codegen
690+
retention-days: 7
691+
path: |
692+
src/generated/regl-codegen/
693+
src/traces/scattergl/regl_precompiled.js
694+
src/traces/scatterpolargl/regl_precompiled.js
695+
src/traces/splom/regl_precompiled.js
696+
src/traces/parcoords/regl_precompiled.js

CONTRIBUTING.md

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,54 @@ npm run schema
163163
#### Step 9: REGL - Review & commit potential changes to precompiled regl shaders
164164

165165
If you are implementing a new feature that involves regl shaders, or if you are
166-
making changes that affect the usage of regl shaders, you would need to run
166+
making changes that affect the usage of regl shaders, you will need to regenerate the precompiled regl shader code. In practice, that means edits under:
167167

168-
```bash
169-
npm run regl-codegen
170-
```
168+
- `src/traces/{scattergl,scatterpolargl,splom,parcoords}/`
169+
- `src/lib/prepare_regl.js`
170+
- `stackgl_modules/` (where the `regl-*` shader libs live)
171+
- `devtools/regl_codegen/`
171172

172-
to regenerate the regl code. This will prompt you to open a browser window. This will then run through all
173-
traces with 'regl' in the tags, and store the captured code into
174-
[src/generated/regl-codegen](https://github.com/plotly/plotly.js/blob/master/src/generated/regl-codegen). If no updates are necessary, it will be a no-op, but if there are changes, you will need to commit them.
173+
CI's `check-regl-codegen` job uses this same list as its trigger — see [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for the authoritative version.
175174

176175
This is needed because regl performs codegen in runtime which breaks CSP
177176
compliance, and so for strict builds we pre-generate regl shader code here.
178177

178+
The CI pipeline will automatically detect when regl-related files have changed and
179+
run the codegen process. If the precompiled shaders are out of date, the
180+
`check-regl-codegen` job will fail and upload a `regl-codegen` artifact containing
181+
the updated files. The artifact represents the full desired state of the codegen
182+
output (CI wipes the output directory before regenerating, so any orphaned shader
183+
files are pruned). To fix this:
184+
185+
1. Download the `regl-codegen` artifact from the failed workflow run
186+
2. Delete `src/generated/regl-codegen/` in your working tree, then unzip the
187+
artifact into `src/` so it replaces (rather than merges into) the existing
188+
directory. Note that `actions/upload-artifact` strips the longest common
189+
parent path from the uploaded paths, so the zip's root contains
190+
`generated/regl-codegen/` and `traces/{scattergl,scatterpolargl,splom,parcoords}/regl_precompiled.js`
191+
directly — extracting into `src/` restores the correct layout and
192+
overwrites the four `regl_precompiled.js` files in one step.
193+
3. Commit and push the changes to your pull request
194+
195+
Alternatively, you can regenerate the code locally:
196+
197+
```bash
198+
rm -rf src/generated/regl-codegen/*
199+
npm run regl-codegen
200+
```
201+
202+
The `rm -rf` step is needed to clean up any orphaned shader files left over from
203+
previous changes. `npm run regl-codegen` will prompt you to open
204+
a browser window, run through the mocks for each regl-using trace
205+
(`parcoords`, `scattergl`, `scatterpolargl`, `splom`), and store the captured
206+
shader code into
207+
[src/generated/regl-codegen](https://github.com/plotly/plotly.js/blob/master/src/generated/regl-codegen).
208+
The four `src/traces/{parcoords,scattergl,scatterpolargl,splom}/regl_precompiled.js`
209+
files are rewritten in the same pass so their imports point at the freshly
210+
generated shader files. Commit any changes that result — both the
211+
`src/generated/regl-codegen/` updates and any modified `regl_precompiled.js`
212+
files.
213+
179214
#### Other npm scripts that may be of interest in development
180215

181216
- `npm run preprocess`: pre-processes the css and svg source file in js. This

devtools/regl_codegen/server.mjs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,20 @@ function handleCodegen(data) {
8585
var exports = ['', '/* eslint-disable quote-props */', 'module.exports = {', ''].join('\n');
8686
var varId = 0;
8787

88-
Object.entries(generated).forEach(function (kv) {
89-
var key = kv[0];
90-
var value = kv[1];
91-
var filePath = path.join(pathToReglCodegenSrc, key);
92-
fs.writeFileSync(filePath, 'module.exports = ' + value);
93-
94-
imports += 'var v' + varId + " = require('../../" + path.join(constants.reglCodegenSubdir, key) + "');\n";
95-
exports += " '" + key + "': v" + varId + ',\n';
96-
varId++;
97-
});
88+
// Sort by shader-hash key so the emitted import/export order is deterministic
89+
// across machines (fs.readdir mock order varies by OS/filesystem, which would
90+
// otherwise leak into regl_precompiled.js).
91+
Object.keys(generated)
92+
.sort()
93+
.forEach((key) => {
94+
var value = generated[key];
95+
var filePath = path.join(pathToReglCodegenSrc, key);
96+
fs.writeFileSync(filePath, 'module.exports = ' + value);
97+
98+
imports += 'var v' + varId + " = require('../../" + path.join(constants.reglCodegenSubdir, key) + "');\n";
99+
exports += " '" + key + "': v" + varId + ',\n';
100+
varId++;
101+
});
98102

99103
if (varId > 0) {
100104
exports = exports.slice(0, -2) + '\n};\n';
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
'use strict';
2-
var v0 = require('../../generated/regl-codegen/453a70fefa48db31713162aeb1ac438cb8579f54504f3b23acf32128df3dfd45');
3-
var v1 = require('../../generated/regl-codegen/30680f8f6712ef1af5cf7547e0af35b036fb300c67b07967cf448492ff4de4d0');
4-
var v2 = require('../../generated/regl-codegen/a3970baf1d8cac9305ee830c7026550387343d4dde2353dd86a4d082c97d3470');
5-
var v3 = require('../../generated/regl-codegen/3fd666968f3ce90d1c048b7a9aab515f3ce387a5401a10f8b66121c9469d1c0d');
2+
var v0 = require('../../generated/regl-codegen/30680f8f6712ef1af5cf7547e0af35b036fb300c67b07967cf448492ff4de4d0');
3+
var v1 = require('../../generated/regl-codegen/3fd666968f3ce90d1c048b7a9aab515f3ce387a5401a10f8b66121c9469d1c0d');
4+
var v2 = require('../../generated/regl-codegen/453a70fefa48db31713162aeb1ac438cb8579f54504f3b23acf32128df3dfd45');
5+
var v3 = require('../../generated/regl-codegen/a3970baf1d8cac9305ee830c7026550387343d4dde2353dd86a4d082c97d3470');
66

77
/* eslint-disable quote-props */
88
module.exports = {
9-
'453a70fefa48db31713162aeb1ac438cb8579f54504f3b23acf32128df3dfd45': v0,
10-
'30680f8f6712ef1af5cf7547e0af35b036fb300c67b07967cf448492ff4de4d0': v1,
11-
'a3970baf1d8cac9305ee830c7026550387343d4dde2353dd86a4d082c97d3470': v2,
12-
'3fd666968f3ce90d1c048b7a9aab515f3ce387a5401a10f8b66121c9469d1c0d': v3
9+
'30680f8f6712ef1af5cf7547e0af35b036fb300c67b07967cf448492ff4de4d0': v0,
10+
'3fd666968f3ce90d1c048b7a9aab515f3ce387a5401a10f8b66121c9469d1c0d': v1,
11+
'453a70fefa48db31713162aeb1ac438cb8579f54504f3b23acf32128df3dfd45': v2,
12+
'a3970baf1d8cac9305ee830c7026550387343d4dde2353dd86a4d082c97d3470': v3
1313
};
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
'use strict';
22
var v0 = require('../../generated/regl-codegen/3e771157d23b4793771f65d83e6387262ed73d488209157f19a7fa027bddd71b');
3-
var v1 = require('../../generated/regl-codegen/cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81');
4-
var v2 = require('../../generated/regl-codegen/8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623');
5-
var v3 = require('../../generated/regl-codegen/fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7');
6-
var v4 = require('../../generated/regl-codegen/db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d');
7-
var v5 = require('../../generated/regl-codegen/49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210');
8-
var v6 = require('../../generated/regl-codegen/dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5');
9-
var v7 = require('../../generated/regl-codegen/bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019');
10-
var v8 = require('../../generated/regl-codegen/6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923');
11-
var v9 = require('../../generated/regl-codegen/8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034');
3+
var v1 = require('../../generated/regl-codegen/49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210');
4+
var v2 = require('../../generated/regl-codegen/6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923');
5+
var v3 = require('../../generated/regl-codegen/8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034');
6+
var v4 = require('../../generated/regl-codegen/8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623');
7+
var v5 = require('../../generated/regl-codegen/bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019');
8+
var v6 = require('../../generated/regl-codegen/cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81');
9+
var v7 = require('../../generated/regl-codegen/db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d');
10+
var v8 = require('../../generated/regl-codegen/dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5');
11+
var v9 = require('../../generated/regl-codegen/fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7');
1212

1313
/* eslint-disable quote-props */
1414
module.exports = {
1515
'3e771157d23b4793771f65d83e6387262ed73d488209157f19a7fa027bddd71b': v0,
16-
'cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81': v1,
17-
'8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623': v2,
18-
'fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7': v3,
19-
'db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d': v4,
20-
'49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210': v5,
21-
'dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5': v6,
22-
'bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019': v7,
23-
'6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923': v8,
24-
'8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034': v9
16+
'49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210': v1,
17+
'6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923': v2,
18+
'8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034': v3,
19+
'8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623': v4,
20+
'bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019': v5,
21+
'cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81': v6,
22+
'db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d': v7,
23+
'dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5': v8,
24+
'fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7': v9
2525
};
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
'use strict';
22
var v0 = require('../../generated/regl-codegen/3e771157d23b4793771f65d83e6387262ed73d488209157f19a7fa027bddd71b');
3-
var v1 = require('../../generated/regl-codegen/cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81');
4-
var v2 = require('../../generated/regl-codegen/8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623');
5-
var v3 = require('../../generated/regl-codegen/fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7');
6-
var v4 = require('../../generated/regl-codegen/db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d');
7-
var v5 = require('../../generated/regl-codegen/49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210');
8-
var v6 = require('../../generated/regl-codegen/dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5');
9-
var v7 = require('../../generated/regl-codegen/bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019');
10-
var v8 = require('../../generated/regl-codegen/6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923');
11-
var v9 = require('../../generated/regl-codegen/8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034');
3+
var v1 = require('../../generated/regl-codegen/49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210');
4+
var v2 = require('../../generated/regl-codegen/6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923');
5+
var v3 = require('../../generated/regl-codegen/8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034');
6+
var v4 = require('../../generated/regl-codegen/8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623');
7+
var v5 = require('../../generated/regl-codegen/bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019');
8+
var v6 = require('../../generated/regl-codegen/cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81');
9+
var v7 = require('../../generated/regl-codegen/db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d');
10+
var v8 = require('../../generated/regl-codegen/dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5');
11+
var v9 = require('../../generated/regl-codegen/fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7');
1212

1313
/* eslint-disable quote-props */
1414
module.exports = {
1515
'3e771157d23b4793771f65d83e6387262ed73d488209157f19a7fa027bddd71b': v0,
16-
'cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81': v1,
17-
'8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623': v2,
18-
'fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7': v3,
19-
'db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d': v4,
20-
'49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210': v5,
21-
'dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5': v6,
22-
'bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019': v7,
23-
'6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923': v8,
24-
'8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034': v9
16+
'49e82bba439f1d9d441c17ba252d05640bc63fefdf22d1219993633af7730210': v1,
17+
'6a5d6bd29c15cf7614221b94c3f384df47c2c46fbe4456e8c57b5cd14c84d923': v2,
18+
'8902aff2b23b600f8103bcc84a8af2999d28795208aedadc2db06f921f9c7034': v3,
19+
'8fad2284703471df7c0e0d0a7b96d983e8c53f6d707dd55d5921c1eab71f6623': v4,
20+
'bfc540da96a87fcc039073cb37b45e6b81ef5ee6ef3529d726ceed8336354019': v5,
21+
'cbf700f001fff25b649fba9c37fa0dc6631c1cdee318ad49473d28ec10dcee81': v6,
22+
'db1b82c68771e7f5012fad1fbdae7ff23b526e58d2995bf6dd2cf30024e0f41d': v7,
23+
'dbd1cc9126a137a605df67dc0706e55116f04e33b4545a80042031752de5aef5': v8,
24+
'fe5b6844077cde1bdd7273f4495969fad93500c26a69b62e74ec2664c447bcc7': v9
2525
};

0 commit comments

Comments
 (0)