Skip to content

Instantly share code, notes, and snippets.

@slhck
Last active June 18, 2025 11:31
Show Gist options
  • Select an option

  • Save slhck/362b234b85b41c42681c937e912fb113 to your computer and use it in GitHub Desktop.

Select an option

Save slhck/362b234b85b41c42681c937e912fb113 to your computer and use it in GitHub Desktop.

Revisions

  1. slhck revised this gist Jun 18, 2025. 1 changed file with 24 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions release.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,30 @@
    #!/usr/bin/env bash
    #
    # Release the project and bump version number in the process.
    #
    # To set up the project, make sure you have in pyproject.toml:
    #
    # [project]
    # name = "foo-bar"
    # version = "2.10.0"
    # ...
    # [project.scripts]
    # foo_bar = "foo_bar.__main__:main"
    # # make uv build the project before running
    # [build-system]
    # requires = ["uv_build>=0.7.13,<0.8.0"]
    # build-backend = "uv_build"
    #
    # # set the module path to the root of the project instead of "src" (default)
    # [tool.uv.build-backend]
    # module-name = "foo_bar"
    # module-root = ""
    #
    # And in `foo_bar/__init__.py`:
    #
    # from importlib.metadata import version
    #
    # __version__ = version("foo-bar")

    set -e

  2. slhck created this gist Jun 18, 2025.
    97 changes: 97 additions & 0 deletions release.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,97 @@
    #!/usr/bin/env bash
    #
    # Release the project and bump version number in the process.

    set -e

    cd "$(dirname "$0")"

    FORCE=false

    usage() {
    echo "Usage: $0 [options] VERSION"
    echo
    echo "VERSION:"
    echo " major: bump major version number"
    echo " minor: bump minor version number"
    echo " patch: bump patch version number"
    echo
    echo "Options:"
    echo " -f, --force: force release"
    echo " -h, --help: show this help message"
    exit 1
    }

    # parse args
    while [ "$#" -gt 0 ]; do
    case "$1" in
    -f | --force)
    FORCE=true
    shift
    ;;
    -h | --help)
    usage
    ;;
    *)
    break
    ;;
    esac
    done

    # check if version is specified
    if [ "$#" -ne 1 ]; then
    usage
    fi

    if [ "$1" != "major" ] && [ "$1" != "minor" ] && [ "$1" != "patch" ]; then
    usage
    fi

    # check if git is clean and force is not enabled
    if ! git diff-index --quiet HEAD -- && [ "$FORCE" = false ]; then
    echo "Error: git is not clean. Please commit all changes first."
    exit 1
    fi

    if ! command -v uv &> /dev/null; then
    echo "Error: uv is not installed. Please install uv from https://docs.astral.sh/uv/"
    exit 1
    fi

    echo "Would bump version:"
    uv version --bump "$1" --dry-run

    # prompt for confirmation
    if [ "$FORCE" = false ]; then
    read -p "Do you want to release? [yY] " -n 1 -r
    echo
    else
    REPLY="y"
    fi
    echo

    if [[ $REPLY =~ ^[Yy]$ ]]; then
    # replace version number
    uv version --bump "$1"

    new_version=$(uv version --short)

    # commit changes
    git add pyproject.toml uv.lock
    git commit -m "bump version to $new_version"
    git tag -a "v$new_version" -m "v$new_version"

    # generate changelog
    uvx --with pystache gitchangelog > CHANGELOG.md

    git add CHANGELOG.md
    git commit --no-verify --amend --no-edit
    git tag -a -f -m "v$new_version" "v$new_version"

    # push changes
    git push origin master
    git push origin "v$new_version"
    else
    echo "Aborted."
    exit 1
    fi