mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-09 16:02:36 +01:00
feat(ci): re-run failed PR jobs once when every failure was a lost runner (#19640)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Contributors wait for PR CI before merge, so CI wall-clock time sets the pace of work > - PR CI runs on self-hosted AWS runners, and these runners are sometimes lost mid-job > - On 2026-11-06, 21 of 51 failed jobs on commits that later passed were runner loss. The losses came in fleet-wide bursts, for example 10 jobs on 10 instances in 51 seconds > - After each loss, a person must notice the failure and click "Re-run failed jobs" > - This pull request adds a workflow that re-runs the failed jobs once, only when every failure was a lost runner > - The benefit is fewer manual re-runs and a shorter wait for CI to pass ## Linked Issues or Issue Description **What existing behavior does this improve?** The recovery of PR CI runs that failed only because a self-hosted runner was lost. **Subsystem affected** CI: the trusted PR workflow (`pr.yml` → `pr-trusted.yml`). **Current behavior** When an AWS runner is lost, the job fails with "The self-hosted runner lost communication with the server" or "The runner has received a shutdown signal". The PR stays red until a person re-runs the failed jobs. **Proposed behavior** When the `PR` workflow completes with a failure on attempt 1, a new workflow examines the failed jobs. If every failed job lost its runner, it re-runs the failed jobs one time. If any job failed for another reason, it does nothing. **Reason and benefit** A runner loss is not a code problem. The re-run starts without waiting for a person to notice the failure. **Breaking changes** None. ## What Changed - Add `.github/workflows/ci-runner-loss-rerun.yml`. It triggers on `workflow_run` for `PR`, and it acts only on attempt 1 failures of `pull_request` runs in this repository. It runs on `ubuntu-latest`, so it does not depend on the AWS fleet. - Add `.github/scripts/runner-loss-rerun.mjs`. The script: - lists the attempt-1 jobs and ignores the aggregate jobs `ci / verify` and `ci / e2e`; - finds runner loss in the check-run annotations. If the only annotation is "The operation was canceled.", it reads the `##[error]` lines in the job log; - calls `rerun-failed-jobs` only if every remaining failed job lost its runner; - does not re-run when the gate job failed, the PR head moved, the PR is closed, or a newer run exists for the same commit; - writes the decision and a job table to the step summary. A `--dry-run` mode never posts. - Add 16 tests, with trimmed fixtures from four real runs. - Add a paragraph about the workflow to the "Trusted PR Workflow" section of `doc/DEVELOPING.md`. ## Verification - `node --test .github/scripts/tests/runner-loss-rerun.test.mjs`: 16/16 pass. The tests cover: - re-run when all jobs were lost, including the case where the signal is only in the log; - no re-run for mixed failures, real failures, only aggregate failures, attempt 2, a failed gate, or a stale run; - pagination, incomplete listings, a cross-host link that is refused, and the workflow guards. - `node --test '.github/scripts/tests/*.test.mjs'`: 760/760 pass. - A read-only dry run against the real GitHub API for six recent runs classified all six correctly. - The workflow can run on GitHub only after it is on master. Reviewers can make sure that the first runner-loss failure after the merge triggers one re-run. ## Risks - **Trust:** a re-run of failed jobs uses the outputs of the gate job that succeeded on attempt 1, including its AWS runner admission. A person who clicks "Re-run failed jobs" gets the same result. The only difference is that `github-actions[bot]` triggers attempt 2. The workflow never checks out or runs PR code. - **Failed gate:** if the gate job itself failed, the script does nothing. A re-run by the bot would put all jobs on GitHub-hosted runners. - **Profiling:** `scripts/ci-profile/export.mjs` exports only attempts triggered by authorized users. The bot-triggered attempt 2 is not exported to Honeycomb. Attempt 1 is still exported. - **Events:** GitHub may not create `workflow_run` events for attempts that `GITHUB_TOKEN` started. Then other `workflow_run` consumers do not react to attempt 2. Required checks still update. - **Permissions:** `actions: write`, `checks: read`, `contents: read` and `pull-requests: read`. The last one lets the script confirm that the run still belongs to the open PR's current head. - **Cancelled jobs:** a runner loss where the lost jobs end as `cancelled` and only the aggregate jobs show `failure` is not re-run. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with tool use and code execution. A Claude sub-agent wrote the change, and the parent session reviewed it. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
913102870d
commit
f2299cb00f
8 files changed
+4651
No files matched your search
@@ -0,0 +1,976 @@
|
||||
{
|
||||
"source": "GET /repos/paperclipai/paperclip/actions/runs/42264785415/attempts/1 (+ jobs and annotations), trimmed",
|
||||
"run": {
|
||||
"id": 42264785415,
|
||||
"name": "PR",
|
||||
"head_branch": "fix/rc16-bootstrap-proof-after-connect",
|
||||
"head_sha": "f418091616c6f7b0af1d4c3115fa47c500015a8a",
|
||||
"path": ".github/workflows/pr.yml",
|
||||
"run_number": 60214,
|
||||
"event": "pull_request",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"workflow_id": 249194268,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415",
|
||||
"created_at": "2026-11-06T17:47:06Z",
|
||||
"run_attempt": 1,
|
||||
"run_started_at": "2026-11-06T17:47:06Z",
|
||||
"actor": {
|
||||
"login": "cryppadotta",
|
||||
"id": 34892728,
|
||||
"type": "User"
|
||||
},
|
||||
"triggering_actor": {
|
||||
"login": "cryppadotta",
|
||||
"id": 34892728,
|
||||
"type": "User"
|
||||
},
|
||||
"repository": {
|
||||
"id": 1170821064,
|
||||
"full_name": "paperclipai/paperclip"
|
||||
},
|
||||
"head_repository": {
|
||||
"id": 1170821064,
|
||||
"full_name": "paperclipai/paperclip"
|
||||
}
|
||||
},
|
||||
"jobs": [
|
||||
{
|
||||
"id": 128053744882,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128053744882",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:47:07Z",
|
||||
"started_at": "2026-11-06T17:47:30Z",
|
||||
"completed_at": "2026-11-06T17:48:06Z",
|
||||
"name": "ci / gate / Select trusted runner",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128053744882",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-ci-routing-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0bd15c639391d3334--e87997a5-9",
|
||||
"runner_group_name": "paperclip-ci-routing"
|
||||
},
|
||||
{
|
||||
"id": 128054259560,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259560",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:32Z",
|
||||
"completed_at": "2026-11-06T17:58:38Z",
|
||||
"name": "ci / Typecheck + Release Registry",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259560",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f9c9e372436e224a--ce576ff8-f",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259668,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259668",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:50:19Z",
|
||||
"name": "ci / policy",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259668",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-02004b0b62771f088--836450ae-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259676,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259676",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:30Z",
|
||||
"completed_at": "2026-11-06T17:53:43Z",
|
||||
"name": "ci / Verify Paperclip Runner (static checks)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259676",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0499d8944ad722cc8--d269ace8-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259678,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259678",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:34Z",
|
||||
"completed_at": "2026-11-06T17:49:18Z",
|
||||
"name": "ci / Docker context integrity",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259678",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f415a1e7415eded5--1ead060a-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259685,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259685",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:57:02Z",
|
||||
"name": "ci / Build",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259685",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-04162f556ced67989--89ceb20a-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259696,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259696",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:32Z",
|
||||
"completed_at": "2026-11-06T17:56:06Z",
|
||||
"name": "ci / Canary Dry Run",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259696",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0e73a58cd878a2eba--ed01493c-d",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259836,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259836",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T18:02:15Z",
|
||||
"name": "ci / Verify Paperclip Runner (vitest package)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259836",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-03b78c874a221b14d--3f9580f1-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259837,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259837",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:34Z",
|
||||
"completed_at": "2026-11-06T17:50:33Z",
|
||||
"name": "ci / Select Vitest files",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259837",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0965b01d7ca22acc7--46a2c286-5",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054259878,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259878",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:34Z",
|
||||
"completed_at": "2026-11-06T17:55:01Z",
|
||||
"name": "ci / Verify Paperclip Runner (vitest native server)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259878",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a3c1c296733234fa--24120234-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260016,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260016",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:55:03Z",
|
||||
"name": "ci / e2e shard (2/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260016",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05170a3c06ca46460--d09cbbe4-4",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260029,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260029",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:56:53Z",
|
||||
"name": "ci / e2e shard (3/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260029",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-03be127710fc5e3f3--1232d471-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260068,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260068",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:34Z",
|
||||
"completed_at": "2026-11-06T17:57:28Z",
|
||||
"name": "ci / e2e shard (4/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260068",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0e30b923f731a8617--7f3f286f-a",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260075,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260075",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:55:25Z",
|
||||
"name": "ci / e2e shard (6/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260075",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0afa242a4729d2f5e--1e1e7e9a-4",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260099,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260099",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:33Z",
|
||||
"completed_at": "2026-11-06T17:54:46Z",
|
||||
"name": "ci / e2e shard (8/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260099",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-08fc2533358d5e023--bc9c002a-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260141,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260141",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:34Z",
|
||||
"completed_at": "2026-11-06T17:53:23Z",
|
||||
"name": "ci / e2e shard (7/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260141",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0e1920f3a20679a6d--4eaf0fed-f",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260232,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260232",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:35Z",
|
||||
"completed_at": "2026-11-06T17:54:31Z",
|
||||
"name": "ci / e2e shard (5/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260232",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-01730060988e5694a--f4f43bb3-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128054260285,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260285",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:48:07Z",
|
||||
"started_at": "2026-11-06T17:48:36Z",
|
||||
"completed_at": "2026-11-06T17:53:55Z",
|
||||
"name": "ci / e2e shard (1/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260285",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0398f5a4a13d3bb86--06283b1d-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055537875,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537875",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:08Z",
|
||||
"completed_at": "2026-11-06T17:54:45Z",
|
||||
"name": "ci / Verify serialized server suites (6/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537875",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-03863cc26751ee81d--ed7003ac-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055537897,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537897",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:09Z",
|
||||
"completed_at": "2026-11-06T17:54:56Z",
|
||||
"name": "ci / Verify serialized server suites (5/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537897",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-07c73636f0cb7025c--f79ac0af-8",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055537952,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537952",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:50:57Z",
|
||||
"completed_at": "2026-11-06T17:54:28Z",
|
||||
"name": "ci / Verify serialized server suites (8/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537952",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-03b2eebb3d82945ba--deae2c56-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055537956,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537956",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:11Z",
|
||||
"completed_at": "2026-11-06T17:54:27Z",
|
||||
"name": "ci / Verify serialized server suites (3/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537956",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0efadc3ad82b120d2--95e7dcf3-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055537962,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537962",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:50:57Z",
|
||||
"completed_at": "2026-11-06T17:57:23Z",
|
||||
"name": "ci / Verify serialized server suites (2/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537962",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-07d521bfd6e73257a--19c15d8d-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538017,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538017",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:54:58Z",
|
||||
"name": "ci / Verify serialized server suites (7/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538017",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-01e662eefaa655648--55d2ece6-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538089,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538089",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:56:27Z",
|
||||
"name": "ci / Verify serialized server suites (1/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538089",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0ad89fde02e893c90--06ed32bb-a",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538125,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538125",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:54:49Z",
|
||||
"name": "ci / Verify serialized server suites (4/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538125",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-064cd806776d929f4--274b294f-f",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538149,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538149",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:09Z",
|
||||
"completed_at": "2026-11-06T18:06:26Z",
|
||||
"name": "ci / General tests (server (2/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538149",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0eea471a99f85b880--00c81037-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538165,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538165",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:08Z",
|
||||
"completed_at": "2026-11-06T17:58:45Z",
|
||||
"name": "ci / General tests (server (1/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538165",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-04800a2d79c810238--b9ce8e93-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538174,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538174",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:08Z",
|
||||
"completed_at": "2026-11-06T17:59:43Z",
|
||||
"name": "ci / General tests (server (6/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538174",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0efaf057cc5a98d48--edea4c47-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538185,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538185",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:57:34Z",
|
||||
"name": "ci / General tests (server (7/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538185",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0205811b68f4b3fd1--52920e1d-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538207,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538207",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:14Z",
|
||||
"completed_at": "2026-11-06T18:00:06Z",
|
||||
"name": "ci / General tests (server (5/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538207",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a37eb2d9fde459d4--36952ebd-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538219,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538219",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:19Z",
|
||||
"completed_at": "2026-11-06T17:59:30Z",
|
||||
"name": "ci / General tests (server (3/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538219",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0188e96e97af2f59c--b8e855e1-4",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538250,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538250",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:13Z",
|
||||
"completed_at": "2026-11-06T18:00:22Z",
|
||||
"name": "ci / General tests (server (9/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538250",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-00c505418cc8ee70e--fb114f23-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538253,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538253",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:12Z",
|
||||
"completed_at": "2026-11-06T17:56:10Z",
|
||||
"name": "ci / General tests (workspaces-b)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538253",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05fc778dbd976d597--c58725c9-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538265,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538265",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:54:31Z",
|
||||
"name": "ci / Verify serialized server suites (9/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538265",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06a3bf8d19333dd51--c4258f53-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538302,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538302",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:33Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:58:51Z",
|
||||
"name": "ci / General tests (server (12/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538302",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-07605db9087df8358--8137b272-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538306,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538306",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:13Z",
|
||||
"completed_at": "2026-11-06T17:59:36Z",
|
||||
"name": "ci / General tests (server (11/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538306",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0d357b1cfb24c69f8--9cc138ac-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538334,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538334",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:14Z",
|
||||
"completed_at": "2026-11-06T17:57:39Z",
|
||||
"name": "ci / General tests (server (8/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538334",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06bee8abdadd855f6--4777aea8-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538337,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538337",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:17Z",
|
||||
"completed_at": "2026-11-06T17:57:43Z",
|
||||
"name": "ci / General tests (server (4/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538337",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-00861ea950b0c2df8--e7934d4c-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538364,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538364",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:16Z",
|
||||
"completed_at": "2026-11-06T17:56:44Z",
|
||||
"name": "ci / General tests (chat (2/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538364",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-04505acda283d309b--e4997141-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538368,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538368",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:23Z",
|
||||
"completed_at": "2026-11-06T17:57:14Z",
|
||||
"name": "ci / General tests (workspaces-a (1/2))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538368",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-01559d90b1c03dafc--39658d89-4",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538374,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538374",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:20Z",
|
||||
"completed_at": "2026-11-06T17:57:56Z",
|
||||
"name": "ci / General tests (server (10/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538374",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05115335e959346eb--0b11d7ba-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538399,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538399",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:16Z",
|
||||
"completed_at": "2026-11-06T17:57:35Z",
|
||||
"name": "ci / General tests (chat (1/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538399",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-020c27d3a16ef9c2b--ea30bd71-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538415,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538415",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:18Z",
|
||||
"completed_at": "2026-11-06T17:55:40Z",
|
||||
"name": "ci / General tests (workspaces-a (2/2))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538415",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0c674a4b6f26936cf--ec849767-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128055538546,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538546",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:50:34Z",
|
||||
"started_at": "2026-11-06T17:51:19Z",
|
||||
"completed_at": "2026-11-06T17:59:30Z",
|
||||
"name": "ci / General tests (chat (3/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538546",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05c610ca30a34300b--725c544b-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128059102519,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128059102519",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T17:57:28Z",
|
||||
"started_at": "2026-11-06T17:58:02Z",
|
||||
"completed_at": "2026-11-06T17:58:07Z",
|
||||
"name": "ci / e2e",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128059102519",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-02635cc9003444823--4f0acae5-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128063690619,
|
||||
"run_id": 42264785415,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128063690619",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"created_at": "2026-11-06T18:06:26Z",
|
||||
"started_at": "2026-11-06T18:07:00Z",
|
||||
"completed_at": "2026-11-06T18:07:08Z",
|
||||
"name": "ci / verify",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128063690619",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-007fb864dc5bb537d--f46a91cb-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"128055538337": [
|
||||
{
|
||||
"path": ".github",
|
||||
"start_line": 285371,
|
||||
"end_line": 285371,
|
||||
"annotation_level": "failure",
|
||||
"title": "",
|
||||
"message": "Process completed with exit code 1.",
|
||||
"raw_details": ""
|
||||
},
|
||||
{
|
||||
"path": "server/src/__tests__/connection-management.integration.test.ts",
|
||||
"start_line": 1806,
|
||||
"end_line": 1806,
|
||||
"annotation_level": "failure",
|
||||
"title": "[@paperclipai/server] src/__tests__/connection-management.integration.test.ts > connection management with production default agents > reads only the authorized Anthropic account identity through actual agent authentication",
|
||||
"message": "AssertionError: expected 3 to be 2 // Object.is equality\n\n- Expected\n+ Received\n\n- 2\n+ 3\n\n ❯ src/__tests__/connection-management.integration.test.ts:1806:21\n\n",
|
||||
"raw_details": ""
|
||||
},
|
||||
{
|
||||
"path": ".github",
|
||||
"start_line": 162423,
|
||||
"end_line": 162423,
|
||||
"annotation_level": "failure",
|
||||
"title": "",
|
||||
"message": "command (/home/runner/_work/paperclip/paperclip/) /home/runner/setup-pnpm/node_modules/.bin/bin/pnpm run test:run:general -- --group general-server-without-chat --shard-index 3 --shard-count 12 exited (1)",
|
||||
"raw_details": ""
|
||||
}
|
||||
],
|
||||
"128063690619": [
|
||||
{
|
||||
"path": ".github",
|
||||
"start_line": 120,
|
||||
"end_line": 120,
|
||||
"annotation_level": "failure",
|
||||
"title": "",
|
||||
"message": "Process completed with exit code 1.",
|
||||
"raw_details": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"logs": {},
|
||||
"total_count": 47
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,979 @@
|
||||
{
|
||||
"source": "GET /repos/paperclipai/paperclip/actions/runs/42277969418/attempts/1 (+ jobs and annotations), trimmed",
|
||||
"run": {
|
||||
"id": 42277969418,
|
||||
"name": "PR",
|
||||
"head_branch": "fix/status-card-compile-inline-guidance",
|
||||
"head_sha": "85a1ebd70ebb687bac36cd7d3aa035f08b1b76fe",
|
||||
"path": ".github/workflows/pr.yml",
|
||||
"run_number": 60340,
|
||||
"event": "pull_request",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"workflow_id": 249194268,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418",
|
||||
"created_at": "2026-11-06T19:15:10Z",
|
||||
"run_attempt": 1,
|
||||
"run_started_at": "2026-11-06T19:15:10Z",
|
||||
"actor": {
|
||||
"login": "cryppadotta",
|
||||
"id": 34892728,
|
||||
"type": "User"
|
||||
},
|
||||
"triggering_actor": {
|
||||
"login": "cryppadotta",
|
||||
"id": 34892728,
|
||||
"type": "User"
|
||||
},
|
||||
"repository": {
|
||||
"id": 1170821064,
|
||||
"full_name": "paperclipai/paperclip"
|
||||
},
|
||||
"head_repository": {
|
||||
"id": 1170821064,
|
||||
"full_name": "paperclipai/paperclip"
|
||||
}
|
||||
},
|
||||
"jobs": [
|
||||
{
|
||||
"id": 128099176127,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099176127",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:11Z",
|
||||
"started_at": "2026-11-06T19:15:35Z",
|
||||
"completed_at": "2026-11-06T19:15:51Z",
|
||||
"name": "ci / gate / Select trusted runner",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099176127",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-ci-routing-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05f6b9b2930a13c18--04e93093-7",
|
||||
"runner_group_name": "paperclip-ci-routing"
|
||||
},
|
||||
{
|
||||
"id": 128099518899,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518899",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:18:48Z",
|
||||
"name": "ci / Select Vitest files",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518899",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-022ce6a3fe4cb976a--9b74ec42-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099518966,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518966",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:13Z",
|
||||
"completed_at": "2026-11-06T19:17:52Z",
|
||||
"name": "ci / policy",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518966",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06dd55e2393795fc3--8bdf1065-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099518969,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518969",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:30:17Z",
|
||||
"name": "ci / Verify Paperclip Runner (vitest package)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518969",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-09eb0ccea8ce6e3f1--bf3c948a-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099518970,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518970",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:26:13Z",
|
||||
"name": "ci / Typecheck + Release Registry",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518970",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06107c2f4ad4e0afa--e8a52bad-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519017,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519017",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:21:53Z",
|
||||
"name": "ci / Verify Paperclip Runner (static checks)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519017",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0ce2155a81766d11b--1c931e39-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519063,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519063",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:16Z",
|
||||
"completed_at": "2026-11-06T19:17:03Z",
|
||||
"name": "ci / Docker context integrity",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519063",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0e251a79a0c87658b--54fd3399-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519192,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519192",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:24:53Z",
|
||||
"name": "ci / Build",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519192",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-005e12d124d262094--566fec4c-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519255,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519255",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:23:21Z",
|
||||
"name": "ci / e2e shard (2/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519255",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0c236e72756ee5767--da386f7f-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519269,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519269",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:15Z",
|
||||
"completed_at": "2026-11-06T19:26:36Z",
|
||||
"name": "ci / e2e shard (6/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519269",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0460327d9a9ad85b9--4e8bc75b-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519294,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519294",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:22Z",
|
||||
"completed_at": "2026-11-06T19:25:00Z",
|
||||
"name": "ci / e2e shard (3/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519294",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0ff835844ee842210--66852b42-8",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519310,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519310",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:14Z",
|
||||
"completed_at": "2026-11-06T19:22:48Z",
|
||||
"name": "ci / e2e shard (4/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519310",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0b5b047d9eb22c701--5e90d2e6-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519324,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519324",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:18Z",
|
||||
"completed_at": "2026-11-06T19:22:50Z",
|
||||
"name": "ci / Verify Paperclip Runner (vitest native server)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519324",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f33e5da352722dec--88ad2175-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519328,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519328",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:15Z",
|
||||
"completed_at": "2026-11-06T19:23:26Z",
|
||||
"name": "ci / e2e shard (5/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519328",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0b4a144abcf5b5ad0--13d99f06-4",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519373,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519373",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:19Z",
|
||||
"completed_at": "2026-11-06T19:23:19Z",
|
||||
"name": "ci / Canary Dry Run",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519373",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-026bbfb8e1f2b02f6--fcd31fd2-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519399,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519399",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:17Z",
|
||||
"completed_at": "2026-11-06T19:22:50Z",
|
||||
"name": "ci / e2e shard (8/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519399",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06fecb3fefefd2b1e--48a7f824-3",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519420,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519420",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:19Z",
|
||||
"completed_at": "2026-11-06T19:22:36Z",
|
||||
"name": "ci / e2e shard (1/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519420",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0b1eec8b49f261f40--0ee7ea96-8",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099519640,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519640",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:16:19Z",
|
||||
"completed_at": "2026-11-06T19:22:41Z",
|
||||
"name": "ci / e2e shard (7/8)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519640",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0c06a9265636bb3c1--29213d2a-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128099521660,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099521660",
|
||||
"status": "completed",
|
||||
"conclusion": "skipped",
|
||||
"created_at": "2026-11-06T19:15:51Z",
|
||||
"started_at": "2026-11-06T19:15:51Z",
|
||||
"completed_at": "2026-11-06T19:15:51Z",
|
||||
"name": "ci / Sandbox provider tests",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099521660",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": null,
|
||||
"runner_group_name": null
|
||||
},
|
||||
{
|
||||
"id": 128101015827,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015827",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:36Z",
|
||||
"completed_at": "2026-11-06T19:23:28Z",
|
||||
"name": "ci / Verify serialized server suites (3/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015827",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f29d5a87a13a3137--0ae30aa5-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015873,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015873",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:37Z",
|
||||
"completed_at": "2026-11-06T19:25:47Z",
|
||||
"name": "ci / Verify serialized server suites (1/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015873",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a92a42f0bc1f9c02--30c81b0a-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015886,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015886",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:57Z",
|
||||
"completed_at": "2026-11-06T19:24:10Z",
|
||||
"name": "ci / Verify serialized server suites (4/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015886",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-050c1bc7159c094e4--1d0ecbb0-5",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015895,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015895",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:24:10Z",
|
||||
"name": "ci / Verify serialized server suites (6/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015895",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0473b976117b1a23d--148e3608-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015916,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015916",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:43Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / Verify serialized server suites (2/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015916",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-06aa99d6dfd3eefa2--6d5659d3-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015954,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015954",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:41Z",
|
||||
"completed_at": "2026-11-06T19:24:11Z",
|
||||
"name": "ci / Verify serialized server suites (8/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015954",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-02e59035275e65dc1--f14d4574-a",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101015978,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015978",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:43Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / Verify serialized server suites (5/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015978",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0fc8f7dbd4ebf8e25--306b0039-6",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016102,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016102",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:43Z",
|
||||
"completed_at": "2026-11-06T19:24:31Z",
|
||||
"name": "ci / Verify serialized server suites (7/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016102",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f30ba7b9604359f6--7247346a-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016153,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016153",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:41Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / General tests (server (1/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016153",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a9149d343f722f73--6c14189b-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016167,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016167",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:36Z",
|
||||
"completed_at": "2026-11-06T19:27:21Z",
|
||||
"name": "ci / General tests (server (5/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016167",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0c26f035abc2181de--db86c3ca-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016193,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016193",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:37Z",
|
||||
"completed_at": "2026-11-06T19:27:48Z",
|
||||
"name": "ci / General tests (chat (1/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016193",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-09edcc5cc037cb21b--a7821027-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016200,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016200",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:37Z",
|
||||
"completed_at": "2026-11-06T19:24:42Z",
|
||||
"name": "ci / General tests (server (8/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016200",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0d85343085d2a7e66--3919a1b5-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016203,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016203",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:41Z",
|
||||
"completed_at": "2026-11-06T19:24:01Z",
|
||||
"name": "ci / Verify serialized server suites (9/9)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016203",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f2a0ad6f8136ed03--3f5b22b1-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016204,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016204",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:38Z",
|
||||
"completed_at": "2026-11-06T19:25:44Z",
|
||||
"name": "ci / General tests (workspaces-b)",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016204",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-022720c628aea9909--3489c3bc-e",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016209,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016209",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:37Z",
|
||||
"completed_at": "2026-11-06T19:27:03Z",
|
||||
"name": "ci / General tests (server (3/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016209",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05cd168e2c805dfa1--2db2f96e-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016247,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016247",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:37Z",
|
||||
"completed_at": "2026-11-06T19:24:39Z",
|
||||
"name": "ci / General tests (workspaces-a (2/2))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016247",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a76b068c81f7024a--8a17bf0c-7",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016250,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016250",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:26:41Z",
|
||||
"name": "ci / General tests (server (12/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016250",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05867958d44053ee3--8a8e3069-9",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016265,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016265",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:26:58Z",
|
||||
"name": "ci / General tests (server (4/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016265",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0bf649f272db17bac--41ee1099-5",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016277,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016277",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:34:40Z",
|
||||
"name": "ci / General tests (server (2/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016277",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-057aa4559787e702b--99da1fc5-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016291,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016291",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:27:31Z",
|
||||
"name": "ci / General tests (server (6/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016291",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0204b721d120e8305--4a8cbdcf-5",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016304,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016304",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:42Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / General tests (workspaces-a (1/2))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016304",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-083ececdc0bee80c6--049cc912-b",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016340,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016340",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:41Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / General tests (server (7/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016340",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0a46ba5536afd6715--10ddddf7-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016380,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016380",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:27:21Z",
|
||||
"name": "ci / General tests (server (11/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016380",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0f1df9c61064c6c00--bfe5ea08-c",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016402,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016402",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:43Z",
|
||||
"completed_at": "2026-11-06T19:24:42Z",
|
||||
"name": "ci / General tests (server (9/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016402",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0cd6219458ec3772c--7a914eac-5",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016432,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016432",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:39Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / General tests (chat (3/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016432",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0fdc6b32e8998c1ba--0724a4a5-2",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016453,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016453",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:44Z",
|
||||
"completed_at": "2026-11-06T19:24:43Z",
|
||||
"name": "ci / General tests (server (10/12))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016453",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05195ce82810fc9ab--39894cef-6",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128101016461,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016461",
|
||||
"status": "completed",
|
||||
"conclusion": "cancelled",
|
||||
"created_at": "2026-11-06T19:18:48Z",
|
||||
"started_at": "2026-11-06T19:19:43Z",
|
||||
"completed_at": "2026-11-06T19:24:42Z",
|
||||
"name": "ci / General tests (chat (2/3))",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016461",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-0722bda62fe122e78--24305ada-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128104989524,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128104989524",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"created_at": "2026-11-06T19:26:36Z",
|
||||
"started_at": "2026-11-06T19:27:42Z",
|
||||
"completed_at": "2026-11-06T19:27:47Z",
|
||||
"name": "ci / e2e",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128104989524",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-03d74c0aaf2a6f9a8--5077b150-0",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
},
|
||||
{
|
||||
"id": 128109082787,
|
||||
"run_id": 42277969418,
|
||||
"workflow_name": "PR",
|
||||
"run_attempt": 1,
|
||||
"html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128109082787",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"created_at": "2026-11-06T19:34:41Z",
|
||||
"started_at": "2026-11-06T19:35:37Z",
|
||||
"completed_at": "2026-11-06T19:35:43Z",
|
||||
"name": "ci / verify",
|
||||
"check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128109082787",
|
||||
"labels": [
|
||||
"runs-on/fleet=paperclip-public-pr-x64/env=public-ci"
|
||||
],
|
||||
"runner_name": "runs-on--i-05ba3f428ff571fab--c14c92a3-1",
|
||||
"runner_group_name": "paperclip-public-pr"
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"128101016102": [
|
||||
{
|
||||
"path": ".github",
|
||||
"start_line": 2,
|
||||
"end_line": 2,
|
||||
"annotation_level": "failure",
|
||||
"title": "",
|
||||
"message": "The operation was canceled.",
|
||||
"raw_details": ""
|
||||
}
|
||||
],
|
||||
"128109082787": [
|
||||
{
|
||||
"path": ".github",
|
||||
"start_line": 124,
|
||||
"end_line": 124,
|
||||
"annotation_level": "failure",
|
||||
"title": "",
|
||||
"message": "Process completed with exit code 1.",
|
||||
"raw_details": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"128101016102": "2026-11-06T19:24:29.1450769Z ##[error]The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.\n2026-11-06T19:24:29.1898916Z ##[error]The operation was canceled.\n2026-11-06T19:24:29.1977091Z Cleaning up orphan processes\n"
|
||||
},
|
||||
"total_count": 48
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import test from "node:test";
|
||||
import {
|
||||
classifyJob, createGithubClient, decide, logShowsRunnerLoss, main, renderSummary,
|
||||
} from "../runner-loss-rerun.mjs";
|
||||
|
||||
// Trimmed attempt-1 snapshots of real PR runs: jobs, check-run annotations for
|
||||
// each failed job, and the error lines of job logs whose only annotation is
|
||||
// "The operation was canceled.".
|
||||
const fixture = (runId) => JSON.parse(readFileSync(
|
||||
new URL(`./fixtures/runner-loss-rerun/run-${runId}.json`, import.meta.url), "utf8",
|
||||
));
|
||||
const MIXED = 42271918832; // six lost runners, one shutdown in the log, one real test timeout
|
||||
const REAL = 42264785415; // a real assertion failure
|
||||
const ALL_LOST = 42272083862; // one lost runner
|
||||
const LOG_ONLY = 42277969418; // shutdown signal visible only in the job log
|
||||
const workflow = readFileSync(new URL("../../workflows/ci-runner-loss-rerun.yml", import.meta.url), "utf8");
|
||||
|
||||
const json = (body, headers = {}) => new Response(JSON.stringify(body), {
|
||||
status: 200, headers: { "content-type": "application/json", ...headers },
|
||||
});
|
||||
|
||||
/**
|
||||
* Serves a fixture as the GitHub REST API. By default the run is the latest
|
||||
* CI for an open PR's current head.
|
||||
*/
|
||||
function fakeGithub(data, {
|
||||
jobsPageSize = 100, pulls, prRuns, mutateRun = (run) => run,
|
||||
} = {}) {
|
||||
const calls = [];
|
||||
const run = mutateRun(structuredClone(data.run));
|
||||
const openPr = {
|
||||
number: 1, state: "open",
|
||||
base: { repo: { id: data.run.repository.id } },
|
||||
head: { sha: data.run.head_sha, repo: { id: data.run.head_repository.id } },
|
||||
};
|
||||
const fetcher = async (href, init) => {
|
||||
const url = new URL(href);
|
||||
calls.push({ method: init.method, path: url.pathname, query: url.search, auth: init.headers.Authorization });
|
||||
const base = `/repos/paperclipai/paperclip`;
|
||||
const route = url.pathname.slice(base.length);
|
||||
if (init.method === "POST" && route === `/actions/runs/${run.id}/rerun-failed-jobs`) {
|
||||
return new Response(null, { status: 201 });
|
||||
}
|
||||
if (route === `/actions/runs/${run.id}`) return json(run);
|
||||
if (route === `/actions/runs/${run.id}/attempts/1/jobs`) {
|
||||
const page = Number(url.searchParams.get("page") ?? 1);
|
||||
const jobs = data.jobs.slice((page - 1) * jobsPageSize, page * jobsPageSize);
|
||||
const last = page * jobsPageSize >= data.jobs.length;
|
||||
const next = new URL(url);
|
||||
next.searchParams.set("page", String(page + 1));
|
||||
return json({ total_count: data.total_count, jobs }, last ? {} : { link: `<${next.href}>; rel="next"` });
|
||||
}
|
||||
let match = route.match(/^\/check-runs\/(\d+)\/annotations$/);
|
||||
if (match) return json(data.annotations[match[1]] ?? []);
|
||||
match = route.match(/^\/actions\/jobs\/(\d+)\/logs$/);
|
||||
if (match) return new Response(data.logs[match[1]] ?? "", { status: 200 });
|
||||
if (route === `/commits/${run.head_sha}/pulls`) return json(pulls ?? [openPr]);
|
||||
if (route === "/actions/workflows/pr.yml/runs") {
|
||||
const runs = prRuns ?? [{ id: run.id, conclusion: "failure" }];
|
||||
return json({ total_count: runs.length, workflow_runs: runs });
|
||||
}
|
||||
return new Response("not found", { status: 404 });
|
||||
};
|
||||
return { calls, fetcher, run, client: createGithubClient({ token: "test-token", fetcher }) };
|
||||
}
|
||||
|
||||
const posted = (calls) => calls.filter((call) => call.method === "POST");
|
||||
|
||||
async function runMain(data, options = {}, eventRun = {}) {
|
||||
const github = fakeGithub(data, options);
|
||||
const directory = mkdtempSync(path.join(tmpdir(), "runner-loss-rerun-"));
|
||||
try {
|
||||
const eventPath = path.join(directory, "event.json");
|
||||
const summaryPath = path.join(directory, "summary.md");
|
||||
writeFileSync(eventPath, JSON.stringify({ workflow_run: { id: data.run.id, run_attempt: 1, ...eventRun } }));
|
||||
writeFileSync(summaryPath, "");
|
||||
const decision = await main({
|
||||
env: { GITHUB_TOKEN: "test-token", GITHUB_EVENT_PATH: eventPath, GITHUB_STEP_SUMMARY: summaryPath },
|
||||
argv: [], fetcher: github.fetcher, log: () => {},
|
||||
});
|
||||
return { decision, calls: github.calls, summary: readFileSync(summaryPath, "utf8") };
|
||||
} finally {
|
||||
rmSync(directory, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
test("all failed jobs lost their runner: re-runs failed jobs once", async () => {
|
||||
const { decision, calls, summary } = await runMain(fixture(ALL_LOST));
|
||||
assert.equal(decision.rerun, true);
|
||||
assert.deepEqual(decision.jobs.map((job) => [job.name, job.lost]), [["ci / General tests (server (3/12))", true]]);
|
||||
assert.deepEqual(posted(calls).map((call) => call.path),
|
||||
[`/repos/paperclipai/paperclip/actions/runs/${ALL_LOST}/rerun-failed-jobs`]);
|
||||
assert.ok(calls.every((call) => call.auth === "Bearer test-token"));
|
||||
// `ci / verify` failed too, but only because its dependency failed.
|
||||
assert.equal(calls.some((call) => call.path.endsWith("/check-runs/128088995071/annotations")), false);
|
||||
assert.match(summary, /\*\*Re-ran failed jobs\*\*/);
|
||||
assert.match(summary, /\| ci \/ General tests \(server \(3\/12\)\) \| yes \| The self-hosted runner lost communication/);
|
||||
});
|
||||
|
||||
test("a shutdown signal found only in the job log counts as runner loss", async () => {
|
||||
const data = fixture(LOG_ONLY);
|
||||
assert.deepEqual(data.annotations["128101016102"].map((annotation) => annotation.message), ["The operation was canceled."]);
|
||||
const { decision, calls } = await runMain(data);
|
||||
assert.equal(decision.rerun, true);
|
||||
assert.match(decision.jobs[0].evidence, /job log/);
|
||||
assert.ok(calls.some((call) => call.path.endsWith("/actions/jobs/128101016102/logs")));
|
||||
assert.equal(posted(calls).length, 1);
|
||||
});
|
||||
|
||||
test("mixed runner loss and a real test failure: no re-run", async () => {
|
||||
const { decision, calls, summary } = await runMain(fixture(MIXED));
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.equal(decision.jobs.length, 8);
|
||||
assert.deepEqual(decision.jobs.filter((job) => !job.lost).map((job) => job.name), ["ci / General tests (workspaces-a (1/2))"]);
|
||||
assert.equal(decision.jobs.find((job) => job.name === "ci / Verify Paperclip Runner (vitest package)").lost, true);
|
||||
assert.equal(posted(calls).length, 0);
|
||||
assert.match(decision.reason, /1 of 8 failed jobs did not lose their runner/);
|
||||
assert.match(summary, /\*\*No automatic re-run\*\*/);
|
||||
});
|
||||
|
||||
test("real test failures: no re-run", async () => {
|
||||
const { decision, calls } = await runMain(fixture(REAL));
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.deepEqual(decision.jobs.map((job) => [job.name, job.lost]), [["ci / General tests (server (4/12))", false]]);
|
||||
assert.equal(posted(calls).length, 0);
|
||||
});
|
||||
|
||||
test("only the verify and e2e aggregates failed: no re-run", async () => {
|
||||
const data = fixture(ALL_LOST);
|
||||
data.jobs = data.jobs.map((job) => job.name.startsWith("ci / General tests") ? { ...job, conclusion: "success" } : job);
|
||||
const { decision, calls } = await runMain(data);
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.match(decision.reason, /no failed jobs other than the verify\/e2e aggregates/);
|
||||
assert.equal(calls.some((call) => call.path.includes("/check-runs/")), false);
|
||||
assert.equal(posted(calls).length, 0);
|
||||
});
|
||||
|
||||
test("attempt 2 or later is never re-run automatically", async () => {
|
||||
// The event was for attempt 1, but someone re-ran the run before this job started.
|
||||
const { decision, calls } = await runMain(fixture(ALL_LOST), { mutateRun: (run) => ({ ...run, run_attempt: 2 }) });
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.match(decision.reason, /attempt 2/);
|
||||
assert.deepEqual(calls.map((call) => call.path), [`/repos/paperclipai/paperclip/actions/runs/${ALL_LOST}`]);
|
||||
});
|
||||
|
||||
test("a failed routing gate is left for a human re-run", async () => {
|
||||
const data = fixture(ALL_LOST);
|
||||
const gate = data.jobs.find((job) => job.name === "ci / gate / Select trusted runner");
|
||||
gate.conclusion = "failure";
|
||||
data.annotations[gate.id] = [{ annotation_level: "failure", message: "The self-hosted runner lost communication with the server." }];
|
||||
const { decision, calls } = await runMain(data);
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.match(decision.jobs.find((job) => job.id === gate.id).evidence, /routing gate/);
|
||||
assert.equal(posted(calls).length, 0);
|
||||
});
|
||||
|
||||
test("runs that are no longer the PR's latest CI are not re-run", async () => {
|
||||
const data = fixture(ALL_LOST);
|
||||
const moved = await decide(fakeGithub(data, {
|
||||
pulls: [{ state: "open", base: { repo: { id: 1170821064 } }, head: { sha: "0".repeat(40), repo: { id: 1170821064 } } }],
|
||||
}).client, data.run);
|
||||
assert.equal(moved.rerun, false);
|
||||
assert.match(moved.reason, /no open pull request/);
|
||||
|
||||
const merged = await decide(fakeGithub(data, {
|
||||
pulls: [{ state: "closed", base: { repo: { id: 1170821064 } }, head: { sha: data.run.head_sha, repo: { id: 1170821064 } } }],
|
||||
}).client, data.run);
|
||||
assert.equal(merged.rerun, false);
|
||||
|
||||
// A later full-ci label run on the same head shares the PR concurrency group;
|
||||
// re-running the older run would cancel it.
|
||||
const newer = await decide(fakeGithub(data, {
|
||||
prRuns: [{ id: data.run.id + 1, conclusion: null }, { id: data.run.id, conclusion: "failure" }],
|
||||
}).client, data.run);
|
||||
assert.equal(newer.rerun, false);
|
||||
assert.match(newer.reason, /newer PR run/);
|
||||
|
||||
// A later label event that did not request CI skips its only job; it is not CI.
|
||||
const skipped = await decide(fakeGithub(data, {
|
||||
prRuns: [{ id: data.run.id + 1, conclusion: "skipped" }, { id: data.run.id, conclusion: "failure" }],
|
||||
}).client, data.run);
|
||||
assert.equal(skipped.rerun, true);
|
||||
});
|
||||
|
||||
test("ineligible runs are rejected before any job is read", async () => {
|
||||
const data = fixture(ALL_LOST);
|
||||
for (const [change, reason] of [
|
||||
[{ event: "push" }, /event is push/],
|
||||
[{ path: ".github/workflows/other.yml" }, /workflow is/],
|
||||
[{ conclusion: "success" }, /completed\/success/],
|
||||
[{ repository: { id: 1, full_name: "someone/paperclip" } }, /canonical repository/],
|
||||
]) {
|
||||
const github = fakeGithub(data);
|
||||
const decision = await decide(github.client, { ...data.run, ...change });
|
||||
assert.equal(decision.rerun, false);
|
||||
assert.match(decision.reason, reason);
|
||||
assert.equal(github.calls.length, 0);
|
||||
}
|
||||
});
|
||||
|
||||
test("job listing follows Link pagination across pages", async () => {
|
||||
const data = fixture(MIXED);
|
||||
const github = fakeGithub(data, { jobsPageSize: 20 });
|
||||
const decision = await decide(github.client, data.run);
|
||||
const pages = github.calls.filter((call) => call.path.endsWith("/attempts/1/jobs"));
|
||||
assert.deepEqual(pages.map((call) => new URLSearchParams(call.query).get("page")), [null, "2", "3"]);
|
||||
// Failed jobs on pages 2 and 3 are all classified.
|
||||
assert.equal(decision.jobs.length, 8);
|
||||
assert.equal(decision.rerun, false);
|
||||
});
|
||||
|
||||
test("an incomplete job listing fails instead of deciding on partial data", async () => {
|
||||
const data = fixture(ALL_LOST);
|
||||
data.total_count += 1;
|
||||
const github = fakeGithub(data);
|
||||
await assert.rejects(decide(github.client, data.run), /Incomplete listing/);
|
||||
assert.equal(posted(github.calls).length, 0);
|
||||
});
|
||||
|
||||
test("the client refuses to follow pagination to another host", async () => {
|
||||
const client = createGithubClient({
|
||||
token: "test-token",
|
||||
fetcher: async () => json([], { link: '<https://example.com/steal?page=2>; rel="next"' }),
|
||||
});
|
||||
await assert.rejects(client.paginate("/repos/paperclipai/paperclip/commits/x/pulls"), /Refusing to call https:\/\/example.com/);
|
||||
});
|
||||
|
||||
test("classification is conservative about cancelled jobs", async () => {
|
||||
const cancelled = [{ annotation_level: "failure", message: "The operation was canceled." }];
|
||||
const noSignal = await classifyJob({ id: 1 }, { annotations: cancelled, readLog: async () => "##[error]The operation was canceled.\n" });
|
||||
assert.equal(noSignal.lost, false);
|
||||
// A job timeout also cancels the step, but adds its own failure annotation.
|
||||
const timedOut = await classifyJob({ id: 1 }, {
|
||||
annotations: [{ annotation_level: "failure", message: "The job has exceeded the maximum execution time of 30m0s" }, ...cancelled],
|
||||
readLog: async () => { throw new Error("log must not be read"); },
|
||||
});
|
||||
assert.equal(timedOut.lost, false);
|
||||
// Notices and warnings are not failure evidence.
|
||||
const warning = await classifyJob({ id: 1 }, {
|
||||
annotations: [{ annotation_level: "warning", message: "The self-hosted runner lost communication with the server." }],
|
||||
readLog: async () => "",
|
||||
});
|
||||
assert.equal(warning.lost, false);
|
||||
// Test output that merely prints the phrase is not a runner error line.
|
||||
assert.equal(logShowsRunnerLoss("2026-11-06T00:00:00Z expected 'received a shutdown signal'\n"), false);
|
||||
assert.equal(logShowsRunnerLoss(fixture(MIXED).logs["128078674151"]), true);
|
||||
});
|
||||
|
||||
test("a real failure before the runner was lost is not counted as runner loss", async () => {
|
||||
const lostMessage = "The self-hosted runner lost communication with the server. Verify the machine is running.";
|
||||
const noLog = async () => { throw new Error("log must not be read"); };
|
||||
// A test fails, then the runner is lost during an always() upload step.
|
||||
const testThenLost = await classifyJob({ id: 1 }, {
|
||||
annotations: [
|
||||
{ annotation_level: "failure", message: "Error: Test timed out in 15000ms." },
|
||||
{ annotation_level: "failure", message: "Process completed with exit code 1." },
|
||||
{ annotation_level: "failure", message: lostMessage },
|
||||
],
|
||||
readLog: noLog,
|
||||
});
|
||||
assert.equal(testThenLost.lost, false);
|
||||
assert.match(testThenLost.evidence, /Test timed out/);
|
||||
// The order of the annotations does not matter.
|
||||
const lostThenExit = await classifyJob({ id: 1 }, {
|
||||
annotations: [
|
||||
{ annotation_level: "failure", message: lostMessage },
|
||||
{ annotation_level: "failure", message: "Process completed with exit code 1." },
|
||||
],
|
||||
readLog: noLog,
|
||||
});
|
||||
assert.equal(lostThenExit.lost, false);
|
||||
// Runner loss with a cancellation only is still runner loss.
|
||||
const lostAndCancelled = await classifyJob({ id: 1 }, {
|
||||
annotations: [
|
||||
{ annotation_level: "failure", message: lostMessage },
|
||||
{ annotation_level: "failure", message: "The operation was canceled." },
|
||||
],
|
||||
readLog: noLog,
|
||||
});
|
||||
assert.equal(lostAndCancelled.lost, true);
|
||||
});
|
||||
|
||||
test("summary cells cannot break the table", () => {
|
||||
const summary = renderSummary({
|
||||
runId: 1, attempt: 1, rerun: false, reason: "test",
|
||||
jobs: [{ name: "ci / a|b", lost: false, evidence: "line one\nline | two" }],
|
||||
});
|
||||
assert.match(summary, /\| ci \/ a\\\|b \| no \| line one line \\\| two \|/);
|
||||
});
|
||||
|
||||
test("workflow acts only on failed first attempts of the canonical PR workflow", () => {
|
||||
const condition = workflow.match(/^ {4}if: >-\n((?: {6}.+\n)+)/m)?.[1].replace(/\s+/g, " ").trim();
|
||||
assert.equal(condition, [
|
||||
"github.repository == 'paperclipai/paperclip' &&",
|
||||
"github.repository_id == '1170821064' &&",
|
||||
"github.event.workflow_run.event == 'pull_request' &&",
|
||||
"github.event.workflow_run.path == '.github/workflows/pr.yml' &&",
|
||||
"github.event.workflow_run.conclusion == 'failure' &&",
|
||||
"github.event.workflow_run.run_attempt == 1",
|
||||
].join(" "));
|
||||
assert.match(workflow, /^on:\n {2}workflow_run:\n {4}workflows: \[PR\]\n {4}types: \[completed\]$/m);
|
||||
assert.match(workflow, /^ {2}group: ci-runner-loss-rerun-\$\{\{ github\.event\.workflow_run\.id \}\}$/m);
|
||||
const permissions = workflow.match(/^permissions:\n((?: {2}.+\n)+)/m)[1]
|
||||
.split("\n").filter((line) => /^ {2}[a-z-]+:/.test(line)).map((line) => line.trim());
|
||||
assert.deepEqual(permissions, ["actions: write", "checks: read", "contents: read", "pull-requests: read"]);
|
||||
});
|
||||
|
||||
test("workflow runs only trusted default-branch code", () => {
|
||||
assert.match(workflow, /ref: \$\{\{ github\.sha \}\}\n {10}persist-credentials: false\n {10}sparse-checkout: \.github\/scripts\n/);
|
||||
assert.doesNotMatch(workflow, /head_sha|head_branch|download-artifact|secrets\.|pull_request_target/);
|
||||
assert.equal([...workflow.matchAll(/uses: /g)].length, 1);
|
||||
assert.match(workflow, /runs-on: ubuntu-latest/);
|
||||
});
|
||||
Reference in new issue
Block a user