Skip to content

Commit 3abf898

Browse files
committed
Combined scripts confirm_release.sh and test_new_version.sh into verify_release.sh.
This reuses the same download for both artifacts and checks both GPG signature and minimal correctness in the same script. Docs and script do_django_release.py were updated.
1 parent 1426591 commit 3abf898

5 files changed

Lines changed: 100 additions & 119 deletions

File tree

docs/internals/howto-release-django.txt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -479,17 +479,11 @@ Building the artifacts
479479

480480
$ PGP_KEY_ID=<key-id> PGP_KEY_URL=<key-url> DEST_FOLDER=~/releases scripts/do_django_release.py
481481

482-
* Test new version script:
482+
* Verify the release (after artifacts were uploaded):
483483

484484
.. code-block:: shell
485485

486-
$ VERSION=5.2.1 scripts/test_new_version.sh
487-
488-
* Confirm release signature script:
489-
490-
.. code-block:: shell
491-
492-
$ VERSION=5.2.1 scripts/confirm_release.sh
486+
$ VERSION=5.2.1 scripts/verify_release.sh
493487

494488
#. Tag the release using ``git tag``. For example:
495489

scripts/confirm_release.sh

Lines changed: 0 additions & 57 deletions
This file was deleted.

scripts/do_django_release.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,9 @@ def do_checksum(checksum_algo, release_file):
206206
f"* Signed checksum {checksum_file_path}.asc"
207207
)
208208

209-
# Test the new version and confirm the signature using Jenkins.
210-
print("\n==> ACTION Test the release artifacts:")
211-
print(f"VERSION={django_version} test_new_version.sh")
212-
213-
print("\n==> ACTION Run confirm-release job:")
214-
print(f"VERSION={django_version} confirm_release.sh")
209+
# Verify the release artifacts (GPG signature, checksums, and smoke test).
210+
print("\n==> ACTION Verify the release artifacts:")
211+
print(f"VERSION={django_version} verify_release.sh")
215212

216213
# Upload to PyPI.
217214
print("\n==> ACTION Upload to PyPI, ensure your release venv is activated:")

scripts/test_new_version.sh

Lines changed: 0 additions & 48 deletions
This file was deleted.

scripts/verify_release.sh

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#! /bin/bash
2+
3+
# Verify a Django release: checks GPG signature, artifact checksums, and
4+
# smoke-tests installation from both the tarball and the wheel.
5+
#
6+
# Usage: VERSION=5.2 bash scripts/verify_release.sh
7+
#
8+
# Set GPG_KEY to a key fingerprint to import it before verifying, e.g.:
9+
# GPG_KEY=<fingerprint> VERSION=5.2 bash scripts/verify_release.sh
10+
11+
set -xue
12+
13+
if [[ -z "${VERSION:-}" ]]; then
14+
echo "Please set VERSION as env var"
15+
exit 1
16+
fi
17+
18+
if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+(\.[0-9]+|a[0-9]+|b[0-9]+|rc[0-9]+)?$ ]]; then
19+
echo "Not a valid version"
20+
exit 1
21+
fi
22+
23+
CHECKSUM_FILE="Django-${VERSION}.checksum.txt"
24+
MEDIA_URL_PREFIX="https://media.djangoproject.com"
25+
DOWNLOAD_PREFIX="https://www.djangoproject.com/download"
26+
27+
WORKDIR=$(mktemp -d)
28+
29+
function cleanup {
30+
rm -rf "${WORKDIR}"
31+
}
32+
trap cleanup EXIT
33+
34+
cd "${WORKDIR}"
35+
36+
echo "Downloading checksum file ..."
37+
curl --fail --output "${CHECKSUM_FILE}" "${MEDIA_URL_PREFIX}/pgp/${CHECKSUM_FILE}"
38+
39+
echo "Verifying checksum file signature ..."
40+
if [[ -n "${GPG_KEY:-}" ]]; then
41+
gpg --recv-keys "${GPG_KEY}"
42+
fi
43+
gpg --verify "${CHECKSUM_FILE}"
44+
45+
echo "Finding release artifacts ..."
46+
mapfile -t RELEASE_ARTIFACTS < <(grep "${DOWNLOAD_PREFIX}" "${CHECKSUM_FILE}")
47+
48+
echo "Found these release artifacts:"
49+
for ARTIFACT_URL in "${RELEASE_ARTIFACTS[@]}"; do
50+
echo "- ${ARTIFACT_URL}"
51+
done
52+
53+
echo "Downloading artifacts ..."
54+
for ARTIFACT_URL in "${RELEASE_ARTIFACTS[@]}"; do
55+
ARTIFACT_ACTUAL_URL=$(curl --head --write-out '%{redirect_url}' --output /dev/null --silent "${ARTIFACT_URL}")
56+
curl --location --fail --output "$(basename "${ARTIFACT_ACTUAL_URL}")" "${ARTIFACT_ACTUAL_URL}"
57+
done
58+
59+
echo "Verifying artifact hashes ..."
60+
# The `2>/dev/null` suppresses notes like "sha256sum: WARNING: 60 lines are
61+
# improperly formatted". Return code is still set on error and a wrong
62+
# checksum will still show up as FAILED.
63+
echo "- MD5 checksums"
64+
md5sum --check "${CHECKSUM_FILE}" 2>/dev/null
65+
echo "- SHA1 checksums"
66+
sha1sum --check "${CHECKSUM_FILE}" 2>/dev/null
67+
echo "- SHA256 checksums"
68+
sha256sum --check "${CHECKSUM_FILE}" 2>/dev/null
69+
70+
PKG_TAR=$(ls Django-*.tar.gz)
71+
PKG_WHL=$(ls Django-*.whl)
72+
73+
echo "Testing tarball install ..."
74+
python3 -m venv django-pip
75+
. django-pip/bin/activate
76+
python -m pip install --no-cache-dir "${WORKDIR}/${PKG_TAR}"
77+
django-admin startproject test_one
78+
cd test_one
79+
./manage.py --help # Ensure executable bits
80+
python manage.py migrate
81+
python manage.py runserver 0
82+
deactivate
83+
cd ..
84+
85+
echo "Testing wheel install ..."
86+
python3 -m venv django-pip-wheel
87+
. django-pip-wheel/bin/activate
88+
python -m pip install --no-cache-dir "${WORKDIR}/${PKG_WHL}"
89+
django-admin startproject test_one
90+
cd test_one
91+
./manage.py --help # Ensure executable bits
92+
python manage.py migrate
93+
python manage.py runserver 0
94+
deactivate
95+
cd ..

0 commit comments

Comments
 (0)