From 38723e904d6738c94714ab0a110790f0cc263184 Mon Sep 17 00:00:00 2001 From: misterquestions Date: Sun, 23 Nov 2025 15:48:42 -0600 Subject: [PATCH 1/2] feat: add ci/cd pipelines for releases --- .github/workflows/{rust.yml => ci.yml} | 120 ++++++++---- .github/workflows/release.yml | 242 +++++++++++++++++++++++++ 2 files changed, 327 insertions(+), 35 deletions(-) rename .github/workflows/{rust.yml => ci.yml} (51%) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/ci.yml similarity index 51% rename from .github/workflows/rust.yml rename to .github/workflows/ci.yml index f913debb..7e7e5c95 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,10 @@ -name: Rust CI +name: CI + on: pull_request: - branches: [ "master" ] + branches: [master] push: - branches: [ "master" ] + branches: [master] workflow_dispatch: concurrency: @@ -12,90 +13,139 @@ concurrency: env: CARGO_TERM_COLOR: always + defaults: run: shell: bash + jobs: - formatting_and_security: - name: Formatting and Security + formatting_and_quality: + name: Formatting and Quality Checks runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v4 + - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly with: components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 + - name: Run cargo fmt run: cargo fmt --all -- --check + - name: Run Clippy - run: cargo clippy --all-targets -- -D warnings + run: cargo clippy --all-targets --all-features -- -D warnings + - name: Install cargo-audit uses: taiki-e/install-action@v2 with: tool: cargo-audit + - name: Run Cargo Audit run: cargo audit --ignore RUSTSEC-2023-0071 - build: - name: Build and Upload Artifacts - if: github.ref == 'refs/heads/master' + + test: + name: Test Suite runs-on: ${{ matrix.os }} - needs: [formatting_and_security, test] strategy: + fail-fast: false matrix: include: - - os: macos-14 - target: aarch64-apple-darwin - os: ubuntu-latest target: x86_64-unknown-linux-gnu + - os: macos-14 + target: aarch64-apple-darwin - os: windows-latest target: x86_64-pc-windows-msvc - - os: ubuntu-24.04-arm - target: aarch64-unknown-linux-gnu + steps: - - uses: actions/checkout@v5 + - name: Checkout repository + uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly + - name: Install Rust nightly + uses: dtolnay/rust-toolchain@nightly with: targets: ${{ matrix.target }} - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} - - name: Build - run: cargo build --release --target ${{ matrix.target }} - - - name: Upload executable - uses: actions/upload-artifact@v4 + - name: Install cargo-nextest + uses: taiki-e/install-action@v2 with: - name: ferrumc-${{ matrix.os }} - path: target/${{ matrix.target }}/release/ferrumc* + tool: cargo-nextest - test: - name: Run Tests + - name: Run tests + run: cargo nextest run --target ${{ matrix.target }} --all-targets --all-features -E "not kind(bench)" + + build: + name: Build Binaries runs-on: ${{ matrix.os }} + needs: [formatting_and_quality, test] + if: github.event_name == 'push' && github.ref == 'refs/heads/master' strategy: + fail-fast: false matrix: include: - - os: macos-14 - target: aarch64-apple-darwin - os: ubuntu-latest target: x86_64-unknown-linux-gnu + - os: ubuntu-latest + target: aarch64-unknown-linux-gnu + cross: true + - os: macos-14 + target: aarch64-apple-darwin + - os: macos-13 + target: x86_64-apple-darwin - os: windows-latest target: x86_64-pc-windows-msvc - - os: ubuntu-24.04-arm - target: aarch64-unknown-linux-gnu + steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v4 + - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly with: targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 - - name: Install cargo-nextest + with: + key: ${{ matrix.target }} + + - name: Install cross + if: matrix.cross uses: taiki-e/install-action@v2 with: - tool: cargo-nextest - - name: Run Tests - run: cargo nextest run --target ${{ matrix.target }} --all-targets --all-features -E "not kind(bench)" + tool: cross + + - name: Build release binary + run: | + if [ "${{ matrix.cross }}" = "true" ]; then + cross build --release --target ${{ matrix.target }} + else + cargo build --release --target ${{ matrix.target }} + fi + + - name: Strip binary (Linux/macOS) + if: runner.os != 'Windows' + run: strip target/${{ matrix.target }}/release/ferrumc || true + + - name: Prepare artifact + run: | + mkdir -p artifacts + if [ "${{ runner.os }}" = "Windows" ]; then + cp target/${{ matrix.target }}/release/ferrumc.exe artifacts/ferrumc-${{ matrix.target }}.exe + else + cp target/${{ matrix.target }}/release/ferrumc artifacts/ferrumc-${{ matrix.target }} + fi + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ferrumc-${{ matrix.target }} + path: artifacts/* + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..a2970f9b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,242 @@ +name: CD - Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g., v0.1.0)' + required: true + type: string + +permissions: + contents: write + packages: write + +env: + CARGO_TERM_COLOR: always + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +defaults: + run: + shell: bash + +jobs: + approval: + name: Require Approval + runs-on: ubuntu-latest + environment: release + steps: + - name: Approval gate + run: echo "Release approved for ${{ inputs.version }}" + + build-binaries: + name: Build Release Binaries + needs: approval + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + - os: ubuntu-latest + target: aarch64-unknown-linux-gnu + cross: true + - os: macos-14 + target: aarch64-apple-darwin + - os: macos-13 + target: x86_64-apple-darwin + - os: windows-latest + target: x86_64-pc-windows-msvc + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust nightly + uses: dtolnay/rust-toolchain@nightly + with: + targets: ${{ matrix.target }} + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + + - name: Install cross + if: matrix.cross + uses: taiki-e/install-action@v2 + with: + tool: cross + + - name: Build release binary + run: | + if [ "${{ matrix.cross }}" = "true" ]; then + cross build --release --target ${{ matrix.target }} + else + cargo build --release --target ${{ matrix.target }} + fi + + - name: Strip binary (Linux/macOS) + if: runner.os != 'Windows' + run: strip target/${{ matrix.target }}/release/ferrumc || true + + - name: Prepare binary + run: | + mkdir -p release + if [ "${{ runner.os }}" = "Windows" ]; then + cp target/${{ matrix.target }}/release/ferrumc.exe release/ferrumc-${{ inputs.version }}-${{ matrix.target }}.exe + else + cp target/${{ matrix.target }}/release/ferrumc release/ferrumc-${{ inputs.version }}-${{ matrix.target }} + fi + + - name: Generate checksums + run: | + cd release + if [ "${{ runner.os }}" = "Windows" ]; then + certutil -hashfile ferrumc-${{ inputs.version }}-${{ matrix.target }}.exe SHA256 > ferrumc-${{ inputs.version }}-${{ matrix.target }}.exe.sha256 + else + shasum -a 256 ferrumc-${{ inputs.version }}-${{ matrix.target }} > ferrumc-${{ inputs.version }}-${{ matrix.target }}.sha256 + fi + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: release-${{ matrix.target }} + path: release/* + + build-docker: + name: Build and Push Docker Image + needs: approval + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ inputs.version }} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + + create-release: + name: Create GitHub Release + needs: [build-binaries, build-docker] + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + pattern: release-* + merge-multiple: true + + - name: Generate release notes + id: notes + run: | + cat > release_notes.md << 'EOF' + ## Installation + + ### Docker (Recommended) + ```bash + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ inputs.version }} + docker run -p 25565:25565 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ inputs.version }} + ``` + + Or use Docker Compose: + ```yaml + version: '3.8' + services: + ferrumc: + image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ inputs.version }} + ports: + - "25565:25565" + restart: unless-stopped + ``` + + ### Native Binaries + Download the appropriate binary for your platform below and run it directly: + + **Linux/macOS:** + ```bash + # Download the binary for your platform + chmod +x ferrumc-* + ./ferrumc-* + ``` + + **Windows:** + ```powershell + # Download ferrumc-*.exe and run it + .\ferrumc-*.exe + ``` + + ### Verify Downloads + Each binary includes a SHA256 checksum file for verification: + ```bash + # Linux/macOS + shasum -a 256 -c ferrumc-*.sha256 + + # Windows PowerShell + Get-FileHash ferrumc-*.exe -Algorithm SHA256 + ``` + + ## What's Changed + + + **Full Changelog**: https://github.com/${{ github.repository }}/compare/...HEAD + EOF + + echo "notes_file=release_notes.md" >> $GITHUB_OUTPUT + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ inputs.version }} + name: Release ${{ inputs.version }} + body_path: ${{ steps.notes.outputs.notes_file }} + draft: false + prerelease: false + files: artifacts/* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + trigger-site-deploy: + name: Trigger Site Deployment + needs: create-release + runs-on: ubuntu-latest + steps: + - name: Trigger site repository workflow + run: | + curl -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.SITE_DEPLOY_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/ferrumc-rs/site/actions/workflows/deploy.yml/dispatches \ + -d '{"ref":"main","inputs":{"release_version":"${{ inputs.version }}"}}' From d55d984d1c3fbc213a5009af38ac3dc05a0f9328 Mon Sep 17 00:00:00 2001 From: misterquestions Date: Sun, 23 Nov 2025 16:47:52 -0600 Subject: [PATCH 2/2] fix: reset original matrix and checkout --- .github/workflows/ci.yml | 23 +++++++++++------------ .github/workflows/release.yml | 17 +++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e7e5c95..67627ef5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly @@ -54,16 +54,18 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - os: macos-14 target: aarch64-apple-darwin + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu - os: windows-latest target: x86_64-pc-windows-msvc + - os: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly @@ -91,21 +93,18 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - cross: true - os: macos-14 target: aarch64-apple-darwin - - os: macos-13 - target: x86_64-apple-darwin + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu - os: windows-latest target: x86_64-pc-windows-msvc + - os: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2970f9b..0b8a1091 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,21 +38,18 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - cross: true - os: macos-14 target: aarch64-apple-darwin - - os: macos-13 - target: x86_64-apple-darwin + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu - os: windows-latest target: x86_64-pc-windows-msvc + - os: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust nightly uses: dtolnay/rust-toolchain@nightly @@ -111,7 +108,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -149,7 +146,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download all artifacts uses: actions/download-artifact@v4