Fix #14
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 Build | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # Trigger on version tags like v0.1.0 | |
| permissions: | |
| contents: write # Needed to create releases | |
| packages: write # Needed to push to GitHub Container Registry | |
| jobs: | |
| create_release: | |
| name: Create Release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| steps: | |
| - name: Create Release | |
| id: create_release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: Release ${{ github.ref_name }} | |
| draft: false | |
| prerelease: false | |
| body: | | |
| ## Traverse Tools ${{ github.ref_name }} | |
| This release includes the following tools: | |
| - `sol-storage-analyzer` - Analyze Solidity storage layouts | |
| - `storage-trace` - Trace storage operations | |
| - `sol2cg` - Generate call graphs from Solidity | |
| - `sol2bnd` - Generate bindings from Solidity | |
| - `sol2test` - Generate tests from Solidity | |
| build_binaries: | |
| name: Build Binaries for ${{ matrix.target }} | |
| needs: create_release | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| asset_name_suffix: linux-amd64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| asset_name_suffix: windows-amd64 | |
| ext: .exe | |
| - os: macos-latest # Intel runner | |
| target: x86_64-apple-darwin | |
| asset_name_suffix: macos-amd64 | |
| - os: macos-14 # ARM64/M1 runner | |
| target: aarch64-apple-darwin | |
| asset_name_suffix: macos-arm64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Rust for target ${{ matrix.target }} | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl-tools (Linux MUSL target only) | |
| if: matrix.os == 'ubuntu-latest' && contains(matrix.target, 'musl') | |
| run: | | |
| sudo apt-get update -y | |
| sudo apt-get install -y musl-tools | |
| - name: Setup macOS build environment | |
| if: matrix.os == 'macos-latest' || matrix.os == 'macos-14' | |
| run: | | |
| # Remove any existing dynamic xz/lzma libraries to force static linking | |
| if [ -d "/opt/homebrew/opt/xz" ]; then | |
| echo "Found Homebrew xz, will configure for static linking" | |
| fi | |
| if [ -d "/usr/local/opt/xz" ]; then | |
| echo "Found local xz, will configure for static linking" | |
| fi | |
| - name: Build all binaries | |
| env: | |
| CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS: "-C link-arg=-mmacosx-version-min=10.15" | |
| CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS: "-C link-arg=-mmacosx-version-min=11.0" | |
| LZMA_API_STATIC: "1" | |
| shell: bash | |
| run: | | |
| # For macOS, we need to ensure static linking of certain libraries | |
| if [[ "${{ matrix.os }}" == "macos-latest" ]] || [[ "${{ matrix.os }}" == "macos-14" ]]; then | |
| # Set feature flags to prefer static linking | |
| export LZMA_API_STATIC=1 | |
| export CARGO_FEATURE_STATIC=1 | |
| # Disable lzma feature in zip crate if possible | |
| export CARGO_NO_DEFAULT_FEATURES=1 | |
| fi | |
| # Build all binaries | |
| cargo build --verbose --release --target ${{ matrix.target }} --package traverse-cli --bin sol-storage-analyzer | |
| cargo build --verbose --release --target ${{ matrix.target }} --package traverse-cli --bin storage-trace | |
| cargo build --verbose --release --target ${{ matrix.target }} --package traverse-cli --bin sol2cg | |
| cargo build --verbose --release --target ${{ matrix.target }} --package traverse-cli --bin sol2bnd | |
| cargo build --verbose --release --target ${{ matrix.target }} --package traverse-cli --bin sol2test | |
| - name: Check dynamic dependencies (macOS only) | |
| if: matrix.os == 'macos-latest' || matrix.os == 'macos-14' | |
| run: | | |
| echo "=== Checking dynamic library dependencies for all binaries ===" | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| echo "Checking $binary:" | |
| otool -L ./target/${{ matrix.target }}/release/$binary || true | |
| echo "" | |
| done | |
| echo "=== Checking for problematic dependencies ===" | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| if otool -L ./target/${{ matrix.target }}/release/$binary | grep -E "(liblzma|/opt/homebrew|/usr/local)"; then | |
| echo "WARNING: Found dynamic dependencies in $binary that may cause issues with code signing" | |
| fi | |
| done | |
| - name: Import Apple Certificate (macOS only) | |
| if: matrix.os == 'macos-latest' || matrix.os == 'macos-14' | |
| env: | |
| APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| # Create temporary keychain with proper extension | |
| security create-keychain -p temp-password build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p temp-password build.keychain | |
| security set-keychain-settings -lut 21600 build.keychain | |
| # Add build keychain to search list | |
| security list-keychains -d user -s build.keychain $(security list-keychains -d user | sed s/\"//g) | |
| # Import certificate with -A flag to avoid access control issues | |
| echo "$APPLE_CERTIFICATE_BASE64" | base64 --decode > certificate.p12 | |
| # Import certificate (should contain both cert and private key) | |
| security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -A -T /usr/bin/codesign | |
| # Import Apple intermediate certificate (DER format) | |
| curl -o DeveloperIDG2CA.cer https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer | |
| security import DeveloperIDG2CA.cer -k build.keychain -A -T /usr/bin/codesign | |
| # Import Apple Worldwide Developer Relations CA G3 (DER format) | |
| curl -o AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer | |
| security import AppleWWDRCAG3.cer -k build.keychain -A -T /usr/bin/codesign | |
| # Set partition list to avoid password prompts | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k temp-password build.keychain | |
| # Clean up certificate files | |
| rm certificate.p12 DeveloperIDG2CA.cer AppleWWDRCAG3.cer | |
| - name: Code Sign Binaries (macOS only) | |
| if: matrix.os == 'macos-latest' || matrix.os == 'macos-14' | |
| env: | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: | | |
| # Check identities in build keychain | |
| echo "=== Code signing identities in build.keychain ===" | |
| security find-identity -v -p codesigning build.keychain || true | |
| # Extract signing identity hash from build keychain | |
| SIGNING_HASH=$(security find-identity -v -p codesigning build.keychain | grep "$APPLE_SIGNING_IDENTITY" | grep -oE "[0-9A-F]{40}" | head -n 1) | |
| echo "Using signing hash: $SIGNING_HASH" | |
| # Sign all binaries | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| echo "Signing $binary..." | |
| /usr/bin/codesign --force --sign "$SIGNING_HASH" --timestamp --options runtime ./target/${{ matrix.target }}/release/$binary -v | |
| # Verify signature | |
| /usr/bin/codesign --verify --verbose ./target/${{ matrix.target }}/release/$binary | |
| done | |
| - name: Notarize Binaries (macOS only) | |
| if: matrix.os == 'macos-latest' || matrix.os == 'macos-14' | |
| env: | |
| APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} | |
| run: | | |
| # Create API key file | |
| echo "=== Creating API key file ===" | |
| API_KEY_FILE="AuthKey_${APPLE_API_KEY_ID}.p8" | |
| echo "$APPLE_API_KEY_BASE64" | base64 --decode > "$API_KEY_FILE" | |
| echo "Created: $API_KEY_FILE" | |
| # Create a single zip with all binaries for notarization | |
| echo "=== Creating zip file for notarization ===" | |
| ZIP_FILE="traverse-tools-${{ matrix.asset_name_suffix }}-notarization.zip" | |
| # Create temporary directory and copy binaries | |
| mkdir -p notarization-temp | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| cp ./target/${{ matrix.target }}/release/$binary notarization-temp/ | |
| done | |
| # Create zip using ditto | |
| ditto -c -k --sequesterRsrc --keepParent notarization-temp "$ZIP_FILE" | |
| echo "Created: $ZIP_FILE" | |
| # Submit for notarization | |
| echo "=== Submitting for notarization ===" | |
| echo "This may take several minutes..." | |
| xcrun notarytool submit "$ZIP_FILE" \ | |
| --key "$API_KEY_FILE" \ | |
| --key-id "$APPLE_API_KEY_ID" \ | |
| --issuer "$APPLE_API_ISSUER_ID" \ | |
| --wait | |
| # Attempt to staple the notarization (will fail for command-line tools - this is expected) | |
| echo "=== Attempting to staple notarization ===" | |
| echo "Note: Stapling fails for command-line tools - this is normal" | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| xcrun stapler staple ./target/${{ matrix.target }}/release/$binary || echo "Stapling failed for $binary (expected for command-line tools)" | |
| done | |
| # Final verification | |
| echo "=== Final signature and notarization verification ===" | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| echo "Verifying $binary:" | |
| codesign --verify --verbose ./target/${{ matrix.target }}/release/$binary | |
| spctl --assess --type execute --verbose ./target/${{ matrix.target }}/release/$binary || echo "spctl assessment completed for $binary" | |
| done | |
| # Clean up files | |
| rm -rf notarization-temp "$ZIP_FILE" "$API_KEY_FILE" | |
| echo "=== Notarization completed successfully ===" | |
| - name: Create archive | |
| shell: bash | |
| run: | | |
| # Create archive directory | |
| mkdir -p dist | |
| # Copy all binaries to dist with proper naming | |
| if [[ "${{ matrix.os }}" == "windows-latest" ]]; then | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| cp ./target/${{ matrix.target }}/release/${binary}.exe dist/${binary}-${{ matrix.asset_name_suffix }}.exe | |
| done | |
| # Create a zip archive for Windows | |
| cd dist | |
| 7z a traverse-tools-${{ matrix.asset_name_suffix }}.zip * | |
| cd .. | |
| else | |
| for binary in sol-storage-analyzer storage-trace sol2cg sol2bnd sol2test; do | |
| cp ./target/${{ matrix.target }}/release/$binary dist/${binary}-${{ matrix.asset_name_suffix }} | |
| done | |
| # Create a tar.gz archive for Unix systems | |
| cd dist | |
| tar czf traverse-tools-${{ matrix.asset_name_suffix }}.tar.gz * | |
| cd .. | |
| fi | |
| - name: Upload individual binaries | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/sol-storage-analyzer-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_name: sol-storage-analyzer-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| - name: Upload storage-trace | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/storage-trace-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_name: storage-trace-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| - name: Upload sol2cg | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/sol2cg-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_name: sol2cg-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| - name: Upload sol2bnd | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/sol2bnd-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_name: sol2bnd-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| - name: Upload sol2test | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/sol2test-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_name: sol2test-${{ matrix.asset_name_suffix }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| - name: Upload archive (Unix) | |
| if: matrix.os != 'windows-latest' | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/traverse-tools-${{ matrix.asset_name_suffix }}.tar.gz | |
| asset_name: traverse-tools-${{ matrix.asset_name_suffix }}.tar.gz | |
| asset_content_type: application/gzip | |
| - name: Upload archive (Windows) | |
| if: matrix.os == 'windows-latest' | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create_release.outputs.upload_url }} | |
| asset_path: ./dist/traverse-tools-${{ matrix.asset_name_suffix }}.zip | |
| asset_name: traverse-tools-${{ matrix.asset_name_suffix }}.zip | |
| asset_content_type: application/zip | |
| build_docker: | |
| name: Build and Push Docker Image | |
| needs: create_release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - 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: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for all-in-one image | |
| id: meta-all | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ghcr.io/${{ github.repository }} | |
| tags: | | |
| type=ref,event=tag | |
| type=raw,value=latest | |
| - name: Build and push all-in-one Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: all | |
| tags: ${{ steps.meta-all.outputs.tags }} | |
| labels: ${{ steps.meta-all.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Build and push individual tool images | |
| - name: Build and push sol2cg image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: sol2cg | |
| tags: | | |
| ghcr.io/${{ github.repository }}/sol2cg:${{ github.ref_name }} | |
| ghcr.io/${{ github.repository }}/sol2cg:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build and push sol2test image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: sol2test | |
| tags: | | |
| ghcr.io/${{ github.repository }}/sol2test:${{ github.ref_name }} | |
| ghcr.io/${{ github.repository }}/sol2test:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build and push sol2bnd image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: sol2bnd | |
| tags: | | |
| ghcr.io/${{ github.repository }}/sol2bnd:${{ github.ref_name }} | |
| ghcr.io/${{ github.repository }}/sol2bnd:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build and push storage-trace image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: storage-trace | |
| tags: | | |
| ghcr.io/${{ github.repository }}/storage-trace:${{ github.ref_name }} | |
| ghcr.io/${{ github.repository }}/storage-trace:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build and push sol-storage-analyzer image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| target: sol-storage-analyzer | |
| tags: | | |
| ghcr.io/${{ github.repository }}/sol-storage-analyzer:${{ github.ref_name }} | |
| ghcr.io/${{ github.repository }}/sol-storage-analyzer:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |