Release #7
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: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*.*.*" | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version to release (e.g., v0.1.0)" | |
| required: true | |
| type: string | |
| dry_run: | |
| description: "Dry run (skip GitHub release and crates.io publish)" | |
| required: false | |
| type: boolean | |
| default: true | |
| publish_crate: | |
| description: "Publish to crates.io (ignored if dry_run is true)" | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| BINARY_NAME: tuigram | |
| jobs: | |
| prepare: | |
| name: Prepare | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.config.outputs.version }} | |
| dry_run: ${{ steps.config.outputs.dry_run }} | |
| publish_crate: ${{ steps.config.outputs.publish_crate }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Cargo dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Determine version and mode | |
| id: config | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT | |
| echo "dry_run=${{ inputs.dry_run }}" >> $GITHUB_OUTPUT | |
| echo "publish_crate=${{ inputs.publish_crate }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT | |
| echo "dry_run=false" >> $GITHUB_OUTPUT | |
| echo "publish_crate=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Print configuration | |
| run: | | |
| echo "🏷️ Version: ${{ steps.config.outputs.version }}" | |
| echo "🧪 Dry run: ${{ steps.config.outputs.dry_run }}" | |
| echo "📦 Publish to crates.io: ${{ steps.config.outputs.publish_crate }}" | |
| - name: Verify crate version matches tag | |
| run: | | |
| TAG="${{ steps.config.outputs.version }}" | |
| TAG_VERSION="${TAG#v}" | |
| CARGO_VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/') | |
| if [[ "$TAG_VERSION" != "$CARGO_VERSION" ]]; then | |
| echo "❌ Error: Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)" | |
| exit 1 | |
| fi | |
| echo "✅ Version verified: $CARGO_VERSION" | |
| - name: Run tests | |
| run: cargo test --all --verbose | |
| - name: Run clippy | |
| run: cargo clippy -- -D warnings | |
| - name: Dry run cargo publish | |
| run: cargo publish --dry-run | |
| build: | |
| name: Build ${{ matrix.target }} | |
| needs: prepare | |
| if: needs.prepare.outputs.dry_run == 'false' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl-tools (Linux musl) | |
| if: matrix.target == 'x86_64-unknown-linux-musl' | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Install cross-compilation tools (Linux ARM) | |
| if: matrix.target == 'aarch64-unknown-linux-gnu' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| - name: Cache Cargo dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Build binary | |
| run: cargo build --release --target ${{ matrix.target }} | |
| env: | |
| CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc | |
| - name: Package binary (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| tar czvf ../../../${{ env.BINARY_NAME }}-${{ needs.prepare.outputs.version }}-${{ matrix.target }}.tar.gz ${{ env.BINARY_NAME }} | |
| - name: Package binary (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| 7z a ../../../${{ env.BINARY_NAME }}-${{ needs.prepare.outputs.version }}-${{ matrix.target }}.zip ${{ env.BINARY_NAME }}.exe | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.BINARY_NAME }}-${{ matrix.target }} | |
| path: ${{ env.BINARY_NAME }}-${{ needs.prepare.outputs.version }}-${{ matrix.target }}.* | |
| release: | |
| name: Release | |
| needs: [prepare, build] | |
| if: needs.prepare.outputs.dry_run == 'false' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: ls -la artifacts/ | |
| - name: Install git-cliff | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: git-cliff | |
| - name: Generate changelog | |
| run: | | |
| TAG="${{ needs.prepare.outputs.version }}" | |
| git cliff --unreleased --tag "$TAG" --strip all -o RELEASE_CHANGELOG.md | |
| git cliff --tag "$TAG" -o CHANGELOG.md | |
| - name: Commit changelog | |
| run: | | |
| TAG="${{ needs.prepare.outputs.version }}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add CHANGELOG.md | |
| git commit -m "chore(release): update changelog for $TAG" || echo "No changes to commit" | |
| git push origin HEAD:main | |
| - name: Update tag | |
| run: | | |
| TAG="${{ needs.prepare.outputs.version }}" | |
| git tag -f "$TAG" -m "Release $TAG" | |
| git push origin "$TAG" --force | |
| - name: Create GitHub release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.version }} | |
| name: ${{ needs.prepare.outputs.version }} | |
| body_path: RELEASE_CHANGELOG.md | |
| draft: false | |
| prerelease: ${{ contains(needs.prepare.outputs.version, '-') }} | |
| files: artifacts/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Summary | |
| run: | | |
| echo "" | |
| echo "========== Release Summary ==========" | |
| echo "Version: ${{ needs.prepare.outputs.version }}" | |
| echo "GitHub Release: ✅ Created with binaries" | |
| echo "=====================================" | |
| publish: | |
| name: Publish to crates.io | |
| needs: [prepare, release] | |
| if: needs.prepare.outputs.dry_run == 'false' && needs.prepare.outputs.publish_crate == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Cargo dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Publish to crates.io | |
| run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| - name: Summary | |
| run: | | |
| echo "" | |
| echo "========== Publish Summary ==========" | |
| echo "Version: ${{ needs.prepare.outputs.version }}" | |
| echo "crates.io: ✅ Published" | |
| echo "=====================================" | |
| dry-run-summary: | |
| name: Dry Run Summary | |
| needs: prepare | |
| if: needs.prepare.outputs.dry_run == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Summary | |
| run: | | |
| echo "" | |
| echo "========== Dry Run Summary ==========" | |
| echo "Version: ${{ needs.prepare.outputs.version }}" | |
| echo "Status: ✅ All checks passed" | |
| echo "" | |
| echo "To perform an actual release, run again with dry_run: false" | |
| echo "=====================================" |