fix(e2e): remove unenforced PTY signing (#9421) #2
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
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| name: CI / Main | |
| on: | |
| push: | |
| branches: [main] | |
| paths-ignore: | |
| - "docs/**" | |
| - "**/*.md" | |
| - ".github/workflows/docs-preview-*.yaml" | |
| - "ISSUE_TEMPLATE/**" | |
| - ".github/ISSUE_TEMPLATE/**" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| static-checks: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Run static checks | |
| uses: ./.github/actions/ci-static-checks | |
| build-typecheck: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Run build and type checks | |
| uses: ./.github/actions/ci-build-typecheck | |
| installer-integration: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Run installer integration tests | |
| uses: ./.github/actions/ci-installer-integration | |
| wechat-runtime-audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Audit locked WeChat runtime graph | |
| uses: ./.github/actions/ci-wechat-runtime-audit | |
| with: | |
| target-root: ${{ github.workspace }} | |
| report-dir: artifacts/wechat-runtime-audit | |
| - name: Upload WeChat runtime audit evidence | |
| if: ${{ always() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: wechat-runtime-audit-${{ github.run_id }}-${{ github.run_attempt }} | |
| path: artifacts/wechat-runtime-audit | |
| if-no-files-found: error | |
| retention-days: 14 | |
| reviewed-npm-audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Audit reviewed production npm graphs | |
| uses: ./.github/actions/ci-reviewed-npm-audit | |
| with: | |
| target-root: ${{ github.workspace }} | |
| report-dir: artifacts/reviewed-npm-audit | |
| real-openclaw-dist-harness: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| env: | |
| # This required proof reads reviewed npm metadata/tarballs. Keep npm's | |
| # transient-registry retry policy explicit at the hard merge boundary. | |
| npm_config_fetch_retries: "3" | |
| npm_config_fetch_retry_mintimeout: "10000" | |
| npm_config_fetch_retry_maxtimeout: "60000" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| - name: Install test dependencies | |
| run: npm ci --ignore-scripts | |
| - name: Audit the real patched OpenClaw distribution | |
| env: | |
| NEMOCLAW_REAL_OPENCLAW_DIST_HARNESS: "1" | |
| run: npx vitest run --project integration test/openclaw-real-patched-dist-harness.test.ts --silent=false --reporter=default | |
| - name: Verify reviewed Jaeger header handling | |
| env: | |
| NEMOCLAW_REAL_OPENCLAW_JAEGER_HARNESS: "1" | |
| run: npx vitest run --project integration test/openclaw-diagnostics-jaeger-runtime.test.ts --silent=false --reporter=default | |
| - name: Audit managed OpenClaw security finding suppressions | |
| env: | |
| NEMOCLAW_REAL_OPENCLAW_AUDIT_HARNESS: "1" | |
| run: npx vitest run --project integration test/openclaw-security-audit-suppressions-real.test.ts --silent=false --reporter=default | |
| cli-test-shards: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Run CLI coverage shard | |
| uses: ./.github/actions/ci-cli-coverage-shard | |
| with: | |
| shard: ${{ matrix.shard }} | |
| shard-count: "12" | |
| cli-tests: | |
| needs: cli-test-shards | |
| if: ${{ always() }} | |
| permissions: | |
| actions: read | |
| code-quality: write | |
| contents: read | |
| pull-requests: read | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Verify CLI shards completed | |
| env: | |
| CLI_SHARD_RESULT: ${{ needs['cli-test-shards'].result }} | |
| GH_TOKEN: ${{ github.token }} | |
| RUN_ATTEMPT: ${{ github.run_attempt }} | |
| RUN_ID: ${{ github.run_id }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| set -u | |
| if [ "$CLI_SHARD_RESULT" != "success" ]; then | |
| details="$RUN_URL" | |
| if jobs_json="$(gh api \ | |
| "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/attempts/$RUN_ATTEMPT/jobs?per_page=100" \ | |
| 2>/dev/null)"; then | |
| if job_ids="$(jq -er ' | |
| if ((.total_count | type) != "number") or | |
| (.total_count < 0) or | |
| (.total_count > 100) or | |
| ((.total_count | floor) != .total_count) or | |
| ((.jobs | type) != "array") or | |
| ((.jobs | length) != .total_count) | |
| then error("invalid workflow job listing") | |
| else | |
| [.jobs[] | | |
| select((.name | type) == "string") | | |
| select(.name | test("^cli-test-shards \\(([1-9]|1[0-2])\\)$")) | | |
| select(.conclusion != "success")] as $failed | | |
| if ($failed | length) == 0 or | |
| ($failed | length) > 12 or | |
| (($failed | map(.name) | unique | length) != ($failed | length)) | |
| then error("invalid failed CLI shard listing") | |
| else | |
| $failed[] | | |
| if ((.id | type) != "number") or | |
| (.id < 1) or | |
| (.id > 9007199254740991) or | |
| ((.id | floor) != .id) or | |
| (.status != "completed") or | |
| ((.conclusion | type) != "string") | |
| then error("invalid failed CLI shard") | |
| else .id | |
| end | |
| end | |
| end | |
| ' <<<"$jobs_json" 2>/dev/null)"; then | |
| details="" | |
| while IFS= read -r job_id; do | |
| [ -n "$details" ] && details="${details}; " | |
| details="${details}${RUN_URL}/job/${job_id}" | |
| done <<<"$job_ids" | |
| fi | |
| fi | |
| echo "::error title=CLI coverage shards failed::Expected success, got ${CLI_SHARD_RESULT}. Details: ${details}" | |
| exit 1 | |
| fi | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Merge CLI coverage | |
| uses: ./.github/actions/ci-cli-coverage-merge | |
| with: | |
| shard-count: "12" | |
| plugin-tests: | |
| permissions: | |
| code-quality: write | |
| contents: read | |
| pull-requests: read | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Run plugin coverage | |
| uses: ./.github/actions/ci-plugin-coverage | |
| checks: | |
| needs: | |
| - static-checks | |
| - build-typecheck | |
| - installer-integration | |
| - wechat-runtime-audit | |
| - reviewed-npm-audit | |
| - real-openclaw-dist-harness | |
| - cli-tests | |
| - plugin-tests | |
| - sandbox-images-and-e2e | |
| if: always() | |
| permissions: | |
| actions: read | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 1 | |
| steps: | |
| - name: Verify required main checks | |
| env: | |
| STATIC_RESULT: ${{ needs['static-checks'].result }} | |
| BUILD_TYPECHECK_RESULT: ${{ needs['build-typecheck'].result }} | |
| INSTALLER_INTEGRATION_RESULT: ${{ needs['installer-integration'].result }} | |
| WECHAT_RUNTIME_AUDIT_RESULT: ${{ needs['wechat-runtime-audit'].result }} | |
| REVIEWED_NPM_AUDIT_RESULT: ${{ needs['reviewed-npm-audit'].result }} | |
| REAL_OPENCLAW_DIST_HARNESS_RESULT: ${{ needs['real-openclaw-dist-harness'].result }} | |
| CLI_TESTS_RESULT: ${{ needs['cli-tests'].result }} | |
| GH_TOKEN: ${{ github.token }} | |
| PLUGIN_TESTS_RESULT: ${{ needs['plugin-tests'].result }} | |
| SANDBOX_IMAGES_E2E_RESULT: ${{ needs['sandbox-images-and-e2e'].result }} | |
| RUN_ATTEMPT: ${{ github.run_attempt }} | |
| RUN_ID: ${{ github.run_id }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| set -euo pipefail | |
| job_listing_state="uninitialized" | |
| jobs_json="" | |
| dependency_url="$RUN_URL" | |
| failed=0 | |
| load_job_listing() { | |
| if [ "$job_listing_state" != "uninitialized" ]; then | |
| return | |
| fi | |
| if jobs_json="$(gh api \ | |
| "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/attempts/$RUN_ATTEMPT/jobs?per_page=100" \ | |
| 2>/dev/null)" && jq -e ' | |
| ((.total_count | type) == "number") and | |
| (.total_count >= 0) and | |
| (.total_count <= 100) and | |
| ((.total_count | floor) == .total_count) and | |
| ((.jobs | type) == "array") and | |
| ((.jobs | length) == .total_count) | |
| ' <<<"$jobs_json" >/dev/null 2>&1; then | |
| job_listing_state="ready" | |
| else | |
| job_listing_state="failed" | |
| fi | |
| } | |
| resolve_dependency_url() { | |
| local name="$1" | |
| local result="$2" | |
| local job_id="" | |
| dependency_url="$RUN_URL" | |
| case "$name" in | |
| static-checks|build-typecheck|installer-integration|wechat-runtime-audit|reviewed-npm-audit|real-openclaw-dist-harness|cli-tests|plugin-tests|sandbox-images-and-e2e) ;; | |
| *) return ;; | |
| esac | |
| load_job_listing | |
| if [ "$job_listing_state" = "ready" ] && job_id="$(jq -er \ | |
| --arg name "$name" \ | |
| --arg result "$result" ' | |
| [.jobs[] | select(.name == $name)] as $matching | | |
| if ($matching | length) != 1 | |
| then error("missing or duplicate dependency job") | |
| elif (($matching[0].id | type) != "number") or | |
| ($matching[0].id < 1) or | |
| ($matching[0].id > 9007199254740991) or | |
| (($matching[0].id | floor) != $matching[0].id) or | |
| ($matching[0].status != "completed") or | |
| (($matching[0].conclusion | type) != "string") or | |
| ($matching[0].conclusion != $result) | |
| then error("invalid dependency job") | |
| else $matching[0].id | |
| end | |
| ' <<<"$jobs_json" 2>/dev/null)"; then | |
| dependency_url="${RUN_URL}/job/${job_id}" | |
| fi | |
| } | |
| require_success() { | |
| local name="$1" | |
| local result="$2" | |
| if [ "$result" != "success" ]; then | |
| resolve_dependency_url "$name" "$result" | |
| echo "::error title=${name} failed::Expected success, got ${result}. Details: ${dependency_url}" | |
| failed=1 | |
| fi | |
| } | |
| require_success "static-checks" "$STATIC_RESULT" | |
| require_success "build-typecheck" "$BUILD_TYPECHECK_RESULT" | |
| require_success "installer-integration" "$INSTALLER_INTEGRATION_RESULT" | |
| require_success "wechat-runtime-audit" "$WECHAT_RUNTIME_AUDIT_RESULT" | |
| require_success "reviewed-npm-audit" "$REVIEWED_NPM_AUDIT_RESULT" | |
| require_success "real-openclaw-dist-harness" "$REAL_OPENCLAW_DIST_HARNESS_RESULT" | |
| require_success "cli-tests" "$CLI_TESTS_RESULT" | |
| require_success "plugin-tests" "$PLUGIN_TESTS_RESULT" | |
| require_success "sandbox-images-and-e2e" "$SANDBOX_IMAGES_E2E_RESULT" | |
| [ "$failed" -eq 0 ] | |
| sandbox-images-and-e2e: | |
| needs: [static-checks, build-typecheck] | |
| uses: ./.github/workflows/sandbox-images-and-e2e.yaml | |
| secrets: | |
| DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} | |
| DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} |