Merge pull request #10 from openSVM/copilot/fix-9 #23
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: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| build-and-test: | |
| name: Build & Test | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-22.04, macos-latest, windows-latest] | |
| include: | |
| - os: ubuntu-22.04 | |
| target: wasm32-unknown-unknown | |
| platform: web | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| platform: desktop | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| platform: desktop | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Cache dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| opensvm-dioxus/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo- | |
| - name: Add WASM target | |
| if: ${{ matrix.platform == 'web' }} | |
| run: rustup target add wasm32-unknown-unknown | |
| - name: Install Linux dependencies | |
| if: ${{ matrix.os == 'ubuntu-22.04' }} | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev patchelf pkg-config libssl-dev libsoup-3.0-dev | |
| - name: Install wasm-bindgen-cli and wasm-opt | |
| if: ${{ matrix.platform == 'web' }} | |
| run: | | |
| cargo install wasm-bindgen-cli | |
| # Install wasm-opt via binaryen | |
| curl -L https://github.com/WebAssembly/binaryen/releases/download/version_117/binaryen-version_117-x86_64-linux.tar.gz | tar xz | |
| sudo cp binaryen-version_117/bin/wasm-opt /usr/local/bin/ | |
| wasm-opt --version | |
| - name: Build for Web | |
| if: ${{ matrix.platform == 'web' }} | |
| run: | | |
| cd opensvm-dioxus | |
| cargo build --target wasm32-unknown-unknown --features web --release --no-default-features | |
| # Optimize WASM binary with wasm-opt | |
| echo "Original WASM size:" | |
| ls -lh target/wasm32-unknown-unknown/release/opensvm_dioxus.wasm | |
| wasm-opt -Oz --enable-mutable-globals \ | |
| target/wasm32-unknown-unknown/release/opensvm_dioxus.wasm \ | |
| -o target/wasm32-unknown-unknown/release/opensvm_dioxus_opt.wasm | |
| # Replace original with optimized version | |
| mv target/wasm32-unknown-unknown/release/opensvm_dioxus_opt.wasm \ | |
| target/wasm32-unknown-unknown/release/opensvm_dioxus.wasm | |
| echo "Optimized WASM size:" | |
| ls -lh target/wasm32-unknown-unknown/release/opensvm_dioxus.wasm | |
| - name: Build for Desktop (macOS) | |
| if: ${{ matrix.platform == 'desktop' && matrix.os == 'macos-latest' }} | |
| run: | | |
| cd opensvm-dioxus | |
| RUSTFLAGS="-C target-cpu=native" cargo build --features desktop --release --no-default-features | |
| shell: bash | |
| - name: Build for Desktop (Linux) | |
| if: ${{ matrix.platform == 'desktop' && matrix.os == 'ubuntu-22.04' }} | |
| run: | | |
| cd opensvm-dioxus | |
| RUSTFLAGS="-C target-cpu=native" cargo build --features desktop --release --no-default-features | |
| shell: bash | |
| - name: Build for Desktop (Windows) | |
| if: ${{ matrix.platform == 'desktop' && matrix.os == 'windows-latest' }} | |
| run: | | |
| cd opensvm-dioxus | |
| $env:RUSTFLAGS="-C target-cpu=native" | |
| cargo build --features desktop --release --no-default-features | |
| shell: pwsh | |
| - name: Run tests | |
| run: | | |
| cd opensvm-dioxus | |
| cargo test --features ${{ matrix.platform }} --no-default-features | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: opensvm-dioxus-${{ matrix.os }}-${{ matrix.platform }} | |
| path: | | |
| opensvm-dioxus/target/*/release/opensvm-dioxus* | |
| opensvm-dioxus/target/release/opensvm-dioxus* | |
| release: | |
| name: Create Release | |
| needs: build-and-test | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Prepare release assets | |
| run: | | |
| mkdir -p release-assets | |
| # Web (WASM) | |
| if [ -d "artifacts/opensvm-dioxus-ubuntu-22.04-web" ]; then | |
| cd artifacts/opensvm-dioxus-ubuntu-22.04-web | |
| zip -r ../release-assets/opensvm-dioxus-web.zip . | |
| cd .. | |
| fi | |
| # macOS | |
| if [ -d "artifacts/opensvm-dioxus-macos-latest-desktop" ]; then | |
| cd artifacts/opensvm-dioxus-macos-latest-desktop | |
| zip -r ../release-assets/opensvm-dioxus-macos.zip . | |
| cd .. | |
| fi | |
| # Windows | |
| if [ -d "artifacts/opensvm-dioxus-windows-latest-desktop" ]; then | |
| cd artifacts/opensvm-dioxus-windows-latest-desktop | |
| zip -r ../release-assets/opensvm-dioxus-windows.zip . | |
| cd .. | |
| fi | |
| # Android | |
| if [ -d "artifacts/opensvm-dioxus-android" ]; then | |
| cd artifacts/opensvm-dioxus-android | |
| zip -r ../release-assets/opensvm-dioxus-android.zip . | |
| cd .. | |
| fi | |
| shell: bash | |
| - name: Create GitHub Release | |
| id: create_release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| files: release-assets/* | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| homebrew: | |
| name: Update Homebrew Formula | |
| needs: release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Git | |
| run: | | |
| git config --global user.name "GitHub Actions" | |
| git config --global user.email "[email protected]" | |
| - name: Download macOS artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: opensvm-dioxus-macos-latest-desktop | |
| path: macos-artifact | |
| - name: Create Homebrew Formula | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| DOWNLOAD_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}/opensvm-dioxus-macos.zip" | |
| # Function to retry downloading with exponential backoff | |
| download_with_retry() { | |
| local url="$1" | |
| local output="$2" | |
| local max_attempts=5 | |
| local attempt=1 | |
| local delay=10 | |
| while [ $attempt -le $max_attempts ]; do | |
| echo "Attempt $attempt/$max_attempts: Downloading $url" | |
| if curl -L --fail --retry 3 --retry-delay 5 -o "$output" "$url"; then | |
| echo "Download successful on attempt $attempt" | |
| return 0 | |
| fi | |
| echo "Download failed on attempt $attempt" | |
| if [ $attempt -eq $max_attempts ]; then | |
| echo "All download attempts failed" | |
| return 1 | |
| fi | |
| echo "Waiting ${delay} seconds before next attempt..." | |
| sleep $delay | |
| delay=$((delay * 2)) # Exponential backoff | |
| attempt=$((attempt + 1)) | |
| done | |
| } | |
| # Wait for release to be available with health check | |
| echo "Checking if release is available..." | |
| HEALTH_CHECK_URL="https://api.github.com/repos/${{ github.repository }}/releases/tags/v${VERSION}" | |
| max_wait_attempts=12 # 12 * 10 seconds = 2 minutes max wait | |
| wait_attempt=1 | |
| while [ $wait_attempt -le $max_wait_attempts ]; do | |
| echo "Health check attempt $wait_attempt/$max_wait_attempts" | |
| if curl -s --fail "$HEALTH_CHECK_URL" > /dev/null; then | |
| echo "Release found in GitHub API" | |
| break | |
| fi | |
| if [ $wait_attempt -eq $max_wait_attempts ]; then | |
| echo "Release not found after waiting, proceeding anyway..." | |
| break | |
| fi | |
| echo "Release not yet available, waiting 10 seconds..." | |
| sleep 10 | |
| wait_attempt=$((wait_attempt + 1)) | |
| done | |
| # Download the release asset with retry logic | |
| if ! download_with_retry "$DOWNLOAD_URL" "opensvm-dioxus-macos.zip"; then | |
| echo "Failed to download release asset after all retries" | |
| echo "URL: $DOWNLOAD_URL" | |
| echo "Checking available assets..." | |
| curl -s "https://api.github.com/repos/${{ github.repository }}/releases/tags/v${VERSION}" | jq '.assets[].name' || true | |
| exit 1 | |
| fi | |
| # Verify the downloaded file | |
| if [ ! -f "opensvm-dioxus-macos.zip" ] || [ ! -s "opensvm-dioxus-macos.zip" ]; then | |
| echo "Downloaded file is missing or empty" | |
| exit 1 | |
| fi | |
| # Calculate SHA256 of the downloaded asset | |
| SHA256=$(shasum -a 256 opensvm-dioxus-macos.zip | awk '{print $1}') | |
| echo "Calculated SHA256: $SHA256" | |
| # Validate SHA256 format | |
| if ! echo "$SHA256" | grep -q '^[a-f0-9]\{64\}$'; then | |
| echo "Invalid SHA256 format: $SHA256" | |
| exit 1 | |
| fi | |
| # Create formula directory if it doesn't exist | |
| mkdir -p Formula | |
| # Create or update formula file | |
| cat > Formula/opensvm-dioxus.rb << EOF | |
| class OpensvmDioxus < Formula | |
| desc "OpenSVM Dioxus application for Solana blockchain ecosystem" | |
| homepage "https://github.com/${{ github.repository }}" | |
| url "$DOWNLOAD_URL" | |
| sha256 "$SHA256" | |
| version "$VERSION" | |
| def install | |
| libexec.install Dir["*"] | |
| bin.install_symlink libexec/"opensvm-dioxus" | |
| end | |
| end | |
| EOF | |
| # Validate the generated formula syntax | |
| if ! ruby -c Formula/opensvm-dioxus.rb; then | |
| echo "Generated formula has syntax errors" | |
| exit 1 | |
| fi | |
| echo "Generated formula:" | |
| cat Formula/opensvm-dioxus.rb | |
| # Create a new branch for the formula update | |
| git checkout -b update-homebrew-formula-v$VERSION | |
| # Commit and push changes with error handling | |
| git add Formula/opensvm-dioxus.rb | |
| git commit -m "Update Homebrew formula to v$VERSION" | |
| if ! git push origin update-homebrew-formula-v$VERSION; then | |
| echo "Failed to push branch, may already exist" | |
| git push --force origin update-homebrew-formula-v$VERSION | |
| fi | |
| # Create pull request using GitHub CLI with error handling | |
| if ! gh pr create --title "Update Homebrew formula to v$VERSION" --body "Updates the Homebrew formula for opensvm-dioxus to version $VERSION" --base main --head update-homebrew-formula-v$VERSION; then | |
| echo "Failed to create PR, it may already exist" | |
| echo "Checking existing PRs..." | |
| gh pr list --head update-homebrew-formula-v$VERSION || true | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| android-build: | |
| name: Build Android | |
| runs-on: ubuntu-22.04 | |
| if: github.event_name == 'push' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-linux-android | |
| - name: Install Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Cache dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| opensvm-dioxus/target | |
| key: android-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: android-cargo- | |
| - name: Build for Android | |
| run: | | |
| cd opensvm-dioxus | |
| RUSTFLAGS="-C opt-level=3 -C lto=thin" cargo build --target aarch64-linux-android --features android --release --no-default-features | |
| - name: Upload Android artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: opensvm-dioxus-android | |
| path: opensvm-dioxus/target/aarch64-linux-android/release/opensvm-dioxus |