Add governed external CLI connectors #392
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 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "0 8 * * *" | |
| env: | |
| DOTNET_VERSION: "10.0.x" | |
| DOTNET_NOLOGO: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| jobs: | |
| go-whatsapp-security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.26.3" | |
| cache-dependency-path: src/whatsapp-whatsmeow-worker/go.sum | |
| - name: Check Go module tidiness | |
| working-directory: src/whatsapp-whatsmeow-worker | |
| run: | | |
| go mod tidy | |
| git diff --exit-code -- go.mod go.sum | |
| - name: Test WhatsApp whatsmeow worker | |
| working-directory: src/whatsapp-whatsmeow-worker | |
| run: go test ./... | |
| - name: Run govulncheck | |
| working-directory: src/whatsapp-whatsmeow-worker | |
| run: go run golang.org/x/vuln/cmd/govulncheck@latest ./... | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Restore solution | |
| run: dotnet restore OpenClaw.Net.slnx | |
| - name: Build solution | |
| run: dotnet build OpenClaw.Net.slnx --no-restore -c Release | |
| - name: Test standard targets | |
| run: dotnet test --no-build -c Release --verbosity normal --logger "trx;LogFileName=results.trx" src/OpenClaw.Tests | |
| - name: Restore sandbox-enabled solution | |
| run: dotnet restore OpenClaw.Net.slnx -p:OpenClawEnableOpenSandbox=true | |
| - name: Build sandbox-enabled solution | |
| run: dotnet build OpenClaw.Net.slnx --no-restore -c Release -p:OpenClawEnableOpenSandbox=true | |
| - name: Test sandbox-enabled targets | |
| run: dotnet test --no-build -c Release -p:OpenClawEnableOpenSandbox=true --verbosity normal --logger "trx;LogFileName=results-sandbox.trx" src/OpenClaw.Tests | |
| - name: Restore MAF-enabled solution | |
| run: dotnet restore OpenClaw.Net.slnx -p:OpenClawEnableMafExperiment=true | |
| - name: Build MAF-enabled solution | |
| run: dotnet build OpenClaw.Net.slnx --no-restore -c Release -p:OpenClawEnableMafExperiment=true | |
| - name: Test MAF-enabled targets | |
| run: dotnet test --no-build -c Release -p:OpenClawEnableMafExperiment=true --verbosity normal --logger "trx;LogFileName=results-maf.trx" src/OpenClaw.Tests | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results | |
| path: "**/*.trx" | |
| publish-aot: | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'schedule' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Install AOT prerequisites | |
| run: sudo apt-get update && sudo apt-get install -y clang zlib1g-dev | |
| - name: Publish and smoke-test standard NativeAOT binaries | |
| run: | | |
| chmod +x ./eng/verify-aot-smoke.sh | |
| ./eng/verify-aot-smoke.sh | |
| - name: Publish and smoke-test MAF NativeAOT gateway | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| chmod +x ./eng/verify-aot-maf-smoke.sh | |
| ./eng/verify-aot-maf-smoke.sh | |
| - name: Upload standard gateway artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gateway-standard-aot-linux-x64 | |
| path: ./artifacts/aot/gateway/ | |
| - name: Upload MAF-enabled gateway artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gateway-maf-enabled-aot-linux-x64 | |
| path: ./artifacts/aot-maf/gateway/ | |
| - name: Upload CLI artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openclaw-cli-aot-linux-x64 | |
| path: ./artifacts/aot/cli/ | |
| macos-gateway-linker-probe: | |
| needs: build-and-test | |
| runs-on: macos-15 | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Configure macOS Swift library path | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| developer_dir="$(xcode-select -p)" | |
| sdk_path="$(xcrun --sdk macosx --show-sdk-path)" | |
| library_paths=() | |
| for candidate in \ | |
| "/usr/lib/swift" \ | |
| "$developer_dir/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx" \ | |
| "$sdk_path/usr/lib/swift"; do | |
| if [[ -d "$candidate" ]]; then | |
| library_paths+=("$candidate") | |
| fi | |
| done | |
| if [[ -n "${LIBRARY_PATH:-}" ]]; then | |
| library_paths+=("$LIBRARY_PATH") | |
| fi | |
| joined="$(IFS=:; echo "${library_paths[*]}")" | |
| echo "LIBRARY_PATH=$joined" >> "$GITHUB_ENV" | |
| echo "Using macOS Swift library paths: $joined" | |
| - name: Probe gateway NativeAOT without classic linker | |
| id: probe | |
| continue-on-error: true | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p artifacts/linker-probe | |
| dotnet publish src/OpenClaw.Gateway/OpenClaw.Gateway.csproj \ | |
| -c Release \ | |
| -r osx-arm64 \ | |
| --self-contained true \ | |
| -p:PublishAot=true \ | |
| -p:OpenClawUseClassicMacLd=false \ | |
| -o artifacts/linker-probe/gateway \ | |
| 2>&1 | tee artifacts/linker-probe/publish.log | |
| - name: Report linker probe outcome | |
| shell: bash | |
| run: | | |
| if [[ "${{ steps.probe.outcome }}" == "success" ]]; then | |
| echo "::notice title=Gateway linked without classic linker::Remove the gateway OpenClawUseClassicMacLd default after validating release smoke coverage." | |
| else | |
| echo "::warning title=Gateway still needs classic linker::The no-classic-linker probe failed on macos-15; keep the scoped gateway fallback." | |
| fi | |
| - name: Upload linker probe log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-gateway-linker-probe | |
| path: artifacts/linker-probe/ | |
| publish-jit: | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Publish and smoke-test JIT binaries | |
| run: | | |
| chmod +x ./eng/verify-jit-smoke.sh | |
| chmod +x ./eng/verify-jit-maf-smoke.sh | |
| ./eng/verify-jit-smoke.sh | |
| ./eng/verify-jit-maf-smoke.sh | |
| - name: Upload standard gateway artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gateway-standard-jit-linux-x64 | |
| path: ./artifacts/jit/gateway/ | |
| - name: Upload MAF-enabled gateway artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gateway-maf-enabled-jit-linux-x64 | |
| path: ./artifacts/jit-maf/gateway/ | |
| - name: Upload CLI artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openclaw-cli-jit-linux-x64 | |
| path: ./artifacts/jit/cli/ | |
| docker: | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: true | |
| tags: | | |
| ghcr.io/${{ github.repository }}:latest | |
| ghcr.io/${{ github.repository }}:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| public-compatibility-smoke: | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| timeout-minutes: 30 | |
| env: | |
| OPENCLAW_PUBLIC_SMOKE: "1" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Restore | |
| run: dotnet restore src/OpenClaw.Tests | |
| - name: Build | |
| run: dotnet build --no-restore -c Release src/OpenClaw.Tests | |
| - name: Run Public Compatibility Smoke | |
| run: dotnet test --no-build -c Release --filter "Category=PublicSmoke" --verbosity normal --logger "trx;LogFileName=public-smoke.trx" src/OpenClaw.Tests | |
| - name: Upload smoke results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: public-smoke-results | |
| path: "**/public-smoke.trx" |