Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ The NVIDIA Container Toolkit consists of the following artifacts:

# Release Process Checklist:
- [ ] Create a release PR:
- [ ] Run the `./hack/prepare-release.sh` script to update the version in all the needed files. This also creates a [release issue](https://github.com/NVIDIA/cloud-native-team/issues?q=is%3Aissue+is%3Aopen+label%3Arelease)
- [ ] Run the `./hack/prepare-release.sh` script to update the version in all the needed files. This also creates a [release issue](https://github.com/NVIDIA/nvidia-container-toolkit/issues?q=is%3Aissue+is%3Aopen+label%3Arelease)
- [ ] Run the `./hack/generate-changelog.sh` script to generate the a draft changelog and update `CHANGELOG.md` with the changes.
- [ ] Create a PR from the created `bump-release-{{ .VERSION }}` branch.
- [ ] Merge the release PR
- [ ] Tag the release and push the tag to the `internal` mirror:
- [ ] Image release pipeline: https://gitlab-master.nvidia.com/dl/container-dev/container-toolkit/-/pipelines/16466098
- [ ] Wait for the image release to complete.
- [ ] Push the tag to the the upstream GitHub repo.
- [ ] Wait for the [`Release`](https://github.com/NVIDIA/k8s-device-plugin/actions/workflows/release.yaml) GitHub Action to complete
- [ ] Publish the [draft release](https://github.com/NVIDIA/k8s-device-plugin/releases) created by the GitHub Action
- [ ] Wait for the [`Release`](https://github.com/NVIDIA/nvidia-container-toolkit/actions/workflows/release.yaml) GitHub Action to complete
- [ ] Publish the [draft release](https://github.com/NVIDIA/nvidia-container-toolkit/releases) created by the GitHub Action
- [ ] Publish the packages to the gh-pages branch of the libnvidia-container repo
- [ ] Create a KitPick
- [ ] For non-experimental releases, schedule the package for publication to the CUDA Downloads repositories.

## Troubleshooting

Expand Down
70 changes: 36 additions & 34 deletions hack/generate-changelog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ this=`basename $0`

usage () {
cat << EOF
Generate a changelog for the specified tag
Usage: $this --reference <tag> [--remote <remote_name>]
Generate a changelog for an NVIDIA Container Toolkit release

Usage: $this [-h] --previous-version <previous_version> --version <version>

Options:
--since specify the tag to start the changelog from (default: latest tag)
--version specify the version to be released
--previous-version specify the previous version
--version specify the version for this release.
--help/-h show this help and exit

EOF
Expand All @@ -33,26 +34,24 @@ EOF
LIB_VERSION=$(awk -F= '/^LIB_VERSION/ { print $2 }' versions.mk | tr -d '[:space:]')
LIB_TAG=$(awk -F= '/^LIB_TAG/ { print $2 }' versions.mk | tr -d '[:space:]')

VERSION="v${LIB_VERSION}${LIB_TAG:+-${LIB_TAG}}"
>&2 echo "VERSION=$VERSION"

REFERENCE=
version="v${LIB_VERSION}${LIB_TAG:+-${LIB_TAG}}"
>&2 echo "version=$version"

previous_version=
# Parse command line options
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--since)
REFERENCE="$2"
shift # past argument
shift # past value
--previous-version)
previous_version="$2"
shift 2
;;
--version)
VERSION="$2"
shift # past argument
shift # past value
version="$2"
shift 2
;;
--help/-h) usage
--help/-h)
usage
exit 0
;;
*) usage
Expand All @@ -61,44 +60,47 @@ while [[ $# -gt 0 ]]; do
esac
done

# Check that no extra args were provided
if [ -z "$release" ]; then
echo -e "ERROR: --version is required"
usage
exit 1
fi

if [ -z ${previous_version} ]; then
echo -e "ERROR: --previous-version is required"
usage
exit 1
fi

# Fetch the latest tags from the remote
remote=$( git remote -v | grep -E "NVIDIA/nvidia-container-toolkit(\.git)?\s" | grep -oE "^[a-z]+" | sort -u )
>&2 echo "Detected remote as '${remote}'"
git fetch ${remote} --tags

SHA=$(git rev-parse ${VERSION})
SHA=$(git rev-parse ${version})
if [[ $? -ne 0 ]]; then
SHA="HEAD"
fi

# if REFERENCE is not set, get the latest tag
if [ -z "$REFERENCE" ]; then
most_recent_tag=$(git tag --sort=-creatordate | head -1)
if [ "${VERSION}" == "${most_recent_tag}" ]; then
REFERENCE=$(git tag --sort=-creatordate | head -2 | tail -1)
else
REFERENCE=${most_recent_tag}
fi
fi

>&2 echo "Using ${REFERENCE} as previous version"
>&2 echo "Using ${previous_version} as previous version"

# Print the changelog
echo "## What's Changed"
echo ""
if [[ ${VERSION} != v*-rc.* ]]; then
echo "- Promote $REFERENCE to $VERSION"
if [[ ${version} != v*-rc.* && ${previous_version} == v*-rc.* ]]; then
echo "- Promote ${previous_version} to $version"
fi

# Iterate over the commit messages and ignore the ones that start with "Merge" or "Bump"
git log --pretty=format:"%s" $REFERENCE..$SHA -- ':!deployments/container' ':!tools' | grep -Ev "(^Merge )|(^Bump)|(no-rel-?note)|(^---)" | sed 's/^\(.*\)/- \1/g'
git log --pretty=format:"%s" ${previous_version}..$SHA -- ':!deployments/container' ':!tools' | grep -Ev "(^Merge )|(^Bump)|(no-rel-?note)|(^---)" | sed 's/^\(.*\)/- \1/g'

echo ""
echo "### Changes in the Toolkit Container"
echo ""
git log --pretty=format:"%s" $REFERENCE..$SHA -- deployments/container tools | grep -Ev "(^Merge )|(no-rel-?note)|(^---)" | sed 's/^\(.*\)/- \1/g'
git log --pretty=format:"%s" ${previous_version}..$SHA -- deployments/container tools | grep -Ev "(^Merge )|(no-rel-?note)|(^---)" | sed 's/^\(.*\)/- \1/g'

LIB_NVIDIA_CONTAINER_REFERENCE=$( git ls-tree $REFERENCE third_party/libnvidia-container --object-only )
LIB_NVIDIA_CONTAINER_REFERENCE=$( git ls-tree ${previous_version} third_party/libnvidia-container --object-only )
LIB_NVIDIA_CONTAINER_VERSION=$( git ls-tree $SHA third_party/libnvidia-container --object-only )

echo ""
Expand All @@ -109,5 +111,5 @@ git -C third_party/libnvidia-container log --pretty=format:"%s" $LIB_NVIDIA_CONT
echo ""
fi

echo "**Full Changelog**: https://github.com/NVIDIA/nvidia-container-toolkit/compare/${REFERENCE}...${VERSION}"
echo "**Full Changelog**: https://github.com/NVIDIA/nvidia-container-toolkit/compare/${previous_version}...${version}"
echo ""
126 changes: 37 additions & 89 deletions hack/prepare-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,112 +20,59 @@ this=`basename $0`

usage () {
cat << EOF
Usage: $this [-h] [-a] RELEASE_VERSION
Prepare for an NVIDIA Container Toolkit release

Usage: $this [-h] --previous-version <previous_version> --version <version>

Options:
--previous-version specify the previous version (default: latest tag)
--previous-version specify the previous version
--version specify the version for this release.
--help/-h show this help and exit

Example:

$this {{ VERSION }}
$this --previous-version {{ PREVIOUS_VERSION}} --version {{ VERSION }}

EOF
}

validate_semver() {
Copy link
Collaborator

@ArangoGutierrez ArangoGutierrez Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed anymore? if so let's document this on the PR description.

local version=$1
local semver_regex="^v([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$"

if [[ $version =~ $semver_regex ]]; then
major=${BASH_REMATCH[1]}
minor=${BASH_REMATCH[2]}
patch=${BASH_REMATCH[3]}

# Check if major, minor, and patch are numeric
if ! [[ $major =~ ^[0-9]+$ ]] || ! [[ $minor =~ ^[0-9]+$ ]] || ! [[ $patch =~ ^[0-9]+$ ]]; then
echo "Invalid SemVer format: $version"
return 1
fi

# Validate prerelease if present
if [[ ! -z "${BASH_REMATCH[5]}" ]]; then
prerelease=${BASH_REMATCH[5]}
prerelease_regex="^([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)$"
if ! [[ $prerelease =~ $prerelease_regex ]]; then
echo "Invalid SemVer format: $version"
return 1
fi
fi

echo "Valid SemVer format: $version"
return 0
else
echo "Invalid SemVer format: $version"
return 1
fi
}

#
# Parse command line
#
no_patching=
previous_version=$(git describe --tags $(git rev-list --tags --max-count=1))
# Parse command line options
previous_version=
version=
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--previous-version)
previous_version="$2"
shift 2
;;
--help/-h) usage
--version)
version="$2"
shift 2
;;
--help/-h)
usage
exit 0
;;
*) break
*) usage
exit 1
;;
esac
done

# Check that no extra args were provided
if [ $# -ne 1 ]; then
if [ $# -lt 1 ]; then
echo -e "ERROR: too few arguments\n"
else
echo -e "ERROR: unknown arguments: ${@:3}\n"
fi
if [ -z "$version" ]; then
echo -e "ERROR: --version is required"
usage
exit 1
fi

release=$1
shift 1

container_image=nvcr.io/nvidia/k8s-device-plugin:$release

#
# Check/parse release number
#
if [ -z "$release" ]; then
echo -e "ERROR: missing RELEASE_VERSION\n"
if [ -z $previous_version ]; then
echo -e "ERROR: --previous-version is required"
usage
exit 1
fi

# validate the release version
if ! validate_semver $release; then
echo -e "ERROR: invalid RELEASE_VERSION\n"
exit 1
fi
semver=${release:1}

# validate the previous version
if ! validate_semver $previous_version; then
echo -e "ERROR: invalid PREVIOUS_VERSION\n"
exit 1
fi
pre_semver=${previous_version:1}

#
# Modify files in the repo to point to new release
#
Expand All @@ -137,10 +84,10 @@ else
SED="sed"
fi

# TODO: We need to ensure that this tooling also works on `release-*` branches.
if [[ "$FORCE" != "yes" ]]; then
if [[ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]]; then
echo "Release scripts should be run on 'main'"
current_head=$(git rev-parse --abbrev-ref HEAD)
if [[ "${current_head}" != "main" || "${current_head}" != release-* ]]; then
echo "Release scripts should be run on 'main' or on a 'release-*' branch"
exit 1
fi
git fetch
Expand All @@ -155,39 +102,40 @@ fi

# Create a release issue.
echo "Creating release tracking issue"
cat RELEASE.md | sed "s/{{ .VERSION }}/$release/g" | \
cat RELEASE.md | sed "s/{{ .VERSION }}/${version}/g" | \
gh issue create -F - \
-R NVIDIA/cloud-native-team \
--title "Release nvidia-container-toolkit $release" \
--label release
-R NVIDIA/nvidia-container-toolkit \
--title "Release nvidia-container-toolkit ${version}" \
--label release \
--milestone ${version}

echo "Creating a version bump branch: bump-release-${release}"
git checkout -f -b bump-release-${release}
echo "Creating a version bump branch: bump-release-${version}"
git checkout -f -b bump-release-${version}

# Patch versions.mk
LIB_VERSION=${release%-*}
LIB_VERSION=${LIB_VERSION#v}
if [[ ${release} == v*-rc.* ]]; then
LIB_TAG_STRING=" ${release#*-}"
LIB_TAG_STRING=" ${version#*-}"
else
LIB_TAG_STRING=
fi

echo Patching versions.mk to refer to $release
echo Patching versions.mk to refer to ${version}
$SED -i "s/^LIB_VERSION.*$/LIB_VERSION := $LIB_VERSION/" versions.mk
$SED -i "s/^LIB_TAG.*$/LIB_TAG :=$LIB_TAG_STRING/" versions.mk

git add versions.mk
git commit -s -m "Bump version for $release release"
git commit -s -m "Bump version for ${version} release"

if [[ $release != *-rc.* ]]; then
if [[ ${version} != *-rc.* ]]; then
# Patch README.md
echo Patching README.md to refer to $release
$SED -E -i -e "s/([^[:space:]])$previous_version([^[:alnum:]]|$)/\1$release\2/g" README.md
echo Patching README.md to refer to ${version}
$SED -E -i -e "s/([^[:space:]])$previous_version([^[:alnum:]]|$)/\1${version}\2/g" README.md
$SED -E -i -e "s/$pre_semver/$semver/g" README.md

git add -u README.md
git commit -s -m "Bump version to $release in README"
git commit -s -m "Bump version to ${version} in README"
else
echo "Skipping README update for prerelease version"
fi
Expand Down