fix: add checkout to upload-binaries, update Cargo.lock, reorder crat… #224
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: | |
| branches: | |
| - main | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: write | |
| packages: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| # ------------------------------------------------------------------ | |
| # 0. Detect whether this is a release run | |
| # ------------------------------------------------------------------ | |
| check-release: | |
| name: Check release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| is_release: ${{ steps.check.outputs.is_release }} | |
| version: ${{ steps.check.outputs.version }} | |
| version_major: ${{ steps.check.outputs.version_major }} | |
| version_minor: ${{ steps.check.outputs.version_minor }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| with: | |
| fetch-depth: 1 | |
| fetch-tags: true | |
| - name: Detect release | |
| id: check | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="v$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')" | |
| RAW="${VERSION#v}" | |
| MAJOR=$(echo "$RAW" | cut -d. -f1) | |
| MINOR="${MAJOR}.$(echo "$RAW" | cut -d. -f2)" | |
| echo "is_release=true" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "version_major=$MAJOR" >> "$GITHUB_OUTPUT" | |
| echo "version_minor=$MINOR" >> "$GITHUB_OUTPUT" | |
| if git tag -l "$VERSION" | grep -q .; then | |
| echo "::error::Tag $VERSION already exists" | |
| exit 1 | |
| fi | |
| echo "Detected release: $VERSION" | |
| else | |
| echo "is_release=false" >> "$GITHUB_OUTPUT" | |
| echo "version=" >> "$GITHUB_OUTPUT" | |
| echo "Not a release run" | |
| fi | |
| # ------------------------------------------------------------------ | |
| # 1. Build binaries for each target (always) | |
| # ------------------------------------------------------------------ | |
| build-binaries: | |
| name: Build ${{ matrix.name }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux x86_64 (baseline) | |
| - name: linux-x86_64 | |
| os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| # Linux x86_64 with AVX2 (x86-64-v3) | |
| - name: linux-x86_64-v3 | |
| os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| target_cpu: x86-64-v3 | |
| # Linux x86_64 with AVX-512 (x86-64-v4) | |
| - name: linux-x86_64-v4 | |
| os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| target_cpu: x86-64-v4 | |
| # Linux aarch64 (native arm64 runner, baseline) | |
| - name: linux-aarch64 | |
| os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| # Linux aarch64 with SVE (Graviton 3+, Axion, Grace) | |
| - name: linux-aarch64-neoverse-v1 | |
| os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| target_cpu: neoverse-v1 | |
| # macOS x86_64 (cross-compiled on Apple Silicon runner) | |
| - name: macos-x86_64 | |
| os: macos-latest | |
| target: x86_64-apple-darwin | |
| # macOS aarch64 (Apple Silicon, baseline) | |
| - name: macos-aarch64 | |
| os: macos-latest | |
| target: aarch64-apple-darwin | |
| # macOS aarch64 (Apple M1 optimized) | |
| - name: macos-aarch64-apple-m1 | |
| os: macos-latest | |
| target: aarch64-apple-darwin | |
| target_cpu: apple-m1 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # ratchet:dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| # Linux build dependencies | |
| - name: Install Linux build deps | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake zlib1g-dev libbz2-dev liblzma-dev \ | |
| libcurl4-openssl-dev libssl-dev libfontconfig1-dev pkg-config clang | |
| # macOS build dependencies | |
| - name: Install macOS build deps | |
| if: runner.os == 'macOS' | |
| run: brew install bzip2 xz | |
| - name: Build | |
| run: > | |
| cargo build --release --target ${{ matrix.target }} | |
| ${TARGET_CPU:+--config "target.'${{ matrix.target }}'.rustflags=['-C', 'target-cpu=$TARGET_CPU']"} | |
| env: | |
| TARGET_CPU: ${{ matrix.target_cpu || '' }} | |
| - name: Package | |
| id: package | |
| run: | | |
| BIN="rustqc" | |
| ARCHIVE="${BIN}-${{ matrix.name }}" | |
| mkdir -p "staging/${ARCHIVE}" | |
| cp "target/${{ matrix.target }}/release/${BIN}" "staging/${ARCHIVE}/" | |
| cp README.md LICENSE "staging/${ARCHIVE}/" 2>/dev/null || true | |
| cd staging | |
| tar czf "../${ARCHIVE}.tar.gz" "${ARCHIVE}" | |
| cd .. | |
| # SHA256 checksum | |
| shasum -a 256 "${ARCHIVE}.tar.gz" > "${ARCHIVE}.tar.gz.sha256" | |
| echo "archive=${ARCHIVE}.tar.gz" >> "$GITHUB_OUTPUT" | |
| echo "checksum=${ARCHIVE}.tar.gz.sha256" >> "$GITHUB_OUTPUT" | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # ratchet:actions/upload-artifact@v7.0.0 | |
| with: | |
| name: binary-${{ matrix.name }} | |
| path: | | |
| ${{ steps.package.outputs.archive }} | |
| ${{ steps.package.outputs.checksum }} | |
| retention-days: 1 | |
| # ------------------------------------------------------------------ | |
| # 2. Build per-platform Docker images on native runners | |
| # ------------------------------------------------------------------ | |
| docker-build: | |
| name: Docker ${{ matrix.platform }} | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: linux/amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Lowercase image name | |
| run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> "$GITHUB_ENV" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4.0.0 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # ratchet:docker/login-action@v4.1.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Get short commit hash | |
| id: git-hash | |
| run: echo "short_hash=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # ratchet:docker/build-push-action@v7.0.0 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| build-args: | | |
| GIT_SHORT_HASH=${{ steps.git-hash.outputs.short_hash }} | |
| outputs: type=image,name=ghcr.io/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true | |
| cache-from: type=gha,scope=${{ matrix.platform }} | |
| cache-to: type=gha,scope=${{ matrix.platform }},mode=max | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # ratchet:actions/upload-artifact@v7.0.0 | |
| with: | |
| name: digests-${{ matrix.runner }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # ------------------------------------------------------------------ | |
| # 2a. Build SIMD-optimized Docker images (single-arch each) | |
| # ------------------------------------------------------------------ | |
| docker-build-simd: | |
| name: Docker ${{ matrix.name }} | |
| needs: [check-release] | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: amd64-avx2 | |
| runner: ubuntu-latest | |
| platform: linux/amd64 | |
| cpu_target: x86-64-v3 | |
| tag_suffix: avx2 | |
| - name: amd64-avx512 | |
| runner: ubuntu-latest | |
| platform: linux/amd64 | |
| cpu_target: x86-64-v4 | |
| tag_suffix: avx512 | |
| - name: arm64-sve | |
| runner: ubuntu-24.04-arm | |
| platform: linux/arm64 | |
| cpu_target: neoverse-v1 | |
| tag_suffix: sve | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Prepare build metadata | |
| id: prep | |
| run: | | |
| echo "IMAGE_NAME=${IMAGE_NAME,,}" >> "$GITHUB_ENV" | |
| echo "short_hash=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4.0.0 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # ratchet:docker/login-action@v4.1.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # ratchet:docker/metadata-action@v6.0.0 | |
| with: | |
| images: ghcr.io/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=${{ needs.check-release.outputs.version }}-${{ matrix.tag_suffix }},enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=latest-${{ matrix.tag_suffix }},enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=dev-${{ matrix.tag_suffix }} | |
| - name: Build and push | |
| uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # ratchet:docker/build-push-action@v7.0.0 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: | | |
| GIT_SHORT_HASH=${{ steps.prep.outputs.short_hash }} | |
| CPU_TARGET=${{ matrix.cpu_target }} | |
| cache-from: type=gha,scope=${{ matrix.name }} | |
| cache-to: type=gha,scope=${{ matrix.name }},mode=max | |
| # ------------------------------------------------------------------ | |
| # 2b. Merge per-platform images into a multi-arch manifest | |
| # ------------------------------------------------------------------ | |
| docker-merge: | |
| name: Docker merge | |
| needs: [check-release, docker-build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Lowercase image name | |
| run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> "$GITHUB_ENV" | |
| - name: Download digests | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8.0.1 | |
| with: | |
| pattern: digests-* | |
| path: /tmp/digests | |
| merge-multiple: true | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # ratchet:docker/metadata-action@v6.0.0 | |
| with: | |
| images: ghcr.io/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=${{ needs.check-release.outputs.version }},enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=${{ needs.check-release.outputs.version_minor }},enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=${{ needs.check-release.outputs.version_major }},enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=latest,enable=${{ needs.check-release.outputs.is_release == 'true' }} | |
| type=raw,value=dev | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4.0.0 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # ratchet:docker/login-action@v4.1.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create manifest list and push | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf 'ghcr.io/${{ env.IMAGE_NAME }}@sha256:%s ' *) | |
| # ------------------------------------------------------------------ | |
| # 3. Create tag and draft release (release only, after all builds) | |
| # ------------------------------------------------------------------ | |
| create-tag-and-release: | |
| name: Create tag and release | |
| if: needs.check-release.outputs.is_release == 'true' | |
| needs: [check-release, build-binaries, docker-merge, docker-build-simd] | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ needs.check-release.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Create tag | |
| run: | | |
| git tag "${{ needs.check-release.outputs.version }}" | |
| git push origin "${{ needs.check-release.outputs.version }}" | |
| - name: Extract changelog | |
| run: | | |
| RAW="${{ needs.check-release.outputs.version }}" | |
| RAW="${RAW#v}" | |
| awk '/^## \[Version '"$RAW"'\]/{found=1; next} /^## \[/{if(found) exit} found' CHANGELOG.md > /tmp/release-notes.md | |
| - name: Create release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release create "${{ needs.check-release.outputs.version }}" \ | |
| --target "${{ github.sha }}" \ | |
| --title "RustQC ${{ needs.check-release.outputs.version }}" \ | |
| --notes-file /tmp/release-notes.md | |
| # ------------------------------------------------------------------ | |
| # 4. Upload binaries to the release | |
| # ------------------------------------------------------------------ | |
| upload-binaries: | |
| name: Upload binaries | |
| if: needs.check-release.outputs.is_release == 'true' | |
| needs: [check-release, create-tag-and-release, build-binaries] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Download all binary artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8.0.1 | |
| with: | |
| pattern: binary-* | |
| path: /tmp/binaries | |
| merge-multiple: true | |
| - name: Upload to release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release upload "${{ needs.create-tag-and-release.outputs.tag }}" \ | |
| /tmp/binaries/*.tar.gz \ | |
| /tmp/binaries/*.sha256 | |
| # ------------------------------------------------------------------ | |
| # 5. Publish to crates.io (release only, last step) | |
| # ------------------------------------------------------------------ | |
| publish-crate: | |
| name: Publish to crates.io | |
| if: needs.check-release.outputs.is_release == 'true' | |
| needs: [check-release, upload-binaries] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 | |
| - name: Authenticate with crates.io | |
| id: auth | |
| uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe # ratchet:rust-lang/crates-io-auth-action@v1.0.4 | |
| - name: Publish to crates.io | |
| run: cargo publish --no-verify | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} |