From 34cc3712b8fa28d82ee60a695edf1a04313bf134 Mon Sep 17 00:00:00 2001 From: Stefano Amorelli Date: Sat, 16 Aug 2025 17:21:41 +0300 Subject: [PATCH] ci: add release workflow for crates.io publishing - Automated publishing to crates.io on version tags - Cross-platform binary builds - GitHub release creation with artifacts - Manual workflow dispatch support --- .github/workflows/release.yml | 194 ++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1e0af87 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,194 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + version: + description: 'Version to publish (e.g., 0.1.0)' + required: true + type: string + +env: + CARGO_TERM_COLOR: always + +jobs: + test: + name: Final Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Run tests + run: cargo test --all-features --release + + - name: Check formatting + run: cargo fmt -- --check + + - name: Run clippy + run: cargo clippy --all-features -- -D warnings + + publish-crates-io: + name: Publish to crates.io + needs: test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + + - name: Verify version + run: | + # Extract version from Cargo.toml + CARGO_VERSION=$(grep -E "^version" Cargo.toml | head -1 | cut -d'"' -f2) + echo "Cargo.toml version: $CARGO_VERSION" + + # For manual workflow dispatch + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + INPUT_VERSION="${{ github.event.inputs.version }}" + if [ "$CARGO_VERSION" != "$INPUT_VERSION" ]; then + echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match input version ($INPUT_VERSION)" + exit 1 + fi + fi + + # For tag push + if [ "${{ github.event_name }}" = "push" ]; then + TAG_VERSION="${GITHUB_REF#refs/tags/v}" + if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then + echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match tag version ($TAG_VERSION)" + exit 1 + fi + fi + + - name: Check if version exists on crates.io + run: | + CRATE_NAME=$(grep -E "^name" Cargo.toml | head -1 | cut -d'"' -f2) + VERSION=$(grep -E "^version" Cargo.toml | head -1 | cut -d'"' -f2) + + if cargo search "$CRATE_NAME" | grep -q "^$CRATE_NAME = \"$VERSION\""; then + echo "Version $VERSION already exists on crates.io" + exit 1 + fi + + - name: Build release + run: cargo build --release --all-features + + - name: Package for crates.io + run: cargo package --all-features + + - name: Publish to crates.io + run: cargo publish --all-features --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + + create-github-release: + name: Create GitHub Release + needs: publish-crates-io + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + + - name: Build release binaries + run: | + cargo build --release --all-features + mkdir -p release + cp target/release/crabrl release/crabrl-linux-x64 + chmod +x release/crabrl-linux-x64 + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: release/* + generate_release_notes: true + body: | + ## Installation + + ### From crates.io + ```bash + cargo install crabrl + ``` + + ### Download Binary + Download the pre-built binary for your platform from the assets below. + + ## What's Changed + See the full changelog below. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-cross-platform: + name: Build ${{ matrix.target }} + needs: test + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + artifact: crabrl-linux-x64 + - os: ubuntu-latest + target: aarch64-unknown-linux-gnu + artifact: crabrl-linux-arm64 + use-cross: true + - os: windows-latest + target: x86_64-pc-windows-msvc + artifact: crabrl-windows-x64.exe + - os: macos-latest + target: x86_64-apple-darwin + artifact: crabrl-macos-x64 + - os: macos-latest + target: aarch64-apple-darwin + artifact: crabrl-macos-arm64 + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Install cross + if: matrix.use-cross + run: cargo install cross + + - name: Build + run: | + if [ "${{ matrix.use-cross }}" = "true" ]; then + cross build --release --target ${{ matrix.target }} --all-features + else + cargo build --release --target ${{ matrix.target }} --all-features + fi + shell: bash + + - name: Package + run: | + mkdir -p release + if [ "${{ matrix.os }}" = "windows-latest" ]; then + cp target/${{ matrix.target }}/release/crabrl.exe release/${{ matrix.artifact }} + else + cp target/${{ matrix.target }}/release/crabrl release/${{ matrix.artifact }} + chmod +x release/${{ matrix.artifact }} + fi + shell: bash + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact }} + path: release/${{ matrix.artifact }} \ No newline at end of file