diff --git a/.gitattributes b/.gitattributes index 6d2618f2f..3f3d2f050 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ test/fixtures/* eol=lf -init-tests-after-clone.sh +*.sh eol=lf +/Makefile eol=lf diff --git a/.gitignore b/.gitignore index 72da84eee..0bd307639 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.py[co] *.swp *~ +.env/ +env/ .venv/ venv/ /*.egg-info diff --git a/Makefile b/Makefile index 389337d08..38090244c 100644 --- a/Makefile +++ b/Makefile @@ -7,16 +7,10 @@ clean: rm -rf build/ dist/ .eggs/ .tox/ release: clean - # Check if latest tag is the current head we're releasing - echo "Latest tag = $$(git tag | sort -nr | head -n1)" - echo "HEAD SHA = $$(git rev-parse head)" - echo "Latest tag SHA = $$(git tag | sort -nr | head -n1 | xargs git rev-parse)" - @test "$$(git rev-parse head)" = "$$(git tag | sort -nr | head -n1 | xargs git rev-parse)" + ./check-version.sh make force_release force_release: clean - # IF we're in a virtual environment, add build tools - test -z "$$VIRTUAL_ENV" || pip install -U build twine - python3 -m build --sdist --wheel || echo "Use a virtual-env with 'python -m venv env && source env/bin/activate' instead" + ./build-release.sh twine upload dist/* git push --tags origin main diff --git a/build-release.sh b/build-release.sh new file mode 100755 index 000000000..5840e4472 --- /dev/null +++ b/build-release.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# This script builds a release. If run in a venv, it auto-installs its tools. +# You may want to run "make release" instead of running this script directly. + +set -eEu + +function release_with() { + $1 -m build --sdist --wheel +} + +if test -n "${VIRTUAL_ENV:-}"; then + deps=(build twine) # Install twine along with build, as we need it later. + echo "Virtual environment detected. Adding packages: ${deps[*]}" + pip install --quiet --upgrade "${deps[@]}" + echo 'Starting the build.' + release_with python +else + function suggest_venv() { + venv_cmd='python -m venv env && source env/bin/activate' + printf "HELP: To avoid this error, use a virtual-env with '%s' instead.\n" "$venv_cmd" + } + trap suggest_venv ERR # This keeps the original exit (error) code. + echo 'Starting the build.' + release_with python3 # Outside a venv, use python3. +fi diff --git a/check-version.sh b/check-version.sh new file mode 100755 index 000000000..6d10d6785 --- /dev/null +++ b/check-version.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# +# This script checks if we are in a consistent state to build a new release. +# See the release instructions in README.md for the steps to make this pass. +# You may want to run "make release" instead of running this script directly. + +set -eEfuo pipefail +trap 'echo "$0: Check failed. Stopping." >&2' ERR + +readonly version_path='VERSION' +readonly changes_path='doc/source/changes.rst' + +echo 'Checking current directory.' +test "$(cd -- "$(dirname -- "$0")" && pwd)" = "$(pwd)" # Ugly, but portable. + +echo "Checking that $version_path and $changes_path exist and have no uncommitted changes." +test -f "$version_path" +test -f "$changes_path" +git status -s -- "$version_path" "$changes_path" +test -z "$(git status -s -- "$version_path" "$changes_path")" + +# This section can be commented out, if absolutely necessary. +echo 'Checking that ALL changes are committed.' +git status -s --ignore-submodules +test -z "$(git status -s --ignore-submodules)" + +version_version="$(cat "$version_path")" +changes_version="$(awk '/^[0-9]/ {print $0; exit}' "$changes_path")" +config_opts="$(printf ' -c versionsort.suffix=-%s' alpha beta pre rc RC)" +latest_tag="$(git $config_opts tag -l '[0-9]*' --sort=-v:refname | head -n1)" +head_sha="$(git rev-parse HEAD)" +latest_tag_sha="$(git rev-parse "$latest_tag")" + +# Display a table of all the current version, tag, and HEAD commit information. +echo $'\nThe VERSION must be the same in all locations, and so must the HEAD and tag SHA' +printf '%-14s = %s\n' 'VERSION file' "$version_version" \ + 'changes.rst' "$changes_version" \ + 'Latest tag' "$latest_tag" \ + 'HEAD SHA' "$head_sha" \ + 'Latest tag SHA' "$latest_tag_sha" + +# Check that the latest tag and current version match the HEAD we're releasing. +test "$version_version" = "$changes_version" +test "$latest_tag" = "$version_version" +test "$head_sha" = "$latest_tag_sha" +echo 'OK, everything looks good.'