diff options
| author | Natalia <124304+nessita@users.noreply.github.com> | 2026-03-09 10:50:44 -0300 |
|---|---|---|
| committer | nessita <124304+nessita@users.noreply.github.com> | 2026-03-16 22:08:17 -0300 |
| commit | 3abf89887993140d28676f26420ee0d46a617f51 (patch) | |
| tree | 3b028144cfd4112731c89b2d14969b296f7d0a1b /scripts/verify_release.sh | |
| parent | 142659133a501a1685902cf654b233e54b641a23 (diff) | |
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.
Diffstat (limited to 'scripts/verify_release.sh')
| -rwxr-xr-x | scripts/verify_release.sh | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/scripts/verify_release.sh b/scripts/verify_release.sh new file mode 100755 index 0000000000..d808b62cfa --- /dev/null +++ b/scripts/verify_release.sh @@ -0,0 +1,95 @@ +#! /bin/bash + +# Verify a Django release: checks GPG signature, artifact checksums, and +# smoke-tests installation from both the tarball and the wheel. +# +# Usage: VERSION=5.2 bash scripts/verify_release.sh +# +# Set GPG_KEY to a key fingerprint to import it before verifying, e.g.: +# GPG_KEY=<fingerprint> VERSION=5.2 bash scripts/verify_release.sh + +set -xue + +if [[ -z "${VERSION:-}" ]]; then + echo "Please set VERSION as env var" + exit 1 +fi + +if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+(\.[0-9]+|a[0-9]+|b[0-9]+|rc[0-9]+)?$ ]]; then + echo "Not a valid version" + exit 1 +fi + +CHECKSUM_FILE="Django-${VERSION}.checksum.txt" +MEDIA_URL_PREFIX="https://media.djangoproject.com" +DOWNLOAD_PREFIX="https://www.djangoproject.com/download" + +WORKDIR=$(mktemp -d) + +function cleanup { + rm -rf "${WORKDIR}" +} +trap cleanup EXIT + +cd "${WORKDIR}" + +echo "Downloading checksum file ..." +curl --fail --output "${CHECKSUM_FILE}" "${MEDIA_URL_PREFIX}/pgp/${CHECKSUM_FILE}" + +echo "Verifying checksum file signature ..." +if [[ -n "${GPG_KEY:-}" ]]; then + gpg --recv-keys "${GPG_KEY}" +fi +gpg --verify "${CHECKSUM_FILE}" + +echo "Finding release artifacts ..." +mapfile -t RELEASE_ARTIFACTS < <(grep "${DOWNLOAD_PREFIX}" "${CHECKSUM_FILE}") + +echo "Found these release artifacts:" +for ARTIFACT_URL in "${RELEASE_ARTIFACTS[@]}"; do + echo "- ${ARTIFACT_URL}" +done + +echo "Downloading artifacts ..." +for ARTIFACT_URL in "${RELEASE_ARTIFACTS[@]}"; do + ARTIFACT_ACTUAL_URL=$(curl --head --write-out '%{redirect_url}' --output /dev/null --silent "${ARTIFACT_URL}") + curl --location --fail --output "$(basename "${ARTIFACT_ACTUAL_URL}")" "${ARTIFACT_ACTUAL_URL}" +done + +echo "Verifying artifact hashes ..." +# The `2>/dev/null` suppresses notes like "sha256sum: WARNING: 60 lines are +# improperly formatted". Return code is still set on error and a wrong +# checksum will still show up as FAILED. +echo "- MD5 checksums" +md5sum --check "${CHECKSUM_FILE}" 2>/dev/null +echo "- SHA1 checksums" +sha1sum --check "${CHECKSUM_FILE}" 2>/dev/null +echo "- SHA256 checksums" +sha256sum --check "${CHECKSUM_FILE}" 2>/dev/null + +PKG_TAR=$(ls Django-*.tar.gz) +PKG_WHL=$(ls Django-*.whl) + +echo "Testing tarball install ..." +python3 -m venv django-pip +. django-pip/bin/activate +python -m pip install --no-cache-dir "${WORKDIR}/${PKG_TAR}" +django-admin startproject test_one +cd test_one +./manage.py --help # Ensure executable bits +python manage.py migrate +python manage.py runserver 0 +deactivate +cd .. + +echo "Testing wheel install ..." +python3 -m venv django-pip-wheel +. django-pip-wheel/bin/activate +python -m pip install --no-cache-dir "${WORKDIR}/${PKG_WHL}" +django-admin startproject test_one +cd test_one +./manage.py --help # Ensure executable bits +python manage.py migrate +python manage.py runserver 0 +deactivate +cd .. |
