@@ -3,6 +3,8 @@ name: Mantis Telegram Desktop Proof
33on :
44 issue_comment :
55 types : [created]
6+ pull_request_target :
7+ types : [labeled]
68 workflow_dispatch :
79 inputs :
810 pr_number :
2527 description : Optional existing Crabbox desktop lease id or slug to reuse
2628 required : false
2729 type : string
30+ publish_artifact_name :
31+ description : Optional existing proof artifact name to publish without recapturing
32+ required : false
33+ type : string
34+ publish_run_id :
35+ description : Workflow run id that owns publish_artifact_name; required with publish_artifact_name
36+ required : false
37+ type : string
2838
2939permissions :
3040 actions : read
4757 if : >-
4858 ${{
4959 github.event_name == 'workflow_dispatch' ||
60+ (
61+ github.event_name == 'pull_request_target' &&
62+ github.event.action == 'labeled' &&
63+ github.event.label.name == 'mantis: telegram-visible-proof'
64+ ) ||
5065 (
5166 github.event_name == 'issue_comment' &&
5267 github.event.issue.pull_request &&
6681 uses : actions/github-script@v8
6782 with :
6883 script : |
84+ if (context.eventName === "pull_request_target") {
85+ core.info(`Accepted Mantis label trigger from ${context.actor}.`);
86+ core.setOutput("authorized", "true");
87+ return;
88+ }
89+
6990 const allowed = new Set(["admin", "maintain", "write"]);
7091 const { owner, repo } = context.repo;
7192 const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
95116 crabbox_provider : ${{ steps.resolve.outputs.crabbox_provider }}
96117 instructions : ${{ steps.resolve.outputs.instructions }}
97118 lease_id : ${{ steps.resolve.outputs.lease_id }}
119+ publish_artifact_name : ${{ steps.resolve.outputs.publish_artifact_name }}
120+ publish_run_id : ${{ steps.resolve.outputs.publish_run_id }}
98121 pr_number : ${{ steps.resolve.outputs.pr_number }}
99122 request_source : ${{ steps.resolve.outputs.request_source }}
100123 steps :
@@ -112,7 +135,11 @@ jobs:
112135
113136 const inputs = context.payload.inputs ?? {};
114137 const prNumber =
115- eventName === "workflow_dispatch" ? inputs.pr_number : String(context.payload.issue?.number ?? "");
138+ eventName === "workflow_dispatch"
139+ ? inputs.pr_number
140+ : eventName === "pull_request_target"
141+ ? String(context.payload.pull_request?.number ?? "")
142+ : String(context.payload.issue?.number ?? "");
116143 if (!prNumber) {
117144 core.setFailed("Mantis Telegram desktop proof requires a pull request.");
118145 return;
@@ -124,7 +151,12 @@ jobs:
124151 repo,
125152 pull_number: Number(prNumber),
126153 });
127- const body = eventName === "workflow_dispatch" ? inputs.instructions || "" : context.payload.comment?.body || "";
154+ const body =
155+ eventName === "workflow_dispatch"
156+ ? inputs.instructions || ""
157+ : eventName === "issue_comment"
158+ ? context.payload.comment?.body || ""
159+ : "";
128160 const provider = inputs.crabbox_provider || "aws";
129161 if (!["aws", "hetzner"].includes(provider)) {
130162 core.setFailed(`Unsupported Crabbox provider for Mantis Telegram desktop proof: ${provider}`);
@@ -137,6 +169,8 @@ jobs:
137169 setOutput("instructions", body);
138170 setOutput("crabbox_provider", provider);
139171 setOutput("lease_id", inputs.crabbox_lease_id || "");
172+ setOutput("publish_artifact_name", inputs.publish_artifact_name || "");
173+ setOutput("publish_run_id", inputs.publish_run_id || "");
140174 setOutput("request_source", eventName);
141175
142176 if (eventName === "issue_comment") {
@@ -151,6 +185,7 @@ jobs:
151185 validate_refs :
152186 name : Validate selected refs
153187 needs : resolve_request
188+ if : needs.resolve_request.outputs.publish_artifact_name == ''
154189 runs-on : ubuntu-24.04
155190 outputs :
156191 baseline_revision : ${{ steps.validate.outputs.baseline_revision }}
@@ -229,6 +264,7 @@ jobs:
229264 run_telegram_desktop_proof :
230265 name : Run agentic native Telegram proof
231266 needs : [resolve_request, validate_refs]
267+ if : needs.resolve_request.outputs.publish_artifact_name == ''
232268 runs-on : blacksmith-16vcpu-ubuntu-2404
233269 timeout-minutes : 360
234270 environment : qa-live-shared
@@ -473,3 +509,92 @@ jobs:
473509 run : |
474510 echo "Mantis Telegram desktop proof failed: comparison=${COMPARISON_STATUS:-unset}." >&2
475511 exit 1
512+
513+ publish_existing_telegram_desktop_proof :
514+ name : Publish existing native Telegram proof
515+ needs : resolve_request
516+ if : needs.resolve_request.outputs.publish_artifact_name != ''
517+ runs-on : ubuntu-24.04
518+ environment : qa-live-shared
519+ steps :
520+ - name : Checkout harness ref
521+ uses : actions/checkout@v6
522+ with :
523+ persist-credentials : false
524+
525+ - name : Setup Node environment
526+ uses : ./.github/actions/setup-node-env
527+ with :
528+ node-version : ${{ env.NODE_VERSION }}
529+ pnpm-version : ${{ env.PNPM_VERSION }}
530+ install-bun : " true"
531+
532+ - name : Download existing proof artifact
533+ env :
534+ GH_TOKEN : ${{ github.token }}
535+ PUBLISH_ARTIFACT_NAME : ${{ needs.resolve_request.outputs.publish_artifact_name }}
536+ PUBLISH_RUN_ID : ${{ needs.resolve_request.outputs.publish_run_id }}
537+ shell : bash
538+ run : |
539+ set -euo pipefail
540+ if [[ -z "${PUBLISH_RUN_ID:-}" ]]; then
541+ echo "publish_run_id is required when publish_artifact_name is set." >&2
542+ exit 1
543+ fi
544+ run_id="$PUBLISH_RUN_ID"
545+ gh run download "$run_id" \
546+ --repo "$GITHUB_REPOSITORY" \
547+ --name "$PUBLISH_ARTIFACT_NAME" \
548+ --dir "$MANTIS_OUTPUT_DIR"
549+
550+ artifacts_json="$(
551+ gh api \
552+ -H "Accept: application/vnd.github+json" \
553+ "repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}/artifacts"
554+ )"
555+ artifact_id="$(jq -r --arg name "$PUBLISH_ARTIFACT_NAME" '.artifacts[] | select(.name == $name) | .id' <<<"$artifacts_json" | head -n 1)"
556+ if [[ -z "$artifact_id" || "$artifact_id" == "null" ]]; then
557+ echo "Could not resolve artifact id for '${PUBLISH_ARTIFACT_NAME}' in run ${run_id}." >&2
558+ exit 1
559+ fi
560+ echo "PUBLISH_RUN_ID=${run_id}" >> "$GITHUB_ENV"
561+ echo "PUBLISH_ARTIFACT_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}/artifacts/${artifact_id}" >> "$GITHUB_ENV"
562+
563+ - name : Create Mantis GitHub App token
564+ id : mantis_app_token
565+ uses : actions/create-github-app-token@v3
566+ with :
567+ app-id : ${{ secrets.MANTIS_GITHUB_APP_ID }}
568+ private-key : ${{ secrets.MANTIS_GITHUB_APP_PRIVATE_KEY }}
569+ owner : ${{ github.repository_owner }}
570+ repositories : ${{ github.event.repository.name }}
571+ permission-issues : write
572+ permission-pull-requests : write
573+
574+ - name : Comment PR with inline QA evidence
575+ env :
576+ GH_TOKEN : ${{ steps.mantis_app_token.outputs.token }}
577+ MANTIS_ARTIFACT_R2_ACCESS_KEY_ID : ${{ secrets.MANTIS_ARTIFACT_R2_ACCESS_KEY_ID }}
578+ MANTIS_ARTIFACT_R2_BUCKET : openclaw-crabbox-artifacts
579+ MANTIS_ARTIFACT_R2_ENDPOINT : ${{ vars.MANTIS_ARTIFACT_R2_ENDPOINT }}
580+ MANTIS_ARTIFACT_R2_PUBLIC_BASE_URL : https://artifacts.openclaw.ai
581+ MANTIS_ARTIFACT_R2_REGION : auto
582+ MANTIS_ARTIFACT_R2_SECRET_ACCESS_KEY : ${{ secrets.MANTIS_ARTIFACT_R2_SECRET_ACCESS_KEY }}
583+ REQUEST_SOURCE : ${{ needs.resolve_request.outputs.request_source }}
584+ TARGET_PR : ${{ needs.resolve_request.outputs.pr_number }}
585+ shell : bash
586+ run : |
587+ set -euo pipefail
588+ root="$MANTIS_OUTPUT_DIR"
589+ if [[ ! -f "$root/mantis-evidence.json" ]]; then
590+ echo "Downloaded artifact does not contain ${root}/mantis-evidence.json." >&2
591+ exit 1
592+ fi
593+ node scripts/mantis/publish-pr-evidence.mjs \
594+ --manifest "$root/mantis-evidence.json" \
595+ --target-pr "$TARGET_PR" \
596+ --artifact-root "mantis/telegram-desktop/pr-${TARGET_PR}/published-${PUBLISH_RUN_ID}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \
597+ --marker "<!-- mantis-telegram-desktop-proof -->" \
598+ --artifact-url "$PUBLISH_ARTIFACT_URL" \
599+ --run-url "https://github.com/${GITHUB_REPOSITORY}/actions/runs/${PUBLISH_RUN_ID}" \
600+ --request-source "$REQUEST_SOURCE"
0 commit comments