Manual Release #115
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Manual Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: 'Release type' | |
| required: true | |
| default: 'patch' | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| - custom | |
| custom_version: | |
| description: 'Custom version (only used if release_type is custom, e.g., 1.16.1)' | |
| required: false | |
| type: string | |
| release_notes: | |
| description: 'Additional release notes (optional)' | |
| required: false | |
| type: string | |
| env: | |
| CARGO_TERM_COLOR: always | |
| permissions: | |
| contents: write | |
| jobs: | |
| prepare-release: | |
| name: Prepare Release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| new_version: ${{ steps.version.outputs.new_version }} | |
| release_notes: ${{ steps.notes.outputs.notes }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Determine version | |
| id: version | |
| run: | | |
| # Get current version from Cargo.toml | |
| CURRENT_VERSION=$(grep "^version" sql-cli/Cargo.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "Current version: $CURRENT_VERSION" | |
| # Parse version components | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" | |
| # Determine new version based on input | |
| if [ "${{ github.event.inputs.release_type }}" = "custom" ]; then | |
| if [ -z "${{ github.event.inputs.custom_version }}" ]; then | |
| echo "Error: Custom version not provided" | |
| exit 1 | |
| fi | |
| NEW_VERSION="${{ github.event.inputs.custom_version }}" | |
| elif [ "${{ github.event.inputs.release_type }}" = "major" ]; then | |
| NEW_VERSION="$((MAJOR + 1)).0.0" | |
| elif [ "${{ github.event.inputs.release_type }}" = "minor" ]; then | |
| NEW_VERSION="$MAJOR.$((MINOR + 1)).0" | |
| else | |
| NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" | |
| fi | |
| echo "New version: $NEW_VERSION" | |
| echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| - name: Update version in Cargo.toml | |
| run: | | |
| sed -i "s/^version = .*/version = \"${{ steps.version.outputs.new_version }}\"/" sql-cli/Cargo.toml | |
| - name: Generate comprehensive release notes | |
| id: notes | |
| run: | | |
| VERSION="${{ steps.version.outputs.new_version }}" | |
| LAST_TAG=$(git tag --sort=-version:refname | head -n 1 || echo "") | |
| # Get commit statistics | |
| if [ -n "$LAST_TAG" ]; then | |
| # Check if there are any commits since last tag | |
| if git rev-list ${LAST_TAG}..HEAD --count > /dev/null 2>&1 && [ "$(git rev-list --count ${LAST_TAG}..HEAD 2>/dev/null)" -gt 0 ]; then | |
| COMMIT_COUNT=$(git rev-list --count ${LAST_TAG}..HEAD) | |
| FILES_CHANGED=$(git diff --name-only ${LAST_TAG}..HEAD | wc -l) | |
| COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%H|%s|%b") | |
| else | |
| # No commits since last tag | |
| COMMIT_COUNT="0" | |
| FILES_CHANGED="0" | |
| COMMITS="" | |
| fi | |
| else | |
| COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null || echo "0") | |
| FILES_CHANGED=$(git ls-files | wc -l || echo "0") | |
| COMMITS=$(git log --pretty=format:"%H|%s|%b" 2>/dev/null || echo "") | |
| fi | |
| { | |
| echo "# SQL CLI v${VERSION}" | |
| echo "" | |
| echo "**Release Date:** $(date +'%B %d, %Y')" | |
| echo "" | |
| # Add custom notes if provided | |
| if [ -n "${{ github.event.inputs.release_notes }}" ]; then | |
| echo "## π’ Release Notes" | |
| echo "" | |
| echo "${{ github.event.inputs.release_notes }}" | |
| echo "" | |
| fi | |
| # Add statistics | |
| echo "## π Release Overview" | |
| echo "- **Commits in this release:** $COMMIT_COUNT" | |
| echo "- **Files updated:** $FILES_CHANGED" | |
| echo "" | |
| # Detect and highlight features | |
| echo "## β¨ Highlights" | |
| echo "" | |
| # Check for visual enhancements | |
| if echo "$COMMITS" | grep -qi "cell.*render\|visual\|key.*indicator\|fade\|theme"; then | |
| echo "### π¨ Visual Improvements" | |
| if echo "$COMMITS" | grep -qi "key.*indicator"; then | |
| echo "- **Key Press Indicator**: Visual feedback for key presses with fade effects (F12 to toggle)" | |
| fi | |
| if echo "$COMMITS" | grep -qi "cell.*highlight"; then | |
| echo "- **Enhanced Cell Selection**: Multiple rendering modes for better visual feedback" | |
| fi | |
| echo "" | |
| fi | |
| # Check for debugging improvements | |
| if echo "$COMMITS" | grep -qi "debug\|log\|diagnostic"; then | |
| echo "### π Enhanced Debugging" | |
| if echo "$COMMITS" | grep -qi "dual.*log"; then | |
| echo "- **Dual Logging**: Simultaneous file and in-memory logging" | |
| fi | |
| echo "- **Better Diagnostics**: Improved error messages and state dumps" | |
| echo "" | |
| fi | |
| # Check for state management | |
| if echo "$COMMITS" | grep -qi "state.*container\|refactor.*v[0-9]"; then | |
| echo "### ποΈ Architecture Improvements" | |
| echo "- **State Management**: Continued migration to centralized AppStateContainer" | |
| echo "- **Code Quality**: Transaction-like state updates for better consistency" | |
| echo "" | |
| fi | |
| # Check for data integrity | |
| if echo "$COMMITS" | grep -qi "history.*protect\|corrupt\|atomic"; then | |
| echo "### πΎ Data Protection" | |
| echo "- **History Recovery**: Automatic recovery from corrupted files" | |
| echo "- **Atomic Writes**: Safer file operations to prevent data loss" | |
| echo "" | |
| fi | |
| # Traditional categorized changes | |
| echo "## π Changes by Category" | |
| echo "" | |
| # Features | |
| if [ -n "$LAST_TAG" ] && [ "$COMMIT_COUNT" -gt 0 ]; then | |
| FEATURES=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" 2>/dev/null | grep -E "^feat(\(.*\))?:" | sed 's/^feat[^:]*: //' | grep -v "bump version" || true) | |
| if [ -n "$FEATURES" ]; then | |
| echo "### π New Features" | |
| echo "$FEATURES" | while IFS= read -r line; do | |
| [ -n "$line" ] && echo "- $line" | |
| done | |
| echo "" | |
| fi | |
| # Bug Fixes | |
| FIXES=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" 2>/dev/null | grep -E "^fix(\(.*\))?:" | sed 's/^fix[^:]*: //' | grep -v "bump version" || true) | |
| if [ -n "$FIXES" ]; then | |
| echo "### π Bug Fixes" | |
| echo "$FIXES" | while IFS= read -r line; do | |
| [ -n "$line" ] && echo "- $line" | |
| done | |
| echo "" | |
| fi | |
| # Refactoring | |
| REFACTORS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" 2>/dev/null | grep -E "^refactor(\(.*\))?:" | sed 's/^refactor[^:]*: //' | grep -v "bump version" || true) | |
| if [ -n "$REFACTORS" ]; then | |
| echo "### π§ Refactoring" | |
| echo "$REFACTORS" | while IFS= read -r line; do | |
| [ -n "$line" ] && echo "- $line" | |
| done | |
| echo "" | |
| fi | |
| # Documentation | |
| DOCS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" 2>/dev/null | grep -E "^docs(\(.*\))?:" | sed 's/^docs[^:]*: //' | grep -v "bump version" || true) | |
| if [ -n "$DOCS" ]; then | |
| echo "### π Documentation" | |
| echo "$DOCS" | while IFS= read -r line; do | |
| [ -n "$line" ] && echo "- $line" | |
| done | |
| echo "" | |
| fi | |
| fi | |
| # Collapsible full commit list | |
| if [ "$COMMIT_COUNT" -gt 0 ]; then | |
| echo "<details>" | |
| echo "<summary>π View all commits</summary>" | |
| echo "" | |
| if [ -n "$LAST_TAG" ]; then | |
| git log ${LAST_TAG}..HEAD --pretty=format:"- %s (%an)" 2>/dev/null | grep -v "bump version" || true | |
| else | |
| git log --pretty=format:"- %s (%an)" 2>/dev/null | head -20 || true | |
| fi | |
| echo "" | |
| echo "</details>" | |
| fi | |
| echo "" | |
| # Key features section | |
| echo "## π― Key Features" | |
| echo "" | |
| echo "- **Instant Data Preview**: CSV/JSON files load immediately" | |
| echo "- **Visual Feedback**: Key press indicator, cell highlighting" | |
| echo "- **Advanced Navigation**: Vim-style keys, viewport/cursor lock" | |
| echo "- **Powerful Search**: Regular search (Ctrl+F), fuzzy filter (Ctrl+/)" | |
| echo "- **Data Export**: Save as CSV or JSON" | |
| echo "- **Debug Mode**: Press F5 for comprehensive state information" | |
| echo "" | |
| # Installation | |
| echo "## π¦ Installation" | |
| echo "" | |
| echo "Download the binary for your platform from the assets below." | |
| echo "" | |
| echo "---" | |
| echo "**Thank you for using SQL CLI!** π" | |
| echo "" | |
| echo "Report issues: [GitHub Issues](https://github.com/TimelordUK/sql-cli/issues)" | |
| } > RELEASE_NOTES.md | |
| # Save to output | |
| echo "notes<<EOF" >> $GITHUB_OUTPUT | |
| cat RELEASE_NOTES.md >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Commit version bump | |
| run: | | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| git add sql-cli/Cargo.toml | |
| git commit -m "chore: bump version to v${{ steps.version.outputs.new_version }}" | |
| git push | |
| - name: Create and push tag | |
| run: | | |
| git tag -a "v${{ steps.version.outputs.new_version }}" -m "Release v${{ steps.version.outputs.new_version }}" | |
| git push origin "v${{ steps.version.outputs.new_version }}" | |
| build: | |
| name: Build Release Binaries | |
| needs: prepare-release | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| artifact: sql-cli-linux-x64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| artifact: sql-cli-windows-x64 | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| artifact: sql-cli-macos-x64 | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| artifact: sql-cli-macos-arm64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: v${{ needs.prepare-release.outputs.new_version }} | |
| - name: Set up Rust | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: stable | |
| target: ${{ matrix.target }} | |
| override: true | |
| - name: Build Release | |
| working-directory: ./sql-cli | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Create artifact directory | |
| run: mkdir -p artifacts | |
| - name: Copy binary (Unix) | |
| if: matrix.os != 'windows-latest' | |
| run: cp sql-cli/target/${{ matrix.target }}/release/sql-cli artifacts/${{ matrix.artifact }} | |
| - name: Copy binary (Windows) | |
| if: matrix.os == 'windows-latest' | |
| run: cp sql-cli/target/${{ matrix.target }}/release/sql-cli.exe artifacts/${{ matrix.artifact }}.exe | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: artifacts/* | |
| release: | |
| name: Create GitHub Release | |
| needs: [prepare-release, build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: v${{ needs.prepare-release.outputs.new_version }} | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: v${{ needs.prepare-release.outputs.new_version }} | |
| name: v${{ needs.prepare-release.outputs.new_version }} | |
| body: ${{ needs.prepare-release.outputs.release_notes }} | |
| files: artifacts/**/* | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |