






















@@ -33,6 +33,21 @@ on:
3333required: false
3434default: ""
3535type: string
36+package_artifact_run_id:
37+description: Prior run id containing package_artifact_name; blank uses this run or packs the selected ref
38+required: false
39+default: ""
40+type: string
41+docker_e2e_bare_image:
42+description: Existing bare Docker E2E image to reuse; blank derives from package SHA/ref
43+required: false
44+default: ""
45+type: string
46+docker_e2e_functional_image:
47+description: Existing functional Docker E2E image to reuse; blank derives from package SHA/ref
48+required: false
49+default: ""
50+type: string
3651include_live_suites:
3752description: Whether to run live-provider coverage
3853required: false
@@ -79,6 +94,21 @@ on:
7994required: false
8095default: ""
8196type: string
97+package_artifact_run_id:
98+description: Prior run id containing package_artifact_name; blank uses this run or packs the selected ref
99+required: false
100+default: ""
101+type: string
102+docker_e2e_bare_image:
103+description: Existing bare Docker E2E image to reuse; blank derives from package SHA/ref
104+required: false
105+default: ""
106+type: string
107+docker_e2e_functional_image:
108+description: Existing functional Docker E2E image to reuse; blank derives from package SHA/ref
109+required: false
110+default: ""
111+type: string
82112include_live_suites:
83113description: Whether to run live-provider coverage
84114required: false
@@ -398,12 +428,21 @@ jobs:
398428 - chunk_id: core
399429label: core
400430timeout_minutes: 120
431+ - chunk_id: package-install
432+label: package/install
433+timeout_minutes: 180
401434 - chunk_id: package-update
402435label: package/update
403-timeout_minutes: 180
404- - chunk_id: plugins-integrations
405-label: plugins/integrations
406-timeout_minutes: 180
436+timeout_minutes: 90
437+ - chunk_id: plugins
438+label: plugins
439+timeout_minutes: 90
440+ - chunk_id: bundled-channel-deps
441+label: bundled/channel deps
442+timeout_minutes: 120
443+ - chunk_id: service-integrations
444+label: service integrations
445+timeout_minutes: 90
407446env:
408447OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
409448OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
@@ -452,6 +491,7 @@ jobs:
452491OPENCLAW_DOCKER_E2E_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.image }}
453492OPENCLAW_DOCKER_E2E_BARE_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.bare_image }}
454493OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
494+OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
455495OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
456496OPENCLAW_SKIP_DOCKER_BUILD: "1"
457497INCLUDE_OPENWEBUI: ${{ inputs.include_openwebui }}
@@ -579,6 +619,7 @@ jobs:
579619OPENCLAW_DOCKER_E2E_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.image }}
580620OPENCLAW_DOCKER_E2E_BARE_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.bare_image }}
581621OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
622+OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
582623OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
583624OPENCLAW_SKIP_DOCKER_BUILD: "1"
584625INCLUDE_OPENWEBUI: ${{ inputs.include_openwebui }}
@@ -656,14 +697,17 @@ jobs:
656697657698validate_docker_openwebui:
658699needs: [validate_selected_ref, prepare_docker_e2e_image]
659-if: inputs.include_openwebui && !inputs.include_release_path_suites && inputs.docker_lanes == ''
700+if: inputs.include_openwebui && inputs.docker_lanes == ''
701+name: Docker E2E (openwebui)
660702runs-on: blacksmith-32vcpu-ubuntu-2404
661703timeout-minutes: 75
662704env:
663705OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
664706OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
665707OPENCLAW_DOCKER_E2E_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.image }}
666708OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
709+OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
710+OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
667711OPENCLAW_SKIP_DOCKER_BUILD: "1"
668712steps:
669713 - name: Checkout selected ref
@@ -695,15 +739,58 @@ jobs:
695739 exit 1
696740 }
697741698- - name: Run Open WebUI Docker E2E
699-run: pnpm test:docker:openwebui
742+ - name: Plan and hydrate Open WebUI Docker E2E chunk
743+id: plan
744+uses: ./.github/actions/docker-e2e-plan
745+with:
746+mode: chunk
747+chunk: openwebui
748+include-openwebui: "true"
749+package-artifact-name: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
750+751+ - name: Run Open WebUI Docker E2E chunk
752+shell: bash
753+run: |
754+ set -euo pipefail
755+ export OPENCLAW_DOCKER_ALL_PROFILE=release-path
756+ export OPENCLAW_DOCKER_ALL_CHUNK=openwebui
757+ export OPENCLAW_DOCKER_ALL_BUILD=0
758+ export OPENCLAW_DOCKER_ALL_PREFLIGHT=0
759+ export OPENCLAW_DOCKER_ALL_FAIL_FAST=0
760+ export OPENCLAW_DOCKER_ALL_INCLUDE_OPENWEBUI=1
761+ export OPENCLAW_DOCKER_ALL_LOG_DIR=".artifacts/docker-tests/release-openwebui"
762+ export OPENCLAW_DOCKER_ALL_TIMINGS_FILE=".artifacts/docker-tests/release-openwebui-timings.json"
763+ export OPENCLAW_DOCKER_ALL_PNPM_COMMAND="$(command -v pnpm)"
764+765+ pnpm test:docker:all
766+767+ - name: Summarize Open WebUI Docker E2E chunk
768+if: always()
769+shell: bash
770+run: |
771+ set -euo pipefail
772+ summary=".artifacts/docker-tests/release-openwebui/summary.json"
773+ if [[ ! -f "$summary" ]]; then
774+ echo "Docker Open WebUI summary missing: \`$summary\`" >> "$GITHUB_STEP_SUMMARY"
775+ exit 0
776+ fi
777+ node scripts/docker-e2e.mjs summary "$summary" "Docker E2E chunk: openwebui" >> "$GITHUB_STEP_SUMMARY"
778+779+ - name: Upload Open WebUI Docker E2E artifacts
780+if: always()
781+uses: actions/upload-artifact@v7
782+with:
783+name: docker-e2e-openwebui
784+path: .artifacts/docker-tests/
785+if-no-files-found: ignore
700786701787prepare_docker_e2e_image:
702788needs: validate_selected_ref
703789if: inputs.include_release_path_suites || inputs.include_openwebui || inputs.docker_lanes != ''
704790runs-on: blacksmith-32vcpu-ubuntu-2404
705791timeout-minutes: 90
706792permissions:
793+actions: read
707794contents: read
708795packages: write
709796outputs:
@@ -736,22 +823,31 @@ jobs:
736823hydrate-artifacts: "false"
737824738825 - name: Setup Node environment
739-if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name == ''
826+if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name == '' && inputs.package_artifact_run_id == ''
740827uses: ./.github/actions/setup-node-env
741828with:
742829node-version: ${{ env.NODE_VERSION }}
743830pnpm-version: ${{ env.PNPM_VERSION }}
744831install-bun: "true"
745832746- - name: Download provided OpenClaw Docker E2E package
747-if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name != ''
833+ - name: Download current-run OpenClaw Docker E2E package
834+if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name != '' && inputs.package_artifact_run_id == ''
748835uses: actions/download-artifact@v8
749836with:
750837name: ${{ inputs.package_artifact_name }}
751838path: .artifacts/docker-e2e-package
752839840+ - name: Download previous-run OpenClaw Docker E2E package
841+if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_run_id != ''
842+uses: actions/download-artifact@v8
843+with:
844+name: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
845+path: .artifacts/docker-e2e-package
846+run-id: ${{ inputs.package_artifact_run_id }}
847+github-token: ${{ github.token }}
848+753849 - name: Pack OpenClaw package for Docker E2E
754-if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name == ''
850+if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name == '' && inputs.package_artifact_run_id == ''
755851shell: bash
756852run: |
757853 set -euo pipefail
@@ -788,10 +884,10 @@ jobs:
788884 } >> "$GITHUB_STEP_SUMMARY"
789885790886 - name: Upload OpenClaw Docker E2E package
791-if: steps.plan.outputs.needs_package == '1' && inputs.package_artifact_name == ''
887+if: steps.plan.outputs.needs_package == '1' && (inputs.package_artifact_name == '' || inputs.package_artifact_run_id != '')
792888uses: actions/upload-artifact@v7
793889with:
794-name: docker-e2e-package
890+name: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
795891path: .artifacts/docker-e2e-package/openclaw-current.tgz
796892if-no-files-found: error
797893@@ -801,12 +897,14 @@ jobs:
801897env:
802898PACKAGE_TAG: ${{ steps.package.outputs.tag }}
803899SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
900+PROVIDED_BARE_IMAGE: ${{ inputs.docker_e2e_bare_image }}
901+PROVIDED_FUNCTIONAL_IMAGE: ${{ inputs.docker_e2e_functional_image }}
804902run: |
805903 set -euo pipefail
806904 repository="${GITHUB_REPOSITORY,,}"
807905 image_tag="${PACKAGE_TAG:-$SELECTED_SHA}"
808- bare_image="ghcr.io/${repository}-docker-e2e-bare:${image_tag}"
809- functional_image="ghcr.io/${repository}-docker-e2e-functional:${image_tag}"
906+ bare_image="${PROVIDED_BARE_IMAGE:-ghcr.io/${repository}-docker-e2e-bare:${image_tag}}"
907+ functional_image="${PROVIDED_FUNCTIONAL_IMAGE:-ghcr.io/${repository}-docker-e2e-functional:${image_tag}}"
810908 image="$functional_image"
811909 echo "image=$image" >> "$GITHUB_OUTPUT"
812910 echo "bare_image=$bare_image" >> "$GITHUB_OUTPUT"
@@ -826,6 +924,9 @@ jobs:
826924id: image_exists
827925if: steps.plan.outputs.needs_e2e_image == '1'
828926shell: bash
927+env:
928+PROVIDED_BARE_IMAGE: ${{ inputs.docker_e2e_bare_image }}
929+PROVIDED_FUNCTIONAL_IMAGE: ${{ inputs.docker_e2e_functional_image }}
829930run: |
830931 set -euo pipefail
831932 bare_exists=0
@@ -836,6 +937,9 @@ jobs:
836937 if docker manifest inspect "${{ steps.image.outputs.bare_image }}" >/dev/null 2>&1; then
837938 bare_exists=1
838939 echo "Shared Docker E2E bare image already exists: ${{ steps.image.outputs.bare_image }}"
940+ elif [[ -n "$PROVIDED_BARE_IMAGE" ]]; then
941+ echo "Provided bare Docker E2E image does not exist: $PROVIDED_BARE_IMAGE" >&2
942+ exit 1
839943 else
840944 needs_build=1
841945 fi
@@ -845,6 +949,9 @@ jobs:
845949 if docker manifest inspect "${{ steps.image.outputs.functional_image }}" >/dev/null 2>&1; then
846950 functional_exists=1
847951 echo "Shared Docker E2E functional image already exists: ${{ steps.image.outputs.functional_image }}"
952+ elif [[ -n "$PROVIDED_FUNCTIONAL_IMAGE" ]]; then
953+ echo "Provided functional Docker E2E image does not exist: $PROVIDED_FUNCTIONAL_IMAGE" >&2
954+ exit 1
848955 else
849956 needs_build=1
850957 fi
@@ -860,33 +967,27 @@ jobs:
860967861968 - name: Build and push bare Docker E2E image
862969if: steps.plan.outputs.needs_bare_image == '1' && steps.image_exists.outputs.bare_exists != '1'
863-uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
970+uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2
864971with:
865972context: .
866973file: ./scripts/e2e/Dockerfile
867974target: bare
868975platforms: linux/amd64
869-cache-from: type=gha,scope=docker-e2e-bare
870-cache-to: type=gha,mode=max,scope=docker-e2e-bare
871976tags: ${{ steps.image.outputs.bare_image }}
872977sbom: true
873978provenance: mode=max
874979push: true
875980876981 - name: Build and push functional Docker E2E image
877982if: steps.plan.outputs.needs_functional_image == '1' && steps.image_exists.outputs.functional_exists != '1'
878-uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
983+uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2
879984with:
880985context: .
881986file: ./scripts/e2e/Dockerfile
882987target: functional
883988build-contexts: |
884989 openclaw_package=.artifacts/docker-e2e-package
885990 platforms: linux/amd64
886-cache-from: |
887- type=gha,scope=docker-e2e-bare
888- type=gha,scope=docker-e2e-functional
889- cache-to: type=gha,mode=max,scope=docker-e2e-functional
890991tags: ${{ steps.image.outputs.functional_image }}
891992sbom: true
892993provenance: mode=max
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。