Update SKILL.md #128
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: Build and Release | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| build: | |
| name: Build - ${{ matrix.platform }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux x86_64 - static musl build | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| platform: linux-x86_64 | |
| artifact_name: payment-linux-x86_64 | |
| use_cross: true | |
| # Linux aarch64 - static musl build | |
| - os: ubuntu-latest | |
| target: aarch64-unknown-linux-musl | |
| platform: linux-aarch64 | |
| artifact_name: payment-linux-aarch64 | |
| use_cross: true | |
| # macOS x86_64 (cross-compile from Apple Silicon) | |
| - os: macos-14 | |
| target: x86_64-apple-darwin | |
| platform: darwin-x86_64 | |
| artifact_name: payment-darwin-x86_64 | |
| # macOS aarch64 (Apple Silicon) | |
| - os: macos-14 | |
| target: aarch64-apple-darwin | |
| platform: darwin-aarch64 | |
| artifact_name: payment-darwin-aarch64 | |
| # Windows x86_64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| platform: windows-x86_64 | |
| artifact_name: payment-windows-x86_64 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install cross (for Linux musl builds) | |
| if: matrix.use_cross | |
| run: cargo install cross --git https://github.com/cross-rs/cross | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ matrix.platform }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ matrix.platform }}-cargo- | |
| - name: Build release binaries (cross) | |
| if: matrix.use_cross | |
| run: cross build --release --target ${{ matrix.target }} | |
| - name: Build release binaries (native) | |
| if: ${{ !matrix.use_cross }} | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Create artifact directory | |
| shell: bash | |
| run: mkdir -p artifacts | |
| - name: Package binaries (Unix) | |
| if: matrix.os != 'windows-latest' | |
| shell: bash | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| chmod +x create-wallet get-address pay payment-config | |
| zip ../../../artifacts/${{ matrix.artifact_name }}.zip \ | |
| create-wallet get-address pay payment-config | |
| - name: Package binaries (Windows) | |
| if: matrix.os == 'windows-latest' | |
| shell: pwsh | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| Compress-Archive -Path create-wallet.exe,get-address.exe,pay.exe,payment-config.exe ` | |
| -DestinationPath ../../../artifacts/${{ matrix.artifact_name }}.zip | |
| - name: Verify static linking (Linux) | |
| if: matrix.use_cross | |
| run: | | |
| echo "=== Checking binary type ===" | |
| file target/${{ matrix.target }}/release/create-wallet | |
| echo "=== Verifying static linking ===" | |
| # The binary should be "statically linked" or "static-pie linked" - fail if not | |
| file target/${{ matrix.target }}/release/create-wallet | grep -qE "(statically linked|static-pie linked)" || { | |
| echo "ERROR: Binary is not statically linked!" | |
| exit 1 | |
| } | |
| echo "=== Checking for dynamic dependencies ===" | |
| # ldd should show "statically linked", "not a dynamic executable", or fail for cross-compiled binaries | |
| LDD_OUTPUT=$(ldd target/${{ matrix.target }}/release/create-wallet 2>&1) || true | |
| if echo "$LDD_OUTPUT" | grep -qE "(statically linked|not a dynamic executable)"; then | |
| echo "SUCCESS: No dynamic dependencies" | |
| echo "$LDD_OUTPUT" | |
| elif echo "$LDD_OUTPUT" | grep -qE "(cannot execute|wrong ELF class|cannot open)"; then | |
| echo "SUCCESS: Cross-compiled binary (ldd cannot analyze, but file confirmed static linking)" | |
| echo "$LDD_OUTPUT" | |
| else | |
| echo "ERROR: Binary has dynamic dependencies:" | |
| echo "$LDD_OUTPUT" | |
| exit 1 | |
| fi | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: artifacts/${{ matrix.artifact_name }}.zip | |
| retention-days: 7 | |
| # Collect all artifacts into single directory | |
| collect-artifacts: | |
| name: Collect Artifacts | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: ls -la artifacts/ | |
| - name: Upload combined artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: all-platforms | |
| path: artifacts/ | |
| retention-days: 30 | |
| # Create GitHub Release on tag push | |
| release: | |
| name: Create Release | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: ls -la artifacts/ | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: artifacts/*.zip | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-beta') || contains(github.ref, '-alpha') }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Run tests | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: test-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| test-cargo- | |
| - name: Run tests | |
| run: cargo test --all | |
| - name: Run clippy | |
| run: cargo clippy --all -- -D warnings | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| # Verify builds work | |
| verify: | |
| name: Verify - ${{ matrix.platform }} | |
| needs: build | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| platform: linux-x86_64 | |
| artifact_name: payment-linux-x86_64 | |
| - os: macos-latest | |
| platform: darwin-aarch64 | |
| artifact_name: payment-darwin-aarch64 | |
| - os: windows-latest | |
| platform: windows-x86_64 | |
| artifact_name: payment-windows-x86_64 | |
| steps: | |
| - name: Download artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: . | |
| - name: Extract and verify (Unix) | |
| if: matrix.os != 'windows-latest' | |
| run: | | |
| unzip ${{ matrix.artifact_name }}.zip | |
| chmod +x * | |
| ./get-address --help | |
| ./create-wallet --help | |
| ./pay --help | |
| ./payment-config --help | |
| - name: Verify static linking (Linux) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| echo "=== Checking binary type ===" | |
| file ./create-wallet | |
| echo "=== Verifying no libc dependency ===" | |
| # The binary should be "statically linked" or "static-pie linked" | |
| file ./create-wallet | grep -qE "(statically linked|static-pie linked)" || { | |
| echo "ERROR: Binary is not statically linked!" | |
| file ./create-wallet | |
| exit 1 | |
| } | |
| # Verify ldd shows no dynamic dependencies | |
| LDD_OUTPUT=$(ldd ./create-wallet 2>&1) | |
| if echo "$LDD_OUTPUT" | grep -qE "(statically linked|not a dynamic executable)"; then | |
| echo "SUCCESS: Binary has no dynamic dependencies (including libc)" | |
| echo "$LDD_OUTPUT" | |
| else | |
| echo "ERROR: Binary has dynamic dependencies:" | |
| echo "$LDD_OUTPUT" | |
| exit 1 | |
| fi | |
| echo "=== All binaries verified as fully static ===" | |
| - name: Extract and verify (Windows) | |
| if: matrix.os == 'windows-latest' | |
| shell: pwsh | |
| run: | | |
| Expand-Archive -Path ${{ matrix.artifact_name }}.zip -DestinationPath . | |
| .\get-address.exe --help | |
| .\create-wallet.exe --help | |
| .\pay.exe --help | |
| .\payment-config.exe --help | |
| # Integration test: wallet creation, address retrieval, payment link | |
| integration-test: | |
| name: Integration Test | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download Linux x86_64 artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: payment-linux-x86_64 | |
| path: . | |
| - name: Set up skill directory | |
| run: | | |
| # Create the skill directory layout: binaries in scripts/, data files in parent | |
| SKILL_DIR="${HOME}/.openclaw/skills/payment" | |
| mkdir -p "${SKILL_DIR}/scripts" | |
| # Extract binaries into scripts/ | |
| unzip payment-linux-x86_64.zip -d "${SKILL_DIR}/scripts" | |
| chmod +x "${SKILL_DIR}/scripts/"* | |
| # Copy default config | |
| cp skills/payment/config-default.toml "${SKILL_DIR}/config.toml" | |
| echo "SKILL_DIR=${SKILL_DIR}" >> "$GITHUB_ENV" | |
| - name: Configure network (base-mainnet) | |
| run: | | |
| "${SKILL_DIR}/scripts/payment-config" show | |
| echo "=== Config verified ===" | |
| - name: Create wallet | |
| run: | | |
| ADDRESS=$("${SKILL_DIR}/scripts/create-wallet" 2>/dev/null) | |
| echo "Created wallet with address: ${ADDRESS}" | |
| # Verify address format (0x + 40 hex chars) | |
| if [[ ! "${ADDRESS}" =~ ^0x[0-9a-fA-F]{40}$ ]]; then | |
| echo "ERROR: Invalid address format: ${ADDRESS}" | |
| exit 1 | |
| fi | |
| echo "WALLET_ADDRESS=${ADDRESS}" >> "$GITHUB_ENV" | |
| - name: Get address and verify | |
| run: | | |
| OUTPUT=$("${SKILL_DIR}/scripts/get-address" 2>/dev/null) | |
| echo "get-address output: ${OUTPUT}" | |
| # Verify JSON output contains the address | |
| ADDR=$(echo "${OUTPUT}" | jq -r '.address') | |
| if [[ -z "${ADDR}" || "${ADDR}" == "null" ]]; then | |
| echo "ERROR: No address in get-address output" | |
| exit 1 | |
| fi | |
| echo "Verified address: ${ADDR}" | |
| - name: Create payment link | |
| run: | | |
| ADDR=$(echo "$("${SKILL_DIR}/scripts/get-address" 2>/dev/null)" | jq -r '.address') | |
| echo "Creating payment link for 0.01 USDC to ${ADDR}..." | |
| RESPONSE=$(curl -s "https://link.x402labs.dev/create-payment-link?amount=0.01&receiver=${ADDR}") | |
| echo "Response: ${RESPONSE}" | |
| # Verify response contains payment_url | |
| PAYMENT_URL=$(echo "${RESPONSE}" | jq -r '.payment_url') | |
| if [[ -z "${PAYMENT_URL}" || "${PAYMENT_URL}" == "null" ]]; then | |
| echo "ERROR: No payment_url in response" | |
| exit 1 | |
| fi | |
| echo "Payment link created: ${PAYMENT_URL}" | |
| # Verify payment status (should be unpaid) | |
| PAYMENT_ID=$(echo "${RESPONSE}" | jq -r '.payment_id') | |
| STATUS=$(curl -s "https://link.x402labs.dev/status/${PAYMENT_ID}") | |
| echo "Payment status: ${STATUS}" | |
| PAID=$(echo "${STATUS}" | jq -r '.paid') | |
| if [[ "${PAID}" != "false" ]]; then | |
| echo "ERROR: Expected paid=false, got paid=${PAID}" | |
| exit 1 | |
| fi | |
| echo "=== Integration test passed ===" |