

























@@ -0,0 +1,169 @@
1+name: Mantis Discord Smoke
2+3+on:
4+workflow_dispatch:
5+inputs:
6+ref:
7+description: Ref, tag, or SHA to run
8+required: true
9+default: main
10+type: string
11+post_message:
12+description: Post a smoke message and reaction to the configured Discord channel
13+required: true
14+default: true
15+type: boolean
16+17+permissions:
18+contents: read
19+pull-requests: read
20+21+concurrency:
22+group: mantis-discord-smoke-${{ inputs.ref }}-${{ github.run_attempt }}
23+cancel-in-progress: false
24+25+env:
26+FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
27+NODE_VERSION: "24.x"
28+PNPM_VERSION: "10.33.0"
29+OPENCLAW_BUILD_PRIVATE_QA: "1"
30+OPENCLAW_ENABLE_PRIVATE_QA_CLI: "1"
31+32+jobs:
33+authorize_actor:
34+name: Authorize workflow actor
35+runs-on: blacksmith-8vcpu-ubuntu-2404
36+steps:
37+ - name: Require maintainer-level repository access
38+uses: actions/github-script@v8
39+with:
40+script: |
41+ const allowed = new Set(["admin", "maintain", "write"]);
42+ const { owner, repo } = context.repo;
43+ const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
44+ owner,
45+ repo,
46+ username: context.actor,
47+ });
48+ const permission = data.permission;
49+ core.info(`Actor ${context.actor} permission: ${permission}`);
50+ if (!allowed.has(permission)) {
51+ core.setFailed(
52+ `Workflow requires write/maintain/admin access. Actor "${context.actor}" has "${permission}".`,
53+ );
54+ }
55+56+ validate_selected_ref:
57+name: Validate selected ref
58+needs: authorize_actor
59+runs-on: blacksmith-8vcpu-ubuntu-2404
60+outputs:
61+selected_revision: ${{ steps.validate.outputs.selected_revision }}
62+trusted_reason: ${{ steps.validate.outputs.trusted_reason }}
63+steps:
64+ - name: Checkout selected ref
65+uses: actions/checkout@v6
66+with:
67+persist-credentials: false
68+ref: ${{ inputs.ref }}
69+fetch-depth: 0
70+71+ - name: Validate selected ref
72+id: validate
73+env:
74+GH_TOKEN: ${{ github.token }}
75+INPUT_REF: ${{ inputs.ref }}
76+shell: bash
77+run: |
78+ set -euo pipefail
79+ selected_revision="$(git rev-parse HEAD)"
80+ trusted_reason=""
81+82+ git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
83+84+ if git merge-base --is-ancestor "$selected_revision" refs/remotes/origin/main; then
85+ trusted_reason="main-ancestor"
86+ elif git tag --points-at "$selected_revision" | grep -Eq '^v'; then
87+ trusted_reason="release-tag"
88+ elif [[ "$INPUT_REF" =~ ^release/[0-9]{4}\.[0-9]+\.[0-9]+$ ]]; then
89+ git fetch --no-tags origin "+refs/heads/${INPUT_REF}:refs/remotes/origin/${INPUT_REF}"
90+ release_branch_sha="$(git rev-parse "refs/remotes/origin/${INPUT_REF}")"
91+ if [[ "$selected_revision" == "$release_branch_sha" ]]; then
92+ trusted_reason="release-branch-head"
93+ fi
94+ else
95+ pr_head_count="$(
96+ gh api \
97+ -H "Accept: application/vnd.github+json" \
98+ "repos/${GITHUB_REPOSITORY}/commits/${selected_revision}/pulls" \
99+ --jq '[.[] | select(.state == "open" and .head.repo.full_name == "'"${GITHUB_REPOSITORY}"'" and .head.sha == "'"${selected_revision}"'")] | length'
100+ )"
101+ if [[ "$pr_head_count" != "0" ]]; then
102+ trusted_reason="open-pr-head"
103+ fi
104+ fi
105+106+ if [[ -z "$trusted_reason" ]]; then
107+ echo "Ref '${INPUT_REF}' resolved to $selected_revision, which is not trusted for this secret-bearing Mantis run." >&2
108+ echo "Allowed refs must be on main, point to a release tag, match a release branch head, or match an open PR head in ${GITHUB_REPOSITORY}." >&2
109+ exit 1
110+ fi
111+112+ echo "selected_revision=$selected_revision" >> "$GITHUB_OUTPUT"
113+ echo "trusted_reason=$trusted_reason" >> "$GITHUB_OUTPUT"
114+ {
115+ echo "Validated ref: \`${INPUT_REF}\`"
116+ echo "Resolved SHA: \`$selected_revision\`"
117+ echo "Trust reason: \`$trusted_reason\`"
118+ } >> "$GITHUB_STEP_SUMMARY"
119+120+ run_discord_smoke:
121+name: Run Mantis Discord smoke
122+needs: validate_selected_ref
123+runs-on: blacksmith-8vcpu-ubuntu-2404
124+timeout-minutes: 20
125+environment: qa-live-shared
126+steps:
127+ - name: Checkout selected ref
128+uses: actions/checkout@v6
129+with:
130+persist-credentials: false
131+ref: ${{ needs.validate_selected_ref.outputs.selected_revision }}
132+fetch-depth: 1
133+134+ - name: Setup Node environment
135+uses: ./.github/actions/setup-node-env
136+with:
137+node-version: ${{ env.NODE_VERSION }}
138+pnpm-version: ${{ env.PNPM_VERSION }}
139+install-bun: "true"
140+141+ - name: Build private QA runtime
142+run: pnpm build
143+144+ - name: Run Mantis Discord smoke
145+shell: bash
146+env:
147+OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN: ${{ secrets.OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN }}
148+OPENCLAW_QA_DISCORD_GUILD_ID: ${{ secrets.OPENCLAW_QA_DISCORD_GUILD_ID }}
149+OPENCLAW_QA_DISCORD_CHANNEL_ID: ${{ secrets.OPENCLAW_QA_DISCORD_CHANNEL_ID }}
150+OPENCLAW_QA_REDACT_PUBLIC_METADATA: "1"
151+run: |
152+ set -euo pipefail
153+ args=()
154+ if [[ "${{ inputs.post_message }}" != "true" ]]; then
155+ args+=(--skip-post)
156+ fi
157+ pnpm openclaw qa mantis discord-smoke \
158+ --repo-root . \
159+ --output-dir .artifacts/qa-e2e/mantis/discord-smoke \
160+ "${args[@]}"
161+162+ - name: Upload Mantis artifacts
163+if: always()
164+uses: actions/upload-artifact@v4
165+with:
166+name: mantis-discord-smoke-${{ github.run_id }}-${{ github.run_attempt }}
167+path: .artifacts/qa-e2e/mantis/
168+retention-days: 14
169+if-no-files-found: warn
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。