-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
38 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,66 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
IFS=$'\n\t' | ||
|
||
# Automate the local side release step. | ||
# Publish a new release. | ||
# | ||
# Usage: | ||
# ./tools/publish.sh <version> [--dry-run] | ||
# USAGE: | ||
# ./tools/publish.sh | ||
# | ||
# Note: | ||
# - This script assumes all crates that this script will publish have the same version numbers | ||
# NOTE: | ||
# - This script requires parse-changelog <https://github.com/taiki-e/parse-changelog> | ||
|
||
set -euo pipefail | ||
IFS=$'\n\t' | ||
|
||
cd "$(cd "$(dirname "$0")" && pwd)"/.. | ||
|
||
# A list of paths to the crate to be published. | ||
MEMBERS=( | ||
"." | ||
) | ||
|
||
error() { | ||
echo "error: $*" >&2 | ||
} | ||
|
||
# Parse arguments. | ||
version="${1:?}" | ||
tag="v${version}" | ||
if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z\.-]+)?(\+[0-9A-Za-z\.-]+)?$ ]]; then | ||
error "invalid version format: '${version}'" | ||
exit 1 | ||
fi | ||
if [[ "${2:-}" == "--dry-run" ]]; then | ||
dry_run="--dry-run" | ||
shift | ||
fi | ||
if [[ -n "${2:-}" ]]; then | ||
error "invalid argument: '$2'" | ||
bail() { | ||
echo >&2 "error: $*" | ||
exit 1 | ||
fi | ||
} | ||
|
||
if [[ -z "${dry_run:-}" ]]; then | ||
git diff --exit-code | ||
git diff --exit-code --staged | ||
if [[ $# -gt 0 ]]; then | ||
bail "invalid argument '$1'" | ||
fi | ||
|
||
# Make sure that the version number of the workspace members matches the specified version. | ||
for member in "${MEMBERS[@]}"; do | ||
if [[ ! -d "${member}" ]]; then | ||
error "not found workspace member '${member}'" | ||
exit 1 | ||
# Make sure that the version number of all publishable workspace members matches. | ||
metadata="$(cargo metadata --format-version=1 --all-features --no-deps)" | ||
for id in $(jq <<<"${metadata}" '.workspace_members[]'); do | ||
pkg="$(jq <<<"${metadata}" ".packages[] | select(.id == ${id})")" | ||
publish=$(jq <<<"${pkg}" -r '.publish') | ||
# Publishing is unrestricted if null, and forbidden if an empty array. | ||
if [[ "${publish}" == "[]" ]]; then | ||
continue | ||
fi | ||
actual_version=$(jq <<<"${pkg}" -r '.version') | ||
if [[ -z "${version:-}" ]]; then | ||
version="${actual_version}" | ||
fi | ||
if [[ "${actual_version}" != "${version}" ]]; then | ||
name=$(jq <<<"${pkg}" -r '.name') | ||
bail "publishable workspace members must be version '${version}', but package '${name}' is version '${actual_version}'" | ||
fi | ||
( | ||
cd "${member}" | ||
actual=$(cargo pkgid | sed 's/.*#//') | ||
if [[ "${actual}" != "${version}" ]] && [[ "${actual}" != *":${version}" ]]; then | ||
error "expected to release version '${version}', but ${member}/Cargo.toml contained '${actual}'" | ||
exit 1 | ||
fi | ||
) | ||
done | ||
tag="v${version}" | ||
|
||
# Make sure there is no uncommitted change. | ||
git diff --exit-code | ||
git diff --exit-code --staged | ||
|
||
# Make sure that a valid release note for this version exists. | ||
# https://github.com/taiki-e/parse-changelog | ||
echo "============== CHANGELOG ==============" | ||
parse-changelog CHANGELOG.md "${version}" | ||
echo "=======================================" | ||
|
||
# Make sure the same release has not been created in the past. | ||
if gh release view "${tag}" &>/dev/null; then | ||
error "tag '${tag}' has already been created and pushed" | ||
exit 1 | ||
if ! grep <CHANGELOG.md -E "^\\[${version//./\\.}\\]: " >/dev/null; then | ||
bail "not found link to [${version}] in CHANGELOG.md" | ||
fi | ||
|
||
# Exit if dry run. | ||
if [[ -n "${dry_run:-}" ]]; then | ||
echo "warning: skip creating a new tag '${tag}' due to dry run" | ||
exit 0 | ||
# Make sure the same release has not been created in the past. | ||
if gh release view "${tag}" &>/dev/null; then | ||
bail "tag '${tag}' has already been created and pushed" | ||
fi | ||
|
||
echo "info: creating and pushing a new tag '${tag}'" | ||
set -x | ||
|
||
git tag "${tag}" | ||
git push origin --tags |