mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-19 16:25:50 +00:00
ci(mantis): add telegram proof label trigger
This commit is contained in:
parent
b764396dee
commit
59efd95669
2 changed files with 176 additions and 2 deletions
129
.github/workflows/mantis-telegram-desktop-proof.yml
vendored
129
.github/workflows/mantis-telegram-desktop-proof.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue