github-mcp-server / script /tag-release
Gemini
Initial commit
fce10de
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
# Initialize variables
TAG=""
DRY_RUN=false
# Parse arguments
for arg in "$@"; do
case $arg in
--dry-run)
DRY_RUN=true
;;
*)
# The first non-flag argument is the tag
if [[ ! $arg == --* ]]; then
if [ -z "$TAG" ]; then
TAG=$arg
fi
fi
;;
esac
done
if [ "$DRY_RUN" = true ]; then
echo "DRY RUN: No changes will be pushed to the remote repository."
echo
fi
# 1. Validate input
if [ -z "$TAG" ]; then
echo "Error: No tag specified."
echo "Usage: ./script/tag-release vX.Y.Z [--dry-run]"
exit 1
fi
# Regular expression for semantic versioning (vX.Y.Z or vX.Y.Z-suffix)
if [[ ! $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
echo "Error: Tag must be in format vX.Y.Z or vX.Y.Z-suffix (e.g., v1.0.0 or v1.0.0-rc1)"
exit 1
fi
# 2. Check current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT_BRANCH" != "main" ]; then
echo "Error: You must be on the 'main' branch to create a release."
echo "Current branch is '$CURRENT_BRANCH'."
exit 1
fi
# 3. Fetch latest from origin
echo "Fetching latest changes from origin..."
git fetch origin main
# 4. Check if the working directory is clean
if ! git diff-index --quiet HEAD --; then
echo "Error: Working directory is not clean. Please commit or stash your changes."
exit 1
fi
# 5. Check if main is up-to-date with origin/main
LOCAL_SHA=$(git rev-parse @)
REMOTE_SHA=$(git rev-parse @{u})
if [ "$LOCAL_SHA" != "$REMOTE_SHA" ]; then
echo "Error: Your local 'main' branch is not up-to-date with 'origin/main'. Please pull the latest changes."
exit 1
fi
echo "βœ… Local 'main' branch is up-to-date with 'origin/main'."
# 6. Check if tag already exists
if git tag -l | grep -q "^${TAG}$"; then
echo "Error: Tag ${TAG} already exists locally."
exit 1
fi
if git ls-remote --tags origin | grep -q "refs/tags/${TAG}$"; then
echo "Error: Tag ${TAG} already exists on remote 'origin'."
exit 1
fi
# 7. Confirm release with user
echo
LATEST_TAG=$(git tag --sort=-version:refname | head -n 1)
if [ -n "$LATEST_TAG" ]; then
echo "Current latest release: $LATEST_TAG"
fi
echo "Proposed new release: $TAG"
echo
read -p "Do you want to proceed with the release? (y/n) " -n 1 -r
echo # Move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Release cancelled."
exit 1
fi
echo
# 8. Create the new release tag
if [ "$DRY_RUN" = true ]; then
echo "DRY RUN: Skipping creation of tag $TAG."
else
echo "Creating new release tag: $TAG"
git tag -a "$TAG" -m "Release $TAG"
fi
# 9. Push the new tag to the remote repository
if [ "$DRY_RUN" = true ]; then
echo "DRY RUN: Skipping push of tag $TAG to origin."
else
echo "Pushing tag $TAG to origin..."
git push origin "$TAG"
fi
# 10. Update and push the 'latest-release' tag
if [ "$DRY_RUN" = true ]; then
echo "DRY RUN: Skipping update and push of 'latest-release' tag."
else
echo "Updating 'latest-release' tag to point to $TAG..."
git tag -f latest-release "$TAG"
echo "Pushing 'latest-release' tag to origin..."
git push origin latest-release --force
fi
if [ "$DRY_RUN" = true ]; then
echo "βœ… DRY RUN complete. No tags were created or pushed."
else
echo "βœ… Successfully tagged and pushed release $TAG."
echo "βœ… 'latest-release' tag has been updated."
fi
# 11. Post-release instructions
REPO_URL=$(git remote get-url origin)
REPO_SLUG=$(echo "$REPO_URL" | sed -e 's/.*github.com[:\/]//' -e 's/\.git$//')
cat << EOF
## πŸŽ‰ Release $TAG has been initiated!
### Next steps:
1. πŸ“‹ Check https://github.com/$REPO_SLUG/releases and wait for the draft release to show up (after the goreleaser workflow completes)
2. ✏️ Edit the new release, delete the existing notes and click the auto-generate button GitHub provides
3. ✨ Add a section at the top calling out the main features
4. πŸš€ Publish the release
5. πŸ“’ Post message in #gh-mcp-releases channel in Slack and then share to the other mcp channels
### Resources:
- πŸ“¦ Draft Release: https://github.com/$REPO_SLUG/releases/tag/$TAG
The release process is now ready for your review and completion!
EOF