From 7256971869e344a7929ce81041c960217041a4bc Mon Sep 17 00:00:00 2001 From: Phillip Cloud <417981+cpcloud@users.noreply.github.com> Date: Thu, 30 Dec 2021 17:58:52 -0500 Subject: [PATCH] ci: setup automatic releases --- .github/workflows/ibis-main.yml | 33 ++++++++------------------ .github/workflows/release.yml | 41 +++++++++++++++++++++++++++++++++ .releaserc.json | 36 +++++++++++++++++++++++++++++ ci/release/dry_run.sh | 40 ++++++++++++++++++++++++++++++++ ci/release/prepare.sh | 11 +++++++++ ci/release/publish.sh | 7 ++++++ ci/release/run.sh | 15 ++++++++++++ ci/release/verify.sh | 15 ++++++++++++ docs/web/release_notes.md | 2 -- pre-commit.nix | 3 ++- pyproject.toml | 8 +++---- 11 files changed, 181 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .releaserc.json create mode 100755 ci/release/dry_run.sh create mode 100755 ci/release/prepare.sh create mode 100755 ci/release/publish.sh create mode 100755 ci/release/run.sh create mode 100755 ci/release/verify.sh diff --git a/.github/workflows/ibis-main.yml b/.github/workflows/ibis-main.yml index 363b7156eb074..475caf74bfaf8 100644 --- a/.github/workflows/ibis-main.yml +++ b/.github/workflows/ibis-main.yml @@ -328,33 +328,20 @@ jobs: simulate_release: runs-on: ubuntu-latest - needs: - - nix - - lint - - test_no_backends - - benchmarks - - docs - - conda_package steps: - - name: checkout - uses: actions/checkout@v2 + - uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Configure git info - run: | - set -euo pipefail - - git config --global user.name 'ibis-project-bot[bot]' - git config --global user.email 'ibis-project-bot[bot]@users.noreply.github.com' - - - name: setup python - uses: actions/setup-python@v2 + - uses: cachix/install-nix-action@v16 with: - python-version: "3.x" + nix_path: nixpkgs=channel:nixos-unstable-small - - name: install poetry and semantic-release - run: python -m pip install poetry python-semantic-release + - uses: cachix/cachix-action@v10 + with: + name: ibis + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + extraPullNames: nix-community,poetry2nix - - name: semantic release - run: semantic-release publish --noop --verbosity=DEBUG + - name: run semantic-release + run: ./ci/release/dry_run.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000..0d45d08373611 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: Release + +on: + workflow_dispatch: + +# we do not want more than one release workflow executing at the same time, ever +concurrency: + group: release + # cancelling in the middle of a release would create incomplete releases + # so cancel-in-progress is false + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: tibdex/github-app-token@v1 + id: generate_token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + token: ${{ steps.generate_token.outputs.token }} + + - uses: cachix/install-nix-action@v16 + with: + nix_path: nixpkgs=channel:nixos-unstable-small + + - uses: cachix/cachix-action@v10 + with: + name: ibis + extraPullNames: nix-community,poetry2nix + + - name: run semantic-release + run: ./ci/release/run.sh + env: + POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000000000..0d90674a81d4b --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,36 @@ +{ + "branches": ["master"], + "tagFormat": "${version}", + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/changelog", + { + "changelogTitle": "# Release Notes", + "changelogFile": "docs/web/release_notes.md" + } + ], + [ + "@semantic-release/exec", + { + "verifyConditionsCmd": "ci/release/verify.sh", + "prepareCmd": "ci/release/prepare.sh ${nextRelease.version}", + "publishCmd": "ci/release/publish.sh" + } + ], + [ + "@semantic-release/github", + { + "assets": ["dist/*.whl"] + } + ], + [ + "@semantic-release/git", + { + "assets": ["pyproject.toml", "docs/web/release_notes.md"], + "message": "chore(release): ${nextRelease.version}" + } + ] + ] +} diff --git a/ci/release/dry_run.sh b/ci/release/dry_run.sh new file mode 100755 index 0000000000000..a6acf01be53e7 --- /dev/null +++ b/ci/release/dry_run.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env nix-shell +#!nix-shell -I nixpkgs=channel:nixos-unstable-small --pure -p git nodejs nix -i bash +# shellcheck shell=bash + +set -euo pipefail + +curdir="$PWD" +worktree="$(mktemp -d)" +branch="$(basename "$worktree")" + +git worktree add "$worktree" + +function cleanup() { + cd "$curdir" || exit 1 + git worktree remove "$worktree" + git worktree prune + git branch -D "$branch" +} + +trap cleanup EXIT ERR + +cd "$worktree" || exit 1 + +npx --yes \ + -p semantic-release \ + -p "@semantic-release/commit-analyzer" \ + -p "@semantic-release/release-notes-generator" \ + -p "@semantic-release/changelog" \ + -p "@semantic-release/exec" \ + -p "@semantic-release/git" \ + semantic-release \ + --ci \ + --dry-run \ + --plugins \ + --analyze-commits "@semantic-release/commit-analyzer" \ + --generate-notes "@semantic-release/release-notes-generator" \ + --verify-conditions "@semantic-release/changelog,@semantic-release/exec,@semantic-release/git" \ + --prepare "@semantic-release/changelog,@semantic-release/exec" \ + --branches "$branch" \ + --repository-url "file://$PWD" diff --git a/ci/release/prepare.sh b/ci/release/prepare.sh new file mode 100755 index 0000000000000..dd942c8ceee3b --- /dev/null +++ b/ci/release/prepare.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env nix-shell +#!nix-shell --pure -p poetry -i bash +# shellcheck shell=bash + +set -euo pipefail + +# set version +poetry version "$1" + +# build artifacts +poetry build diff --git a/ci/release/publish.sh b/ci/release/publish.sh new file mode 100755 index 0000000000000..225197ce1966d --- /dev/null +++ b/ci/release/publish.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env nix-shell +#!nix-shell --pure --keep POETRY_PYPI_TOKEN_PYPI -p poetry -i bash +# shellcheck shell=bash + +set -euo pipefail + +poetry publish diff --git a/ci/release/run.sh b/ci/release/run.sh new file mode 100755 index 0000000000000..b404eac733712 --- /dev/null +++ b/ci/release/run.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p cacert poetry git nodejs nix -i bash +# shellcheck shell=bash + +set -euo pipefail + +npx --yes \ + -p semantic-release \ + -p "@semantic-release/commit-analyzer" \ + -p "@semantic-release/release-notes-generator" \ + -p "@semantic-release/changelog" \ + -p "@semantic-release/github" \ + -p "@semantic-release/exec" \ + -p "@semantic-release/git" \ + semantic-release --ci diff --git a/ci/release/verify.sh b/ci/release/verify.sh new file mode 100755 index 0000000000000..82fb86350072d --- /dev/null +++ b/ci/release/verify.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env nix-shell +#!nix-shell --pure --keep POETRY_PYPI_TOKEN_PYPI -p poetry -p git -i bash +# shellcheck shell=bash + +set -euo pipefail + +# verify TOML is sane +poetry check + +# verify that the lock file is up to date +poetry lock --no-update +git diff --exit-code poetry.lock + +# verify that we have a token available to push to pypi using set -u +: "${POETRY_PYPI_TOKEN_PYPI}" diff --git a/docs/web/release_notes.md b/docs/web/release_notes.md index cbe5a9f1e0080..38bf0d779f19c 100644 --- a/docs/web/release_notes.md +++ b/docs/web/release_notes.md @@ -1,3 +1 @@ # Release Notes - - diff --git a/pre-commit.nix b/pre-commit.nix index 5b57a34d6b88e..32f8626d6ae2c 100644 --- a/pre-commit.nix +++ b/pre-commit.nix @@ -47,13 +47,14 @@ in enable = true; entry = lib.mkForce "shellcheck"; files = "\\.sh$"; - types_or = lib.mkForce [ ]; + types_or = [ "file" ]; }; shfmt = { enable = true; entry = lib.mkForce "shfmt -i 2 -sr -d -s -l"; files = "\\.sh$"; + types_or = [ "file" ]; }; pyupgrade = { diff --git a/pyproject.toml b/pyproject.toml index 66560dd473827..7535b88e2a461 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -135,15 +135,15 @@ sqlite = "ibis.backends.sqlite" [tool.semantic_release] version_toml = "pyproject.toml:tool.poetry.version" version_variable = [ - "ibis/__init__.py:__version__", "docs/source/conf.py:version" ] branch = "master" -upload_to_pypi = false -upload_to_release = false +tag_format = "{version}" +upload_to_pypi = true +upload_to_release = true build_command = "poetry build" commit_subject = "chore(release): {version}" -commit_author = "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" +commit_author = "ibis-project-bot[bot] " changelog_file = "docs/web/release_notes.md" [tool.pytest.ini_options]