Skip to content
205 changes: 205 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
name: 🏷️ Auto Tag and Release

# Triggers on push to master branch (fully automated)
on:
push:
branches: [ master ]
workflow_dispatch: # Manual trigger option

# Required permissions for tagging and releasing
permissions:
contents: write
packages: write

jobs:
auto-tag-and-release:
runs-on: ubuntu-latest

steps:
# Step 1: Checkout with full history for proper versioning
- name: 🔄 Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

# Step 2: Validate shell scripts (maintain keegees quality standards)
- name: 🔍 Run ShellCheck
run: |
shellcheck keegees.sh
shellcheck install.sh

# Step 3: Calculate Next Version for custom tag format
- name: 📊 Calculate Next Version
id: get_next_version
run: |
# Get latest tag or default to 0.0.0
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")

# Extract version number (remove v prefix)
CURRENT_VERSION=${LATEST_TAG#v}

# Split version into components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Increment patch version (as per requirement 1.1)
NEXT_PATCH=$((PATCH + 1))
NEXT_VERSION="${MAJOR}.${MINOR}.${NEXT_PATCH}"

echo "version=$NEXT_VERSION" >> $GITHUB_OUTPUT
echo "tag=v$NEXT_VERSION" >> $GITHUB_OUTPUT
echo "📊 Next version will be: v$NEXT_VERSION"

# Step 4: Update all version references in codebase
- name: 🔄 Synchronize Version Across Files
run: |
NEW_VERSION="${{ steps.get_next_version.outputs.version }}"
echo "🔄 Updating version to $NEW_VERSION across all files..."

# Update README.md version badge
sed -i "s/Version-[0-9.]*/Version-$NEW_VERSION/g" README.md

# Update README.md version warning text
sed -i "s/version [0-9.]*/version $NEW_VERSION/g" README.md

# Update CLI example in README.md (the "Version 1.0.0" display)
sed -i "s/Version [0-9.]\+/Version $NEW_VERSION/g" README.md

# Update keegees.sh VERSION constant
sed -i "s/readonly VERSION=\"[0-9.]*\"/readonly VERSION=\"$NEW_VERSION\"/g" keegees.sh

# Verify changes
echo "📊 Version references updated:"
echo " README.md badge: $(grep -o 'Version-[0-9.]*' README.md)"
echo " README.md warning: $(grep -o 'version [0-9.]*' README.md)"
echo " keegees.sh VERSION: $(grep -o 'readonly VERSION=\"[0-9.]*\"' keegees.sh)"

# Step 5: Commit version updates before creating tag
- name: 💾 Commit Version Updates
run: |
NEW_VERSION="${{ steps.get_next_version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

# Add updated files
git add README.md keegees.sh

# Check if there are changes to commit
if git diff --cached --quiet; then
echo "No version updates needed"
else
git commit -m "🔄 Sync version to $NEW_VERSION across all files

- Update README.md version badge and references
- Update keegees.sh VERSION constant
- Ensure consistency across codebase

[skip ci]"
fi

# Step 6: Create the custom formatted tag
- name: 🏷️ Create Custom Tag
run: |
TAG="v${{ steps.get_next_version.outputs.version }}"
git tag -a "$TAG" -m "🤖 Automated version tag: $TAG"
# Push commits first, then tag (commits have [skip ci] to prevent recursion)
git push
git push origin "$TAG"

# Step 7: Create release archives (source code)
- name: 📦 Create Release Archives
run: |
# Create release directory
mkdir -p release

# Create tarball
tar -czf "release/keegees-${{ steps.get_next_version.outputs.version }}.tar.gz" \
--exclude='.git' \
--exclude='.github' \
--exclude='release' \
--transform "s|^|keegees-${{ steps.get_next_version.outputs.version }}/|" \
.

# Create zip archive
zip -r "release/keegees-${{ steps.get_next_version.outputs.version }}.zip" \
. \
-x '.git/*' '.github/*' 'release/*'

# Step 8: Generate release notes
- name: 📝 Generate Release Notes
id: release_notes
run: |
# Get commits since last tag (exclude current version being created)
LAST_TAG=$(git describe --tags --abbrev=0 --exclude="v${{ steps.get_next_version.outputs.version }}" 2>/dev/null || echo "")

if [ -n "$LAST_TAG" ]; then
COMMITS=$(git log $LAST_TAG..HEAD --oneline --no-merges | grep -v "🔄 Sync version" || true)
else
COMMITS=$(git log --oneline --no-merges | grep -v "🔄 Sync version" || true)
fi

# Set dynamic version warning based on version
NEW_VERSION="${{ steps.get_next_version.outputs.version }}"
MAJOR=$(echo "$NEW_VERSION" | cut -d. -f1)
if [ "$MAJOR" = "0" ]; then
EARLY_WARNING="**⚠️ Early Release Notice**: This is a pre-1.0 release. Always use \`--dry-run\` before making changes to your system keybindings."
else
EARLY_WARNING="**✅ Stable Release**: Ready for production use."
fi

# Create release notes
cat << EOF > release_notes.md
## 🚀 keegees v${{ steps.get_next_version.outputs.version }}

**Professional GNOME keybinding management tool**

### 📋 What's Included
- \`keegees.sh\` - Main executable script (1889+ lines)
- \`install.sh\` - POSIX-compliant installation script
- Complete documentation and examples

### ⚡ Quick Install
\`\`\`bash
# Download and extract
wget https://github.com/nutthead/keegees/releases/download/v${{ steps.get_next_version.outputs.version }}/keegees-${{ steps.get_next_version.outputs.version }}.tar.gz
tar -xzf keegees-${{ steps.get_next_version.outputs.version }}.tar.gz
cd keegees-${{ steps.get_next_version.outputs.version }}
./install.sh
\`\`\`

### 🔧 Requirements
- bash (script execution)
- gsettings (GNOME integration)
- bc (POSIX arithmetic)

### 📈 Changes in this release
$COMMITS

---
${EARLY_WARNING}
EOF

# Step 9: Create GitHub Release (fully automated)
- name: 🎉 Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.get_next_version.outputs.version }}
name: "keegees v${{ steps.get_next_version.outputs.version }}"
body_path: release_notes.md
draft: false
prerelease: false
generate_release_notes: true
make_latest: true
files: |
release/keegees-${{ steps.get_next_version.outputs.version }}.tar.gz
release/keegees-${{ steps.get_next_version.outputs.version }}.zip
token: ${{ secrets.GITHUB_TOKEN }}

# Step 10: Output summary
- name: ✅ Release Summary
run: |
echo "🎉 Successfully created release: v${{ steps.get_next_version.outputs.version }}"
echo "📦 Release assets:"
echo " - keegees-${{ steps.get_next_version.outputs.version }}.tar.gz"
echo " - keegees-${{ steps.get_next_version.outputs.version }}.zip"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.get_next_version.outputs.version }}"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ keegees --help
╭──────────────────────────────────────────────────────────────────────────────╮
│ KEEGEES │
│ GNOME keybinding management system │
│ Version 1.0.0 │
│ Version 0.0.1
╰──────────────────────────────────────────────────────────────────────────────╯


Expand Down
2 changes: 1 addition & 1 deletion keegees.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ set -euo pipefail
# ══════════════════════════════════════════════════════════════════

readonly SCRIPT_NAME="keybind"
readonly VERSION="1.0.0"
readonly VERSION="0.0.1"

# Animation sequences for different states
readonly SPINNER_FRAMES=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
Expand Down