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,313 +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@v5
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- - run : npm publish --dry-run
64- working-directory : dist/package
65- - name : Run JavaScript tests (including WebGL)
66- run : npm test
67- if : ${{ runner.os != 'macOS' }}
68- - name : Run JavaScript tests (excluding WebGL)
69- run : npm test -- --project node
70- if : ${{ runner.os == 'macOS' }}
71- - name : Run JavaScript benchmarks
72- run : npm run benchmark
73- - name : Upload NPM package as artifact
74- uses : actions/upload-artifact@v4
75- with :
76- name : npm-package
77- path : dist/package
78- if : ${{ runner.os == 'Linux' }}
79- - name : Upload client as artifact
80- uses : actions/upload-artifact@v4
81- with :
82- name : client
83- path : dist/client
84- if : ${{ runner.os == 'Linux' }}
85- example-project-test :
86- runs-on : ubuntu-latest
87- steps :
88- - uses : actions/checkout@v4
89- - name : Install pnpm
90- uses : pnpm/action-setup@v4
91- with :
92- version : 10
93- - uses : actions/setup-node@v4
94- with :
95- node-version : 22.x
96- cache : " pnpm"
97- cache-dependency-path : |
98- examples/**/pnpm-lock.yaml
99- - uses : actions/setup-node@v4
100- with :
101- node-version : 22.x
102- cache : " npm"
103- cache-dependency-path : |
104- package-lock.json
105- - run : npm ci
106- - run : npm run example-project-test -- --reporter=html
107- - name : Upload report and built clients
108- uses : actions/upload-artifact@v4
109- if : ${{ !cancelled() }}
110- with :
111- name : example-project-test-results
112- path : |
113- playwright-report/
114- examples/*/*/dist/
115-
116- # Builds Python package and runs Python tests
117- #
118- # On ubuntu-latest, this also runs browser-based tests. On Mac OS and
119- # Windows, this only runs tests that do not require a browser, since a working
120- # headless WebGL2 implementation is not available on Github actions.
121- python-tests :
122- strategy :
123- matrix :
124- python-version :
125- - " 3.9"
126- - " 3.12"
127- os :
128- - " ubuntu-latest"
129- - " windows-latest"
130- - " macos-latest"
131- runs-on : ${{ matrix.os }}
132- steps :
133- - uses : actions/checkout@v4
134- with :
135- # Need full history to determine version number.
136- fetch-depth : 0
137- - uses : actions/setup-node@v4
138- with :
139- node-version : 22.x
140- - uses : astral-sh/setup-uv@v5
141- with :
142- enable-cache : false
143- - name : Set up Python ${{ matrix.python-version }}
144- uses : actions/setup-python@v5
145- with :
146- python-version : ${{ matrix.python-version }}
147- - uses : ./.github/actions/setup-firefox
148- - name : Setup tmate session
149- uses : mxschmitt/action-tmate@v3
150- if : ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
151- - run : uvx nox -s lint format mypy
152- - name : Check for dirty working directory
153- run : git diff --exit-code
154- - name : Run python tests (skip browser tests)
155- run : uvx nox -s test -- --skip-browser-tests
156- if : ${{ runner.os != 'Linux' }}
157- - name : Run python tests (include browser tests)
158- run : uvx nox -s test_xvfb -- --browser firefox
159- if : ${{ runner.os == 'Linux' }}
160- # Verify that editable install works
161- - name : Test in editable form
162- run : uvx nox -s test_editable
163-
164- python-build-package :
165- strategy :
166- matrix :
167- include :
168- - os : " ubuntu-latest"
169- cibw_build : " *"
170- wheel_identifier : " linux"
171- - os : " windows-latest"
172- cibw_build : " *"
173- wheel_identifier : " windows"
174- - os : " macos-14"
175- cibw_build : " *_x86_64"
176- wheel_identifier : " macos_x86_64"
177- - os : " macos-14"
178- cibw_build : " *_arm64"
179- wheel_identifier : " macos_arm64"
180- runs-on : ${{ matrix.os }}
181- steps :
182- - uses : actions/checkout@v4
183- with :
184- # Need full history to determine version number.
185- fetch-depth : 0
186- - uses : actions/setup-node@v4
187- with :
188- node-version : 22.x
189- cache : " npm"
190- - uses : astral-sh/setup-uv@v5
191- with :
192- enable-cache : false
193- - name : Set up Python
194- uses : actions/setup-python@v5
195- with :
196- python-version : 3.x
197- - name : Get uv cache dir
198- id : uv-cache
199- run : |
200- echo "dir=$(uv cache dir)" >> "$GITHUB_OUTPUT"
201- - run : npm ci
202- - run : |
203- build_info="{'tag':'$(git describe --always --tags)', 'url':'https://github.com/google/neuroglancer/commit/$(git rev-parse HEAD)', 'timestamp':'$(date)'}"
204- 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
20542 shell : bash
20643 - name : Check for dirty working directory
20744 run : git diff --exit-code
208- - name : Build Python source distribution (sdist)
209- run : uv build --sdist
210- if : ${{ runner.os == 'Linux' }}
211- - name : Build Python wheels
212- run : uvx nox -s cibuildwheel
213- env :
214- # On Linux, share uv cache with manylinux docker containers
215- CIBW_ENVIRONMENT_LINUX : UV_CACHE_DIR=/host${{ steps.uv-cache.outputs.dir }}
216- CIBW_BEFORE_ALL_LINUX : /project/python/build_tools/cibuildwheel_linux_cache_setup.sh /host${{ steps.uv-cache.outputs.dir }}
217- CIBW_BUILD : ${{ matrix.cibw_build }}
218- - name : Upload wheels as artifacts
219- uses : actions/upload-artifact@v4
220- with :
221- name : python-wheels-${{ matrix.wheel_identifier }}
222- path : |
223- dist/*.whl
224- dist/*.tar.gz
225-
226- docs :
227- runs-on : ubuntu-latest
228- steps :
229- - uses : actions/checkout@v4
230- - uses : astral-sh/setup-uv@v5
231- with :
232- enable-cache : false
233- - name : Set up Python
234- uses : actions/setup-python@v5
235- with :
236- python-version : 3.12
237- - name : Setup Graphviz
238- uses : ts-graphviz/setup-graphviz@b1de5da23ed0a6d14e0aeee8ed52fdd87af2363c # v2.0.2
239- with :
240- macos-skip-brew-update : " true"
241- - name : Build docs
242- run : uvx nox -s docs
243- - name : Upload docs as artifact
244- uses : actions/upload-artifact@v4
245- with :
246- name : docs
247- path : |
248- dist/docs
249-
250- publish-package :
251- # Only publish package on push to tag or default branch.
252- if : ${{ github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') }}
253- runs-on : ubuntu-latest
254- needs :
255- - " client"
256- - " python-build-package"
257- - " docs"
258- steps :
259- - uses : actions/checkout@v4
260- - name : Use Node.js
261- uses : actions/setup-node@v4
262- with :
263- node-version : 22.x
264- registry-url : " https://registry.npmjs.org"
265- - uses : actions/download-artifact@v4
266- with :
267- pattern : python-wheels-*
268- path : dist
269- merge-multiple : true
270- - uses : actions/download-artifact@v4
271- with :
272- name : npm-package
273- path : npm-package
274- # - name: Publish to PyPI (test server)
275- # uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
276- # with:
277- # user: __token__
278- # password: ${{ secrets.pypi_test_token }}
279- - name : Publish to PyPI (main server)
280- uses : pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
281- with :
282- user : __token__
283- password : ${{ secrets.pypi_token }}
284- if : ${{ startsWith(github.ref, 'refs/tags/v') }}
285- - name : Publish to NPM registry
286- if : ${{ startsWith(github.ref, 'refs/tags/v') }}
287- run : npm publish
288- working-directory : npm-package
289- env :
290- NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
291- # Download dist/client after publishing to PyPI, because PyPI publish
292- # action fails if dist/client directory is present.
293- - uses : actions/download-artifact@v4
294- with :
295- name : client
296- path : dist/client
297- - name : Publish client 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 : app
304- # Download dist/docs after publishing to PyPI, because PyPI publish
305- # action fails if dist/docs directory is present.
306- - uses : actions/download-artifact@v4
307- with :
308- name : docs
309- path : dist/docs
310- - name : Publish docs to Firebase hosting
311- uses : FirebaseExtended/action-hosting-deploy@v0
312- with :
313- firebaseServiceAccount : " ${{ secrets.FIREBASE_HOSTING_SERVICE_ACCOUNT_KEY }}"
314- projectId : neuroglancer-demo
315- channelId : live
316- target : docs
317-
318- ngauth :
319- strategy :
320- matrix :
321- os :
322- - ubuntu-latest
323- runs-on : ${{ matrix.os }}
324- steps :
325- - uses : actions/checkout@v4
326- - name : Setup go
327- uses : actions/setup-go@v5
328- with :
329- go-version-file : ngauth_server/go.mod
330- cache-dependency-path : ngauth_server/go.sum
331- - run : go build .
332- working-directory : ngauth_server
333- wasm :
334- # Ensures that .wasm files are reproducible.
335- strategy :
336- matrix :
337- os :
338- - ubuntu-latest
339- runs-on : ${{ matrix.os }}
340- steps :
341- - uses : actions/checkout@v4
342- - run : ./src/mesh/draco/build.sh
343- - run : ./src/sliceview/compresso/build.sh
344- - run : ./src/sliceview/png/build.sh
345- - run : ./src/sliceview/jxl/build.sh
346- # Check that there are no differences.
347- - 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