Skip to content

[ARCHIVE] Release MOP

Joris Roovers edited this page Feb 24, 2023 · 1 revision

Start by quickly reviewing this page so that you are aware of all steps. This whole process takes about an hour.

Prepare the code for release

  1. Do basic Manual testing on Windows!
  2. Check that you've included the latest CLI output in the documentation homepage
  3. Update the CHANGELOG.md
  4. Check if the long_description in setup.py requires updating
  5. Bump the version number in gitlint-core/gitlint/__init__.py, run gitlint --version and check the version.
  6. Bump the version number in setup.py
  7. Make sure your ~/.pypirc file looks like this:
[distutils]
index-servers =
   pypi
   pypitest

[pypi]
# No 'repository' key required here, only for pypitest
# Make sure you have the right password (if you see 403 error, check passwd manager again :-) )
username=xxx
password=xxx

[pypitest]
repository=https://test.pypi.org/legacy/
username=xxx
password=xxx

Final round of pre-release testing

Code Tests

  1. On your host machine, make sure to reinstall your virtualenv and install gitlint in develop mode:

    deactivate && rm -rf .venv && virtualenv .venv && source .venv/bin/activate && pip install -e "gitlint-core[trusted-deps]" . && pip install -r test-requirements.txt && pip install -r doc-requirements.txt
  2. Run tests

    ./run_tests.sh -a

Doc tests

  1. Check if docs build

    mkdocs build

Manual Build tests

  1. remove any previous builds
    ./run_tests.sh --clean
  2. Check whether the builds work
    # gitlint-core
    pushd gitlint-core && python setup.py sdist bdist_wheel && popd
    # gitlint
    python setup.py sdist bdist_wheel
  3. Now extract the source distributions in dist/ and gitlint-core/dist/ and check whether they contains all files

Dry Run

Test upload to test.pypi.org

Decent info on how to upload to pypitest https://packaging.python.org/guides/using-testpypi/

gitlint-core

# remove any previous builds
./run_tests.sh --clean
# Do a rebuild
cd gitlint-core
python setup.py sdist bdist_wheel
# Upload to pypitest 
twine upload -r pypitest dist/*

gitlint

# Make sure you're at the top-level gitlint directory
cd ..
# remove any previous builds
./run_tests.sh --clean
# Do a rebuild
python setup.py sdist bdist_wheel
# Upload to pypitest 
twine upload -r pypitest dist/*

Check if package is properly uploaded and documentation looks good at:

Test installation of test package

# Set release variable for the next steps
export RELEASE_VERSION=`python -c "import gitlint; print(gitlint.__version__)"`; export GITLINT_DIR=`pwd`; export GITLINT_TEST_DIR="/tmp/release-test-$RELEASE_VERSION"
echo -e "RELEASE_VERSION: $RELEASE_VERSION\nGITLINT_DIR: $GITLINT_DIR\nGITLINT_TEST_DIR: $GITLINT_TEST_DIR"

deactivate # deactivate current virtualenv

# Create virtualenv to test the release
mkdir $GITLINT_TEST_DIR && cd $GITLINT_TEST_DIR
# Python 3.8:
virtualenv -p /usr/bin/python3.8 .venv38 && source .venv38/bin/activate

# Install (make sure the virtualenv of the new release is active)
gitlint # should not work
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple gitlint
pip freeze 

# Do some basic manual testing
cd $GITLINT_TEST_DIR
gitlint --version # should print the correct version
rm -rf foo && git init foo && cd foo
git config user.email foo@bar.com && git config user.name "John Doe"
git commit --allow-empty -m "WIP: föo"
gitlint
# Expected:
# 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: föo"
# 3: B6 Body message is missing

gitlint --debug
# Check version at the top, python version

echo "WIP: föo2" | gitlint
# Expected:
# 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: föo2"
# 3: B6 Body message is missing

echo "föo3" | gitlint -c title-max-length.line-length=2
# Expected:
# 1: T1 Title exceeds max length (4>2): "föo3"
# 1: T8 Title is too short (4<5): "föo3"
# 3: B6 Body message is missing


gitlint install-hook
git commit --allow-empty -m "WIP: föo4"

# Run integration tests
pip install -r $GITLINT_DIR/qa/requirements.txt
pushd $GITLINT_DIR && ./run_tests.sh -i && popd

# Cleanup
deactivate; cd $GITLINT_DIR && rm -rf $GITLINT_TEST_DIR

Production release

Release on PyPi

gitlint-core

# remove any previous builds
./run_tests.sh --clean
# Do a rebuild
cd gitlint-core
python setup.py sdist bdist_wheel
# Upload to pypitest 
twine upload dist/*

gitlint

# Make sure you're at the top-level gitlint directory
cd ..
# remove any previous builds
./run_tests.sh --clean
# Do a rebuild
python setup.py sdist bdist_wheel
# Upload to pypitest 
twine upload dist/*

Check packages at:

Test installation of released package

# Set release variable for the next steps
export RELEASE_VERSION=`python -c "import gitlint; print(gitlint.__version__)"`; export GITLINT_DIR=`pwd`; export GITLINT_TEST_DIR="/tmp/release-$RELEASE_VERSION"
echo -e "RELEASE_VERSION: $RELEASE_VERSION\nGITLINT_DIR: $GITLINT_DIR\nGITLINT_TEST_DIR: $GITLINT_TEST_DIR"

deactivate # deactivate current virtualenv

# Create virtualenv to test the release
mkdir $GITLINT_TEST_DIR && cd $GITLINT_TEST_DIR
virtualenv -p /usr/bin/python3.8 .venv38 && source .venv38/bin/activate

# Install
gitlint # should not work
pip install --no-cache-dir gitlint # no-cache-dir to disable caching (otherwise pip doesn't always find the new package)

# Do some basic manual testing
cd $GITLINT_TEST_DIR
gitlint --version # should print the correct version
rm -rf foo && git init foo && cd foo
git config user.email foo@bar.com && git config user.name "John Doe"

git commit --allow-empty -m "WIP: föo"
gitlint
# Expected:
# 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: föo"
# 3: B6 Body message is missing

gitlint --debug
# Check version at the top, python version

echo "WIP: föo2" | gitlint
# Expected:
# 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: föo2"
# 3: B6 Body message is missing

echo "föo3" | gitlint -c title-max-length.line-length=2
# Expected:
# 1: T1 Title exceeds max length (4>2): "föo3"
# 1: T8 Title is too short (4<5): "föo3"
# 3: B6 Body message is missing

gitlint install-hook
git commit --allow-empty -m "WIP: föo4"

# Run integration tests
pip install -r $GITLINT_DIR/qa/requirements.txt
pushd $GITLINT_DIR && ./run_tests.sh -i && popd

# Cleanup
deactivate; cd $GITLINT_DIR && rm -rf $GITLINT_TEST_DIR

Publish Docker Image

# NOTE: These docker images perform a 'pip install', so its assumed that 
# the version passed via `GITLINT_VERSION` is available for installation on pypi.
export GITLINT_VERSION=`python3 -c "import gitlint; print(gitlint.__version__)"`; echo $GITLINT_VERSION
docker rm jorisroovers/gitlint:$GITLINT_VERSION # remove any previous builds
docker build --build-arg GITLINT_VERSION=$GITLINT_VERSION -t jorisroovers/gitlint:$GITLINT_VERSION .
docker build --build-arg GITLINT_VERSION=$GITLINT_VERSION -t jorisroovers/gitlint:latest .

# Local copy Sanity test
docker run -v $(pwd):/repo jorisroovers/gitlint:$GITLINT_VERSION --version
docker run -v $(pwd):/repo jorisroovers/gitlint:$GITLINT_VERSION --debug
docker run -v $(pwd):/repo jorisroovers/gitlint:latest --version
docker run -v $(pwd):/repo jorisroovers/gitlint:latest --debug
docker run -v $(pwd):/repo jorisroovers/gitlint --version
docker run -v $(pwd):/repo jorisroovers/gitlint --debug

# Login and push to dockerhub
docker login -u jorisroovers
docker push jorisroovers/gitlint:$GITLINT_VERSION
docker push jorisroovers/gitlint:latest
# Check results at https://hub.docker.com/r/jorisroovers/gitlint/tags

# Remove local copies
docker image rm -f jorisroovers/gitlint:$GITLINT_VERSION
docker image rm -f jorisroovers/gitlint:latest
docker image rm -f jorisroovers/gitlint


# Pull image from dockerhub and test again
docker run -v $(pwd):/repo jorisroovers/gitlint:$GITLINT_VERSION --version
docker run -v $(pwd):/repo jorisroovers/gitlint:$GITLINT_VERSION --debug
docker run -v $(pwd):/repo jorisroovers/gitlint:latest --version
docker run -v $(pwd):/repo jorisroovers/gitlint:latest --debug
docker run -v $(pwd):/repo jorisroovers/gitlint --version
docker run -v $(pwd):/repo jorisroovers/gitlint --debug

Push new docs

mkdocs gh-deploy

Commit and push release commit to github

Template commit message:

0.1.0 release

[copy release notes here]

Full Release details in CHANGELOG.md.

WAIT FOR CI TO FINISH TESTING

Tag git commit

export GITLINT_VERSION_TAG=v`python3 -c "import gitlint; print(gitlint.__version__)"`; echo $GITLINT_VERSION_TAG
git tag $GITLINT_VERSION_TAG
git tag --list
git push --tags

Create a new release on github

Go to the releases page and create a new release. Copy in changes from the raw CHANGELOG.md

Post Release Steps

Bump version to dev

Bump the version number in gitlint/__init__.py

# From host system
export NEW_VERSION="0.9.0dev"
echo "__version__ = \"$NEW_VERSION\"" > gitlint-core/gitlint/__init__.py && cat gitlint-core/gitlint/__init__.py
echo "TODO: manually updated version in setup.py to $NEW_VERSION"
git add gitlint/__init__.py && git status && git diff --staged
echo -e "Version bump to $NEW_VERSION\n\nBumped version to $NEW_VERSION." > /tmp/gitlint-$NEW_VERSION-version-bump-commitmsg
git commit -F /tmp/gitlint-$NEW_VERSION-version-bump-commitmsg
git show
git push

Make sure to shutdown any AWS Windows testing VMs

Ask harens in associated Release Plan issue to push builds for homebrew and macports

Create Release Plan issue and milestone for next release on github