Skip to content

Commit e56ff07

Browse files
author
Lukas Puehringer
committed
build: add 'gpg sign' option to verify_release
Add option to sign locally built release artifacts with gpg, if they match the downloaded artifacts from GitHub, PyPI. Signed-off-by: Lukas Puehringer <[email protected]>
1 parent e7544bf commit e56ff07

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

verify_release

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,26 @@ def verify_pypi_release(version: str, compare_dir: str) -> bool:
122122
return sorted(same) == [wheel, tar]
123123

124124

125+
def sign_release_artifacts(
126+
version: str, build_dir: str, key_id: str = None
127+
) -> None:
128+
"""Sign built release artifacts with gpg and write signature files to cwd"""
129+
tar = f"{PYPI_PROJECT}-{version}.tar.gz"
130+
wheel = f"{PYPI_PROJECT}-{version}-py3-none-any.whl"
131+
cmd = ["gpg", "--detach-sign", "--armor"]
132+
133+
if key_id is not None:
134+
cmd += ["--local-user", key_id]
135+
136+
for filename in [tar, wheel]:
137+
artifact_path = os.path.join(build_dir, filename)
138+
signature_path = f"{filename}.asc"
139+
subprocess.run(
140+
cmd + ["--output", signature_path, artifact_path], check=True
141+
)
142+
assert os.path.exists(signature_path)
143+
144+
125145
def finished(s: str) -> None:
126146
# clear line
127147
sys.stdout.write("\033[K")
@@ -143,6 +163,15 @@ def main() -> int:
143163
dest="skip_pypi",
144164
help="Skip PyPI release check.",
145165
)
166+
parser.add_argument(
167+
"--sign",
168+
nargs="?",
169+
const=True,
170+
metavar="<key id>",
171+
dest="sign",
172+
help="Sign release artifacts with 'gpg'. If no <key id> is passed, the default "
173+
"signing key is used. Resulting '*.asc' files are written to CWD.",
174+
)
146175
args = parser.parse_args()
147176

148177
success = True
@@ -173,15 +202,28 @@ def main() -> int:
173202
finished("ERROR: PyPI artifacts do not match built release")
174203
success = False
175204
else:
176-
finished(f"PyPI artifacts match the built release")
205+
finished("PyPI artifacts match the built release")
177206

178207
progress("Downloading release from GitHub")
179208
if not verify_github_release(build_version, build_dir):
180209
# This is expected while build is not reproducible
181210
finished("ERROR: GitHub artifacts do not match built release")
182211
success = False
183212
else:
184-
finished(f"GitHub artifacts match the built release")
213+
finished("GitHub artifacts match the built release")
214+
215+
# NOTE: 'gpg' might prompt for password or ask if it should override files...
216+
if args.sign:
217+
progress("Signing built release with gpg")
218+
if success:
219+
key_id = None
220+
if args.sign is not True:
221+
key_id = args.sign
222+
223+
sign_release_artifacts(build_version, build_dir, key_id)
224+
finished("Created signatures in cwd (see '*.asc' files)")
225+
else:
226+
finished("WARNING: Skip signing of non-matching artifacts")
185227

186228
return 0 if success else 1
187229

0 commit comments

Comments
 (0)