• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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