mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
ci(qa): reuse Matrix live workflow for releases (#103604)
* ci(qa): reuse Matrix live workflow for releases * docs(testing): restore Tailscale isolation flag * fix(ci): make Matrix artifact names ref-safe * test(ci): type Matrix workflow profiles * style(testing): format Tailscale isolation guidance
This commit is contained in:
@@ -1468,104 +1468,24 @@ jobs:
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
|
||||
qa_live_matrix_release_checks:
|
||||
name: Run QA Lab live Matrix lane
|
||||
qa_live_release_checks:
|
||||
name: Run QA Live Matrix profile
|
||||
needs: [resolve_target]
|
||||
if: contains(fromJSON('["all","qa","qa-live"]'), needs.resolve_target.outputs.rerun_group) && needs.resolve_target.outputs.qa_live_matrix_enabled == 'true'
|
||||
continue-on-error: true
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
environment: qa-live-shared
|
||||
env:
|
||||
OPENCLAW_BUILD_PRIVATE_QA: "1"
|
||||
OPENCLAW_ENABLE_PRIVATE_QA_CLI: "1"
|
||||
steps:
|
||||
- name: Checkout selected ref
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ needs.resolve_target.outputs.revision }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
install-bun: "true"
|
||||
|
||||
- name: Build private QA runtime
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
run: node scripts/build-all.mjs qaRuntime
|
||||
|
||||
- name: Run Matrix live lane
|
||||
id: run_lane
|
||||
shell: bash
|
||||
env:
|
||||
OPENCLAW_QA_REDACT_PUBLIC_METADATA: "1"
|
||||
OPENCLAW_QA_MATRIX_CANARY_TIMEOUT_MS: "90000"
|
||||
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS: "3000"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
output_dir=".artifacts/qa-e2e/matrix-live-release-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
matrix_args=(
|
||||
--repo-root . \
|
||||
--provider-mode mock-openai \
|
||||
--model mock-openai/gpt-5.6-luna \
|
||||
--alt-model mock-openai/gpt-5.6-luna-alt \
|
||||
--profile fast \
|
||||
--fast
|
||||
)
|
||||
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
|
||||
matrix_args+=(--fail-fast)
|
||||
fi
|
||||
|
||||
for attempt in 1 2; do
|
||||
attempt_output_dir="${output_dir}/attempt-${attempt}"
|
||||
if pnpm openclaw qa matrix --output-dir "${attempt_output_dir}" "${matrix_args[@]}"; then
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${attempt}" == "2" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "Matrix live lane failed on attempt ${attempt}; retrying once..." >&2
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: Upload Matrix QA artifacts
|
||||
id: upload_matrix_qa_artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: release-qa-live-matrix-${{ needs.resolve_target.outputs.revision }}
|
||||
path: .artifacts/qa-e2e/
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Record advisory status
|
||||
if: always()
|
||||
shell: bash
|
||||
env:
|
||||
RELEASE_CHECK_JOB: qa_live_matrix_release_checks
|
||||
RELEASE_CHECK_TARGET_SHA: ${{ needs.resolve_target.outputs.revision }}
|
||||
JOB_STATUS: ${{ job.status }}
|
||||
RELEASE_CHECK_STEP_OUTCOMES: ${{ steps.run_lane.outcome }} ${{ steps.upload_matrix_qa_artifacts.outcome }}
|
||||
run: *record_release_check_advisory_status
|
||||
|
||||
- name: Upload advisory status
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: release-check-status-qa-live-matrix-${{ needs.resolve_target.outputs.revision }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
path: .artifacts/release-check-status/qa_live_matrix_release_checks-${{ github.run_id }}-${{ github.run_attempt }}.env
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
uses: ./.github/workflows/qa-live-transports-convex.yml
|
||||
with:
|
||||
ref: ${{ needs.resolve_target.outputs.revision }}
|
||||
expected_sha: ${{ needs.resolve_target.outputs.revision }}
|
||||
matrix_profile: release
|
||||
matrix_provider_mode: mock-openai
|
||||
matrix_primary_model: mock-openai/gpt-5.6-luna
|
||||
matrix_alternate_model: mock-openai/gpt-5.6-luna-alt
|
||||
matrix_attempts: 2
|
||||
run_matrix: true
|
||||
matrix_advisory: true
|
||||
|
||||
# The dispatched child owns Telegram evidence/status artifacts; this blocking job
|
||||
# carries its exact conclusion into the parent summary without copying secrets or artifacts.
|
||||
@@ -2022,7 +1942,7 @@ jobs:
|
||||
- qa_lab_parity_report_release_checks
|
||||
- qa_lab_runtime_parity_release_checks
|
||||
- runtime_tool_coverage_release_checks
|
||||
- qa_live_matrix_release_checks
|
||||
- qa_live_release_checks
|
||||
- qa_live_telegram_release_checks
|
||||
- qa_live_discord_release_checks
|
||||
- qa_live_whatsapp_release_checks
|
||||
@@ -2057,7 +1977,7 @@ jobs:
|
||||
QA_LAB_PARITY_REPORT_RELEASE_CHECKS_RESULT: ${{ needs.qa_lab_parity_report_release_checks.result }}
|
||||
QA_LAB_RUNTIME_PARITY_RELEASE_CHECKS_RESULT: ${{ needs.qa_lab_runtime_parity_release_checks.result }}
|
||||
RUNTIME_TOOL_COVERAGE_RELEASE_CHECKS_RESULT: ${{ needs.runtime_tool_coverage_release_checks.result }}
|
||||
QA_LIVE_MATRIX_RELEASE_CHECKS_RESULT: ${{ needs.qa_live_matrix_release_checks.result }}
|
||||
QA_LIVE_RELEASE_CHECKS_RESULT: ${{ needs.qa_live_release_checks.result == 'skipped' && 'skipped' || needs.qa_live_release_checks.outputs.matrix_status || 'failure' }}
|
||||
QA_LIVE_TELEGRAM_RELEASE_CHECKS_RESULT: ${{ needs.qa_live_telegram_release_checks.result }}
|
||||
QA_LIVE_TELEGRAM_SELECTED: ${{ contains(fromJSON('["all","qa","qa-live"]'), needs.resolve_target.outputs.rerun_group) && needs.resolve_target.outputs.qa_live_telegram_enabled == 'true' }}
|
||||
QA_LIVE_DISCORD_RELEASE_CHECKS_RESULT: ${{ needs.qa_live_discord_release_checks.result }}
|
||||
@@ -2083,7 +2003,7 @@ jobs:
|
||||
"qa_lab_parity_report_release_checks=${QA_LAB_PARITY_REPORT_RELEASE_CHECKS_RESULT}"
|
||||
"qa_lab_runtime_parity_release_checks=${QA_LAB_RUNTIME_PARITY_RELEASE_CHECKS_RESULT}"
|
||||
"runtime_tool_coverage_release_checks=${RUNTIME_TOOL_COVERAGE_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_matrix_release_checks=${QA_LIVE_MATRIX_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_release_checks=${QA_LIVE_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_telegram_release_checks=${QA_LIVE_TELEGRAM_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_discord_release_checks=${QA_LIVE_DISCORD_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_whatsapp_release_checks=${QA_LIVE_WHATSAPP_RELEASE_CHECKS_RESULT}"
|
||||
@@ -2093,7 +2013,6 @@ jobs:
|
||||
"qa_lab_parity_lane_release_checks=${QA_LAB_PARITY_LANE_RELEASE_CHECKS_RESULT}"
|
||||
"qa_lab_parity_report_release_checks=${QA_LAB_PARITY_REPORT_RELEASE_CHECKS_RESULT}"
|
||||
"qa_lab_runtime_parity_release_checks=${QA_LAB_RUNTIME_PARITY_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_matrix_release_checks=${QA_LIVE_MATRIX_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_discord_release_checks=${QA_LIVE_DISCORD_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_whatsapp_release_checks=${QA_LIVE_WHATSAPP_RELEASE_CHECKS_RESULT}"
|
||||
"qa_live_slack_release_checks=${QA_LIVE_SLACK_RELEASE_CHECKS_RESULT}"
|
||||
@@ -2247,7 +2166,7 @@ jobs:
|
||||
}
|
||||
advisory_status_override_allowed() {
|
||||
case "$1" in
|
||||
qa_lab_parity_lane_release_checks|qa_lab_parity_report_release_checks|qa_lab_runtime_parity_release_checks|qa_live_matrix_release_checks|qa_live_discord_release_checks|qa_live_whatsapp_release_checks|qa_live_slack_release_checks)
|
||||
qa_lab_parity_lane_release_checks|qa_lab_parity_report_release_checks|qa_lab_runtime_parity_release_checks|qa_live_discord_release_checks|qa_live_whatsapp_release_checks|qa_live_slack_release_checks)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -3,6 +3,80 @@ name: QA-Lab - All Lanes
|
||||
on:
|
||||
schedule:
|
||||
- cron: "41 4 * * *"
|
||||
workflow_call:
|
||||
outputs:
|
||||
matrix_status:
|
||||
description: Matrix release profile status
|
||||
value: ${{ jobs.run_live_matrix.outputs.status }}
|
||||
inputs:
|
||||
ref:
|
||||
description: Ref, tag, or SHA to run
|
||||
required: true
|
||||
type: string
|
||||
expected_sha:
|
||||
description: Exact resolved SHA expected from the trusted caller
|
||||
required: true
|
||||
type: string
|
||||
matrix_profile:
|
||||
description: Matrix QA profile
|
||||
required: false
|
||||
default: release
|
||||
type: string
|
||||
matrix_provider_mode:
|
||||
description: Matrix provider mode
|
||||
required: false
|
||||
default: mock-openai
|
||||
type: string
|
||||
matrix_primary_model:
|
||||
description: Matrix primary model
|
||||
required: false
|
||||
default: mock-openai/gpt-5.6-luna
|
||||
type: string
|
||||
matrix_alternate_model:
|
||||
description: Matrix alternate model
|
||||
required: false
|
||||
default: mock-openai/gpt-5.6-luna-alt
|
||||
type: string
|
||||
matrix_attempts:
|
||||
description: Matrix lane attempts
|
||||
required: false
|
||||
default: 2
|
||||
type: number
|
||||
run_mock_parity:
|
||||
description: Run the mock parity lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
run_matrix:
|
||||
description: Run the Matrix live lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
run_telegram:
|
||||
description: Run the Telegram live lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
run_discord:
|
||||
description: Run the Discord live lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
run_whatsapp:
|
||||
description: Run the WhatsApp live lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
run_slack:
|
||||
description: Run the Slack live lane
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
matrix_advisory:
|
||||
description: Report Matrix failure through the status output instead of failing the reusable job
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
@@ -33,19 +107,16 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- fast
|
||||
- release
|
||||
- all
|
||||
- transport
|
||||
- media
|
||||
- e2ee-smoke
|
||||
- e2ee-deep
|
||||
- e2ee-cli
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
concurrency:
|
||||
group: qa-lab-all-lanes-${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.sha }}
|
||||
group: qa-lab-all-lanes-${{ github.event_name != 'schedule' && inputs.ref || github.sha }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
@@ -66,10 +137,12 @@ jobs:
|
||||
- name: Require maintainer-level repository access
|
||||
id: permission
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
env:
|
||||
EXPECTED_SHA: ${{ inputs.expected_sha }}
|
||||
with:
|
||||
script: |
|
||||
if (context.eventName === "schedule") {
|
||||
core.info("Scheduled default-branch QA run; actor permission check is only required for manual dispatch.");
|
||||
if (context.eventName === "schedule" || (process.env.EXPECTED_SHA ?? "") !== "") {
|
||||
core.info("Trusted scheduled or reusable QA run; actor permission check is only required for manual dispatch.");
|
||||
core.setOutput("authorized", "true");
|
||||
return;
|
||||
}
|
||||
@@ -104,23 +177,37 @@ jobs:
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.sha }}
|
||||
ref: ${{ github.event_name != 'schedule' && inputs.ref || github.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Validate selected ref
|
||||
id: validate
|
||||
env:
|
||||
EXPECTED_SHA: ${{ inputs.expected_sha }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
INPUT_REF: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.sha }}
|
||||
INPUT_REF: ${{ github.event_name != 'schedule' && inputs.ref || github.sha }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
selected_revision="$(git rev-parse HEAD)"
|
||||
trusted_reason=""
|
||||
|
||||
if [[ -n "${EXPECTED_SHA}" && "${selected_revision}" != "${EXPECTED_SHA}" ]]; then
|
||||
echo "Ref '${INPUT_REF}' resolved to ${selected_revision}, expected ${EXPECTED_SHA}." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
|
||||
|
||||
if git merge-base --is-ancestor "$selected_revision" refs/remotes/origin/main; then
|
||||
if [[ -n "${EXPECTED_SHA}" ]]; then
|
||||
git fetch --no-tags origin '+refs/heads/*:refs/remotes/origin/*'
|
||||
git fetch --tags origin '+refs/tags/*:refs/tags/*'
|
||||
if git tag --points-at "$selected_revision" | grep -Eq '^v'; then
|
||||
trusted_reason="release-tag"
|
||||
elif git for-each-ref --format='%(refname:short)' --contains "$selected_revision" refs/remotes/origin | grep -Eq '^origin/'; then
|
||||
trusted_reason="repository-branch"
|
||||
fi
|
||||
elif git merge-base --is-ancestor "$selected_revision" refs/remotes/origin/main; then
|
||||
trusted_reason="main-ancestor"
|
||||
elif git tag --points-at "$selected_revision" | grep -Eq '^v'; then
|
||||
trusted_reason="release-tag"
|
||||
@@ -159,6 +246,7 @@ jobs:
|
||||
run_mock_parity:
|
||||
name: Run QA Lab mock parity lane
|
||||
needs: [validate_selected_ref]
|
||||
if: inputs.expected_sha == '' || inputs.run_mock_parity
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
@@ -322,10 +410,13 @@ jobs:
|
||||
run_live_matrix:
|
||||
name: Run Matrix live QA lane
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.matrix_profile == 'all') }}
|
||||
if: (github.event_name != 'workflow_call' || inputs.run_matrix) && !(github.event_name == 'workflow_dispatch' && inputs.matrix_profile == 'all')
|
||||
continue-on-error: ${{ github.event_name == 'workflow_call' && inputs.matrix_advisory }}
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
environment: qa-live-shared
|
||||
outputs:
|
||||
status: ${{ steps.record_status.outputs.status }}
|
||||
steps:
|
||||
- name: Checkout selected ref
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
@@ -342,12 +433,13 @@ jobs:
|
||||
|
||||
- name: Validate required QA credential env
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
MATRIX_PROVIDER_MODE: ${{ inputs.expected_sha != '' && inputs.matrix_provider_mode || github.event_name == 'workflow_dispatch' && 'mock-openai' || 'live-frontier' }}
|
||||
OPENAI_API_KEY: ${{ (inputs.expected_sha != '' && inputs.matrix_provider_mode == 'live-frontier' || inputs.expected_sha == '' && github.event_name != 'workflow_dispatch') && secrets.OPENAI_API_KEY || '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ -z "${OPENAI_API_KEY:-}" ]]; then
|
||||
if [[ "${MATRIX_PROVIDER_MODE}" == "live-frontier" && -z "${OPENAI_API_KEY:-}" ]]; then
|
||||
echo "Missing required OPENAI_API_KEY." >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -361,40 +453,85 @@ jobs:
|
||||
id: run_lane
|
||||
shell: bash
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
INPUT_MATRIX_PROFILE: ${{ github.event_name == 'workflow_dispatch' && inputs.matrix_profile || 'fast' }}
|
||||
OPENAI_API_KEY: ${{ (inputs.expected_sha != '' && inputs.matrix_provider_mode == 'live-frontier' || inputs.expected_sha == '' && github.event_name != 'workflow_dispatch') && secrets.OPENAI_API_KEY || '' }}
|
||||
INPUT_MATRIX_PROFILE: ${{ inputs.expected_sha != '' && inputs.matrix_profile || github.event_name == 'workflow_dispatch' && inputs.matrix_profile || 'release' }}
|
||||
MATRIX_ALTERNATE_MODEL: ${{ inputs.expected_sha != '' && inputs.matrix_alternate_model || github.event_name == 'workflow_dispatch' && 'mock-openai/gpt-5.6-luna-alt' || env.OPENCLAW_CI_OPENAI_FALLBACK_MODEL }}
|
||||
MATRIX_ATTEMPTS: ${{ inputs.expected_sha != '' && inputs.matrix_attempts || 1 }}
|
||||
MATRIX_PRIMARY_MODEL: ${{ inputs.expected_sha != '' && inputs.matrix_primary_model || github.event_name == 'workflow_dispatch' && 'mock-openai/gpt-5.6-luna' || env.OPENCLAW_CI_OPENAI_MODEL }}
|
||||
MATRIX_PROVIDER_MODE: ${{ inputs.expected_sha != '' && inputs.matrix_provider_mode || github.event_name == 'workflow_dispatch' && 'mock-openai' || 'live-frontier' }}
|
||||
OPENCLAW_QA_REDACT_PUBLIC_METADATA: "1"
|
||||
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS: "3000"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
output_dir=".artifacts/qa-e2e/matrix-live-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
if [[ ! "${MATRIX_ATTEMPTS}" =~ ^[1-9][0-9]*$ ]]; then
|
||||
echo "matrix_attempts must be a positive integer; got: ${MATRIX_ATTEMPTS}" >&2
|
||||
exit 1
|
||||
fi
|
||||
case "${MATRIX_PROVIDER_MODE}" in
|
||||
mock-openai|live-frontier) ;;
|
||||
*)
|
||||
echo "matrix_provider_mode must be mock-openai or live-frontier; got: ${MATRIX_PROVIDER_MODE}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
output_dir=".artifacts/qa-e2e/matrix-live-${INPUT_MATRIX_PROFILE}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
matrix_args=(
|
||||
--repo-root . \
|
||||
--output-dir "${output_dir}" \
|
||||
--provider-mode live-frontier \
|
||||
--model "${OPENCLAW_CI_OPENAI_MODEL}" \
|
||||
--alt-model "${OPENCLAW_CI_OPENAI_FALLBACK_MODEL}" \
|
||||
--profile "${INPUT_MATRIX_PROFILE}" \
|
||||
--fast
|
||||
)
|
||||
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
|
||||
matrix_args+=(--fail-fast)
|
||||
fi
|
||||
|
||||
pnpm openclaw qa matrix "${matrix_args[@]}"
|
||||
for attempt in $(seq 1 "${MATRIX_ATTEMPTS}"); do
|
||||
attempt_output_dir="${output_dir}/attempt-${attempt}"
|
||||
if pnpm openclaw qa matrix \
|
||||
--repo-root . \
|
||||
--output-dir "${attempt_output_dir}" \
|
||||
--provider-mode "${MATRIX_PROVIDER_MODE}" \
|
||||
--model "${MATRIX_PRIMARY_MODEL}" \
|
||||
--alt-model "${MATRIX_ALTERNATE_MODEL}" \
|
||||
--profile "${INPUT_MATRIX_PROFILE}" \
|
||||
--fast; then
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${attempt}" == "${MATRIX_ATTEMPTS}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "Matrix live lane failed on attempt ${attempt}; retrying..." >&2
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: Upload Matrix QA artifacts
|
||||
id: upload_artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: qa-live-matrix-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
name: ${{ inputs.expected_sha != '' && format('release-qa-live-matrix-{0}', inputs.expected_sha) || format('qa-live-matrix-{0}-{1}', github.run_id, github.run_attempt) }}
|
||||
path: ${{ steps.run_lane.outputs.output_dir }}
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Record Matrix QA status
|
||||
id: record_status
|
||||
if: always()
|
||||
shell: bash
|
||||
env:
|
||||
RUN_OUTCOME: ${{ steps.run_lane.outcome }}
|
||||
UPLOAD_OUTCOME: ${{ steps.upload_artifacts.outcome }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
status="success"
|
||||
for outcome in "${RUN_OUTCOME:-}" "${UPLOAD_OUTCOME:-}"; do
|
||||
case "${outcome}" in
|
||||
failure) status="failure" ;;
|
||||
cancelled)
|
||||
if [[ "${status}" != "failure" ]]; then
|
||||
status="cancelled"
|
||||
fi
|
||||
;;
|
||||
success|skipped|"") ;;
|
||||
*) status="failure" ;;
|
||||
esac
|
||||
done
|
||||
echo "status=${status}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
run_live_matrix_sharded:
|
||||
name: Run Matrix live QA lane (${{ matrix.profile }})
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
@@ -448,14 +585,13 @@ jobs:
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENCLAW_QA_REDACT_PUBLIC_METADATA: "1"
|
||||
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS: "3000"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
output_dir=".artifacts/qa-e2e/matrix-live-${{ matrix.profile }}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
matrix_args=(
|
||||
pnpm openclaw qa matrix \
|
||||
--repo-root . \
|
||||
--output-dir "${output_dir}" \
|
||||
--provider-mode live-frontier \
|
||||
@@ -463,12 +599,6 @@ jobs:
|
||||
--alt-model "${OPENCLAW_CI_OPENAI_FALLBACK_MODEL}" \
|
||||
--profile "${{ matrix.profile }}" \
|
||||
--fast
|
||||
)
|
||||
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
|
||||
matrix_args+=(--fail-fast)
|
||||
fi
|
||||
|
||||
pnpm openclaw qa matrix "${matrix_args[@]}"
|
||||
|
||||
- name: Upload Matrix QA shard artifacts
|
||||
if: always()
|
||||
@@ -482,6 +612,7 @@ jobs:
|
||||
run_live_telegram:
|
||||
name: Run Telegram live QA lane with Convex leases
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
if: inputs.expected_sha == '' || inputs.run_telegram
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
environment: qa-live-shared
|
||||
@@ -578,6 +709,7 @@ jobs:
|
||||
run_live_discord:
|
||||
name: Run Discord live QA lane with Convex leases
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
if: inputs.expected_sha == '' || inputs.run_discord
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
environment: qa-live-shared
|
||||
@@ -653,6 +785,7 @@ jobs:
|
||||
run_live_whatsapp:
|
||||
name: Run WhatsApp live QA lane with Convex leases
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
if: inputs.expected_sha == '' || inputs.run_whatsapp
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
concurrency:
|
||||
@@ -731,6 +864,7 @@ jobs:
|
||||
run_live_slack:
|
||||
name: Run Slack live QA lane with Convex leases
|
||||
needs: [authorize_actor, validate_selected_ref]
|
||||
if: inputs.expected_sha == '' || inputs.run_slack
|
||||
runs-on: blacksmith-16vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
environment: qa-live-shared
|
||||
|
||||
Reference in New Issue
Block a user