1
+ name : ' Build Extension'
2
+ description : ' Build and test a JupyterLab extension'
3
+ inputs :
4
+ example :
5
+ description : ' The example to build'
6
+ required : true
7
+ run-ui-tests :
8
+ description : ' Whether to run UI tests'
9
+ required : false
10
+ default : ' false'
11
+
12
+ runs :
13
+ using : ' composite'
14
+ steps :
15
+ - name : Path filter
16
+ id : filter
17
+ uses : dorny/paths-filter@v2
18
+ with :
19
+ filters : |
20
+ extension:
21
+ - '${{ inputs.example }}/**'
22
+ - name : Cache lerna
23
+ if : steps.filter.outputs.extension == 'true'
24
+ uses : actions/cache@v4
25
+ with :
26
+ path : ' **/node_modules'
27
+ key : ${{ runner.os }}-lerna-${{ hashFiles('**/package.json') }}
28
+ restore-keys : ${{ runner.os }}-lerna-
29
+ - name : Check config files
30
+ if : steps.filter.outputs.extension == 'true'
31
+ run : |
32
+ diff ../hello-world/setup.py setup.py
33
+ diff ../hello-world/tsconfig.json tsconfig.json
34
+ diff ../hello-world/.yarnrc.yml .yarnrc.yml
35
+ diff ../hello-world/ui-tests/jupyter_server_test_config.py ./ui-tests/jupyter_server_test_config.py
36
+ diff ../hello-world/ui-tests/playwright.config.js ./ui-tests/playwright.config.js
37
+ shell : bash
38
+ working-directory : ${{ inputs.example }}
39
+ - name : Install node
40
+ if : steps.filter.outputs.extension == 'true'
41
+ uses : actions/setup-node@v4
42
+ with :
43
+ node-version : ' 18.x'
44
+ - name : Install Python
45
+ if : steps.filter.outputs.extension == 'true'
46
+ uses : actions/setup-python@v5
47
+ with :
48
+ python-version : ' 3.11'
49
+ architecture : ' x64'
50
+ - name : Get pip cache dir
51
+ if : steps.filter.outputs.extension == 'true'
52
+ id : pip-cache
53
+ run : |
54
+ echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
55
+ shell : bash
56
+ - name : Cache pip
57
+ if : steps.filter.outputs.extension == 'true'
58
+ uses : actions/cache@v4
59
+ with :
60
+ path : ${{ steps.pip-cache.outputs.dir }}
61
+ key : ${{ runner.os }}-pip-${{ hashFiles('environment.yml') }}
62
+ restore-keys : |
63
+ ${{ runner.os }}-pip-
64
+ - name : Install the Python dependencies
65
+ if : steps.filter.outputs.extension == 'true'
66
+ run : |
67
+ python -m pip install --upgrade pip "jupyterlab>=4.0.0"
68
+ shell : bash
69
+ # This is challenging to test in collaboration;
70
+ # got trouble with the file ID service and the uncontrolled auto-save
71
+ # - if: steps.filter.outputs.extension == 'true' && inputs.example == 'clap-button-message'
72
+ # run: |
73
+ # python -m pip install jupyter-collaboration
74
+ - name : Build the extension
75
+ if : steps.filter.outputs.extension == 'true'
76
+ run : |
77
+ # Same commands as in TL;DR to ensure it works
78
+ touch yarn.lock
79
+ pip install -e . -v
80
+ jupyter labextension develop . --overwrite
81
+ shell : bash
82
+ working-directory : ${{ inputs.example }}
83
+ - name : Lint the files
84
+ if : steps.filter.outputs.extension == 'true'
85
+ run : jlpm run lint:check
86
+ shell : bash
87
+ working-directory : ${{ inputs.example }}
88
+ - name : Check extension installation
89
+ if : steps.filter.outputs.extension == 'true'
90
+ run : |
91
+ jupyter labextension list 2>&1 | tee labextension.list
92
+ cat labextension.list | grep -ie "@jupyterlab-examples/*.*OK"
93
+ shell : bash
94
+ working-directory : ${{ inputs.example }}
95
+ # clap-button-message example will have one plugin failing as it is requiring a
96
+ # Jupyter Notebook specific token. This is expected. Hence we need to skip this
97
+ # test for that example
98
+ - name : Browser check
99
+ if : steps.filter.outputs.extension == 'true' && inputs.example != 'clap-button-message'
100
+ run : |
101
+ python -m jupyterlab.browser_check
102
+ shell : bash
103
+
104
+ - name : Install galata
105
+ if : steps.filter.outputs.extension == 'true' && inputs.run-ui-tests == 'true'
106
+ working-directory : ${{ inputs.example }}/ui-tests
107
+ env :
108
+ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD : 1
109
+ run : jlpm install
110
+ shell : bash
111
+ - name : Set up browser cache
112
+ if : steps.filter.outputs.extension == 'true' && inputs.run-ui-tests == 'true'
113
+ uses : actions/cache@v4
114
+ with :
115
+ path : |
116
+ ${{ github.workspace }}/pw-browsers
117
+ key : ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
118
+ - name : Install browser
119
+ if : steps.filter.outputs.extension == 'true' && inputs.run-ui-tests == 'true'
120
+ run : jlpm playwright install chromium
121
+ working-directory : ${{ inputs.example }}/ui-tests
122
+ shell : bash
123
+ - name : Install kernel-output dependencies
124
+ if : steps.filter.outputs.extension == 'true' && inputs.example == 'kernel-output'
125
+ run : pip install numpy pandas
126
+ shell : bash
127
+ - name : Integration tests
128
+ if : steps.filter.outputs.extension == 'true' && inputs.run-ui-tests == 'true'
129
+ working-directory : ${{ inputs.example }}/ui-tests
130
+ run : jlpm playwright test
131
+ shell : bash
132
+ - name : Upload UI Test artifacts
133
+ if : steps.filter.outputs.extension == 'true' && inputs.run-ui-tests == 'true' && always()
134
+ uses : actions/upload-artifact@v4
135
+ with :
136
+ name : ${{ inputs.example }}-ui-test-output
137
+ path : |
138
+ ${{ inputs.example }}/ui-tests/test-results
139
+ - name : Uninstall extension
140
+ if : steps.filter.outputs.extension == 'true' && (runner.os == 'Linux' || runner.os == 'macOS')
141
+ run : |
142
+ export NAME=`python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])"`
143
+ pip uninstall -y ${NAME}
144
+ shell : bash
145
+ working-directory : ${{ inputs.example }}
0 commit comments