Install Smoke #26
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: Install Smoke | |
| on: | |
| schedule: | |
| - cron: "17 3 * * *" | |
| workflow_dispatch: | |
| inputs: | |
| run_bun_global_install_smoke: | |
| description: Run the Bun global install image-provider smoke | |
| required: false | |
| default: false | |
| type: boolean | |
| update_baseline_version: | |
| description: Baseline openclaw version or dist-tag for installer update smoke | |
| required: false | |
| default: latest | |
| type: string | |
| workflow_call: | |
| inputs: | |
| ref: | |
| description: Git ref to validate | |
| required: false | |
| type: string | |
| run_bun_global_install_smoke: | |
| description: Run the Bun global install image-provider smoke | |
| required: false | |
| default: true | |
| type: boolean | |
| update_baseline_version: | |
| description: Baseline openclaw version or dist-tag for installer update smoke | |
| required: false | |
| default: latest | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-manual-{1}', github.workflow, github.run_id) || format('{0}-{1}', github.workflow, github.ref) }} | |
| cancel-in-progress: true | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| preflight: | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| docs_only: ${{ steps.manifest.outputs.docs_only }} | |
| run_install_smoke: ${{ steps.manifest.outputs.run_install_smoke }} | |
| run_fast_install_smoke: ${{ steps.manifest.outputs.run_fast_install_smoke }} | |
| run_full_install_smoke: ${{ steps.manifest.outputs.run_full_install_smoke }} | |
| run_bun_global_install_smoke: ${{ steps.manifest.outputs.run_bun_global_install_smoke }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref || github.ref }} | |
| fetch-depth: 1 | |
| fetch-tags: false | |
| persist-credentials: false | |
| submodules: false | |
| - name: Build install-smoke CI manifest | |
| id: manifest | |
| env: | |
| OPENCLAW_CI_EVENT_NAME: ${{ github.event_name }} | |
| OPENCLAW_CI_WORKFLOW_BUN_GLOBAL_INSTALL_SMOKE: ${{ inputs.run_bun_global_install_smoke || 'false' }} | |
| run: | | |
| event_name="${OPENCLAW_CI_EVENT_NAME:-}" | |
| workflow_bun_global_install_smoke="${OPENCLAW_CI_WORKFLOW_BUN_GLOBAL_INSTALL_SMOKE:-false}" | |
| docs_only=false | |
| run_fast_install_smoke=true | |
| run_full_install_smoke=true | |
| run_bun_global_install_smoke=false | |
| run_install_smoke=true | |
| if [ "$event_name" = "schedule" ]; then | |
| run_bun_global_install_smoke=true | |
| elif [ "$event_name" = "workflow_dispatch" ] || [ "$event_name" = "workflow_call" ]; then | |
| if [ "$workflow_bun_global_install_smoke" = "true" ]; then | |
| run_bun_global_install_smoke=true | |
| fi | |
| fi | |
| { | |
| echo "docs_only=$docs_only" | |
| echo "run_install_smoke=$run_install_smoke" | |
| echo "run_fast_install_smoke=$run_fast_install_smoke" | |
| echo "run_full_install_smoke=$run_full_install_smoke" | |
| echo "run_bun_global_install_smoke=$run_bun_global_install_smoke" | |
| } >> "$GITHUB_OUTPUT" | |
| install-smoke-fast: | |
| needs: [preflight] | |
| if: needs.preflight.outputs.run_fast_install_smoke == 'true' && needs.preflight.outputs.run_full_install_smoke != 'true' | |
| runs-on: blacksmith-16vcpu-ubuntu-2404 | |
| env: | |
| DOCKER_BUILD_SUMMARY: "false" | |
| DOCKER_BUILD_RECORD_UPLOAD: "false" | |
| steps: | |
| - name: Checkout CLI | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref || github.ref }} | |
| - name: Set up Blacksmith Docker Builder | |
| uses: useblacksmith/setup-docker-builder@ac083cc84672d01c60d5e8561d0a939b697de542 # v1 | |
| # Blacksmith's builder owns the Docker layer cache; keep smoke builds off | |
| # explicit gha cache directives so local tags still load cleanly. | |
| - name: Build root Dockerfile smoke image | |
| uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| build-args: | | |
| OPENCLAW_EXTENSIONS=matrix | |
| tags: | | |
| openclaw-dockerfile-smoke:local | |
| openclaw-ext-smoke:local | |
| load: true | |
| push: false | |
| provenance: false | |
| - name: Run root Dockerfile CLI smoke | |
| run: | | |
| docker run --rm --entrypoint sh openclaw-dockerfile-smoke:local -lc ' | |
| which openclaw && | |
| openclaw --version && | |
| node -e " | |
| const fs = require(\"node:fs\"); | |
| const path = require(\"node:path\"); | |
| const pkg = require(\"/app/package.json\"); | |
| for (const [dep, rel] of Object.entries(pkg.pnpm?.patchedDependencies ?? {})) { | |
| const absolute = path.join(\"/app\", rel); | |
| if (!fs.existsSync(absolute)) { | |
| throw new Error(`missing patch for ${dep}: ${rel}`); | |
| } | |
| } | |
| " | |
| ' | |
| - name: Run agents delete shared workspace Docker CLI smoke | |
| env: | |
| OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD: "1" | |
| run: bash scripts/e2e/agents-delete-shared-workspace-docker.sh | |
| - name: Run Docker gateway network e2e | |
| env: | |
| OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_GATEWAY_NETWORK_E2E_SKIP_BUILD: "1" | |
| run: bash scripts/e2e/gateway-network-docker.sh | |
| - name: Smoke test Dockerfile with matrix extension build arg | |
| run: | | |
| docker run --rm --entrypoint sh openclaw-ext-smoke:local -lc ' | |
| which openclaw && | |
| openclaw --version && | |
| node -e " | |
| const Module = require(\"node:module\"); | |
| const matrixPackage = require(\"/app/extensions/matrix/package.json\"); | |
| const requireFromMatrix = Module.createRequire(\"/app/extensions/matrix/package.json\"); | |
| const runtimeDeps = Object.keys(matrixPackage.dependencies ?? {}); | |
| if (runtimeDeps.length === 0) { | |
| throw new Error( | |
| \"matrix package has no declared runtime dependencies; smoke cannot validate install mirroring\", | |
| ); | |
| } | |
| for (const dep of runtimeDeps) { | |
| requireFromMatrix.resolve(dep); | |
| } | |
| const { spawnSync } = require(\"node:child_process\"); | |
| const run = spawnSync(\"openclaw\", [\"plugins\", \"list\", \"--json\"], { encoding: \"utf8\" }); | |
| if (run.status !== 0) { | |
| process.stderr.write(run.stderr || run.stdout || \"plugins list failed\\n\"); | |
| process.exit(run.status ?? 1); | |
| } | |
| const parsed = JSON.parse(run.stdout); | |
| const matrix = (parsed.plugins || []).find((entry) => entry.id === \"matrix\"); | |
| if (!matrix) { | |
| throw new Error(\"matrix plugin missing from bundled plugin list\"); | |
| } | |
| const matrixDiag = (parsed.diagnostics || []).filter( | |
| (diag) => | |
| typeof diag.source === \"string\" && | |
| diag.source.includes(\"/extensions/matrix\") && | |
| typeof diag.message === \"string\" && | |
| diag.message.includes(\"extension entry escapes package directory\"), | |
| ); | |
| if (matrixDiag.length > 0) { | |
| throw new Error( | |
| \"unexpected matrix diagnostics: \" + | |
| matrixDiag.map((diag) => diag.message).join(\"; \"), | |
| ); | |
| } | |
| " | |
| ' | |
| install-smoke: | |
| needs: [preflight] | |
| if: needs.preflight.outputs.run_full_install_smoke == 'true' | |
| runs-on: blacksmith-16vcpu-ubuntu-2404 | |
| env: | |
| DOCKER_BUILD_SUMMARY: "false" | |
| DOCKER_BUILD_RECORD_UPLOAD: "false" | |
| steps: | |
| - name: Checkout CLI | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref || github.ref }} | |
| - name: Set up Blacksmith Docker Builder | |
| uses: useblacksmith/setup-docker-builder@ac083cc84672d01c60d5e8561d0a939b697de542 # v1 | |
| # Blacksmith's builder owns the Docker layer cache; keep smoke builds off | |
| # explicit gha cache directives so local tags still load cleanly. | |
| - name: Run QR package install smoke | |
| env: | |
| OPENCLAW_QR_SMOKE_FORCE_INSTALL: "1" | |
| run: bash scripts/e2e/qr-import-docker.sh | |
| # Build once with the matrix extension and tag both smoke names. This | |
| # keeps the build-arg coverage without a second Blacksmith build action. | |
| - name: Build root Dockerfile smoke image | |
| uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| build-args: | | |
| OPENCLAW_EXTENSIONS=matrix | |
| tags: | | |
| openclaw-dockerfile-smoke:local | |
| openclaw-ext-smoke:local | |
| load: true | |
| push: false | |
| provenance: false | |
| - name: Run root Dockerfile CLI smoke | |
| run: | | |
| docker run --rm --entrypoint sh openclaw-dockerfile-smoke:local -lc 'which openclaw && openclaw --version' | |
| - name: Run agents delete shared workspace Docker CLI smoke | |
| env: | |
| OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD: "1" | |
| run: bash scripts/e2e/agents-delete-shared-workspace-docker.sh | |
| - name: Run Docker gateway network e2e | |
| env: | |
| OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_GATEWAY_NETWORK_E2E_SKIP_BUILD: "1" | |
| run: bash scripts/e2e/gateway-network-docker.sh | |
| - name: Smoke test Dockerfile with matrix extension build arg | |
| run: | | |
| docker run --rm --entrypoint sh openclaw-ext-smoke:local -lc ' | |
| which openclaw && | |
| openclaw --version && | |
| node -e " | |
| const Module = require(\"node:module\"); | |
| const matrixPackage = require(\"/app/extensions/matrix/package.json\"); | |
| const requireFromMatrix = Module.createRequire(\"/app/extensions/matrix/package.json\"); | |
| const runtimeDeps = Object.keys(matrixPackage.dependencies ?? {}); | |
| if (runtimeDeps.length === 0) { | |
| throw new Error( | |
| \"matrix package has no declared runtime dependencies; smoke cannot validate install mirroring\", | |
| ); | |
| } | |
| for (const dep of runtimeDeps) { | |
| requireFromMatrix.resolve(dep); | |
| } | |
| const { spawnSync } = require(\"node:child_process\"); | |
| const run = spawnSync(\"openclaw\", [\"plugins\", \"list\", \"--json\"], { encoding: \"utf8\" }); | |
| if (run.status !== 0) { | |
| process.stderr.write(run.stderr || run.stdout || \"plugins list failed\\n\"); | |
| process.exit(run.status ?? 1); | |
| } | |
| const parsed = JSON.parse(run.stdout); | |
| const matrix = (parsed.plugins || []).find((entry) => entry.id === \"matrix\"); | |
| if (!matrix) { | |
| throw new Error(\"matrix plugin missing from bundled plugin list\"); | |
| } | |
| const matrixDiag = (parsed.diagnostics || []).filter( | |
| (diag) => | |
| typeof diag.source === \"string\" && | |
| diag.source.includes(\"/extensions/matrix\") && | |
| typeof diag.message === \"string\" && | |
| diag.message.includes(\"extension entry escapes package directory\"), | |
| ); | |
| if (matrixDiag.length > 0) { | |
| throw new Error( | |
| \"unexpected matrix diagnostics: \" + | |
| matrixDiag.map((diag) => diag.message).join(\"; \"), | |
| ); | |
| } | |
| " | |
| ' | |
| - name: Build installer smoke image | |
| uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2 | |
| with: | |
| context: ./scripts/docker | |
| file: ./scripts/docker/install-sh-smoke/Dockerfile | |
| tags: openclaw-install-smoke:local | |
| load: true | |
| push: false | |
| provenance: false | |
| - name: Build installer non-root image | |
| uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2 | |
| with: | |
| context: ./scripts/docker | |
| file: ./scripts/docker/install-sh-nonroot/Dockerfile | |
| tags: openclaw-install-nonroot:local | |
| load: true | |
| push: false | |
| provenance: false | |
| - name: Setup Node environment for installer smoke | |
| uses: ./.github/actions/setup-node-env | |
| with: | |
| install-bun: ${{ needs.preflight.outputs.run_bun_global_install_smoke }} | |
| install-deps: "true" | |
| - name: Run Bun global install image-provider smoke | |
| if: needs.preflight.outputs.run_bun_global_install_smoke == 'true' | |
| env: | |
| OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD: "0" | |
| run: bash scripts/e2e/bun-global-install-smoke.sh | |
| - name: Run installer docker tests | |
| env: | |
| OPENCLAW_INSTALL_URL: https://openclaw.ai/install.sh | |
| OPENCLAW_INSTALL_CLI_URL: https://openclaw.ai/install-cli.sh | |
| OPENCLAW_NO_ONBOARD: "1" | |
| OPENCLAW_INSTALL_SMOKE_SKIP_CLI: "1" | |
| OPENCLAW_INSTALL_SMOKE_SKIP_IMAGE_BUILD: "1" | |
| OPENCLAW_INSTALL_NONROOT_SKIP_IMAGE_BUILD: "1" | |
| OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT: "0" | |
| OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL: "1" | |
| OPENCLAW_INSTALL_SMOKE_SKIP_PREVIOUS: "1" | |
| OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE: ${{ inputs.update_baseline_version || 'latest' }} | |
| OPENCLAW_INSTALL_SMOKE_UPDATE_DIST_IMAGE: openclaw-dockerfile-smoke:local | |
| OPENCLAW_INSTALL_SMOKE_UPDATE_SKIP_LOCAL_BUILD: "1" | |
| run: bash scripts/test-install-sh-docker.sh | |
| docker-e2e-fast: | |
| needs: [preflight] | |
| if: needs.preflight.outputs.run_fast_install_smoke == 'true' || needs.preflight.outputs.run_full_install_smoke == 'true' | |
| runs-on: blacksmith-16vcpu-ubuntu-2404 | |
| timeout-minutes: 8 | |
| env: | |
| DOCKER_BUILD_SUMMARY: "false" | |
| DOCKER_BUILD_RECORD_UPLOAD: "false" | |
| steps: | |
| - name: Checkout CLI | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref || github.ref }} | |
| - name: Set up Blacksmith Docker Builder | |
| uses: useblacksmith/setup-docker-builder@ac083cc84672d01c60d5e8561d0a939b697de542 # v1 | |
| - name: Setup Node environment for package smoke | |
| uses: ./.github/actions/setup-node-env | |
| with: | |
| install-bun: "false" | |
| install-deps: "true" | |
| - name: Run fast bundled plugin Docker E2E | |
| env: | |
| OPENCLAW_BUNDLED_CHANNEL_DEPS_E2E_IMAGE: openclaw-bundled-channel-fast:local | |
| OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT: 90s | |
| run: timeout 240s pnpm test:docker:bundled-channel-deps:fast |