chore(ci): a manually-run workflow to delete old Actions runs #324

Closed
opened 2026-09-09 09:27:32 -05:00 by bermudalamb · 0 comments
Owner

Gitea 1.27.3 has no retention for workflow run records — only for their logs and artifacts. LOG_RETENTION_DAYS clears the logs after 7 days, but the run entries stay listed forever, so the Actions page grows without limit.

On 2026-09-09 that list was 632 entries and had to be cleared by hand: 455 runs older than 7 days deleted through DELETE /api/v1/repos/{owner}/{repo}/actions/runs/{run_id}, one call each. It worked, but it lived in a scratch file on one machine, which is the wrong place for something that has to happen again every few weeks.

Scope

A workflow_dispatch workflow that deletes completed runs older than a given age, plus the script it calls.

  • Dry run by default. Deleting has to be asked for explicitly, not defaulted into — the operation is irreversible and there is no undo.
  • keep_days as an input, defaulting to 7 to match LOG_RETENTION_DAYS. Beyond that window the logs are already gone, so the entries being removed are empty shells.
  • Never touches a run that is not completed, which also means the cleanup run cannot delete itself.
  • Never touches a run with no usable start time. Queued runs report an epoch timestamp and cannot be aged, so they are kept rather than guessed at.
  • Reads the host and repository from the Actions context rather than hardcoding them.

The part that needs a decision

Which token. Deleting a run may be beyond what the automatic per-job token can do. The workflow therefore reads a repository secret, ACTIONS_CLEANUP_TOKEN, rather than assuming the built-in one is enough.

If the built-in token turns out to be sufficient, the secret can be dropped and the workflow simplified — worth checking on the first real run, since a token with delete rights sitting in repository secrets is not nothing on an instance that also hosts the deploy.

Out of scope

Running it on a schedule. Manual only for now: the operation is irreversible, the list is only an annoyance rather than a problem, and a cron that quietly deletes history should be a deliberate second step rather than the default.

Done when

The workflow can be dispatched from the Actions tab, a dry run reports what it would delete without deleting it, and an applied run clears the backlog.

Gitea 1.27.3 has no retention for workflow **run records** — only for their logs and artifacts. `LOG_RETENTION_DAYS` clears the logs after 7 days, but the run entries stay listed forever, so the Actions page grows without limit. On 2026-09-09 that list was 632 entries and had to be cleared by hand: 455 runs older than 7 days deleted through `DELETE /api/v1/repos/{owner}/{repo}/actions/runs/{run_id}`, one call each. It worked, but it lived in a scratch file on one machine, which is the wrong place for something that has to happen again every few weeks. ## Scope A `workflow_dispatch` workflow that deletes completed runs older than a given age, plus the script it calls. - **Dry run by default.** Deleting has to be asked for explicitly, not defaulted into — the operation is irreversible and there is no undo. - **`keep_days` as an input**, defaulting to 7 to match `LOG_RETENTION_DAYS`. Beyond that window the logs are already gone, so the entries being removed are empty shells. - **Never touches a run that is not completed**, which also means the cleanup run cannot delete itself. - **Never touches a run with no usable start time.** Queued runs report an epoch timestamp and cannot be aged, so they are kept rather than guessed at. - Reads the host and repository from the Actions context rather than hardcoding them. ## The part that needs a decision **Which token.** Deleting a run may be beyond what the automatic per-job token can do. The workflow therefore reads a repository secret, `ACTIONS_CLEANUP_TOKEN`, rather than assuming the built-in one is enough. If the built-in token turns out to be sufficient, the secret can be dropped and the workflow simplified — worth checking on the first real run, since a token with delete rights sitting in repository secrets is not nothing on an instance that also hosts the deploy. ## Out of scope Running it on a schedule. Manual only for now: the operation is irreversible, the list is only an annoyance rather than a problem, and a cron that quietly deletes history should be a deliberate second step rather than the default. ## Done when The workflow can be dispatched from the Actions tab, a dry run reports what it would delete without deleting it, and an applied run clears the backlog.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bermudalamb/redefined-designs#324