ci(mantis): add telegram proof label trigger

This commit is contained in:
Ayaan Zaidi 2026-05-17 21:15:40 +05:30
parent b764396dee
commit 59efd95669
No known key found for this signature in database
2 changed files with 176 additions and 2 deletions

View file

@ -3,6 +3,8 @@ name: Mantis Telegram Desktop Proof
on:
issue_comment:
types: [created]
pull_request_target:
types: [labeled]
workflow_dispatch:
inputs:
pr_number:
@ -25,6 +27,14 @@ on:
description: Optional existing Crabbox desktop lease id or slug to reuse
required: false
type: string
publish_artifact_name:
description: Optional existing proof artifact name to publish without recapturing
required: false
type: string
publish_run_id:
description: Workflow run id that owns publish_artifact_name; required with publish_artifact_name
required: false
type: string
permissions:
actions: read
@ -47,6 +57,11 @@ jobs:
if: >-
${{
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'pull_request_target' &&
github.event.action == 'labeled' &&
github.event.label.name == 'mantis: telegram-visible-proof'
) ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
@ -66,6 +81,12 @@ jobs:
uses: actions/github-script@v8
with:
script: |
if (context.eventName === "pull_request_target") {
core.info(`Accepted Mantis label trigger from ${context.actor}.`);
core.setOutput("authorized", "true");
return;
}
const allowed = new Set(["admin", "maintain", "write"]);
const { owner, repo } = context.repo;
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
@ -95,6 +116,8 @@ jobs:
crabbox_provider: ${{ steps.resolve.outputs.crabbox_provider }}
instructions: ${{ steps.resolve.outputs.instructions }}
lease_id: ${{ steps.resolve.outputs.lease_id }}
publish_artifact_name: ${{ steps.resolve.outputs.publish_artifact_name }}
publish_run_id: ${{ steps.resolve.outputs.publish_run_id }}
pr_number: ${{ steps.resolve.outputs.pr_number }}
request_source: ${{ steps.resolve.outputs.request_source }}
steps:
@ -112,7 +135,11 @@ jobs:
const inputs = context.payload.inputs ?? {};
const prNumber =
eventName === "workflow_dispatch" ? inputs.pr_number : String(context.payload.issue?.number ?? "");
eventName === "workflow_dispatch"
? inputs.pr_number
: eventName === "pull_request_target"
? String(context.payload.pull_request?.number ?? "")
: String(context.payload.issue?.number ?? "");
if (!prNumber) {
core.setFailed("Mantis Telegram desktop proof requires a pull request.");
return;
@ -124,7 +151,12 @@ jobs:
repo,
pull_number: Number(prNumber),
});
const body = eventName === "workflow_dispatch" ? inputs.instructions || "" : context.payload.comment?.body || "";
const body =
eventName === "workflow_dispatch"
? inputs.instructions || ""
: eventName === "issue_comment"
? context.payload.comment?.body || ""
: "";
const provider = inputs.crabbox_provider || "aws";
if (!["aws", "hetzner"].includes(provider)) {
core.setFailed(`Unsupported Crabbox provider for Mantis Telegram desktop proof: ${provider}`);
@ -137,6 +169,8 @@ jobs:
setOutput("instructions", body);
setOutput("crabbox_provider", provider);
setOutput("lease_id", inputs.crabbox_lease_id || "");
setOutput("publish_artifact_name", inputs.publish_artifact_name || "");
setOutput("publish_run_id", inputs.publish_run_id || "");
setOutput("request_source", eventName);
if (eventName === "issue_comment") {
@ -151,6 +185,7 @@ jobs:
validate_refs:
name: Validate selected refs
needs: resolve_request
if: needs.resolve_request.outputs.publish_artifact_name == ''
runs-on: ubuntu-24.04
outputs:
baseline_revision: ${{ steps.validate.outputs.baseline_revision }}
@ -229,6 +264,7 @@ jobs:
run_telegram_desktop_proof:
name: Run agentic native Telegram proof
needs: [resolve_request, validate_refs]
if: needs.resolve_request.outputs.publish_artifact_name == ''
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 360
environment: qa-live-shared
@ -473,3 +509,92 @@ jobs:
run: |
echo "Mantis Telegram desktop proof failed: comparison=${COMPARISON_STATUS:-unset}." >&2
exit 1
publish_existing_telegram_desktop_proof:
name: Publish existing native Telegram proof
needs: resolve_request
if: needs.resolve_request.outputs.publish_artifact_name != ''
runs-on: ubuntu-24.04
environment: qa-live-shared
steps:
- name: Checkout harness ref
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Setup Node environment
uses: ./.github/actions/setup-node-env
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
install-bun: "true"
- name: Download existing proof artifact
env:
GH_TOKEN: ${{ github.token }}
PUBLISH_ARTIFACT_NAME: ${{ needs.resolve_request.outputs.publish_artifact_name }}
PUBLISH_RUN_ID: ${{ needs.resolve_request.outputs.publish_run_id }}
shell: bash
run: |
set -euo pipefail
if [[ -z "${PUBLISH_RUN_ID:-}" ]]; then
echo "publish_run_id is required when publish_artifact_name is set." >&2
exit 1
fi
run_id="$PUBLISH_RUN_ID"
gh run download "$run_id" \
--repo "$GITHUB_REPOSITORY" \
--name "$PUBLISH_ARTIFACT_NAME" \
--dir "$MANTIS_OUTPUT_DIR"
artifacts_json="$(
gh api \
-H "Accept: application/vnd.github+json" \
"repos/${GITHUB_REPOSITORY}/actions/runs/${run_id}/artifacts"
)"
artifact_id="$(jq -r --arg name "$PUBLISH_ARTIFACT_NAME" '.artifacts[] | select(.name == $name) | .id' <<<"$artifacts_json" | head -n 1)"
if [[ -z "$artifact_id" || "$artifact_id" == "null" ]]; then
echo "Could not resolve artifact id for '${PUBLISH_ARTIFACT_NAME}' in run ${run_id}." >&2
exit 1
fi
echo "PUBLISH_RUN_ID=${run_id}" >> "$GITHUB_ENV"
echo "PUBLISH_ARTIFACT_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}/artifacts/${artifact_id}" >> "$GITHUB_ENV"
- name: Create Mantis GitHub App token
id: mantis_app_token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.MANTIS_GITHUB_APP_ID }}
private-key: ${{ secrets.MANTIS_GITHUB_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: ${{ github.event.repository.name }}
permission-issues: write
permission-pull-requests: write
- name: Comment PR with inline QA evidence
env:
GH_TOKEN: ${{ steps.mantis_app_token.outputs.token }}
MANTIS_ARTIFACT_R2_ACCESS_KEY_ID: ${{ secrets.MANTIS_ARTIFACT_R2_ACCESS_KEY_ID }}
MANTIS_ARTIFACT_R2_BUCKET: openclaw-crabbox-artifacts
MANTIS_ARTIFACT_R2_ENDPOINT: ${{ vars.MANTIS_ARTIFACT_R2_ENDPOINT }}
MANTIS_ARTIFACT_R2_PUBLIC_BASE_URL: https://artifacts.openclaw.ai
MANTIS_ARTIFACT_R2_REGION: auto
MANTIS_ARTIFACT_R2_SECRET_ACCESS_KEY: ${{ secrets.MANTIS_ARTIFACT_R2_SECRET_ACCESS_KEY }}
REQUEST_SOURCE: ${{ needs.resolve_request.outputs.request_source }}
TARGET_PR: ${{ needs.resolve_request.outputs.pr_number }}
shell: bash
run: |
set -euo pipefail
root="$MANTIS_OUTPUT_DIR"
if [[ ! -f "$root/mantis-evidence.json" ]]; then
echo "Downloaded artifact does not contain ${root}/mantis-evidence.json." >&2
exit 1
fi
node scripts/mantis/publish-pr-evidence.mjs \
--manifest "$root/mantis-evidence.json" \
--target-pr "$TARGET_PR" \
--artifact-root "mantis/telegram-desktop/pr-${TARGET_PR}/published-${PUBLISH_RUN_ID}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \
--marker "<!-- mantis-telegram-desktop-proof -->" \
--artifact-url "$PUBLISH_ARTIFACT_URL" \
--run-url "https://github.com/${GITHUB_REPOSITORY}/actions/runs/${PUBLISH_RUN_ID}" \
--request-source "$REQUEST_SOURCE"

View file

@ -14,9 +14,11 @@ type WorkflowStep = {
name?: string;
run?: string;
uses?: string;
with?: Record<string, string>;
};
type WorkflowJob = {
if?: string;
steps?: WorkflowStep[];
};
@ -24,6 +26,20 @@ type Workflow = {
concurrency?: unknown;
env?: Record<string, string>;
jobs?: Record<string, WorkflowJob>;
on?: {
pull_request_target?: {
types?: string[];
};
workflow_dispatch?: {
inputs?: Record<
string,
{
required?: boolean;
type?: string;
}
>;
};
};
permissions?: Record<string, string>;
};
@ -102,6 +118,39 @@ describe("Mantis Telegram Desktop proof workflow", () => {
expect(workflow).not.toContain('"/mantis"');
});
it("runs when ClawSweeper applies the Telegram proof label", () => {
const workflow = parse(readFileSync(WORKFLOW, "utf8")) as Workflow;
const workflowText = readFileSync(WORKFLOW, "utf8");
expect(workflow.on?.pull_request_target?.types).toContain("labeled");
expect(workflowText).toContain("github.event.label.name == 'mantis: telegram-visible-proof'");
expect(workflowText).toContain('eventName === "pull_request_target"');
expect(workflowText).toContain("context.payload.pull_request?.number");
expect(workflowText).toContain("Accepted Mantis label trigger");
});
it("can publish an existing proof artifact without recapturing", () => {
const workflow = parse(readFileSync(WORKFLOW, "utf8")) as Workflow;
const workflowText = readFileSync(WORKFLOW, "utf8");
const publishJob = workflow.jobs?.publish_existing_telegram_desktop_proof;
const captureJob = workflow.jobs?.run_telegram_desktop_proof;
const validateJob = workflow.jobs?.validate_refs;
expect(workflow.on?.workflow_dispatch?.inputs?.publish_artifact_name?.required).toBe(false);
expect(workflow.on?.workflow_dispatch?.inputs?.publish_run_id?.required).toBe(false);
expect(captureJob?.if).toBe("needs.resolve_request.outputs.publish_artifact_name == ''");
expect(validateJob?.if).toBe("needs.resolve_request.outputs.publish_artifact_name == ''");
expect(publishJob?.if).toBe("needs.resolve_request.outputs.publish_artifact_name != ''");
expect(workflowText).toContain("publish_run_id is required when publish_artifact_name is set.");
expect(workflowText).toContain('gh run download "$run_id"');
expect(workflowText).toContain(
'--artifact-root "mantis/telegram-desktop/pr-${TARGET_PR}/published-',
);
expect(workflowText).toContain(
"PUBLISH_ARTIFACT_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/",
);
});
it("uses the repo-owned Telegram user driver by default", () => {
expect(existsSync(USER_DRIVER)).toBe(true);
expect(readFileSync(PROOF_SCRIPT, "utf8")).toContain(