From a3501f0b7d4d5885996dc7e271f0501bfe40e5f9 Mon Sep 17 00:00:00 2001 From: David Brochart Date: Thu, 14 Oct 2021 17:41:16 +0200 Subject: [PATCH] Prepare for Jupyter Releaser --- .github/workflows/check-release.yml | 80 +++++++++++++++++ docs/source/changelog.md => CHANGELOG.md | 3 + README.md | 2 +- docs/source/conf.py | 8 ++ package.json | 8 +- packages/base-manager/package.json | 1 - packages/base/package.json | 1 - packages/controls/package.json | 1 - packages/html-manager/package.json | 1 - packages/output/package.json | 1 - python/ipywidgets/pyproject.toml | 30 ++++++- python/jupyterlab_widgets/package.json | 1 - python/jupyterlab_widgets/pyproject.toml | 17 ++++ python/widgetsnbextension/package.json | 1 - python/widgetsnbextension/pyproject.toml | 17 ++++ scripts/bump-version.py | 110 +++++++++++++++++++++++ 16 files changed, 268 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/check-release.yml rename docs/source/changelog.md => CHANGELOG.md (99%) create mode 100644 scripts/bump-version.py diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml new file mode 100644 index 0000000000..5917aff2c8 --- /dev/null +++ b/.github/workflows/check-release.yml @@ -0,0 +1,80 @@ +name: Check Release +on: + push: + branches: ["master"] + pull_request: + branches: ["*"] + +permissions: + contents: write + +jobs: + check_release: + timeout-minutes: 720 + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + group: [check_release, link_check] + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + architecture: "x64" + - name: Install node + uses: actions/setup-node@v2 + with: + node-version: "14.x" + # Cache yarn + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Cache yarn + uses: actions/cache@v2 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + - name: Cache pip + uses: actions/cache@v1 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }} + restore-keys: | + ${{ runner.os }}-pip- + ${{ runner.os }}-pip- + - name: Cache checked links + if: ${{ matrix.group == 'link_check' }} + uses: actions/cache@v2 + with: + path: ~/.cache/pytest-link-check + key: ${{ runner.os }}-linkcheck-${{ hashFiles('**/*.md', '**/*.rst') }}-md-links + restore-keys: | + ${{ runner.os }}-linkcheck- + - name: Upgrade packaging dependencies + run: | + pip install --upgrade pip setuptools wheel --user + - name: Check Release + if: ${{ matrix.group == 'check_release' }} + uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + env: + RH_VERSION_SPEC: next + - name: Check Links + if: ${{ matrix.group == 'link_check' }} + uses: jupyter-server/jupyter_releaser/.github/actions/check-links@v1 + - name: Upload Distributions + uses: actions/upload-artifact@v2 + with: + name: ipywidgets-jupyter-releaser-dist-${{ github.run_number }} + path: .jupyter_releaser_checkout/dist diff --git a/docs/source/changelog.md b/CHANGELOG.md similarity index 99% rename from docs/source/changelog.md rename to CHANGELOG.md index 2f77b6ed20..a564b95b37 100644 --- a/docs/source/changelog.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ A summary of changes in ipywidgets. For more detailed information, see the issues and pull requests for the appropriate milestone on [GitHub](https://github.com/jupyter-widgets/ipywidgets). + + ## [8.0](https://github.com/jupyter-widgets/ipywidgets/releases/tag/v8.0) (not released yet) See the [ipywidgets @@ -58,6 +60,7 @@ milestone on GitHub for the full list of pull requests and issues closed. * Removed deprecated signature of the `register` decorator ([#2695](https://github.com/jupyter-widgets/ipywidgets/pull/2695)) * Remove deprecated `handle_kernel` alias ([#2694](https://github.com/jupyter-widgets/ipywidgets/pull/2694)) + ## 7.6 diff --git a/README.md b/README.md index 70c83c7e96..820029ad60 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ See the [examples](docs/source/examples.md) section of the documentation. The wi ## Change log -[Change log](docs/source/changelog.md) +[Change log](CHANGELOG.md) ### Version Compatibility with Front-End Clients diff --git a/docs/source/conf.py b/docs/source/conf.py index 36860b13fb..5b0006fc72 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 # +import os.path as osp +import shutil # -- source files and parsers ----------------------------------- @@ -135,3 +137,9 @@ 'includehidden': True, 'titles_only': False } + + +def setup(app): + HERE = osp.abspath(osp.dirname(__file__)) + dest = osp.join(HERE, 'changelog.md') + shutil.copy(osp.join(HERE, '..', '..', 'CHANGELOG.md'), dest) diff --git a/package.json b/package.json index d0dd9b350b..171ff3e349 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,6 @@ { + "name": "@jupyter-widgets/root", + "version": "0.1.0", "private": true, "workspaces": [ "packages/*", @@ -19,11 +21,7 @@ "lint:check": "yarn run prettier:check && yarn run eslint:check", "prettier": "prettier --ignore-path .gitignore --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\"", "prettier:check": "prettier --ignore-path .gitignore --check \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\"", - "publish": "yarn run clean && yarn run build && lerna publish --pre-dist-tag next from-git", - "sort-package-json": "lerna exec --parallel sort-package-json && sort-package-json", - "update-dependency": "update-dependency --lerna", - "updated": "lerna updated", - "version": "yarn run clean && yarn run build && lerna version --no-push -m \"Bump version\" " + "sort-package-json": "lerna exec --parallel sort-package-json && sort-package-json" }, "husky": { "hooks": { diff --git a/packages/base-manager/package.json b/packages/base-manager/package.json index b7e894e8a2..5daee2f31a 100644 --- a/packages/base-manager/package.json +++ b/packages/base-manager/package.json @@ -21,7 +21,6 @@ "build:test": "tsc --build test && webpack --config test/webpack.conf.js", "clean": "npm run clean:src", "clean:src": "rimraf lib && rimraf tsconfig.tsbuildinfo", - "prepublish": "npm run clean && npm run build", "test": "npm run test:unit", "test:coverage": "npm run build:test && webpack --config test/webpack-cov.conf.js && karma start test/karma-cov.conf.js", "test:unit": "npm run test:unit:firefox && npm run test:unit:chrome", diff --git a/packages/base/package.json b/packages/base/package.json index ce7f448897..ba12a5e455 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -21,7 +21,6 @@ "build:test": "tsc --build test && webpack --config test/webpack.conf.js", "clean": "npm run clean:src", "clean:src": "rimraf lib && rimraf tsconfig.tsbuildinfo", - "prepublish": "npm run clean && npm run build", "test": "npm run test:unit", "test:coverage": "npm run build:test && webpack --config test/webpack-cov.conf.js && karma start test/karma-cov.conf.js", "test:unit": "npm run test:unit:firefox && npm run test:unit:chrome", diff --git a/packages/controls/package.json b/packages/controls/package.json index 3b622d9e0e..b8b428194f 100644 --- a/packages/controls/package.json +++ b/packages/controls/package.json @@ -23,7 +23,6 @@ "build:test": "tsc --build test && webpack --config test/webpack.conf.js", "clean": "npm run clean:src", "clean:src": "rimraf lib && rimraf tsconfig.tsbuildinfo", - "prepublish": "npm run clean && npm run build", "test": "npm run test:unit", "test:coverage": "npm run build:test && webpack --config test/webpack-cov.conf.js && karma start test/karma-cov.conf.js", "test:unit": "npm run test:unit:firefox && npm run test:unit:chrome", diff --git a/packages/html-manager/package.json b/packages/html-manager/package.json index 3af8bd6616..796da62ec6 100644 --- a/packages/html-manager/package.json +++ b/packages/html-manager/package.json @@ -26,7 +26,6 @@ "build:src": "tsc --build", "build:test": "tsc --build test && webpack --config test/webpack.conf.js", "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo && rimraf dist", - "prepublish": "npm run clean && npm run build", "test": "npm run test:unit", "test:unit": "npm run test:unit:firefox && npm run test:unit:chrome", "test:unit:chrome": "npm run test:unit:default -- --browsers=Chrome", diff --git a/packages/output/package.json b/packages/output/package.json index 6ed590dfdf..4567be4141 100644 --- a/packages/output/package.json +++ b/packages/output/package.json @@ -21,7 +21,6 @@ "build": "npm run build:src", "build:src": "tsc --build", "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo", - "prepublish": "npm run clean && npm run build", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { diff --git a/python/ipywidgets/pyproject.toml b/python/ipywidgets/pyproject.toml index 88a94d6b91..27d0692c1d 100644 --- a/python/ipywidgets/pyproject.toml +++ b/python/ipywidgets/pyproject.toml @@ -2,4 +2,32 @@ # These are the assumed default build requirements from pip: # https://pip.pypa.io/en/stable/reference/pip/#pep-517-and-518-support requires = ["setuptools>=40.8.0", "wheel"] -build-backend = "setuptools.build_meta" \ No newline at end of file +build-backend = "setuptools.build_meta" + +[tool.check-manifest] +ignore = [".*"] + +[tool.tbump.version] +current = "8.0.0a6" +regex = ''' + (?P\d+)\.(?P\d+)\.(?P\d+) + ((?Pa|b|rc|.dev)(?P\d+))? +''' + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "v{new_version}" + +[[tool.tbump.file]] +src = "ipywidgets/_version.py" + +[tool.jupyter-releaser] +skip = ["check-links", "check-manifest"] + +[tool.jupyter-releaser.hooks] +before-prep-git = ["python -m pip install -U jupyterlab~=3.0"] +before-bump-version = ["python -m pip install bump2version", "yarn"] + +[tool.jupyter-releaser.options] +version-cmd = "python scripts/bump-version.py --force" +python_packages = [".", "jupyterlab_widgets", "widgetsnbextension"] diff --git a/python/jupyterlab_widgets/package.json b/python/jupyterlab_widgets/package.json index efd7e33d76..80176b368b 100644 --- a/python/jupyterlab_widgets/package.json +++ b/python/jupyterlab_widgets/package.json @@ -42,7 +42,6 @@ "eslint": "eslint . --ext .ts,.tsx --fix", "eslint:check": "eslint . --ext .ts,.tsx", "install:extension": "jlpm run build", - "prepare": "jlpm run clean && jlpm run build:prod", "watch": "run-p watch:src watch:labextension", "watch:labextension": "jupyter labextension watch .", "watch:src": "tsc -w" diff --git a/python/jupyterlab_widgets/pyproject.toml b/python/jupyterlab_widgets/pyproject.toml index 4a8da22eb7..f6fc636f09 100644 --- a/python/jupyterlab_widgets/pyproject.toml +++ b/python/jupyterlab_widgets/pyproject.toml @@ -15,3 +15,20 @@ npm = ["jlpm"] [tool.check-manifest] ignore = ["jupyterlab_widgets/labextension/**", "yarn.lock", ".*", "package-lock.json"] + +[tool.tbump.version] +current = "2.0.0a3" +regex = ''' + (?P\d+)\.(?P\d+)\.(?P\d+) + ((?Pa|b|rc|.dev)(?P\d+))? +''' + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "v{new_version}" + +[[tool.tbump.file]] +src = "jupyterlab_widgets/_version.py" + +[tool.jupyter-releaser] +skip = ["check-links"] diff --git a/python/widgetsnbextension/package.json b/python/widgetsnbextension/package.json index 609d0e3eb8..5ecda1e39f 100644 --- a/python/widgetsnbextension/package.json +++ b/python/widgetsnbextension/package.json @@ -17,7 +17,6 @@ "scripts": { "build": "webpack", "clean": "rimraf widgetsnbextension/static", - "prepublish": "npm run clean && npm run build", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { diff --git a/python/widgetsnbextension/pyproject.toml b/python/widgetsnbextension/pyproject.toml index b289136f7e..6bad3cd9d9 100644 --- a/python/widgetsnbextension/pyproject.toml +++ b/python/widgetsnbextension/pyproject.toml @@ -16,3 +16,20 @@ npm = ["yarn"] [tool.check-manifest] ignore = ["widgetnbextension/static/**", "yarn.lock", ".*", "package-lock.json"] + +[tool.tbump.version] +current = "4.0.0a4" +regex = ''' + (?P\d+)\.(?P\d+)\.(?P\d+) + ((?Pa|b|rc|.dev)(?P\d+))? +''' + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "v{new_version}" + +[[tool.tbump.file]] +src = "widgetsnbextension/_version.py" + +[tool.jupyter-releaser] +skip = ["check-links"] diff --git a/scripts/bump-version.py b/scripts/bump-version.py new file mode 100644 index 0000000000..0dd39df714 --- /dev/null +++ b/scripts/bump-version.py @@ -0,0 +1,110 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License.import click + +# Heavily inspired by: +# - https://github.com/jupyterlab/jupyterlab/blob/master/buildutils/src/bumpversion.ts +# - https://github.com/jupyterlab/retrolab/blob/main/buildutils/src/release-bump.ts + +import click +from jupyter_releaser.util import is_prerelease, get_version, run + + +OPTIONS = ["major", "minor", "release", "build"] + + +def patch(force=False): + version = get_version() + if is_prerelease(version): + raise Exception("Can only make a patch release from a final version") + + run("bumpversion patch", quiet=True) + # switches to alpha + run("bumpversion release --allow-dirty", quiet=True) + # switches to beta + run("bumpversion release --allow-dirty", quiet=True) + # switches to rc. + run("bumpversion release --allow-dirty", quiet=True) + # switches to final. + + # Version the changed + cmd = "yarn run lerna version patch --no-push --force-publish --no-git-tag-version" + if force: + cmd += " --yes" + run(cmd) + + +def update(spec, force=False): + prev = get_version() + + # Make sure we have a valid version spec. + if spec not in OPTIONS: + raise Exception(f"Version spec must be one of: {OPTIONS}") + + is_final = not is_prerelease(prev) + + if is_final and spec == "release": + raise Exception('Use "major" or "minor" to switch back to alpha release') + + if is_final and spec == "build": + raise Exception("Cannot increment a build on a final release") + + # If this is a major release during the alpha cycle, bump + # just the Python version. + if "a" in prev and spec == "major": + run(f"bumpversion {spec}") + return + + # Determine the version spec to use for yarn. + version = "preminor" + if spec == "build": + version = "prerelease" + # a -> b + elif spec == "release" and "a" in prev: + version = "prerelease --preid beta" + # b -> rc + elif spec == "release" and "b" in prev: + version = "prerelease --preid rc" + # rc -> final + elif spec == "release" and "c" in prev: + version = "patch" + if version == "preminor": + version += " --preid alpha" + + cmd = f"yarn run lerna version --no-push --force-publish --no-git-tag-version {version}" + if force: + cmd += " --yes" + + # For a preminor release, we bump 10 minor versions so that we do + # not conflict with versions during minor releases of the top level package. + if version == "preminor": + for i in range(10): + run(cmd) + else: + run(cmd) + + # Bump the version. + run(f"bumpversion {spec} --allow-dirty") + + +@click.command() +@click.option("--force", default=False, is_flag=True) +@click.argument("spec", nargs=1) +def bump(force, spec): + status = run("git status --porcelain").strip() + if len(status) > 0: + raise Exception("Must be in a clean git state with no untracked files") + + prev = get_version() + is_final = not is_prerelease(prev) + if spec == "next": + spec = "patch" if is_final else "build" + + if spec == "patch": + patch(force) + return + + update(spec, force) + + +if __name__ == "__main__": + bump()