Skip to content

Instantly share code, notes, and snippets.

@BMTLab
Last active April 24, 2024 15:22
Show Gist options
  • Save BMTLab/28709f017c338a53e5845d04c00e6eb9 to your computer and use it in GitHub Desktop.
Save BMTLab/28709f017c338a53e5845d04c00e6eb9 to your computer and use it in GitHub Desktop.
Script that checks if a NuGet package is indexed and available on nuget.org
#!/bin/bash
# Author: Nikita Neverov (BMTLab)
# Version: 2.0.2
# Description: Checks if a NuGet package is indexed and available on nuget.org.
# Used in CI/CD to automatically check if a dependency package is indexed before pushing a dependent package.
# Usage:
# chmod +x check-nuget-pkg-indexed.sh
# ./check-nuget-pkg-indexed.sh [-p] <package> [-a] <attempts> -v <version>
set -uo pipefail
IFS=$'\n\t'
# Default settings
readonly DEFAULT_PACKAGE_NAME='BMTLab.OneOf.Reduced'
readonly DEFAULT_MAX_ATTEMPTS=10
readonly SLEEP_SECONDS=30
# Error codes
readonly ERR_MISSING_ARGUMENT=20
readonly ERR_INVALID_OPTION=30
readonly ERR_INVALID_VERSION=40
readonly ERR_PACKAGE_NOT_FOUND=50
#######################################
# Display usage information.
# Outputs:
# Help information.
#######################################
function usage() {
cat <<EOF
Usage: $(basename "$0") [-p] <package> [-a] <attempts> -v <version>
Options:
-p <package> : Specify the NuGet package name. Default is '${DEFAULT_PACKAGE_NAME}'.
-a <attempts> : Specify the max attempts count. Default is ${DEFAULT_MAX_ATTEMPTS}.
-v <version> : Specify the package version to check. Required.
-h : Display this help message.
Example:
$(basename "$0") -p "${DEFAULT_PACKAGE_NAME}" -a 5 -v "1.2.3"
EOF
}
#######################################
# Displays an error message, outputs usage, and terminates the script with an error.
# Arguments:
# 1: The error message to display.
# 2: The error exit code (optional).
#######################################
function __error() {
local -r message="$1"
local -ir code=${2:-1} # Default error code is 1
usage
printf '\nError: %s.\n' "$message" >&2
exit $code
}
#######################################
# Parses command line options.
# Arguments:
# References to package, version, and max_attempts variables.
#######################################
function __parse_options() {
local -n _package="$1"
local -n _version="$2"
local -n _max_attempts=$3
local opt
shift 3
while getopts ':p:v:a:h' opt; do
case $opt in
p)
_package="$OPTARG"
;;
v)
_version="$OPTARG"
;;
a)
_max_attempts=$OPTARG
;;
h)
usage
exit 0
;;
\?)
__error "Invalid option: -${OPTARG}" $ERR_INVALID_OPTION
;;
:)
__error "Option -$OPTARG requires an argument" $ERR_MISSING_ARGUMENT
;;
esac
done
if [[ -z $_version || $_version =~ ^[[:space:]]+$ ]]; then
__error "Version (-v) is required" $ERR_INVALID_VERSION
fi
}
#######################################
# Check if the specified NuGet package version is indexed on nuget.org.
# Arguments:
# 1: The NuGet package name.
# 2: The package version.
# 3: Maximum number of attempts to check the package availability.
#######################################
function _check_package_indexing() {
local -r package="$1"
local -r version="$2"
local -ir max_attempts=$3
local -i attempt=1
local -r nuget_package_url="https://www.nuget.org/api/v2/package/${package}/${version}"
local -i status_code
while [[ $attempt -le $max_attempts ]]; do
printf "Checking if %s version %s is indexed on nuget.org (Attempt: %d)...\n" "$package" "$version" $attempt
status_code=$(curl --silent -L --output /dev/null --write-out '%{http_code}' "$nuget_package_url")
if [[ $status_code -eq 200 ]]; then
printf "Package %s version %s is indexed on nuget.org.\n" "$package" "$version"
exit 0
else
printf "Pending. Package %s version %s is not indexed yet. Status code: %d\n" "$package" "$version" "$status_code"
if [[ $attempt -lt $max_attempts ]]; then
printf "Sleeping for %d seconds before the next attempt %d of %d...\n" $SLEEP_SECONDS $attempt $max_attempts >&2
sleep $SLEEP_SECONDS
fi
fi
((attempt++))
done
__error "Package $package version $version was not indexed after $max_attempts attempts" $ERR_PACKAGE_NOT_FOUND
}
#######################################
# Main function to orchestrate script execution.
# Uses global defaults and user inputs to check NuGet package versions.
#######################################
function main() {
local package="$DEFAULT_PACKAGE_NAME"
local version=''
local -i max_attempts=$DEFAULT_MAX_ATTEMPTS
__parse_options package version max_attempts "$@"
_check_package_indexing "$package" "$version" "$max_attempts"
}
# Execute the main function with all passed arguments
main "$@"
@BMTLab
Copy link
Author

BMTLab commented Apr 24, 2024

NuGet Package Index Checker

This Bash script is designed to verify whether a specific version of a NuGet package is available and indexed on nuget.org.

It's particularly useful in CI/CD pipelines to ensure that dependent packages are available before proceeding with deployments or further package publishing.

Tip

To use this kind of checking via GitHub Actions, instead of embedding this script, you can add this action to your workflow nuget-package-check-action

Prerequisites

  • bash environment (Linux, macOS, or Windows Subsystem for Linux)
  • curl must be installed on your system to make HTTP requests.

Features

✅ Checks the indexing status of a specified NuGet package.
✅ Allows multiple attempts to check for package indexing.
✅ Configurable parameters via command-line options.
✅ Detailed logging for each attempt.

Installation

  1. Download the script to your local machine or CI/CD environment.
  2. Make the script executable:
chmod +x check-nuget-pkg-indexed.sh

Usage

Run the script from the command line with the necessary parameters:

./check-nuget-pkg-indexed.sh [-p] <package> [-a] <attempts> -v <version>

Parameters:

-p : Specifies the NuGet package name. Default is BMTLab.OneOf.Reduced.
-a : Specifies the maximum number of attempts to check if the package is indexed. Default is 10.
-v : Specifies the version of the package to check. This parameter is required.
-h: Displays help information.

Examples:

Check a package with default settings:

./check-nuget-pkg-indexed.sh -v "1.2.3"

Check a package with custom settings:

./check-nuget-pkg-indexed.sh -p "MyCustomPackage" -a 5 -v "1.2.3-beta"

Handling Outputs

✅ The script logs detailed information about each check attempt.
✅ Upon success, a message indicating the package is indexed will be shown.
❌ If the package is not indexed after the specified attempts, the script will exit with an error.

Exit Codes

0: Success - Package is indexed.
20: Missing required argument.
30: Invalid option was provided.
40: Invalid version format.
50: Package not found or not indexed after all attempts.

Script Modifications

You can modify default values directly in the script to better fit your workflow or environment requirements. Ensure to maintain proper syntax and test changes in a controlled environment 😇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment