1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#!/usr/bin/env python3
# Copyright 2019 juga (juga at riseup dot net), CC0 license.
"""Script to help release new versions.
usage: release.py GPG_KEY_IDENTIFIER
This is a fast and dirty script to help release new sbws versions.
It does not intent to cover all possible cases and errors because this is out
of the scope of sbws.
There are other tools [*] that help manage release tags, branches and
changelogs, but we should not add more requirements to sbws to just release a
new version.
This script will:
0. Detect the current program version
1. Ask which version to release
2. Update the changelog automatically with ``gitchangelog``
and leave the option to user to manually edit it
3. Commit the changelog
4. Create a version with the tag and sign it
5. Push the commit and tag to the repository
6. Obtain the release tarball
7. Sign the release tarball
8. Modify the program to the next prerelease version and commit it
9. Push the commit
All is done in sequence and doesn't recover from any previous step.
It assumes that:
- the program version can be obtained with ``sbws.__version__``
- ``gitchangelog`` and ``semantic_version`` python packages are installed
- the official tarball releases are at gitlab.torproject.org
- the key to sign the release is only one and is available in the system
[*] See for instance https://semantic-release.gitbook.io,
https://github.com/GitTools/GitVersion
"""
import subprocess
import sys
try:
import semantic_version
except ImportError:
print(
"Please, install semantic_version: "
"`apt install python3-semantic-version` or "
"`pip install semantic_version`")
sys.exit(1)
try:
import gitchangelog # noqa
except ImportError:
print("Please, install gitchangelog: `pip install gitchangelog`")
sys.exit(1)
# Not used directly, but gitchangelog depends on it
try:
import mako # noqa
except ImportError:
print("Please, install mako: `pip install mako`")
sys.exit(1)
import sbws
def obtain_release_version(version):
release_type_dict = {
1: version.next_patch(),
2: version.next_minor(),
3: version.next_major(),
}
print("Current prerelease version: ", version)
print("which version would you like to release?:")
print("1. to patch release: ", release_type_dict[1])
print("2. to minor release: ", release_type_dict[2])
print("3. to major release: ", release_type_dict[3])
release_type = int(input())
try:
return release_type_dict[release_type]
except KeyError:
print("Invalid release.")
sys.exit(1)
def main(args):
print(__doc__)
try:
keyid = args[0]
except IndexError:
print("Please, pass a GPG key identifier as argument.")
sys.exit(1)
print("1. Which version to release")
print("---------------------------")
current_version = semantic_version.Version(sbws.__version__)
release_version = obtain_release_version(current_version)
print("\n2. Update changelog")
print("-------------------")
print("Creating tag v{} so that gitchangelog will create the new section "
"with the correct new tag...".format(release_version))
subprocess.call(['git', 'tag', 'v{}'.format(release_version),
'-m', '\"Release version {}.\"'.format(release_version)])
print("\nUpdating the changelog automatically...")
subprocess.call('gitchangelog'.split(' '))
print("\nEdit the changelog manually to remove merge commits and "
"leave only the apropiate paragraph for every bug/feature.")
input("Press enter when done.\n")
print("\nRemoving the tag...")
subprocess.call(['git', 'tag', '-d', 'v{}'.format(release_version)])
print("\n3. Commit the changelog")
print("--------------------------")
print("\nCommiting CHANGELOG.rst...")
subprocess.call(['git', 'commit',
'-am', '"Release version {}."'.format(release_version)])
print("\n4. Create tag and sign it")
print("--------------------------")
print("\nCreating the final tag and signing it...")
subprocess.call(['git', 'tag', '-s', 'v{}'.format(release_version),
'-m', '"Release version {}."'.format(release_version)])
print("\n5. Push commit and tag")
print("------------------------")
print("\nPush now so that the Gitlab creates the tarball from the new "
" commit and tag, eg:")
print("git push myremote mybranch")
print("git push myremote --tags")
input("Press enter when you are done.")
print("\n6. Obtain the release tarball")
print("-------------------------------")
print("Obtaining Gitlab tarball...")
subprocess.call(
"wget https://gitlab.torproject.org/tpo/network-health/sbws/-/archive/v{}/sbws-v{}.tar.gz " # noqa
"-O v{}.tar.gz"
.format(release_version, release_version, release_version).split(' ')
)
print("\n7. Create the tarball signature")
print("-------------------------------")
print("Creating detached signature...")
subprocess.call("gpg --default-key {} "
"--output v{}.tar.gz.asc "
"--detach-sign v{}.tar.gz"
.format(keyid, release_version, release_version)
.split(' '))
print("\nUpload the signature manually to Gitlab.")
input("Press enter when done.")
print("\nRelease done!!!.")
print("\n8. Create next prerelease branch")
print("----------------------------------")
print("\nIf this release happens in a maintainance branch, merge the "
"the commit to master and push, eg:"
"git checkout master"
"git merge --no-ff mybranch"
"git push myremote master")
next_branch_version = "maint{}".format(release_version)
print("And create the next prerelease branch, eg:"
"git checkout -b {}".format(next_branch_version))
if __name__ == "__main__":
main(sys.argv[1:])
|