GitHub Release Management Skill
This skill provides operations for managing GitHub releases, including creating releases, uploading assets, managing tags, and distributing software versions.
Available Operations
1. Create Release
Create a new release with tag, title, and release notes.
2. List Releases
View all releases in a repository.
3. View Release
Get details about a specific release.
4. Edit Release
Update release information.
5. Delete Release
Remove a release (keeps the tag).
6. Upload Assets
Add files to a release.
7. Download Assets
Download release assets.
8. Delete Assets
Remove assets from a release.
9. Manage Tags
Create and manage Git tags for releases.
Usage Examples
Create Release
Create release from tag:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes "Initial release with core features"
Create with auto-generated notes:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --generate-notes
Create from notes file:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes-file CHANGELOG.md
Create pre-release:
gh release create v2.0.0-beta.1 --repo owner/repo-name \ --title "Version 2.0.0 Beta 1" \ --notes "Beta release for testing" \ --prerelease
Create draft release:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes "Release draft" \ --draft
Create with assets:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes "Release with binaries" \ dist/app-linux-x64.tar.gz \ dist/app-macos-x64.tar.gz \ dist/app-windows-x64.zip
Create on specific branch/commit:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes "Release notes" \ --target main
Latest release:
gh release create v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0" \ --notes "Latest stable release" \ --latest
List Releases
List all releases:
gh release list --repo owner/repo-name
Limit results:
gh release list --repo owner/repo-name --limit 10
Exclude drafts:
gh release list --repo owner/repo-name --exclude-drafts
Exclude pre-releases:
gh release list --repo owner/repo-name --exclude-pre-releases
JSON output:
gh release list --repo owner/repo-name --json tagName,name,publishedAt,isPrerelease,isDraft
Using API:
gh api repos/owner/repo-name/releases --jq '.[] | {tag: .tag_name, name: .name, published: .published_at}'
View Release
View latest release:
gh release view --repo owner/repo-name
View specific release:
gh release view v1.0.0 --repo owner/repo-name
View in browser:
gh release view v1.0.0 --repo owner/repo-name --web
JSON output:
gh release view v1.0.0 --repo owner/repo-name --json tagName,name,body,assets,publishedAt
View assets:
gh release view v1.0.0 --repo owner/repo-name --json assets --jq '.assets[] | {name, size, download_count}'
Edit Release
Update title and notes:
gh release edit v1.0.0 --repo owner/repo-name \ --title "Version 1.0.0 - Updated" \ --notes "Updated release notes"
Update from file:
gh release edit v1.0.0 --repo owner/repo-name \ --notes-file RELEASE_NOTES.md
Mark as latest:
gh release edit v1.0.0 --repo owner/repo-name --latest
Mark as pre-release:
gh release edit v1.0.0 --repo owner/repo-name --prerelease
Publish draft:
gh release edit v1.0.0 --repo owner/repo-name --draft=false
Change to draft:
gh release edit v1.0.0 --repo owner/repo-name --draft
Update discussion category:
gh release edit v1.0.0 --repo owner/repo-name --discussion-category announcements
Delete Release
Delete release (keeps tag):
gh release delete v1.0.0 --repo owner/repo-name
Delete with confirmation:
gh release delete v1.0.0 --repo owner/repo-name --yes
Delete and cleanup tag:
gh release delete v1.0.0 --repo owner/repo-name --yes git push --delete origin v1.0.0 # Delete remote tag
Upload Assets
Upload single file:
gh release upload v1.0.0 dist/app.tar.gz --repo owner/repo-name
Upload multiple files:
gh release upload v1.0.0 --repo owner/repo-name \ dist/app-linux.tar.gz \ dist/app-macos.tar.gz \ dist/app-windows.zip
Upload with glob pattern:
gh release upload v1.0.0 dist/*.tar.gz --repo owner/repo-name
Overwrite existing asset:
gh release upload v1.0.0 dist/app.tar.gz --repo owner/repo-name --clobber
Using API:
# Get upload URL
UPLOAD_URL=$(gh api repos/owner/repo-name/releases/tags/v1.0.0 --jq '.upload_url' | sed 's/{?name,label}//')
# Upload asset
gh api "$UPLOAD_URL?name=app.tar.gz" \
-X POST \
-H "Content-Type: application/gzip" \
--input dist/app.tar.gz
Download Assets
Download all assets:
gh release download v1.0.0 --repo owner/repo-name
Download specific asset:
gh release download v1.0.0 --repo owner/repo-name --pattern "*.tar.gz"
Download to directory:
gh release download v1.0.0 --repo owner/repo-name --dir downloads/
Download latest release:
gh release download --repo owner/repo-name
Download with pattern matching:
gh release download v1.0.0 --repo owner/repo-name --pattern "*linux*"
Using API to get download URL:
# Get asset URL
gh api repos/owner/repo-name/releases/tags/v1.0.0 --jq '.assets[] | {name, browser_download_url}'
# Download with curl
ASSET_URL=$(gh api repos/owner/repo-name/releases/tags/v1.0.0 --jq '.assets[0].browser_download_url')
curl -L -o app.tar.gz "$ASSET_URL"
Delete Assets
Using API to delete asset:
# Get asset ID ASSET_ID=$(gh api repos/owner/repo-name/releases/tags/v1.0.0 --jq '.assets[] | select(.name=="app.tar.gz") | .id') # Delete asset gh api repos/owner/repo-name/releases/assets/$ASSET_ID -X DELETE
Delete and re-upload:
# Delete old asset ASSET_ID=$(gh api repos/owner/repo-name/releases/tags/v1.0.0 --jq '.assets[] | select(.name=="app.tar.gz") | .id') gh api repos/owner/repo-name/releases/assets/$ASSET_ID -X DELETE # Upload new version gh release upload v1.0.0 dist/app.tar.gz --repo owner/repo-name
Manage Tags
Create tag:
cd repo-name git tag -a v1.0.0 -m "Version 1.0.0" git push origin v1.0.0
List tags:
cd repo-name git tag -l
View tag details:
cd repo-name git show v1.0.0
Delete tag:
cd repo-name git tag -d v1.0.0 # Delete local git push --delete origin v1.0.0 # Delete remote
Create tag from specific commit:
cd repo-name git tag -a v1.0.0 abc123def -m "Version 1.0.0" git push origin v1.0.0
Common Patterns
Standard Release Workflow
# 1. Prepare release VERSION="v1.2.0" cd repo-name # 2. Update version files echo "1.2.0" > VERSION git add VERSION git commit -m "Bump version to 1.2.0" git push # 3. Create and push tag git tag -a $VERSION -m "Release $VERSION" git push origin $VERSION # 4. Build release artifacts npm run build # or your build command mkdir -p dist # 5. Create release with artifacts gh release create $VERSION \ --title "Release $VERSION" \ --generate-notes \ dist/*.tar.gz \ dist/*.zip
Pre-release to Stable
# 1. Create pre-release gh release create v2.0.0-rc.1 --repo owner/repo-name \ --title "Release Candidate 1" \ --notes "Testing release" \ --prerelease \ dist/* # 2. After testing, promote to stable gh release edit v2.0.0-rc.1 --repo owner/repo-name \ --prerelease=false \ --latest # 3. Or create new stable release gh release create v2.0.0 --repo owner/repo-name \ --title "Version 2.0.0" \ --notes "Stable release" \ dist/*
Draft Release for Review
# 1. Create draft gh release create v1.5.0 --repo owner/repo-name \ --title "Version 1.5.0" \ --notes-file CHANGELOG.md \ --draft \ dist/* # 2. Review in browser gh release view v1.5.0 --repo owner/repo-name --web # 3. Publish when ready gh release edit v1.5.0 --repo owner/repo-name --draft=false
Multi-Platform Release
VERSION="v1.0.0" # Build for all platforms ./build-linux.sh ./build-macos.sh ./build-windows.sh # Create release with all platform binaries gh release create $VERSION --repo owner/repo-name \ --title "Version 1.0.0 - Multi-platform" \ --notes "Available for Linux, macOS, and Windows" \ dist/app-linux-amd64.tar.gz \ dist/app-linux-arm64.tar.gz \ dist/app-darwin-amd64.tar.gz \ dist/app-darwin-arm64.tar.gz \ dist/app-windows-amd64.zip \ dist/app-windows-arm64.zip
Automated Release with GitHub Actions
# Trigger release workflow (example) gh workflow run release.yml --repo owner/repo-name \ -f version=1.2.0 \ -f prerelease=false # Monitor release workflow gh run watch $(gh run list --workflow release.yml --limit 1 --json databaseId --jq '.[0].databaseId')
Rollback Release
# 1. Delete problematic release gh release delete v1.2.0 --repo owner/repo-name --yes # 2. Delete tag git push --delete origin v1.2.0 # 3. Mark previous version as latest gh release edit v1.1.0 --repo owner/repo-name --latest
Generate Release Notes from Commits
VERSION="v1.3.0" PREV_VERSION="v1.2.0" # Get commits since last release git log $PREV_VERSION..HEAD --pretty=format:"- %s (%h)" > release_notes.txt # Create release gh release create $VERSION --repo owner/repo-name \ --title "Release $VERSION" \ --notes-file release_notes.txt \ dist/*
Download Latest Release for Installation
# Script to download and install latest release REPO="owner/repo-name" # Get latest release tag LATEST=$(gh release view --repo $REPO --json tagName --jq '.tagName') # Download release assets gh release download $LATEST --repo $REPO --pattern "*linux*" # Extract and install tar -xzf app-linux-*.tar.gz sudo mv app /usr/local/bin/
Advanced Usage
Release Statistics
View download counts:
gh api repos/owner/repo-name/releases --jq '.[] | {
tag: .tag_name,
downloads: [.assets[].download_count] | add
}'
Most popular release:
gh api repos/owner/repo-name/releases --jq 'map({
tag: .tag_name,
downloads: [.assets[].download_count] | add
}) | sort_by(.downloads) | reverse | .[0]'
Asset-level statistics:
gh release view v1.0.0 --repo owner/repo-name --json assets --jq '.assets[] | {
name,
size,
downloads: .download_count
} | sort_by(.downloads) | reverse'
Bulk Release Management
List all tags without releases:
# Get all tags ALL_TAGS=$(git tag) # Get tags with releases RELEASE_TAGS=$(gh release list --repo owner/repo-name --limit 1000 --json tagName --jq '.[].tagName') # Find difference comm -23 <(echo "$ALL_TAGS" | sort) <(echo "$RELEASE_TAGS" | sort)
Delete old pre-releases:
gh api repos/owner/repo-name/releases --jq '.[] | select(.prerelease==true) | select(.created_at < "2024-01-01") | .tag_name' | \
while read tag; do
echo "Deleting $tag"
gh release delete $tag --repo owner/repo-name --yes
done
Custom Release Notes Template
# Create release notes from template cat > release_notes.md << EOF ## What's Changed $(git log v1.0.0..v1.1.0 --pretty=format:"- %s by @%an" | grep -v "Merge pull request") ## New Contributors $(git log v1.0.0..v1.1.0 --pretty=format:"%an" | sort -u | sed 's/^/* @/') **Full Changelog**: https://github.com/owner/repo-name/compare/v1.0.0...v1.1.0 EOF gh release create v1.1.0 --notes-file release_notes.md
Error Handling
Tag Already Exists
# Check if tag exists git tag -l v1.0.0 # Delete and recreate if needed git tag -d v1.0.0 git push --delete origin v1.0.0 git tag -a v1.0.0 -m "Release v1.0.0" git push origin v1.0.0
Release Already Exists
# Check if release exists gh release view v1.0.0 --repo owner/repo-name 2>&1 | grep -q "release not found" || echo "Release exists" # Delete and recreate gh release delete v1.0.0 --repo owner/repo-name --yes gh release create v1.0.0 --title "Version 1.0.0" --notes "Release notes"
Asset Upload Failures
# Verify asset exists locally [ -f dist/app.tar.gz ] && echo "File exists" || echo "File not found" # Check file size (GitHub limit is 2GB per asset) ls -lh dist/app.tar.gz # Retry upload gh release upload v1.0.0 dist/app.tar.gz --repo owner/repo-name --clobber
Best Practices
- •Use semantic versioning: Follow vX.Y.Z format (e.g., v1.2.3)
- •Write meaningful notes: Include what changed, breaking changes, and upgrade instructions
- •Use draft releases: Review before publishing
- •Tag commits properly: Create annotated tags with messages
- •Include checksums: Provide SHA256 checksums for assets
- •Test pre-releases: Use beta/rc releases for testing
- •Clean naming: Use consistent asset naming conventions
- •Keep releases focused: One release per version
- •Link to documentation: Include links to docs in release notes
- •Archive old releases: Delete very old pre-releases to reduce clutter
Semantic Versioning
- •Major (X.0.0): Breaking changes
- •Minor (1.X.0): New features, backwards compatible
- •Patch (1.2.X): Bug fixes, backwards compatible
- •Pre-release: v1.2.0-alpha.1, v1.2.0-beta.1, v1.2.0-rc.1
Integration with Other Skills
- •Use
workflow-managementto automate releases with GitHub Actions - •Use
issue-managementto reference issues fixed in release - •Use
pull-request-managementto include PR links in notes - •Use
commit-operationsto generate changelog from commits