#!/usr/bin/env bash
########################################################
# Update the Sage version
# To be called by the release manager
########################################################
CMD="${0##*/}"
die () {
echo >&2 -e "$@"
exit 1
}
usage () {
echo "usage: $CMD <SAGE_VERSION>"
}
if [ $# -ne 1 ]; then
usage
die
fi
if [ -z "$SAGE_ROOT" ]; then
SAGE_ROOT="$(pwd)"
fi
if [ -z "$SAGE_SRC" ]; then
SAGE_SRC="$SAGE_ROOT/src"
fi
set -e
# If $1 starts with "sage-", remove this prefix
SAGE_VERSION=`echo "$1" | sed 's/^sage-//'`
SAGE_RELEASE_DATE=`date -u +'%Y-%m-%d'`
SAGE_VERSION_BANNER="SageMath version $SAGE_VERSION, Release Date: $SAGE_RELEASE_DATE"
# Update Sage version file for all distribution packages
for version_file in "$SAGE_ROOT"/pkgs/*/VERSION.txt; do
if [ -f "$version_file" ]; then
echo $SAGE_VERSION > "$version_file"
fi
done
# Update version_requirements.txt for all distribution packages
( cd "$SAGE_ROOT"/build/pkgs/ && for spkg in sage*; do
if [ -f "$spkg"/version_requirements.txt -a -d "$spkg"/src ]; then
( echo "# This file is updated on every release by the update-version script"
# Normalize the package name to PyPI convention (dashes, not underscores)
pkg=${spkg//_/-}
# Normalize the version (updated above as VERSION.txt) according to PEP440.
version=$(cat "$spkg"/package-version.txt)
version=${version//.beta/b}
version=${version//.rc/rc}
# ~= asks for a compatible release. https://peps.python.org/pep-0440/#compatible-release
echo "$pkg ~= $version" ) > "$spkg"/version_requirements.txt
fi
done )
# Update Sage version file for Python in SAGE_SRC/sage
cat <<EOF > "$SAGE_SRC/sage/version.py"
# Sage version information for Python scripts
# This file is auto-generated by the update-version script, do not edit!
version = '$SAGE_VERSION'
date = '$SAGE_RELEASE_DATE'
banner = '$SAGE_VERSION_BANNER'
EOF
# Update Sage version file for shell scripts in SAGE_SRC/bin/sage-version.sh
cat <<EOF > "$SAGE_SRC/bin/sage-version.sh"
# Sage version information for shell scripts.
#
# #31049: The following line is valid shell code but not valid Python code,
# which stops "setup.py develop" from rewriting it as a Python file.
:
# This file is auto-generated by the update-version script, do not edit!
SAGE_VERSION='$SAGE_VERSION'
SAGE_RELEASE_DATE='$SAGE_RELEASE_DATE'
SAGE_VERSION_BANNER='$SAGE_VERSION_BANNER'
EOF
# Create a top-level VERSION.txt file, which some external utilities rely on
echo "$SAGE_VERSION" > "$SAGE_ROOT/VERSION.txt"
# Add version to the front of GitHub release assets URLs.
SAGE_MINOR_VERSION=${SAGE_VERSION//.alpha*/}
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.beta*/}
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.dev*/}
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.post*/}
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.rc*/}
( echo "https://github.com/sagemath/sage/releases/download/$SAGE_MINOR_VERSION/"
sed '/^#/d' "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases"
) | uniq | head -n 3 > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
( cat <<EOF
# Upstream packages as uploaded as GitHub release assets.
# This file is automatically updated by the update-version script.
EOF
cat "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
) > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases"
rm -f "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
# Regenerate auto-generated files tarball
"$SAGE_ROOT/bootstrap" -s
# Create CITATION file for Zenodo-GitHub integration
export SAGE_VERSION
export SAGE_RELEASE_DATE
envsubst <"$SAGE_ROOT/CITATION.cff.in" >"$SAGE_ROOT/CITATION.cff"
# Update src/doc/versions.txt file storing the URLs of the docs for the recent stable releases
if [[ $SAGE_VERSION =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
file_path="$SAGE_ROOT/src/doc/en/website/versions.txt"
# Extract the most recent version line from versions.txt
line_number=$(grep -n '^[0-9]' "$file_path" | head -n 1 | cut -d: -f1)
version_line=$(sed -n "${line_number}p" "$file_path")
domain=${version_line#*--}
version=${SAGE_VERSION//./-}
# For the origin of this format, see .github/workflows/doc-publish.yml
url="doc-$version--$domain"
# Add new line to versions.txt
sed -i "${line_number}i $SAGE_VERSION $url" "$file_path"
# If the number of version lines is more than 10, remove the last line
line_count=$(grep -c '^[0-9]' "$file_path")
if [ "$line_count" -gt 10 ]; then
sed -i '$ d' "$file_path"
fi
fi
# Commit auto-generated changes
git commit -m "Updated SageMath version to $SAGE_VERSION" -- \
"$SAGE_ROOT/VERSION.txt" \
"$SAGE_SRC/sage/version.py" \
"$SAGE_ROOT/CITATION.cff" \
"$SAGE_SRC/bin/sage-version.sh" \
"$SAGE_ROOT/build/pkgs/configure/checksums.ini" \
"$SAGE_ROOT/build/pkgs/configure/package-version.txt" \
"$SAGE_ROOT/build/pkgs/*/version_requirements.txt" \
"$SAGE_ROOT"/pkgs/*/VERSION.txt \
"$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" \
"$SAGE_ROOT/src/doc/en/website/versions.txt" \
|| die "Error committing to the repository."
git tag -a "$SAGE_VERSION" -m "$SAGE_VERSION_BANNER" \
|| die "Error tagging the repository."