release: v0.18.2 (#2547) #74
Workflow file for this run
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*" | |
| env: | |
| CARGO_TERM_COLOR: always | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-binaries: | |
| name: Build (${{ matrix.target }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| archive: tar.gz | |
| use_cross: false | |
| - os: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| archive: tar.gz | |
| use_cross: true | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| archive: tar.gz | |
| use_cross: false | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| archive: tar.gz | |
| use_cross: false | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| archive: zip | |
| use_cross: false | |
| # aarch64-pc-windows-msvc removed: cross-compilation from Linux | |
| # fails for crypto crates (ring, aws-lc-sys) that require | |
| # Windows ARM64 SDK headers unavailable in cross containers. | |
| # Re-enable when GitHub provides hosted Windows ARM64 runners. | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: stable | |
| targets: ${{ matrix.target }} | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| cache-targets: "false" | |
| shared-key: "release-${{ matrix.target }}" | |
| - uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9 | |
| if: "!matrix.use_cross" | |
| - uses: taiki-e/install-action@06e1821e928f70c3a625134f4f93bfc876141b9a # cross | |
| - name: Build binary (cross) | |
| if: matrix.use_cross | |
| run: cross build --release --features full --target ${{ matrix.target }} | |
| - name: Build binary (native) | |
| if: "!matrix.use_cross" | |
| run: cargo build --release --features full --target ${{ matrix.target }} | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| - name: Strip binary (Unix) | |
| if: "!matrix.use_cross && runner.os != 'Windows'" | |
| run: strip target/${{ matrix.target }}/release/zeph | |
| - name: Create archive (tar.gz) | |
| if: matrix.archive == 'tar.gz' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| tar czf ../../../zeph-${{ matrix.target }}.tar.gz zeph | |
| cd ../../.. | |
| shasum -a 256 zeph-${{ matrix.target }}.tar.gz > zeph-${{ matrix.target }}.tar.gz.sha256 | |
| - name: Create archive (zip) | |
| if: matrix.archive == 'zip' | |
| shell: bash | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| if [ -f zeph.exe ]; then | |
| 7z a ../../../zeph-${{ matrix.target }}.zip zeph.exe | |
| else | |
| 7z a ../../../zeph-${{ matrix.target }}.zip zeph | |
| fi | |
| cd ../../.. | |
| if command -v shasum &> /dev/null; then | |
| shasum -a 256 zeph-${{ matrix.target }}.zip > zeph-${{ matrix.target }}.zip.sha256 | |
| else | |
| sha256sum zeph-${{ matrix.target }}.zip > zeph-${{ matrix.target }}.zip.sha256 | |
| fi | |
| - name: Upload archive | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: binary-${{ matrix.target }} | |
| path: | | |
| zeph-${{ matrix.target }}.tar.gz | |
| zeph-${{ matrix.target }}.tar.gz.sha256 | |
| zeph-${{ matrix.target }}.zip | |
| zeph-${{ matrix.target }}.zip.sha256 | |
| retention-days: 3 | |
| publish-crates: | |
| name: Publish to crates.io | |
| needs: [build-binaries] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| environment: release | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: stable | |
| - name: Verify version matches tag | |
| run: | | |
| TAG_VERSION="${GITHUB_REF#refs/tags/v}" | |
| CARGO_VERSION=$(grep '^version' Cargo.toml | grep -m1 'version' | sed 's/.*version = "\(.*\)".*/\1/') | |
| if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then | |
| echo "Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)" | |
| exit 1 | |
| fi | |
| - name: Authenticate with crates.io (OIDC) | |
| uses: rust-lang/crates-io-auth-action@b7e9a28eded4986ec6b1fa40eeee8f8f165559ec # v1 | |
| id: auth | |
| - name: Publish crates to crates.io | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} | |
| run: | | |
| PUBLISH_ORDER=$(python3 -c " | |
| import json, subprocess, sys | |
| from collections import defaultdict, deque | |
| meta = json.loads(subprocess.check_output( | |
| ['cargo', 'metadata', '--no-deps', '--format-version', '1'] | |
| )) | |
| ws = set(meta['workspace_members']) | |
| pkgs = {p['id']: p for p in meta['packages'] if p['id'] in ws} | |
| pub_pkgs = {id: p for id, p in pkgs.items() if p.get('publish') != []} | |
| name_to_id = {p['name']: p['id'] for p in pub_pkgs.values()} | |
| in_deg = defaultdict(int) | |
| graph = defaultdict(list) | |
| for pkg in pub_pkgs.values(): | |
| for dep in pkg['dependencies']: | |
| if dep['name'] in name_to_id and dep['name'] != pkg['name']: | |
| dep_id = name_to_id[dep['name']] | |
| graph[dep_id].append(pkg['id']) | |
| in_deg[pkg['id']] += 1 | |
| queue = deque(id for id in pub_pkgs if in_deg[id] == 0) | |
| order = [] | |
| while queue: | |
| node = queue.popleft() | |
| order.append(pub_pkgs[node]['name']) | |
| for nxt in graph[node]: | |
| in_deg[nxt] -= 1 | |
| if in_deg[nxt] == 0: | |
| queue.append(nxt) | |
| print(chr(10).join(order)) | |
| ") | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| FIRST=true | |
| for CRATE in $PUBLISH_ORDER; do | |
| REMOTE=$(curl -sf "https://crates.io/api/v1/crates/${CRATE}/versions" \ | |
| -H "User-Agent: zeph-release-ci" \ | |
| | python3 -c "import sys,json; vs=[v['num'] for v in json.load(sys.stdin).get('versions',[])]; print('yes' if '${VERSION}' in vs else 'no')" 2>/dev/null || echo "no") | |
| if [ "$REMOTE" = "yes" ]; then | |
| echo "Skipping $CRATE@$VERSION (already published)" | |
| continue | |
| fi | |
| if [ "$FIRST" = "false" ]; then | |
| echo "Waiting 60s for crates.io sparse index propagation..." | |
| sleep 60 | |
| fi | |
| FIRST=false | |
| echo "Publishing $CRATE@$VERSION..." | |
| cargo publish --no-verify -p "$CRATE" | |
| done | |
| create-release: | |
| name: Create GitHub Release | |
| needs: [build-binaries, publish-crates] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| path: artifacts | |
| pattern: binary-* | |
| - name: Create release | |
| uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 | |
| with: | |
| generate_release_notes: true | |
| files: | | |
| artifacts/**/*.tar.gz | |
| artifacts/**/*.zip | |
| artifacts/**/*.sha256 | |
| scripts/install.sh | |
| docker-publish: | |
| name: Publish Docker Image | |
| needs: [build-binaries] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download Linux binaries | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: binary-*-unknown-linux-gnu | |
| path: artifacts | |
| - name: Extract and prepare binaries | |
| run: | | |
| mkdir -p binaries | |
| tar -xzf artifacts/binary-x86_64-unknown-linux-gnu/zeph-x86_64-unknown-linux-gnu.tar.gz -C binaries | |
| mv binaries/zeph binaries/zeph-amd64 | |
| tar -xzf artifacts/binary-aarch64-unknown-linux-gnu/zeph-aarch64-unknown-linux-gnu.tar.gz -C binaries | |
| mv binaries/zeph binaries/zeph-arm64 | |
| chmod +x binaries/zeph-* | |
| ls -lh binaries/ | |
| - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 | |
| - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 | |
| id: meta | |
| with: | |
| images: ghcr.io/${{ github.repository }} | |
| tags: | | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 | |
| with: | |
| context: . | |
| file: docker/Dockerfile | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |