Skip to content

Commit 3f9b0db

Browse files
Update CI (jupyterlab#396)
* Update CI * Add dev install script * Automatic application of license header * Add update snapshots workflow * Update snapshots --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 20a3735 commit 3f9b0db

15 files changed

+3249
-3272
lines changed

.github/workflows/test.yml

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ jobs:
2828
- name: Install dependencies
2929
run: |
3030
pip install "jupyterlab>=4.0.0,<5"
31-
pip install -e .
32-
pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
33-
jlpm
31+
jlpm install
3432
3533
- name: Run pre-commit
3634
uses: pre-commit/[email protected]
@@ -55,6 +53,7 @@ jobs:
5553
test-js:
5654
name: Test JavaScript
5755
runs-on: ubuntu-latest
56+
needs: [pre-commit]
5857
steps:
5958
- name: Checkout
6059
uses: actions/checkout@v4
@@ -69,13 +68,7 @@ jobs:
6968

7069
- name: Install dependencies
7170
run: |
72-
pip install "jupyterlab>=4.0.0,<5"
73-
pip install -e .
74-
pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
75-
jupyter labextension develop --overwrite projects/jupyter-collaboration-ui
76-
jupyter labextension develop --overwrite projects/jupyter-docprovider
77-
jlpm
78-
jlpm build
71+
yarn dev
7972
8073
- name: Run Tests
8174
run: |
@@ -84,13 +77,14 @@ jobs:
8477
8578
test-py:
8679
name: Test Python
80+
needs: [pre-commit]
8781
runs-on: ${{ matrix.os }}
8882
timeout-minutes: 20
8983
strategy:
9084
fail-fast: false
9185
matrix:
9286
os: [ubuntu-latest, windows-latest, macos-latest]
93-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
87+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
9488
# PyPy is not supported because we use the file_id_manager. See:
9589
# https://github.com/jupyter-server/jupyter_server_fileid/issues/44
9690
#include:
@@ -106,9 +100,8 @@ jobs:
106100

107101
- name: Install the Python dependencies
108102
run: |
109-
python -m pip install "jupyterlab>=4.0.0,<5"
110-
python -m pip install -e ".[test]" codecov
111-
python -m pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
103+
python -m pip install codecov
104+
yarn dev
112105
113106
- name: List installed packages
114107
run: |
@@ -148,7 +141,7 @@ jobs:
148141
149142
test_minimum_versions:
150143
name: Test Minimum Versions
151-
needs: [pre-commit, test-js, test-py]
144+
needs: [test-js, test-py]
152145
timeout-minutes: 20
153146
runs-on: ubuntu-latest
154147
steps:
@@ -157,21 +150,20 @@ jobs:
157150
- name: Base Setup
158151
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
159152
with:
160-
python_version: "3.8"
153+
python_version: "3.9"
161154
dependency_type: minimum
162155

163156
- name: Install the Python dependencies
164157
run: |
165-
pip install -e ".[test]"
166-
pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
158+
yarn dev
167159
168160
- name: Run the unit tests
169161
run: |
170162
pytest -vv -W default || pytest -vv -W default --lf
171163
172164
test_prereleases:
173165
name: Test Prereleases
174-
needs: [pre-commit, test-js, test-py]
166+
needs: [test-js, test-py]
175167
runs-on: ubuntu-latest
176168
timeout-minutes: 20
177169
steps:
@@ -183,8 +175,7 @@ jobs:
183175

184176
- name: Install the Python dependencies
185177
run: |
186-
pip install -e ".[test]"
187-
pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
178+
yarn dev
188179
189180
- name: List installed packages
190181
run: |
@@ -197,7 +188,7 @@ jobs:
197188
198189
make_sdist:
199190
name: Make SDist
200-
needs: [pre-commit, test-js, test-py]
191+
needs: [pre-commit]
201192
runs-on: ubuntu-latest
202193
timeout-minutes: 10
203194
steps:
@@ -269,16 +260,21 @@ jobs:
269260

270261
ui_tests:
271262
runs-on: ubuntu-latest
272-
needs: [pre-commit, test-js]
263+
needs: [make_sdist]
273264
timeout-minutes: 30
274265
env:
275266
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/pw-browsers
276267
steps:
277268
- uses: actions/checkout@v4
278269
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
270+
- name: Download sdist
271+
uses: actions/download-artifact@v4
272+
with:
273+
name: "sdist"
279274
- name: Install dependencies
280275
run: |
281-
pip install jupyterlab .
276+
pip install jupyterlab jupyter_collaboration_ui*.tar.gz jupyter_docprovider*.tar.gz jupyter_server_ydoc*.tar.gz
277+
282278
- name: Install playwright
283279
env:
284280
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Update Galata References
2+
3+
on:
4+
issue_comment:
5+
types: [created, edited]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
defaults:
12+
run:
13+
shell: bash -l {0}
14+
15+
jobs:
16+
update-snapshots:
17+
if: >
18+
(
19+
github.event.comment.author_association == 'OWNER' ||
20+
github.event.comment.author_association == 'COLLABORATOR' ||
21+
github.event.comment.author_association == 'MEMBER'
22+
) && github.event.issue.pull_request && contains(github.event.comment.body, 'please update snapshots')
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: React to the triggering comment
26+
run: |
27+
gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions --raw-field 'content=+1'
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Checkout
32+
uses: actions/checkout@v4
33+
with:
34+
token: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Get PR Info
37+
id: pr
38+
env:
39+
PR_NUMBER: ${{ github.event.issue.number }}
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
GH_REPO: ${{ github.repository }}
42+
COMMENT_AT: ${{ github.event.comment.created_at }}
43+
run: |
44+
pr="$(gh api /repos/${GH_REPO}/pulls/${PR_NUMBER})"
45+
head_sha="$(echo "$pr" | jq -r .head.sha)"
46+
pushed_at="$(echo "$pr" | jq -r .pushed_at)"
47+
48+
if [[ $(date -d "$pushed_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then
49+
echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)"
50+
exit 1
51+
fi
52+
53+
echo "head_sha=$head_sha" >> $GITHUB_OUTPUT
54+
55+
- name: Checkout the branch from the PR that triggered the job
56+
env:
57+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
run: gh pr checkout ${{ github.event.issue.number }}
59+
60+
- name: Validate the fetched branch HEAD revision
61+
env:
62+
EXPECTED_SHA: ${{ steps.pr.outputs.head_sha }}
63+
run: |
64+
actual_sha="$(git rev-parse HEAD)"
65+
66+
if [[ "$actual_sha" != "$EXPECTED_SHA" ]]; then
67+
echo "The HEAD of the checked out branch ($actual_sha) differs from the HEAD commit available at the time when trigger comment was submitted ($EXPECTED_SHA)"
68+
exit 1
69+
fi
70+
71+
- name: Base Setup
72+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
73+
74+
- name: Build the extension
75+
run: yarn dev
76+
77+
- uses: jupyterlab/maintainer-tools/.github/actions/update-snapshots@main
78+
with:
79+
npm_client: jlpm
80+
github_token: ${{ secrets.GITHUB_TOKEN }}
81+
start_server_script: 'null'
82+
test_folder: ui-tests

docs/source/developer/contributing.rst

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,8 @@ Once you have installed the dependencies above, use the following steps:
3737
3838
git clone https://github.com/jupyterlab/jupyter-collaboration.git
3939
cd jupyter-collaboration
40-
# install monorepo
41-
pip install -e ".[dev,test]"
42-
# install local dependencies as editable
43-
pip install -e projects/jupyter-collaboration-ui -e projects/jupyter-docprovider -e projects/jupyter-server-ydoc
44-
# link lab extensions
45-
jupyter labextension develop --overwrite projects/jupyter-collaboration-ui
46-
jupyter labextension develop --overwrite projects/jupyter-docprovider
40+
# install monorepo in dev mode
41+
python scripts/dev_install.py
4742
4843
4944
If you are using a system-wide Python installation and you only want to install the server for you,

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"packages/*"
2626
],
2727
"scripts": {
28+
"dev": "python scripts/dev_install.py",
2829
"build": "lerna run build",
2930
"build:prod": "lerna run build:prod",
3031
"build:test": "lerna run build:test",

scripts/dev_install.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (c) Jupyter Development Team.
2+
# Distributed under the terms of the Modified BSD License.
3+
4+
import subprocess
5+
from pathlib import Path
6+
from typing import Optional
7+
8+
9+
def execute(cmd: str, cwd: Optional[Path] = None) -> None:
10+
subprocess.run(cmd.split(" "), check=True, cwd=cwd)
11+
12+
13+
def install_dev() -> None:
14+
install_build_deps = "python -m pip install jupyterlab>=4,<5"
15+
install_js_deps = "jlpm install"
16+
17+
python_package_prefix = "projects"
18+
python_packages = ["jupyter-collaboration-ui", "jupyter-docprovider", "jupyter-server-ydoc"]
19+
20+
execute(install_build_deps)
21+
execute(install_js_deps)
22+
23+
for py_package in python_packages:
24+
real_package_name = py_package.replace("-", "_")
25+
execute(f"pip uninstall {real_package_name} -y")
26+
execute(f"pip install -e {python_package_prefix}/{py_package}[test]")
27+
28+
# List of server extensions
29+
if py_package in ["jupyter-server-ydoc"]:
30+
execute(f"jupyter server extension enable {real_package_name}")
31+
32+
# List of jupyterlab extensions
33+
if py_package in ["jupyter-collaboration-ui", "jupyter-docprovider"]:
34+
execute(
35+
f"jupyter labextension develop --overwrite {python_package_prefix}/{py_package} --overwrite"
36+
)
37+
38+
39+
if __name__ == "__main__":
40+
install_dev()

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"strict": true,
1717
"strictNullChecks": true,
1818
"target": "es2018",
19-
"types": []
19+
"types": [],
20+
"lib": ["DOM", "ES2018", "ES2020.Intl"]
2021
}
2122
}

ui-tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"test:update": "npx playwright test --update-snapshots"
1010
},
1111
"devDependencies": {
12-
"@jupyterlab/galata": "^5.1.5",
12+
"@jupyterlab/galata": "^5.3.0",
1313
"@jupyterlab/services": "^7.1.5",
1414
"@playwright/test": "^1.35.0"
1515
},

ui-tests/playwright.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,10 @@ module.exports = {
1717
url: 'http://localhost:8888/lab',
1818
timeout: 120 * 1000,
1919
reuseExistingServer: !process.env.CI
20+
},
21+
expect: {
22+
toMatchSnapshot: {
23+
maxDiffPixelRatio: 0.01
24+
}
2025
}
2126
};
-8 Bytes
Loading

ui-tests/tests/notebook.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ test.describe('Initialization', () => {
108108
await guestPage.filebrowser.refresh();
109109
await guestPage.notebook.open(pathUntitled);
110110

111-
const nbPanel = await page.notebook.getNotebookInPanel();
111+
const nbPanel = await page.notebook.getNotebookInPanelLocator();
112112
expect.soft(await nbPanel?.screenshot()).toMatchSnapshot(
113113
'initialization-create-notebook-host.png'
114114
);
115115

116-
const nbPanelGuest = await guestPage.notebook.getNotebookInPanel();
116+
const nbPanelGuest = await guestPage.notebook.getNotebookInPanelLocator();
117117
expect(await nbPanelGuest?.screenshot()).toMatchSnapshot(
118118
'initialization-create-notebook-guest.png'
119119
);
@@ -133,12 +133,12 @@ test.describe('Initialization', () => {
133133
await guestPage.notebook.open(exampleNotebook);
134134
await guestPage.notebook.activate(exampleNotebook);
135135

136-
const nbPanel = await page.notebook.getNotebookInPanel();
136+
const nbPanel = await page.notebook.getNotebookInPanelLocator();
137137
expect.soft(await nbPanel?.screenshot()).toMatchSnapshot(
138138
'initialization-open-notebook-host.png'
139139
);
140140

141-
const nbPanelGuest = await guestPage.notebook.getNotebookInPanel();
141+
const nbPanelGuest = await guestPage.notebook.getNotebookInPanelLocator();
142142
expect(await nbPanelGuest?.screenshot()).toMatchSnapshot(
143143
'initialization-open-notebook-guest.png'
144144
);
@@ -245,7 +245,7 @@ test.describe('Ten clients', () => {
245245
async () => (await page.notebook.getCellCount()) === numCells + numClients
246246
);
247247

248-
const nbPanel = await page.notebook.getNotebookInPanel();
248+
const nbPanel = await page.notebook.getNotebookInPanelLocator();
249249
expect(await nbPanel?.screenshot()).toMatchSnapshot(
250250
'ten-clients-add-a-new-cell.png'
251251
);

0 commit comments

Comments
 (0)