You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parent: #1936
Related: #2270 (this triggers off the contributor_cap close that issue introduces)
Motivation
#2270 adds a per-contributor open-PR/issue cap with auto-close over the limit. Closing a PR for
being over the cap should also stop burning CI minutes on that PR's in-flight Actions runs — today nothing in this codebase cancels a GitHub Actions run: there is no call to POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel (or any equivalent) anywhere in src/.
Important constraint found while scoping this: the GitHub App's default_permissions
(src/selfhost/setup-wizard.ts) currently requests pull_requests, contents, issues, checks, metadata — notactions. Listing/cancelling workflow runs via the Actions REST API needs actions: write (and effectively actions: read to list runs for a head SHA first). Adding this
scope means every already-installed self-hosted operator will see a "this app wants additional
permissions" prompt and must re-approve before cancellation works for them — this is a permission
rollout, not just a code change, and installs that haven't re-approved must degrade gracefully
rather than error.
On trigger: list in-progress/queued workflow runs for the closed PR's head SHA
(GET /repos/{owner}/{repo}/actions/runs?head_sha={sha}&status=in_progress plus queued), then
cancel each (POST .../actions/runs/{run_id}/cancel).
Must degrade gracefully when the installation hasn't granted actions: write (a 403/permission
error from the list/cancel call must be caught, logged via the audit ledger, and must NOT block or
fail the underlying close action that already succeeded).
Deliverables
Add actions: write to default_permissions in the App manifest (src/selfhost/setup-wizard.ts),
plus operator-facing docs on re-approving the permission bump for existing installs.
New GitHub REST wrappers (alongside the existing src/github/app.ts / src/github/pr-actions.ts
helpers) for listing workflow runs by head SHA and cancelling a run.
New settings field (e.g. contributorCapCancelCi?: boolean) threaded through the same
migration → schema → RepositorySettings → FocusManifestSettings/parseSettingsOverride → resolveEffectiveSettings chain used for every other per-repo toggle, plus a global env var
default (e.g. CONTRIBUTOR_CAP_CANCEL_CI_DEFAULT).
Hook into the action executor: after a closeKind: "contributor_cap" close executes successfully,
if enabled, cancel in-flight runs for that PR's head SHA.
Audit event (recordAuditEvent) for both outcomes: cancelled (with run count) and skipped/failed
due to missing permission.
Tests: disabled (default) → no cancel attempt; enabled + contributor_cap close → runs cancelled;
enabled + any other close kind → no cancel attempt; missing actions:write → soft-fails, close
action itself still reports success.
Acceptance criteria
A repo with this disabled (the default) sees zero behavior change from today.
An installation that hasn't granted actions: write still closes the PR successfully; cancellation
is skipped and logged, never surfaced as a failure to the contributor or the maintainer dashboard.
Expected outcome
Contributor-cap enforcement (#2270) actually saves the CI minutes it's meant to save, without
silently breaking (or requiring a forced upgrade for) self-hosted installs that haven't granted the
new Actions permission.
Parent: #1936
Related: #2270 (this triggers off the
contributor_capclose that issue introduces)Motivation
#2270 adds a per-contributor open-PR/issue cap with auto-close over the limit. Closing a PR for
being over the cap should also stop burning CI minutes on that PR's in-flight Actions runs — today
nothing in this codebase cancels a GitHub Actions run: there is no call to
POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel(or any equivalent) anywhere insrc/.Important constraint found while scoping this: the GitHub App's
default_permissions(
src/selfhost/setup-wizard.ts) currently requestspull_requests,contents,issues,checks,metadata— notactions. Listing/cancelling workflow runs via the Actions REST API needsactions: write(and effectivelyactions: readto list runs for a head SHA first). Adding thisscope means every already-installed self-hosted operator will see a "this app wants additional
permissions" prompt and must re-approve before cancellation works for them — this is a permission
rollout, not just a code change, and installs that haven't re-approved must degrade gracefully
rather than error.
Requirements
or per-repo (
.gittensory.yml/repository_settings), independent of (but only meaningful whenpaired with) the feat(agent-actions): configurable per-contributor open PR/issue cap with auto-close over the limit #2270 cap being enabled.
closeKind: "contributor_cap"close (from feat(agent-actions): configurable per-contributor open PR/issue cap with auto-close over the limit #2270)succeeds. (Extending to the existing
"blacklist"closeKind is a natural follow-up, not v1 here.)(
GET /repos/{owner}/{repo}/actions/runs?head_sha={sha}&status=in_progressplusqueued), thencancel each (
POST .../actions/runs/{run_id}/cancel).actions: write(a 403/permissionerror from the list/cancel call must be caught, logged via the audit ledger, and must NOT block or
fail the underlying close action that already succeeded).
Deliverables
actions: writetodefault_permissionsin the App manifest (src/selfhost/setup-wizard.ts),plus operator-facing docs on re-approving the permission bump for existing installs.
src/github/app.ts/src/github/pr-actions.tshelpers) for listing workflow runs by head SHA and cancelling a run.
contributorCapCancelCi?: boolean) threaded through the samemigration → schema →
RepositorySettings→FocusManifestSettings/parseSettingsOverride→resolveEffectiveSettingschain used for every other per-repo toggle, plus a global env vardefault (e.g.
CONTRIBUTOR_CAP_CANCEL_CI_DEFAULT).closeKind: "contributor_cap"close executes successfully,if enabled, cancel in-flight runs for that PR's head SHA.
recordAuditEvent) for both outcomes: cancelled (with run count) and skipped/faileddue to missing permission.
enabled + any other close kind → no cancel attempt; missing
actions:write→ soft-fails, closeaction itself still reports success.
Acceptance criteria
cancelled in the same actuation cycle.
actions: writestill closes the PR successfully; cancellationis skipped and logged, never surfaced as a failure to the contributor or the maintainer dashboard.
Expected outcome
Contributor-cap enforcement (#2270) actually saves the CI minutes it's meant to save, without
silently breaking (or requiring a forced upgrade for) self-hosted installs that haven't granted the
new Actions permission.