Release Binaries #76
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 Binaries | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version tag (e.g., v1.0.0)' | |
| required: true | |
| type: string | |
| compare_from: | |
| description: 'Compare from tag (optional, auto-detects if empty)' | |
| required: false | |
| type: string | |
| prerelease: | |
| description: 'Mark as pre-release' | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| packages: write | |
| env: | |
| BINARY_NAME: pchaind | |
| PROJECT_NAME: push-chain | |
| jobs: | |
| # =========================================== | |
| # Linux Build (ubuntu) | |
| # =========================================== | |
| build-linux: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| else | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Building version: $VERSION" | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22.3' | |
| cache: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup dkls23-rs | |
| uses: ./.github/actions/setup-dkls23 | |
| with: | |
| ci_token: ${{ secrets.CI_DKLS_GARBLING }} | |
| - name: Copy dkls23-rs and garbling into build context | |
| run: | | |
| cp -r ../dkls23-rs ./dkls23-rs | |
| cp -r ../garbling ./garbling | |
| sed -i 's|go-wrapper => ../dkls23-rs/wrapper/go-wrappers|go-wrapper => ./dkls23-rs/wrapper/go-wrappers|' go.mod | |
| - name: Build dkls23-rs Rust library | |
| run: | | |
| cd dkls23-rs | |
| cargo build --release | |
| - name: Create and push version tag | |
| if: github.event_name == 'workflow_dispatch' | |
| run: | | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| VERSION=${{ steps.version.outputs.version }} | |
| if git tag --list | grep -q "^${VERSION}$"; then | |
| echo "Tag $VERSION already exists, deleting it first" | |
| git tag -d $VERSION || true | |
| git push --delete origin $VERSION || true | |
| fi | |
| git tag -a $VERSION -m "Release $VERSION" | |
| git push origin $VERSION | |
| - name: Build with GoReleaser | |
| uses: goreleaser/goreleaser-action@v5 | |
| with: | |
| version: v1.26.2 | |
| args: release --clean --skip=validate --skip=publish | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CGO_ENABLED: "1" | |
| CGO_LDFLAGS: "-L${{ github.workspace }}/dkls23-rs/target/release" | |
| - name: Upload Linux artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-binaries | |
| path: | | |
| dist/*.tar.gz | |
| dist/*.txt | |
| retention-days: 1 | |
| # =========================================== | |
| # Linux ARM64 Build | |
| # =========================================== | |
| build-linux-arm64: | |
| runs-on: ubuntu-22.04-arm | |
| needs: build-linux # Wait for version tag to be created | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| else | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| fi | |
| VERSION_NO_V="${VERSION#v}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT | |
| echo "Building version: $VERSION" | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22.3' | |
| cache: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup dkls23-rs | |
| uses: ./.github/actions/setup-dkls23 | |
| with: | |
| ci_token: ${{ secrets.CI_DKLS_GARBLING }} | |
| - name: Copy dkls23-rs and garbling into build context | |
| run: | | |
| cp -r ../dkls23-rs ./dkls23-rs | |
| cp -r ../garbling ./garbling | |
| sed -i 's|go-wrapper => ../dkls23-rs/wrapper/go-wrappers|go-wrapper => ./dkls23-rs/wrapper/go-wrappers|' go.mod | |
| - name: Build dkls23-rs Rust library | |
| run: | | |
| cd dkls23-rs | |
| cargo build --release | |
| - name: Build Linux ARM64 Binary | |
| run: | | |
| mkdir -p dist | |
| VERSION=${{ steps.version.outputs.version }} | |
| VERSION_NO_V=${{ steps.version.outputs.version_no_v }} | |
| export CGO_ENABLED=1 | |
| export CGO_LDFLAGS="-L$(pwd)/dkls23-rs/target/release" | |
| echo "Building for Linux ARM64..." | |
| GOOS=linux GOARCH=arm64 go build \ | |
| -tags "netgo,ledger" \ | |
| -ldflags="-s -w -X github.com/cosmos/cosmos-sdk/version.Version=${VERSION}" \ | |
| -o dist/${BINARY_NAME} \ | |
| ./cmd/pchaind | |
| # Create archive with bin/ structure for Cosmovisor compatibility | |
| cd dist | |
| mkdir -p bin | |
| mv ${BINARY_NAME} bin/ | |
| tar -czvf ${PROJECT_NAME}_${VERSION_NO_V}_linux_arm64.tar.gz bin/ | |
| shasum -a 256 ${PROJECT_NAME}_${VERSION_NO_V}_linux_arm64.tar.gz > ${PROJECT_NAME}_${VERSION_NO_V}_linux_arm64.tar.gz.sha256 | |
| rm -rf bin | |
| ls -la | |
| - name: Upload Linux ARM64 artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-arm64-binaries | |
| path: | | |
| dist/*.tar.gz | |
| dist/*.sha256 | |
| retention-days: 1 | |
| # =========================================== | |
| # macOS Build (Apple Silicon) | |
| # =========================================== | |
| build-macos: | |
| runs-on: macos-latest | |
| needs: build-linux # Wait for version tag to be created | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| else | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| fi | |
| # Strip 'v' prefix to match GoReleaser naming convention | |
| VERSION_NO_V="${VERSION#v}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT | |
| echo "Building version: $VERSION (stripped: $VERSION_NO_V)" | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22.3' | |
| cache: true | |
| - name: Set up Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup dkls23-rs | |
| uses: ./.github/actions/setup-dkls23 | |
| with: | |
| ci_token: ${{ secrets.CI_DKLS_GARBLING }} | |
| - name: Copy dkls23-rs and garbling into build context | |
| run: | | |
| rsync -a --exclude='ci/template' ../dkls23-rs/ ./dkls23-rs/ | |
| rsync -a ../garbling/ ./garbling/ | |
| sed -i '' 's|go-wrapper => ../dkls23-rs/wrapper/go-wrappers|go-wrapper => ./dkls23-rs/wrapper/go-wrappers|' go.mod | |
| - name: Build dkls23-rs dependency | |
| run: | | |
| cd dkls23-rs | |
| cargo build --release | |
| - name: Import Code Signing Certificate | |
| env: | |
| APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12 | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | |
| echo "$APPLE_CERTIFICATE_BASE64" | base64 --decode > "$CERTIFICATE_PATH" | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security import "$CERTIFICATE_PATH" \ | |
| -P "$APPLE_CERTIFICATE_PASSWORD" \ | |
| -A \ | |
| -t cert \ | |
| -f pkcs12 \ | |
| -k "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" | |
| security set-key-partition-list \ | |
| -S apple-tool:,apple:,codesign: \ | |
| -s \ | |
| -k "$KEYCHAIN_PASSWORD" \ | |
| "$KEYCHAIN_PATH" | |
| echo "Available signing identities:" | |
| security find-identity -v -p codesigning "$KEYCHAIN_PATH" | |
| - name: Download libwasmvm | |
| run: | | |
| # Get wasmvm version from go.mod | |
| WASM_VER=$(grep "github.com/CosmWasm/wasmvm/v2" go.mod | head -1 | awk '{print $2}') | |
| echo "Wasmvm version: $WASM_VER" | |
| # Download dylib for bundling with release | |
| curl -L -o libwasmvm.dylib \ | |
| "https://github.com/CosmWasm/wasmvm/releases/download/${WASM_VER}/libwasmvm.dylib" | |
| ls -la libwasmvm.dylib | |
| - name: Build Mac Binary (ARM64 only - native build) | |
| run: | | |
| # Note: GitHub macos-latest is ARM64, can't cross-compile for AMD64 with CGO | |
| # We only build ARM64 (Apple Silicon) which covers most modern Macs | |
| mkdir -p dist | |
| VERSION=${{ steps.version.outputs.version }} | |
| export CGO_ENABLED=1 | |
| export CGO_LDFLAGS="-L$(pwd)/dkls23-rs/target/release" | |
| echo "Building for Apple Silicon (arm64)..." | |
| GOOS=darwin GOARCH=arm64 go build \ | |
| -tags "netgo,ledger" \ | |
| -ldflags="-s -w -X github.com/cosmos/cosmos-sdk/version.Version=${VERSION}" \ | |
| -o dist/${BINARY_NAME}-darwin-arm64 \ | |
| ./cmd/pchaind | |
| # Copy libwasmvm.dylib to dist for bundling | |
| cp libwasmvm.dylib dist/ | |
| # Fix rpath to look in same directory as binary (before signing!) | |
| install_name_tool -change @rpath/libwasmvm.dylib @loader_path/libwasmvm.dylib dist/${BINARY_NAME}-darwin-arm64 | |
| ls -la dist/ | |
| # Verify dependencies | |
| echo "Checking dependencies..." | |
| otool -L dist/${BINARY_NAME}-darwin-arm64 || true | |
| - name: Sign Binaries | |
| env: | |
| APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }} | |
| run: | | |
| # Sign both the binary and the dylib | |
| codesign --force --options runtime --timestamp --sign "$APPLE_IDENTITY" dist/${BINARY_NAME}-darwin-arm64 | |
| codesign --force --options runtime --timestamp --sign "$APPLE_IDENTITY" dist/libwasmvm.dylib | |
| echo "Verifying signatures..." | |
| codesign -dv --verbose=2 dist/${BINARY_NAME}-darwin-arm64 | |
| codesign -dv --verbose=2 dist/libwasmvm.dylib | |
| - name: Notarize Binary | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| xcrun notarytool store-credentials "notary-profile" \ | |
| --apple-id "$APPLE_ID" \ | |
| --team-id "$APPLE_TEAM_ID" \ | |
| --password "$APPLE_APP_PASSWORD" | |
| cd dist | |
| # Use version without 'v' prefix to match GoReleaser naming convention | |
| VERSION_NO_V="${VERSION#v}" | |
| # Create archive with bin/ directory structure for Cosmovisor compatibility | |
| # Cosmovisor extracts binary to upgrades/<name>/bin/ but leaves other files in parent | |
| # By including both in bin/, they'll end up in the same directory | |
| mkdir -p bin | |
| cp ${BINARY_NAME}-darwin-arm64 bin/${BINARY_NAME} | |
| cp libwasmvm.dylib bin/ | |
| tar -czvf ${PROJECT_NAME}_${VERSION_NO_V}_darwin_arm64.tar.gz bin/ | |
| rm -rf bin | |
| # For notarization, use flat structure (zip handles differently) | |
| zip -j ${BINARY_NAME}-darwin-arm64-notarize.zip ${BINARY_NAME}-darwin-arm64 libwasmvm.dylib | |
| cd .. | |
| # Notarize | |
| xcrun notarytool submit dist/${BINARY_NAME}-darwin-arm64-notarize.zip \ | |
| --keychain-profile "notary-profile" --wait | |
| rm -f dist/*-notarize.zip | |
| - name: Create Checksums | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| VERSION_NO_V="${VERSION#v}" | |
| cd dist | |
| shasum -a 256 ${PROJECT_NAME}_${VERSION_NO_V}_darwin_arm64.tar.gz > ${PROJECT_NAME}_${VERSION_NO_V}_darwin_arm64.tar.gz.sha256 | |
| ls -la | |
| - name: Upload macOS artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-binaries | |
| path: | | |
| dist/*.tar.gz | |
| dist/*.sha256 | |
| retention-days: 1 | |
| # =========================================== | |
| # Create Unified Release | |
| # =========================================== | |
| create-release: | |
| runs-on: ubuntu-latest | |
| needs: [build-linux, build-linux-arm64, build-macos] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| else | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| fi | |
| # Strip 'v' prefix for file naming (matches GoReleaser convention) | |
| VERSION_NO_V="${VERSION#v}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT | |
| - name: Download Linux artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: linux-binaries | |
| path: dist/linux | |
| - name: Download Linux ARM64 artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: linux-arm64-binaries | |
| path: dist/linux-arm64 | |
| - name: Download macOS artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: macos-binaries | |
| path: dist/macos | |
| - name: Prepare release assets | |
| run: | | |
| mkdir -p release | |
| # Copy all artifacts to release folder | |
| cp dist/linux/*.tar.gz release/ 2>/dev/null || true | |
| cp dist/linux/*.txt release/ 2>/dev/null || true | |
| cp dist/linux-arm64/*.tar.gz release/ 2>/dev/null || true | |
| cp dist/linux-arm64/*.txt release/ 2>/dev/null || true | |
| cp dist/macos/*.tar.gz release/ 2>/dev/null || true | |
| cp dist/macos/*.sha256 release/ 2>/dev/null || true | |
| echo "Release assets:" | |
| ls -la release/ | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| # Use provided compare_from or auto-detect previous tag | |
| COMPARE_FROM="${{ github.event.inputs.compare_from }}" | |
| if [ -z "$COMPARE_FROM" ]; then | |
| COMPARE_FROM=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | grep -v "$VERSION" | head -1) | |
| fi | |
| if [ -z "$COMPARE_FROM" ]; then | |
| COMPARE_FROM=$(git rev-list --max-parents=0 HEAD) | |
| fi | |
| echo "Generating changelog from $COMPARE_FROM to $VERSION" | |
| { | |
| echo "## What's Changed" | |
| echo "" | |
| git log ${COMPARE_FROM}..HEAD --pretty=format:"- %s" | head -30 | |
| } > changelog.md | |
| cat changelog.md | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| name: Release ${{ steps.version.outputs.version }} | |
| body: | | |
| ## 📦 Binaries | |
| | Platform | Architecture | File | | |
| |----------|--------------|------| | |
| | Linux | AMD64 (x86_64) | `${{ env.PROJECT_NAME }}_*_linux_amd64.tar.gz` | | |
| | Linux | ARM64 (aarch64) | `${{ env.PROJECT_NAME }}_*_linux_arm64.tar.gz` | | |
| | macOS | Apple Silicon (arm64) | `${{ env.PROJECT_NAME }}_*_darwin_arm64.tar.gz` | | |
| ## ✅ Verification | |
| macOS binaries are code-signed and notarized by Apple. | |
| Verify checksums using the `.sha256` files. | |
| draft: false | |
| prerelease: ${{ github.event.inputs.prerelease || false }} | |
| files: release/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| continue-on-error: true | |
| - name: Verify Release | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| echo "Verifying release assets..." | |
| gh release view $VERSION --json assets --jq '.assets[].name' || true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |