1#!/bin/bash 2set -euo pipefail 3IFS=$'\n\t' 4cd "$(dirname "$0")"/.. 5 6# Publish a new release. 7# 8# USAGE: 9# ./tools/publish.sh 10# 11# Note: 12# - This script requires parse-changelog <https://github.com/taiki-e/parse-changelog> 13 14bail() { 15 echo >&2 "error: $*" 16 exit 1 17} 18 19if [[ $# -gt 0 ]]; then 20 bail "invalid argument '$1'" 21fi 22 23# Make sure that the version number of all publishable workspace members matches. 24metadata="$(cargo metadata --format-version=1 --all-features --no-deps)" 25for id in $(jq <<<"${metadata}" '.workspace_members[]'); do 26 pkg="$(jq <<<"${metadata}" ".packages[] | select(.id == ${id})")" 27 publish=$(jq <<<"${pkg}" -r '.publish') 28 # Publishing is unrestricted if null, and forbidden if an empty array. 29 if [[ "${publish}" == "[]" ]]; then 30 continue 31 fi 32 actual_version=$(jq <<<"${pkg}" -r '.version') 33 if [[ -z "${version:-}" ]]; then 34 version="${actual_version}" 35 fi 36 if [[ "${actual_version}" != "${version}" ]]; then 37 name=$(jq <<<"${pkg}" -r '.name') 38 bail "publishable workspace members must be version '${version}', but package '${name}' is version '${actual_version}'" 39 fi 40done 41tag="v${version}" 42 43# Make sure there is no uncommitted change. 44git diff --exit-code 45git diff --exit-code --staged 46 47# Make sure the same release has not been created in the past. 48if gh release view "${tag}" &>/dev/null; then 49 bail "tag '${tag}' has already been created and pushed" 50fi 51 52# Make sure that a valid release note for this version exists. 53# https://github.com/taiki-e/parse-changelog 54echo "============== CHANGELOG ==============" 55parse-changelog CHANGELOG.md "${version}" 56echo "=======================================" 57 58release_date=$(date --utc '+%Y-%m-%d') 59if ! grep -Eq "^## \\[${version//./\\.}\\] - ${release_date}$" CHANGELOG.md; then 60 bail "not found section '[${version}] - ${release_date}' in CHANGELOG.md" 61fi 62if ! grep -Eq "^\\[${version//./\\.}\\]: " CHANGELOG.md; then 63 bail "not found link to [${version}] in CHANGELOG.md" 64fi 65 66if ! git branch | grep -q '\* main'; then 67 bail "current branch is not 'main'" 68fi 69 70set -x 71 72git tag "${tag}" 73git push origin main 74git push origin --tags 75