11name : Build
22
3- on :
4- push :
5- branches :
6- - master
7- tags :
8- - v**
9- pull_request :
10- workflow_dispatch :
11- inputs :
12- debug_enabled :
13- type : boolean
14- description : " Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
15- required : false
16- default : false
3+ on : [push, pull_request]
174
185jobs :
19- client :
6+ build-and-deploy :
7+ permissions :
8+ contents : " read"
9+ id-token : " write"
10+ deployments : " write"
2011 strategy :
2112 matrix :
2213 os :
2314 - " ubuntu-latest"
24- - " windows-latest"
25- - " macos-latest"
2615 runs-on : ${{ matrix.os }}
2716 steps :
2817 - uses : actions/checkout@v4
@@ -35,300 +24,56 @@ jobs:
3524 cache : " npm"
3625 cache-dependency-path : |
3726 package-lock.json
38- # uv required for javascript tests
39- - uses : astral-sh/setup-uv@v7
40- with :
41- enable-cache : false
42- # go needed for fake_gcs_server used by the javascript tests
43- - name : Setup go
44- uses : actions/setup-go@v5
45- with :
46- go-version : " stable"
47- - run : npm ci
48- - run : npm run format:fix
49- - name : Check for dirty working directory
50- run : git diff --exit-code
51- - run : npm run lint:check
27+ examples/**/package-lock.json
28+ - run : npm install
5229 - name : Typecheck with TypeScript
5330 run : npm run typecheck
54- - name : Build client bundles
55- run : |
56- build_info="{'tag':'$(git describe --always --tags)', 'url':'https://github.com/google/neuroglancer/commit/$(git rev-parse HEAD)', 'timestamp':'$(date)'}"
57- npm run build -- --no-typecheck --no-lint --define NEUROGLANCER_BUILD_INFO="${build_info}"
58- echo $build_info > ./dist/client/version.json
31+ - name : Get branch name (merge)
32+ if : github.event_name != 'pull_request'
5933 shell : bash
60- - name : Build Python client bundles
61- run : npm run build-python -- --no-typecheck --no-lint
62- - run : npm run build-package
63- - name : Run JavaScript tests (including WebGL)
64- run : npm test
65- if : ${{ runner.os != 'macOS' }}
66- - name : Run JavaScript tests (excluding WebGL)
67- run : npm test -- --project node
68- if : ${{ runner.os == 'macOS' }}
69- - name : Run JavaScript benchmarks
70- run : npm run benchmark
71- - name : Upload NPM package as artifact
72- uses : actions/upload-artifact@v4
73- with :
74- name : npm-package
75- path : dist/package
76- if : ${{ runner.os == 'Linux' }}
77- - name : Upload client as artifact
78- uses : actions/upload-artifact@v4
79- with :
80- name : client
81- path : dist/client
82- if : ${{ runner.os == 'Linux' }}
83- example-project-test :
84- runs-on : ubuntu-latest
85- steps :
86- - uses : actions/checkout@v4
87- - name : Install pnpm
88- uses : pnpm/action-setup@v4
89- with :
90- version : 10
91- - uses : actions/setup-node@v4
92- with :
93- node-version : 24.x
94- cache : " pnpm"
95- cache-dependency-path : |
96- examples/**/pnpm-lock.yaml
97- - uses : actions/setup-node@v4
98- with :
99- node-version : 24.x
100- cache : " npm"
101- cache-dependency-path : |
102- package-lock.json
103- - run : npm ci
104- - run : npm run example-project-test -- --reporter=html
105- - name : Upload report and built clients
106- uses : actions/upload-artifact@v4
107- if : ${{ !cancelled() }}
108- with :
109- name : example-project-test-results
110- path : |
111- playwright-report/
112- examples/*/*/dist/
113-
114- # Builds Python package and runs Python tests
115- #
116- # On ubuntu-latest, this also runs browser-based tests. On Mac OS and
117- # Windows, this only runs tests that do not require a browser, since a working
118- # headless WebGL2 implementation is not available on Github actions.
119- python-tests :
120- strategy :
121- matrix :
122- python-version :
123- - " 3.11"
124- - " 3.13"
125- os :
126- - " ubuntu-latest"
127- - " windows-latest"
128- - " macos-latest"
129- runs-on : ${{ matrix.os }}
130- steps :
131- - uses : actions/checkout@v4
132- with :
133- # Need full history to determine version number.
134- fetch-depth : 0
135- - uses : actions/setup-node@v4
136- with :
137- node-version : 24.x
138- - uses : astral-sh/setup-uv@v7
139- with :
140- enable-cache : false
141- python-version : ${{ matrix.python-version }}
142- - uses : ./.github/actions/setup-firefox
143- - name : Setup tmate session
144- uses : mxschmitt/action-tmate@v3
145- if : ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
146- - run : uvx nox -s lint format mypy
147- - name : Check for dirty working directory
148- run : git diff --exit-code
149- - name : Run python tests (skip browser tests)
150- run : uvx nox -s test -- --skip-browser-tests
151- if : ${{ runner.os != 'Linux' }}
152- - name : Run python tests (include browser tests)
153- run : uvx nox -s test_xvfb -- --browser firefox
154- if : ${{ runner.os == 'Linux' }}
155- # Verify that editable install works
156- - name : Test in editable form
157- run : uvx nox -s test_editable
158-
159- python-build-package :
160- strategy :
161- matrix :
162- include :
163- - os : " ubuntu-latest"
164- cibw_build : " *"
165- wheel_identifier : " linux"
166- - os : " windows-latest"
167- cibw_build : " *"
168- wheel_identifier : " windows"
169- - os : " macos-14"
170- cibw_build : " *_x86_64"
171- wheel_identifier : " macos_x86_64"
172- - os : " macos-14"
173- cibw_build : " *_arm64"
174- wheel_identifier : " macos_arm64"
175- runs-on : ${{ matrix.os }}
176- steps :
177- - uses : actions/checkout@v4
178- with :
179- # Need full history to determine version number.
180- fetch-depth : 0
181- - uses : actions/setup-node@v4
182- with :
183- node-version : 24.x
184- cache : " npm"
185- - uses : astral-sh/setup-uv@v7
186- with :
187- enable-cache : false
188- - name : Get uv cache dir
189- id : uv-cache
190- run : |
191- echo "dir=$(uv cache dir)" >> "$GITHUB_OUTPUT"
192- - run : npm ci
193- - run : |
194- build_info="{'tag':'$(git describe --always --tags)', 'url':'https://github.com/google/neuroglancer/commit/$(git rev-parse HEAD)', 'timestamp':'$(date)'}"
195- npm run build-python -- --no-typecheck --no-lint --define NEUROGLANCER_BUILD_INFO="${build_info}"
34+ run : echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV
35+ - name : Get branch name (pull request)
36+ if : github.event_name == 'pull_request'
37+ shell : bash
38+ run : echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV
39+ - run : echo "BRANCH_NAME_URL=$(echo ${{ env.BRANCH_NAME }} | tr / - | tr _ -)" >> $GITHUB_ENV
40+ - name : Get build info
41+ run : echo "BUILD_INFO={\"tag\":\"$(git describe --always --tags)\", \"url\":\"https://github.com/${{github.repository}}/commit/$(git rev-parse HEAD)\", \"timestamp\":\"$(date)\", \"branch\":\"${{github.repository}}/${{env.BRANCH_NAME}}\"}" >> $GITHUB_ENV
19642 shell : bash
19743 - name : Check for dirty working directory
19844 run : git diff --exit-code
199- - name : Build Python source distribution (sdist)
200- run : uv build --sdist
201- if : ${{ runner.os == 'Linux' }}
202- - name : Build Python wheels
203- run : uvx nox -s cibuildwheel
204- env :
205- # On Linux, share uv cache with manylinux docker containers
206- CIBW_ENVIRONMENT_LINUX : UV_CACHE_DIR=/host${{ steps.uv-cache.outputs.dir }}
207- CIBW_BEFORE_ALL_LINUX : /project/python/build_tools/cibuildwheel_linux_cache_setup.sh /host${{ steps.uv-cache.outputs.dir }}
208- CIBW_BUILD : ${{ matrix.cibw_build }}
209- - name : Upload wheels as artifacts
210- uses : actions/upload-artifact@v4
211- with :
212- name : python-wheels-${{ matrix.wheel_identifier }}
213- path : |
214- dist/*.whl
215- dist/*.tar.gz
216-
217- docs :
218- runs-on : ubuntu-latest
219- steps :
220- - uses : actions/checkout@v4
221- - uses : astral-sh/setup-uv@v7
222- with :
223- enable-cache : false
224- - name : Setup Graphviz
225- uses : ts-graphviz/setup-graphviz@b1de5da23ed0a6d14e0aeee8ed52fdd87af2363c # v2.0.2
226- with :
227- macos-skip-brew-update : " true"
228- - name : Build docs
229- run : uvx nox -s docs
230- - name : Upload docs as artifact
231- uses : actions/upload-artifact@v4
232- with :
233- name : docs
234- path : |
235- dist/docs
236-
237- publish-package :
238- # Only publish package on push to tag or default branch.
239- if : ${{ github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') }}
240- runs-on : ubuntu-latest
241- needs :
242- - " client"
243- - " python-build-package"
244- - " docs"
245- steps :
246- - uses : actions/checkout@v4
247- - name : Use Node.js
248- uses : actions/setup-node@v4
249- with :
250- node-version : 24.x
251- registry-url : " https://registry.npmjs.org"
252- - uses : actions/download-artifact@v4
253- with :
254- pattern : python-wheels-*
255- path : dist
256- merge-multiple : true
257- - uses : actions/download-artifact@v4
258- with :
259- name : npm-package
260- path : npm-package
261- # - name: Publish to PyPI (test server)
262- # uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
263- # with:
264- # user: __token__
265- # password: ${{ secrets.pypi_test_token }}
266- - name : Publish to PyPI (main server)
267- uses : pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
268- with :
269- user : __token__
270- password : ${{ secrets.pypi_token }}
271- if : ${{ startsWith(github.ref, 'refs/tags/v') }}
272- - name : Publish to NPM registry
273- if : ${{ startsWith(github.ref, 'refs/tags/v') }}
274- run : npm publish
275- working-directory : npm-package
276- env :
277- NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
278- # Download dist/client after publishing to PyPI, because PyPI publish
279- # action fails if dist/client directory is present.
280- - uses : actions/download-artifact@v4
281- with :
282- name : client
283- path : dist/client
284- - name : Publish client to Firebase hosting
285- uses : FirebaseExtended/action-hosting-deploy@v0
286- with :
287- firebaseServiceAccount : " ${{ secrets.FIREBASE_HOSTING_SERVICE_ACCOUNT_KEY }}"
288- projectId : neuroglancer-demo
289- channelId : live
290- target : app
291- # Download dist/docs after publishing to PyPI, because PyPI publish
292- # action fails if dist/docs directory is present.
293- - uses : actions/download-artifact@v4
294- with :
295- name : docs
296- path : dist/docs
297- - name : Publish docs to Firebase hosting
298- uses : FirebaseExtended/action-hosting-deploy@v0
299- with :
300- firebaseServiceAccount : " ${{ secrets.FIREBASE_HOSTING_SERVICE_ACCOUNT_KEY }}"
301- projectId : neuroglancer-demo
302- channelId : live
303- target : docs
304-
305- ngauth :
306- strategy :
307- matrix :
308- os :
309- - ubuntu-latest
310- runs-on : ${{ matrix.os }}
311- steps :
312- - uses : actions/checkout@v4
313- - name : Setup go
314- uses : actions/setup-go@v5
315- with :
316- go-version-file : ngauth_server/go.mod
317- cache-dependency-path : ngauth_server/go.sum
318- - run : go build .
319- working-directory : ngauth_server
320- wasm :
321- # Ensures that .wasm files are reproducible.
322- strategy :
323- matrix :
324- os :
325- - ubuntu-latest
326- runs-on : ${{ matrix.os }}
327- steps :
328- - uses : actions/checkout@v4
329- - run : ./src/mesh/draco/build.sh
330- - run : ./src/sliceview/compresso/build.sh
331- - run : ./src/sliceview/png/build.sh
332- - run : ./src/sliceview/jxl/build.sh
333- # Check that there are no differences.
334- - run : git diff --exit-code
45+ - name : Build client bundles
46+ run : npm run build -- --no-typecheck --no-lint --define STATE_SERVERS=$(cat config/state_servers.json | tr -d " \t\n\r") --define NEUROGLANCER_BUILD_INFO='${{ env.BUILD_INFO }}' --define NEUROGLANCER_CUSTOM_INPUT_BINDINGS=$(cat config/custom-keybinds.json | tr -d " \t\n\r")
47+ - name : Write build info
48+ run : echo $BUILD_INFO > ./dist/client/version.json
49+ shell : bash
50+ - run : cp -r ./dist/client appengine/frontend/static/
51+ - name : start deployment
52+ uses : bobheadxi/deployments@v1
53+ id : deployment
54+ with :
55+ step : start
56+ token : ${{ secrets.GITHUB_TOKEN }}
57+ env : ${{ env.BRANCH_NAME }}
58+ desc : Setting up staging deployment for ${{ env.BRANCH_NAME }}
59+ - id : " auth"
60+ uses : " google-github-actions/auth@v1"
61+ with :
62+ workload_identity_provider : " projects/483670036293/locations/global/workloadIdentityPools/neuroglancer-github/providers/github"
63+ service_account :
" [email protected] " 64+ - id : deploy
65+ uses : google-github-actions/deploy-appengine@main
66+ with :
67+ version : ${{ env.BRANCH_NAME_URL }}
68+ deliverables : appengine/frontend/app.yaml
69+ promote : false
70+ - name : update deployment status
71+ uses : bobheadxi/deployments@v1
72+ if : always()
73+ with :
74+ step : finish
75+ token : ${{ secrets.GITHUB_TOKEN }}
76+ env : ${{ steps.deployment.outputs.env }}
77+ env_url : ${{ steps.deploy.outputs.url }}
78+ status : ${{ job.status }}
79+ deployment_id : ${{ steps.deployment.outputs.deployment_id }}
0 commit comments