diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 731b0aa6..c3ea9a00 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -8,8 +8,9 @@ version: 2 updates: # Maintain dependencies in our GitHub Workflows - package-ecosystem: github-actions - directory: "/" + directory: / + labels: [ci] schedule: interval: monthly time: "05:00" - timezone: "Etc/UTC" + timezone: Etc/UTC diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 287696db..3ca53fcc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,8 +26,8 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" @@ -39,31 +39,3 @@ jobs: run: | cd docs make linkcheck - - build-and-publish: - runs-on: ubuntu-22.04 - - permissions: - # required to push to the gh-pages branch - contents: write - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - - - name: Install dependencies - run: | - pip install -r docs/doc-requirements.txt - - - name: make html (Builds documentation) - run: | - cd docs - make html - - - name: Publish to GitHub Pages - if: github.ref == 'refs/heads/main' - run: | - pip install ghp-import - ghp-import --no-jekyll --push --message "Update documentation [skip ci]" docs/_build/html diff --git a/.github/workflows/publish.yml b/.github/workflows/release.yaml similarity index 51% rename from .github/workflows/publish.yml rename to .github/workflows/release.yaml index 04485db9..6eca1877 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/release.yaml @@ -1,18 +1,20 @@ # This is a GitHub workflow defining a set of jobs with a set of steps. -# ref: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions +# ref: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions # -# Build releases and publish to PyPI if a tag is pushed name: Release +# Always tests wheel building, but only publish to PyPI on pushed tags. on: pull_request: paths-ignore: - "docs/**" - - "**/docs.yml" + - ".github/workflows/*.yaml" + - "!.github/workflows/release.yaml" push: paths-ignore: - "docs/**" - - "**/docs.yml" + - ".github/workflows/*.yaml" + - "!.github/workflows/release.yaml" branches-ignore: - "dependabot/**" - "pre-commit-ci-update-config" @@ -22,12 +24,20 @@ on: jobs: build-release: runs-on: ubuntu-22.04 + permissions: + # id-token=write is required for pypa/gh-action-pypi-publish, and the PyPI + # project needs to be configured to trust this workflow. + # + # ref: https://github.com/jupyterhub/team-compass/issues/648 + # + id-token: write + steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: "18" @@ -43,8 +53,5 @@ jobs: ls -l dist - name: publish to pypi - uses: pypa/gh-action-pypi-publish@v1.8.1 + uses: pypa/gh-action-pypi-publish@release/v1 if: startsWith(github.ref, 'refs/tags/') - with: - user: __token__ - password: ${{ secrets.pypi_password }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d8112c7b..6e09290c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,17 +26,47 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] - node-version: ["16"] + include: + - python-version: "3.7" + pip-install: "jupyter_server==1.* notebook==5.*" + - python-version: "3.8" + pip-install: "jupyter_server==1.* notebook==6.*" + # 2.17 is in ubuntu 18.04 + git-version: "2.17" + - python-version: "3.9" + # 2.25 is in ubuntu 20.04 + git-version: "2.25" + - python-version: "3.10" + # 2.34 is in ubuntu 22.04 + git-version: "2.34" + - python-version: "3.11" + - python-version: "3.12" + # 2.43 is in ubuntu 24.04 + git-version: "2.43" steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "${{ matrix.python-version }}" - - uses: actions/setup-node@v3 + + - uses: actions/setup-node@v4 with: - node-version: "${{ matrix.node-version }}" + node-version: "lts/*" + + - name: install git ${{ matrix.git-version }} + if: ${{ matrix.git-version }} + run: | + export MAMBA_ROOT_PREFIX=$/tmp/conda + mkdir -p $MAMBA_ROOT_PREFIX/bin + curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/1.5.8 | tar -xvj -C $MAMBA_ROOT_PREFIX/bin/ --strip-components=1 bin/micromamba + $MAMBA_ROOT_PREFIX/bin/micromamba install -c conda-forge -p $MAMBA_ROOT_PREFIX "git=${{ matrix.git-version }}" + echo "PATH=$MAMBA_ROOT_PREFIX/bin:$PATH" >> $GITHUB_ENV + + - name: git version + run: | + which git + git --version - name: Run webpack to build static assets run: | @@ -45,10 +75,12 @@ jobs: - name: Install dependencies run: | - pip install -r dev-requirements.txt - pip install . + pip install -r dev-requirements.txt ${{ matrix.pip-install }} . + + - name: List dependencies + run: | pip freeze - name: Run tests run: | - pytest --verbose --maxfail=2 --color=yes --cov nbgitpuller + pytest --maxfail=2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c14893ff..561aca8e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: # Autoformat: markdown, yaml, javascript (see the file .prettierignore) - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.6 + rev: v4.0.0-alpha.8 hooks: - id: prettier # FIXME: Autoformatting of our .js files is initially not enabled as it @@ -56,7 +56,7 @@ repos: # Autoformat and linting, misc. details - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: end-of-file-fixer - id: requirements-txt-fixer @@ -65,7 +65,7 @@ repos: # Linting: Python code (see the file .flake8) - repo: https://github.com/PyCQA/flake8 - rev: "6.0.0" + rev: "7.1.1" hooks: - id: flake8 diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..b165d7e5 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,17 @@ +# Configuration on how ReadTheDocs (RTD) builds our documentation +# ref: https://readthedocs.org/projects/nbgitpuller/ +# ref: https://docs.readthedocs.io/en/stable/config-file/v2.html +# +version: 2 + +sphinx: + configuration: docs/conf.py + +build: + os: ubuntu-20.04 + tools: + python: "3.10" + +python: + install: + - requirements: docs/doc-requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a804ac0..d85bb293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,77 @@ -## 1.0 +## 1.2 + +### 1.2.1 - 2024-03-29 + +This release provides compatibility with JupyterHub >=4.1. + +([full changelog](https://github.com/jupyterhub/nbgitpuller/compare/1.2.0...1.2.1)) + +#### Bugs fixed + +- 403 on failed auth for EventStream [#347](https://github.com/jupyterhub/nbgitpuller/pull/347) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio)) +- include xsrf token in event stream request [#346](https://github.com/jupyterhub/nbgitpuller/pull/346) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda)) + +#### Maintenance and upkeep improvements + +- Add test for Python 3.12, jupyter_server 1, notebook 5 and 7, and git 2.43 (ubuntu 24.04) [#345](https://github.com/jupyterhub/nbgitpuller/pull/345) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk), [@yuvipanda](https://github.com/yuvipanda)) + +#### Documentation improvements -### 1.1.1 +- Fix automatic merging link in README.md [#328](https://github.com/jupyterhub/nbgitpuller/pull/328) ([@mathbunnyru](https://github.com/mathbunnyru), [@manics](https://github.com/manics)) +- Add a FAQ entry for 'nbgitpuller link selecting profile options' [#322](https://github.com/jupyterhub/nbgitpuller/pull/322) ([@yuvipanda](https://github.com/yuvipanda), [@consideRatio](https://github.com/consideRatio), [@ryanlovett](https://github.com/ryanlovett), [@sgibson91](https://github.com/sgibson91)) + +#### Contributors to this release + +The following people contributed discussions, new ideas, code and documentation contributions, and review. +See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports). + +([GitHub contributors page for this release](https://github.com/jupyterhub/nbgitpuller/graphs/contributors?from=2023-08-07&to=2024-03-29&type=c)) + +@balajialg ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Abalajialg+updated%3A2023-08-07..2024-03-29&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3AconsideRatio+updated%3A2023-08-07..2024-03-29&type=Issues)) | @fomightez ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Afomightez+updated%3A2023-08-07..2024-03-29&type=Issues)) | @jtpio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajtpio+updated%3A2023-08-07..2024-03-29&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Amanics+updated%3A2023-08-07..2024-03-29&type=Issues)) | @mathbunnyru ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Amathbunnyru+updated%3A2023-08-07..2024-03-29&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aminrk+updated%3A2023-08-07..2024-03-29&type=Issues)) | @ryanlovett ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aryanlovett+updated%3A2023-08-07..2024-03-29&type=Issues)) | @sgibson91 ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Asgibson91+updated%3A2023-08-07..2024-03-29&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ayuvipanda+updated%3A2023-08-07..2024-03-29&type=Issues)) + +### 1.2.0 - 2023-08-07 + +([full changelog](https://github.com/jupyterhub/nbgitpuller/compare/1.1.1...1.2.0)) + +#### Enhancements made + +- Depend on jupyter-server only, compatibility with jupyter server >= 2, notebook < 7 [#240](https://github.com/jupyterhub/nbgitpuller/pull/240) ([@manics](https://github.com/manics), [@yuvipanda](https://github.com/yuvipanda), [@consideRatio](https://github.com/consideRatio), [@akhmerov](https://github.com/akhmerov), [@minrk](https://github.com/minrk), [@jtpio](https://github.com/jtpio)) + +#### Bugs fixed + +- fix handling of deleted-but-not-staged files with git 2.40 [#302](https://github.com/jupyterhub/nbgitpuller/pull/302) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda)) + +#### Maintenance and upkeep improvements + +- avoid deprecation warnings in test_api teardown [#301](https://github.com/jupyterhub/nbgitpuller/pull/301) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda)) +- redirect gh-pages to readthedocs [#298](https://github.com/jupyterhub/nbgitpuller/pull/298) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio)) +- migrate docs to RTD [#297](https://github.com/jupyterhub/nbgitpuller/pull/297) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda), [@frankier](https://github.com/frankier)) +- Bootstrap pre-commit config, add dependabot config, test py311 [#288](https://github.com/jupyterhub/nbgitpuller/pull/288) ([@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda)) +- Fix test_exception_branch_exists [#287](https://github.com/jupyterhub/nbgitpuller/pull/287) ([@a3626a](https://github.com/a3626a), [@minrk](https://github.com/minrk), [@yuvipanda](https://github.com/yuvipanda)) +- Make tests work with different default branch, or different locale [#284](https://github.com/jupyterhub/nbgitpuller/pull/284) ([@jdmansour](https://github.com/jdmansour), [@yuvipanda](https://github.com/yuvipanda)) + +#### Documentation improvements + +- Link generator - support generating links for named servers [#309](https://github.com/jupyterhub/nbgitpuller/pull/309) ([@Snozzberries](https://github.com/Snozzberries), [@consideRatio](https://github.com/consideRatio)) +- Update README.md [#306](https://github.com/jupyterhub/nbgitpuller/pull/306) ([@Snozzberries](https://github.com/Snozzberries), [@yuvipanda](https://github.com/yuvipanda)) + +#### Continuous integration improvements + +- dependabot: monthly updates of github actions [#299](https://github.com/jupyterhub/nbgitpuller/pull/299) ([@consideRatio](https://github.com/consideRatio)) +- ci: relocate dependabot.yaml to correct location [#294](https://github.com/jupyterhub/nbgitpuller/pull/294) ([@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda)) + +#### Contributors to this release + +The following people contributed discussions, new ideas, code and documentation contributions, and review. +See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports). + +([GitHub contributors page for this release](https://github.com/jupyterhub/nbgitpuller/graphs/contributors?from=2022-11-08&to=2023-08-07&type=c)) + +@a3626a ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aa3626a+updated%3A2022-11-08..2023-08-07&type=Issues)) | @akhmerov ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aakhmerov+updated%3A2022-11-08..2023-08-07&type=Issues)) | @albertmichaelj ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aalbertmichaelj+updated%3A2022-11-08..2023-08-07&type=Issues)) | @balajialg ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Abalajialg+updated%3A2022-11-08..2023-08-07&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3AconsideRatio+updated%3A2022-11-08..2023-08-07&type=Issues)) | @frankier ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Afrankier+updated%3A2022-11-08..2023-08-07&type=Issues)) | @jdmansour ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajdmansour+updated%3A2022-11-08..2023-08-07&type=Issues)) | @jtpio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajtpio+updated%3A2022-11-08..2023-08-07&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Amanics+updated%3A2022-11-08..2023-08-07&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aminrk+updated%3A2022-11-08..2023-08-07&type=Issues)) | @Snozzberries ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3ASnozzberries+updated%3A2022-11-08..2023-08-07&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ayuvipanda+updated%3A2022-11-08..2023-08-07&type=Issues)) + +## 1.1 + +### 1.1.1 - 2022-11-08 ([full changelog](https://github.com/jupyterhub/nbgitpuller/compare/1.1.0...1.1.1)) @@ -13,7 +84,7 @@ - Deal with modify/delete conflicts [#269](https://github.com/jupyterhub/nbgitpuller/pull/269) ([@jdmansour](https://github.com/jdmansour)) - Fix regression: can't reset some files anymore [#264](https://github.com/jupyterhub/nbgitpuller/pull/264) ([@jdmansour](https://github.com/jdmansour)) -#### Other merged PRs +#### Maintenance and upkeep improvements - Modernize JS a little [#273](https://github.com/jupyterhub/nbgitpuller/pull/273) ([@yuvipanda](https://github.com/yuvipanda)) - Remove jquery dependency [#272](https://github.com/jupyterhub/nbgitpuller/pull/272) ([@yuvipanda](https://github.com/yuvipanda)) @@ -29,7 +100,7 @@ [@balajialg](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Abalajialg+updated%3A2022-03-19..2022-11-08&type=Issues) | [@consideRatio](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3AconsideRatio+updated%3A2022-03-19..2022-11-08&type=Issues) | [@farcila](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Afarcila+updated%3A2022-03-19..2022-11-08&type=Issues) | [@jdmansour](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajdmansour+updated%3A2022-03-19..2022-11-08&type=Issues) | [@yuvipanda](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ayuvipanda+updated%3A2022-03-19..2022-11-08&type=Issues) -### 1.1.0 +### 1.1.0 - 2022-03-19 ([full changelog](https://github.com/jupyterhub/nbgitpuller/compare/1.0.2...1.1.0)) @@ -68,6 +139,8 @@ [@akhmerov](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aakhmerov+updated%3A2021-09-02..2022-03-18&type=Issues) | [@brian-rose](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Abrian-rose+updated%3A2021-09-02..2022-03-18&type=Issues) | [@choldgraf](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Acholdgraf+updated%3A2021-09-02..2022-03-18&type=Issues) | [@consideRatio](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3AconsideRatio+updated%3A2021-09-02..2022-03-18&type=Issues) | [@jameshowison](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajameshowison+updated%3A2021-09-02..2022-03-18&type=Issues) | [@jdmansour](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ajdmansour+updated%3A2021-09-02..2022-03-18&type=Issues) | [@manics](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Amanics+updated%3A2021-09-02..2022-03-18&type=Issues) | [@ryanlovett](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Aryanlovett+updated%3A2021-09-02..2022-03-18&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Awelcome+updated%3A2021-09-02..2022-03-18&type=Issues) | [@yuvipanda](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3Ayuvipanda+updated%3A2021-09-02..2022-03-18&type=Issues) | [@Zsailer](https://github.com/search?q=repo%3Ajupyterhub%2Fnbgitpuller+involves%3AZsailer+updated%3A2021-09-02..2022-03-18&type=Issues) +## 1.0 + ### 1.0.2 - 2021-09-03 A release to fix an issue that stopped us from publishing nbgitpuller on diff --git a/README.md b/README.md index da2a2575..7326b4fd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # [nbgitpuller](https://github.com/jupyterhub/nbgitpuller) [![GitHub Workflow Status - Test](https://img.shields.io/github/workflow/status/jupyterhub/nbgitpuller/Tests?logo=github&label=tests)](https://github.com/jupyterhub/nbgitpuller/actions) -[![CircleCI build status](https://img.shields.io/circleci/build/github/jupyterhub/nbgitpuller?logo=circleci&label=docs)](https://circleci.com/gh/jupyterhub/nbgitpuller) +[![Documentation Status](https://readthedocs.org/projects/nbgitpuller/badge/?version=latest)](https://nbgitpuller.readthedocs.io/en/latest/?badge=latest) [![](https://img.shields.io/pypi/v/nbgitpuller.svg?logo=pypi)](https://pypi.python.org/pypi/nbgitpuller) [![GitHub](https://img.shields.io/badge/issue_tracking-github-blue?logo=github)](https://github.com/jupyterhub/nbgitpuller/issues) [![Discourse](https://img.shields.io/badge/help_forum-discourse-blue?logo=discourse)](https://discourse.jupyter.org/c/jupyterhub) @@ -9,11 +9,11 @@ `nbgitpuller` lets you distribute content in a git repository to your students by having them click a simple link. [Automatic -merging](https://jupyterhub.github.io/nbgitpuller/topic/automatic-merging.html) +merging](https://nbgitpuller.readthedocs.io/en/latest/topic/automatic-merging.html) ensures that your students are never exposed to `git` directly. It is primarily used with a JupyterHub, but can also work on students' local computers. -See [the documentation](https://jupyterhub.github.io/nbgitpuller) for more +See [the documentation](https://nbgitpuller.readthedocs.io) for more information. ## Installation @@ -24,10 +24,12 @@ pip install nbgitpuller ## Example -This example shows how to use the [nbgitpuller link generator](https://jupyterhub.github.io/nbgitpuller/link) +This example shows how to use the [nbgitpuller link generator] to create an nbgitpuller link, which a user then clicks. -1. The [nbgitpuller link generator GUI](https://jupyterhub.github.io/nbgitpuller/link) is used to create a +[nbgitpuller link generator]: https://nbgitpuller.readthedocs.io/en/latest/link.html + +1. The nbgitpuller link generator GUI is used to create a link. ![](https://raw.githubusercontent.com/jupyterhub/nbgitpuller/9f380a933335f0f069b6e2f9965ed78c3abcce7a/docs/_static/nbgitpuller-link-generator.png) diff --git a/RELEASE.md b/RELEASE.md index c8488f03..a51fe33b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,67 +1,60 @@ # How to make a release -`nbgitpuller` is a package available on -[PyPI](https://pypi.org/project/nbgitpuller/) and -[conda-forge](https://anaconda.org/conda-forge/nbgitpuller). -These are instructions on how to make a release on PyPI. -The PyPI release is done automatically by TravisCI when a tag is pushed. +`nbgitpuller` is a package available on [PyPI] and [conda-forge]. + +These are the instructions on how to make a release. + +## Pre-requisites + +- Push rights to this GitHub repository ## Steps to make a release -1. Checkout main and make sure it is up to date. +1. Create a PR updating `CHANGELOG.md` with [github-activity] and continue when + its merged. - ```shell - ORIGIN=${ORIGIN:-origin} # set to the canonical remote, e.g. 'upstream' if 'origin' is not the official repo - git checkout main - git fetch $ORIGIN main - git reset --hard $ORIGIN/main - # WARNING! This next command deletes any untracked files in the repo - git clean -xfd - ``` + Advice on this procedure can be found in [this team compass + issue](https://github.com/jupyterhub/team-compass/issues/563). -1. Set the `__version__` variable in - [`nbgitpuller/version.py`](nbgitpuller/version.py) - and make a commit. +2. Checkout main and make sure it is up to date. ```shell - git add nbgitpuller/version.py - VERSION=... # e.g. 1.2.3 - git commit -m "release $VERSION" + git checkout main + git fetch origin main + git reset --hard origin/main ``` -1. Reset the `__version__` variable in - [`nbgitpuller/version.py`](nbgitpuller/version.py) - to an incremented patch version with a `dev` element, then make a commit. +3. Update the version, make commits, and push a git tag with `tbump`. ```shell - git add nbgitpuller/version.py - git commit -m "back to dev" + pip install tbump ``` -1. Push your two commits to main. + `tbump` will ask for confirmation before doing anything. ```shell - # first push commits without a tags to ensure the - # commits comes through, because a tag can otherwise - # be pushed all alone without company of rejected - # commits, and we want have our tagged release coupled - # with a specific commit in main - git push $ORIGIN main + # Example versions to set: 1.0.0, 1.0.0b1 + VERSION= + tbump ${VERSION} ``` -1. Create a git tag for the pushed release commit and push it. - - ```shell - git tag -a $VERSION -m $VERSION HEAD~1 + Following this, the [CI system] will build and publish a release. - # then verify you tagged the right commit - git log +4. Reset the version back to dev, e.g. `1.0.1.dev` after releasing `1.0.0`. - # then push it - git push $ORIGIN refs/tags/$VERSION + ```shell + # Example version to set: 1.0.1.dev + NEXT_VERSION= + tbump --no-tag ${NEXT_VERSION}.dev ``` -1. Following the release to PyPI, an automated PR should arrive to - [conda-forge/nbgitpuller-feedstock](https://github.com/conda-forge/nbgitpuller-feedstock), - check for the tests to succeed on this PR and then merge it to successfully - update the package for `conda` on the `conda-forge` channel. +5. Following the release to PyPI, an automated PR should arrive within 24 hours + to [conda-forge/nbgitpuller-feedstock] with instructions + on releasing to conda-forge. You are welcome to volunteer doing this, but + aren't required as part of making this release to PyPI. + +[github-activity]: https://github.com/executablebooks/github-activity +[pypi]: https://pypi.org/project/nbgitpuller/ +[conda-forge]: https://anaconda.org/conda-forge/nbgitpuller +[conda-forge/nbgitpuller-feedstock]: https://github.com/conda-forge/nbgitpuller-feedstock +[ci system]: https://github.com/jupyterhub/nbgitpuller/actions/workflows/release.yaml diff --git a/dev-requirements.txt b/dev-requirements.txt index 03baf1b9..820cbabd 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,6 @@ jupyter-packaging>=0.10 nbclassic +notebook>=5.5 +packaging pytest pytest-cov diff --git a/docs/_static/link_gen/link.js b/docs/_static/link_gen/link.js index f5e11e2d..3dd0dab7 100644 --- a/docs/_static/link_gen/link.js +++ b/docs/_static/link_gen/link.js @@ -1,5 +1,5 @@ // Pure function that generates an nbgitpuller URL -function generateRegularUrl(hubUrl, urlPath, repoUrl, branch) { +function generateRegularUrl(hubUrl, serverPath, urlPath, repoUrl, branch) { // assume hubUrl is a valid URL var url = new URL(hubUrl); @@ -17,7 +17,12 @@ function generateRegularUrl(hubUrl, urlPath, repoUrl, branch) { if (!url.pathname.endsWith('/')) { url.pathname += '/' } - url.pathname += 'hub/user-redirect/git-pull'; + + if (serverPath) { + url.pathname += 'hub/user-redirect/'+serverPath+'/git-pull'; + } else { + url.pathname += 'hub/user-redirect/git-pull'; + } return url.toString(); } @@ -160,6 +165,7 @@ function displayLink() { var contentRepoUrl = document.getElementById('content-repo').value; var contentRepoBranch = document.getElementById('content-branch').value; var filePath = document.getElementById('filepath').value; + var server = document.getElementById('server').value; var appName = form.querySelector('input[name="app"]:checked').value; var activeTab = document.querySelector(".nav-link.active").id; @@ -178,14 +184,14 @@ function displayLink() { if (activeTab === "tab-auth-default") { document.getElementById('default-link').value = generateRegularUrl( - hubUrl, urlPath, repoUrl, branch + hubUrl, server, urlPath, repoUrl, branch ); } else if (activeTab === "tab-auth-canvas"){ document.getElementById('canvas-link').value = generateCanvasUrl( hubUrl, urlPath, repoUrl, branch ); } else if (activeTab === "tab-auth-binder"){ - // FIXME: userName parsing using new URL(...) assumes a + // FIXME: userName parsing using new URL(...) assumes a // HTTP based repoUrl. Does it make sense to create a // BinderHub link for SSH URLs? Then let's fix this parsing. var userName = new URL(repoUrl).pathname.split('/')[1]; @@ -248,7 +254,7 @@ function render() { /** * Entry point */ -function main() { +function linkMain() { // Hook up any changes in form elements to call render() document.querySelectorAll('#linkgenerator input[type="radio"]').forEach( function (element) { @@ -265,16 +271,22 @@ function main() { // Activate tabs based on search parameters var params = new URL(window.location).searchParams; - if (params.get("tab")) { - if (params.get("tab") === "binder") { - $("#tab-auth-binder").click() - } else if (params.get("tab") === "canvas") { - $("#tab-auth-canvas").click() - } + switch(params.get("tab")) { + case "binder": + $("#tab-auth-binder").click(); + break; + case "canvas": + $("#tab-auth-canvas").click(); + break; } // Do an initial render, to make sure our disabled / enabled properties are correctly set render(); } -window.onload = main; +function copyLink(elementId) { + var copyText = document.getElementById(elementId); + copyText.select(); + copyText.setSelectionRange(0, copyText.value.length); + navigator.clipboard.writeText(copyText.value); +} diff --git a/docs/conf.py b/docs/conf.py index baa0be9a..c21428a1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -53,7 +53,7 @@ def setup(app): # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. diff --git a/docs/contributing.md b/docs/contributing.md index 85097105..c8acf96c 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -3,7 +3,7 @@ ## Setup nbgitpuller is a jupyter extension that works with both the -[classic Notebook Server](https://jupyter-notebook.readthedocs.io/en/stable/extending/handlers.html), +[classic Notebook Server](https://nbclassic.readthedocs.io/en/latest/extending/handlers.html), and the newer [Jupyter Server](https://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html). Hence, nbgitpuller can be developed locally without needing a JupyterHub. diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..2cec8c76 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,23 @@ +# Frequently asked questions + +## Can I automatically tell JupyterHub what kind of server to start (node size, profile name, etc) as part of my nbgitpuller link? + +You can use Kubespawner's profile_list or ProfileSpawner to allow your +end users to choose the resources (memory, cpu, GPUs, etc) they want before +starting their server. Wouldn't it be nice if this information could be +embedded in the nbgitpuller link, so this (often confusing) choice is made +for your students? + +While it would indeed be very nice, this is currently not easy for two +reasons: + +1. nbgitpuller is a Jupyter Server extension, and only runs _after_ the server + is started. It knows nothing about JupyterHub. So it can not influence the + options JupyterHub uses to start the server. +2. There is UX complexity in what happens if the user clicks an nbgitpuller + link when a server is _already_ running, but with a different set of resource + requests / profile options. Do we shut that existing one down? Just error? Do + nothing? Many valid options, but takes a bunch of work. + +So while this workflow _is_ possible, it would most likely be done at the +JupyterHub level to make it possible, rather than in nbgitpuller diff --git a/docs/index.md b/docs/index.md index 799a7bab..90013a35 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,9 +10,7 @@ It is commonly used to distribute content to multiple users of a JupyterHub, tho Here's an example of `nbgitpuller` in action: -1. The [nbgitpuller link - generator](https://jupyterhub.github.io/nbgitpuller/link) is used to create a - link. +1. The [nbgitpuller link generator](link) is used to create a link. ```{image} _static/nbgitpuller-link-generator.png @@ -71,5 +69,6 @@ contributing topic/automatic-merging topic/url-options topic/repo-best-practices +faq link ``` diff --git a/docs/link.rst b/docs/link.rst index c7516897..969caf67 100644 --- a/docs/link.rst +++ b/docs/link.rst @@ -12,42 +12,51 @@ Use the following form to create your own ``nbgitpuller`` links. .. raw:: html -
((a|b|rc)\d+)|) + \.? + (?P(?<=\.)dev\d*|) +''' + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "{new_version}" + +[[tool.tbump.file]] +src = "nbgitpuller/version.py" + +[[tool.tbump.file]] +src = "setup.py" diff --git a/setup.py b/setup.py index 3efef420..8eec22bb 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ from jupyter_packaging import wrap_installers, npm_builder from setuptools import find_packages, setup -from distutils.util import convert_path import os.path HERE = os.path.abspath(os.path.dirname(__file__)) @@ -17,28 +16,21 @@ pre_develop=jsdeps, pre_dist=jsdeps, ensured_targets=jstargets) -# Imports __version__, reference: https://stackoverflow.com/a/24517154/2220152 -ns = {} -ver_path = convert_path('nbgitpuller/version.py') -with open(ver_path) as ver_file: - exec(ver_file.read(), ns) -__version__ = ns['__version__'] - setup( name='nbgitpuller', - version=__version__, + version="1.2.2.dev", url='https://github.com/jupyterhub/nbgitpuller', license='3-clause BSD', author='Peter Veerman, YuviPanda', author_email='peterkangveerman@gmail.com', cmdclass=cmdclass, - description='Notebook Extension to do one-way synchronization of git repositories', + description='Jupyter Extension to do one-way synchronization of git repositories', long_description=open('README.md').read(), long_description_content_type='text/markdown', packages=find_packages(), include_package_data=True, platforms='any', - install_requires=['notebook>=5.5.0', 'jupyter_server>=1.10.1', 'tornado'], + install_requires=['jupyter_server>=1.10.1', 'tornado'], data_files=[ ('etc/jupyter/jupyter_server_config.d', ['nbgitpuller/etc/jupyter_server_config.d/nbgitpuller.json']), ('etc/jupyter/jupyter_notebook_config.d', ['nbgitpuller/etc/jupyter_notebook_config.d/nbgitpuller.json']) @@ -50,7 +42,7 @@ ], }, classifiers=[ - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: BSD License', 'Operating System :: POSIX', 'Operating System :: MacOS', diff --git a/tests/repohelpers.py b/tests/repohelpers.py index 2052bcf2..98bfd110 100644 --- a/tests/repohelpers.py +++ b/tests/repohelpers.py @@ -7,6 +7,7 @@ import subprocess as sp from uuid import uuid4 +from packaging.version import Version as V from nbgitpuller import GitPuller @@ -18,7 +19,14 @@ def __init__(self, path=None): def __enter__(self): os.makedirs(self.path, exist_ok=True) - self.git('init', '--bare', '--initial-branch=master') + + # --initial-branch added in git 2.28 + git_version = self.git("--version").split()[-1] + if V(git_version) >= V("2.28"): + extra_args = ('--initial-branch=master',) + else: + extra_args = () + self.git('init', '--bare', *extra_args) return self def __exit__(self, *args): diff --git a/tests/test_api.py b/tests/test_api.py index 3622bb6c..edb78170 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,9 +1,10 @@ import os from http.client import HTTPConnection import subprocess -from time import sleep -from urllib.parse import quote +import time +from urllib.parse import urlencode from uuid import uuid4 +import notebook import pytest from repohelpers import Pusher, Remote @@ -12,127 +13,172 @@ def request_api(params, host='localhost'): + query_args = {"token": "secret"} + query_args.update(params) + query = urlencode(query_args) + url = f'/git-pull/api?{query}' h = HTTPConnection(host, PORT, 10) - query = '&'.join('{}={}'.format(k, quote(v)) for (k, v) in params.items()) - url = '/git-pull/api?token=secret&{}'.format(query) h.request('GET', url) return h.getresponse() +def wait_for_server(host='localhost', port=PORT, timeout=10): + """Wait for an HTTP server to be responsive""" + t = 0.1 + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + try: + h = HTTPConnection(host, port, 10) + h.request("GET", "/") + r = h.getresponse() + except Exception as e: + print(f"Server not ready: {e}") + time.sleep(t) + t *= 2 + t = min(t, 1) + else: + # success + return + assert False, f"Server never showed up at http://{host}:{port}" -class TestNbGitPullerApi: - def setup(self): - self.jupyter_proc = None +@pytest.fixture +def jupyterdir(tmpdir): + path = tmpdir.join("jupyter") + path.mkdir() + return str(path) - def teardown(self): - if self.jupyter_proc: - self.jupyter_proc.kill() - def start_jupyter(self, jupyterdir, extraenv, backend_type): - env = os.environ.copy() - env.update(extraenv) - if "server" in backend_type: - command = [ - 'jupyter-server', - '--NotebookApp.token=secret', - '--port={}'.format(PORT), - ] - else: - command = [ - 'jupyter-notebook', - '--no-browser', - '--NotebookApp.token=secret', - '--port={}'.format(PORT), - ] - self.jupyter_proc = subprocess.Popen(command, cwd=jupyterdir, env=env) - sleep(2) - - @pytest.mark.parametrize( - "backend_type", - [ - ("jupyter-server"), - ("jupyter-notebook"), - ], - ) - def test_clone_default(self, tmpdir, backend_type): - """ - Tests use of 'repo' and 'branch' parameters. - """ - jupyterdir = str(tmpdir) - self.start_jupyter(jupyterdir, {}, backend_type) - - with Remote() as remote, Pusher(remote) as pusher: - pusher.push_file('README.md', 'Testing some content') - print(f'path: {remote.path}') - params = { - 'repo': remote.path, - 'branch': 'master', - } - r = request_api(params) - assert r.code == 200 - s = r.read().decode() - print(s) - target_path = os.path.join(jupyterdir, os.path.basename(remote.path)) - assert '--branch master' in s - assert f"Cloning into '{target_path}" in s - assert os.path.isdir(os.path.join(target_path, '.git')) - - @pytest.mark.parametrize( - "backend_type", - [ - ("jupyter-server"), - ("jupyter-notebook"), - ], - ) - def test_clone_targetpath(self, tmpdir, backend_type): - """ - Tests use of 'targetpath' parameter. - """ - jupyterdir = str(tmpdir) - target = str(uuid4()) - self.start_jupyter(jupyterdir, {}, backend_type) - with Remote() as remote, Pusher(remote) as pusher: - pusher.push_file('README.md', 'Testing some content') - params = { - 'repo': remote.path, - 'branch': 'master', - 'targetpath': target, - } - r = request_api(params) - assert r.code == 200 - s = r.read().decode() - print(s) - target_path = os.path.join(jupyterdir, target) - assert f"Cloning into '{target_path}" in s - assert os.path.isdir(os.path.join(target_path, '.git')) - - @pytest.mark.parametrize( - "backend_type", - [ - ("jupyter-server"), - ("jupyter-notebook"), - ], - ) - def test_clone_parenttargetpath(self, tmpdir, backend_type): - """ - Tests use of the NBGITPULLER_PARENTPATH environment variable. - """ - jupyterdir = str(tmpdir) - parent = str(uuid4()) - target = str(uuid4()) - self.start_jupyter(jupyterdir, {'NBGITPULLER_PARENTPATH': parent}, backend_type) - - with Remote() as remote, Pusher(remote) as pusher: - pusher.push_file('README.md', 'Testing some content') - params = { - 'repo': remote.path, - 'branch': 'master', - 'targetpath': target, - } - r = request_api(params) - assert r.code == 200 - s = r.read().decode() - print(s) - target_path = os.path.join(jupyterdir, parent, target) - assert f"Cloning into '{target_path}" in s - assert os.path.isdir(os.path.join(target_path, '.git')) +@pytest.fixture(params=["jupyter-server", "jupyter-notebook"]) +def jupyter_server(request, tmpdir, jupyterdir): + # allow passing extra_env via @pytest.mark.jupyter_server(extra_env={"key": "value"}) + if "jupyter_server" in request.keywords: + extra_env = request.keywords["jupyter_server"].kwargs.get("extra_env") + else: + extra_env = None + + backend_type = request.param + + env = os.environ.copy() + # avoid interacting with user configuration, state + env["JUPYTER_CONFIG_DIR"] = str(tmpdir / "dotjupyter") + env["JUPYTER_RUNTIME_DIR"] = str(tmpdir / "runjupyter") + + if extra_env: + env.update(extra_env) + + extension_command = ["jupyter", "server", "extension"] + if backend_type == "jupyter-server": + command = [ + 'jupyter-server', + '--ServerApp.token=secret', + '--port={}'.format(PORT), + ] + elif backend_type == "jupyter-notebook": + command = [ + 'jupyter-notebook', + '--no-browser', + '--NotebookApp.token=secret', + '--port={}'.format(PORT), + ] + # notebook <7 require "jupyter serverextension" instead of "jupyter + # server extension" + if notebook.version_info[0] < 7: + extension_command = ["jupyter", "serverextension"] + else: + raise ValueError( + f"backend_type must be 'jupyter-server' or 'jupyter-notebook' not {backend_type!r}" + ) + + # enable the extension + subprocess.check_call(extension_command + ["enable", "nbgitpuller"], env=env) + + # launch the server + jupyter_proc = subprocess.Popen(command, cwd=jupyterdir, env=env) + wait_for_server() + + with jupyter_proc: + yield jupyter_proc + jupyter_proc.terminate() + + +def test_clone_default(jupyterdir, jupyter_server): + """ + Tests use of 'repo' and 'branch' parameters. + """ + with Remote() as remote, Pusher(remote) as pusher: + pusher.push_file('README.md', 'Testing some content') + print(f'path: {remote.path}') + params = { + 'repo': remote.path, + 'branch': 'master', + } + r = request_api(params) + assert r.code == 200 + s = r.read().decode() + print(s) + target_path = os.path.join(jupyterdir, os.path.basename(remote.path)) + assert '--branch master' in s + assert f"Cloning into '{target_path}" in s + assert os.path.isdir(os.path.join(target_path, '.git')) + + +def test_clone_auth(jupyterdir, jupyter_server): + """ + Tests use of 'repo' and 'branch' parameters. + """ + with Remote() as remote, Pusher(remote) as pusher: + pusher.push_file('README.md', 'Testing some content') + print(f'path: {remote.path}') + params = { + 'repo': remote.path, + 'branch': 'master', + 'token': 'wrong', + } + r = request_api(params) + # no token, redirect to login + assert r.code == 403 + + +def test_clone_targetpath(jupyterdir, jupyter_server): + """ + Tests use of 'targetpath' parameter. + """ + target = str(uuid4()) + with Remote() as remote, Pusher(remote) as pusher: + pusher.push_file('README.md', 'Testing some content') + params = { + 'repo': remote.path, + 'branch': 'master', + 'targetpath': target, + } + r = request_api(params) + assert r.code == 200 + s = r.read().decode() + print(s) + target_path = os.path.join(jupyterdir, target) + assert f"Cloning into '{target_path}" in s + assert os.path.isdir(os.path.join(target_path, '.git')) + + +@pytest.mark.jupyter_server(extra_env={'NBGITPULLER_PARENTPATH': "parent"}) +def test_clone_parenttargetpath(jupyterdir, jupyter_server): + """ + Tests use of the NBGITPULLER_PARENTPATH environment variable. + """ + parent = "parent" + target = str(uuid4()) + + with Remote() as remote, Pusher(remote) as pusher: + pusher.push_file('README.md', 'Testing some content') + params = { + 'repo': remote.path, + 'branch': 'master', + 'targetpath': target, + } + r = request_api(params) + assert r.code == 200 + s = r.read().decode() + print(s) + target_path = os.path.join(jupyterdir, parent, target) + assert f"Cloning into '{target_path}" in s + assert os.path.isdir(os.path.join(target_path, '.git')) diff --git a/tests/test_gitpuller.py b/tests/test_gitpuller.py index b4d742aa..02f7c2cc 100644 --- a/tests/test_gitpuller.py +++ b/tests/test_gitpuller.py @@ -88,13 +88,11 @@ def test_exception_branch_exists(): with Remote() as remote, Pusher(remote) as pusher: pusher.push_file('README.md', '1') with Puller(remote) as puller: - orig_url = puller.gp.git_url - try: + with pytest.raises(sp.CalledProcessError): + orig_url = puller.gp.git_url + puller.gp.git_url = "" puller.gp.branch_exists("wrong") - except Exception as e: - assert type(e) == ValueError - puller.gp.git_url = orig_url - + puller.gp.git_url = orig_url def test_resolve_default_branch(): with Remote() as remote, Pusher(remote) as pusher: