1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
#!/usr/bin/env bash
set -euo pipefail
VERSION="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version')"
DATE="$(date +%Y-%m-%d)"
echo "Preparing release version $VERSION"
# Check if the version is already in the changelog
if git rev-parse -q --verify "v$VERSION" >/dev/null 2>&1; then
echo "Error: git tag v$VERSION already exists! Aborting."
exit 1
fi
# Change to version and date if Unreleased
if ! grep -qE "^## \\[$VERSION\\]" CHANGELOG.md; then
if grep -qE "^## \\[Unreleased\\]" CHANGELOG.md; then
echo "Renaming [Unreleased] to [$VERSION] - $DATE"
sed -i "s/^## \\[Unreleased\\]/## [$VERSION] - $DATE/" CHANGELOG.md
else
echo "Error: No '## [Unreleased]' or '## [$VERSION]' heading found in CHANGELOG.md."
exit 1
fi
fi
# Extract the changes text for this version
CHANGELOG_CONTENT="$(
awk "/^## \\[$VERSION\\]/ {found=1; next} /^## \\[/ {found=0} found" CHANGELOG.md
)"
if [ -z "$(echo "$CHANGELOG_CONTENT" | sed 's/^[[:space:]]*\$//')" ]; then
echo "Error: No content found for version $VERSION in CHANGELOG.md!"
exit 1
fi
echo "Changelog content for version $VERSION:"
echo "$CHANGELOG_CONTENT"
# Abort if dirty
if ! git diff-index --quiet HEAD --; then
echo "Error: Working directory is dirty! Please commit or stash your changes before proceeding."
exit 1
fi
# Ensure on main
if ! git rev-parse --abbrev-ref HEAD | grep -q "main"; then
echo "Error: Not on main branch! Please switch to the main branch before proceeding."
exit 1
fi
echo "Creating signed git tag v$VERSION"
echo "$CHANGELOG_CONTENT" | git tag -a "v$VERSION" -F -
echo "Tag v$VERSION created."
# Check to continue
read -r -p "Tag v$VERSION created locally. Push tag to origin? [y/N] " answer
case "$answer" in
[Yy]* )
echo "Pushing tag v$VERSION to origin..."
# Ensure the tagged commit is pushed to the remote
git push origin
git push origin "v$VERSION"
;;
* )
echo "Skipping tag push."
exit 0
;;
esac
read -r -p "Create GitHub release with 'gh release create v$VERSION --notes-from-tag'? [y/N] " answer
case "$answer" in
[Yy]* )
echo "Creating GitHub release from tag..."
gh release create "v$VERSION" --notes-from-tag --verify-tag --title "v$VERSION"
;;
* )
echo "Skipping GitHub release creation."
;;
esac
read -r -p "Publish version $VERSION to crates.io? [y/N] " answer
case "$answer" in
[Yy]* )
echo "Publishing to crates.io..."
cargo publish
;;
* )
echo "Skipping crates.io publish."
;;
esac
|