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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$SCRIPT_DIR/.."
# Parse arguments
version="${1:-}"
repo="${2:-direnv/direnv}"
if [[ -z $version ]]; then
echo "USAGE: $0 version [owner/repo]" >&2
echo "Example: $0 v2.37.0" >&2
echo "Example: $0 v2.37.0-test Mic92/direnv" >&2
exit 1
fi
# Remove 'v' prefix if present for consistency
version_number="${version#v}"
version_tag="v${version_number}"
# Determine remote URL
if [[ "$repo" == "direnv/direnv" ]]; then
remote_url="origin"
else
remote_url="git@github.com:${repo}.git"
fi
if [[ "$(git symbolic-ref --short HEAD)" != "master" ]]; then
echo "must be on master branch" >&2
exit 1
fi
waitForPr() {
local pr_branch=$1
while true; do
if gh pr view "$pr_branch" --repo "$repo" --json state --jq '.state' | grep -q 'MERGED'; then
break
fi
echo "Waiting for PR to be merged..."
sleep 5
done
}
# Ensure we are up-to-date
uncommitted_changes=$(git diff --compact-summary)
if [[ -n $uncommitted_changes ]]; then
echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2
exit 1
fi
if [[ "$remote_url" == "origin" ]]; then
git fetch origin
unpushed_commits=$(git log --format=oneline origin/master..master)
if [[ $unpushed_commits != "" ]]; then
echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2
exit 1
fi
git pull origin master
else
# For forks, we need to fetch from the fork repo
git fetch "$remote_url" master
git pull "$remote_url" master
fi
# Make sure tag does not exist
if git tag -l | grep -q "^${version_tag}\$"; then
echo "Tag ${version_tag} already exists, exiting" >&2
exit 1
fi
echo "Generating changelog..."
git changelog
echo ""
read -p "Continue with release ${version_tag}? (y/N): " -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Release aborted. Resetting changes..."
exit 0
fi
echo "Updating version.txt to ${version_number}..."
echo "${version_number}" > version.txt
echo "Creating release branch..."
git branch -D "release-${version_tag}" 2>/dev/null || true
git checkout -b "release-${version_tag}"
echo "Committing changes..."
git add version.txt CHANGELOG.md
git commit -m "Release ${version_tag}"
echo "Pushing release branch..."
if [[ "$remote_url" == "origin" ]]; then
git push origin "release-${version_tag}"
else
git push "$remote_url" "release-${version_tag}"
fi
echo "Creating pull request..."
pr_url=$(gh pr create \
--repo "$repo" \
--base master \
--head "release-${version_tag}" \
--title "Release ${version_tag}" \
--body "Release ${version_tag}")
# Extract PR number from URL
pr_number=$(echo "$pr_url" | grep -oE '[0-9]+$')
echo "Enabling auto-merge..."
gh pr merge "$pr_number" --repo "$repo" --auto --merge
echo "Switching back to master..."
git checkout master
echo "Waiting for PR to be merged..."
waitForPr "release-${version_tag}"
echo "Fetching latest master..."
if [[ "$remote_url" == "origin" ]]; then
git pull origin master
else
git pull "$remote_url" master
fi
echo "Creating and pushing tag..."
git tag "${version_tag}"
if [[ "$remote_url" == "origin" ]]; then
git push origin "${version_tag}"
else
git push "$remote_url" "${version_tag}"
fi
echo ""
echo "✅ Release ${version_tag} has been created!"
echo "🚀 CI will now build and publish the binaries automatically."
echo "📦 Check the release at: https://github.com/${repo}/releases/tag/${version_tag}"
|