Proposal
Gitea Actions has no dedicated KEDA scaler. Today the options are the forgejo-runner scaler, which does not work against Gitea, or the github-runner scaler, which does work but is expensive against a self-hosted instance.
The forgejo-runner scaler calls /api/v1/admin/runners/jobs. Gitea has never implemented that endpoint — it returns 404 (verified against Gitea 1.27.2), and go-gitea/gitea#32862, which requested it, is still open. The response shapes also differ: Forgejo returns a bare array, Gitea returns {jobs, total_count}. Gitea also ignores the labels query parameter the scaler relies on, so even a path fix would silently return the page cap rather than a real count.
The github-runner scaler does work against Gitea (see #6765), because Gitea implements GitHub-compatible Actions endpoints. But it was written for an API with no instance-wide jobs endpoint, so it enumerates repos, then runs per repo, then jobs per run — roughly 1 + 2R + W requests per poll. Its enableEtags mitigation does not help here either, as Gitea sends no ETag on these endpoints.
Gitea exposes something GitHub does not: /api/v1/admin/actions/jobs, instance-wide, where total_count honours a status filter and repeated status parameters are OR-ed. That answers the scaling question in a single request.
Scaler Source
Gitea Actions job queue — /api/v1/admin/actions/jobs, plus the org, repo and user equivalents.
Scaling Mechanics
Count jobs whose status is queued or in_progress — both, so that replicas are not torn down the moment their jobs start running. Gitea accepts both statuses in a single call.
With no label filter, read total_count: one request per poll regardless of queue size. With labels, Gitea has no server-side filter for this endpoint, so the scaler pages and matches client-side. Page size is capped by MAX_RESPONSE_ITEMS (50 by default) and pagination is bounded at 20 pages, logging a line when the bound is hit so the lower bound is never silent.
Scopes: global (admin), org, owner+repo, and the token owner's own jobs.
Authentication Source
Gitea access token supplied via TriggerAuthentication, scoped to match the level used: read:admin for global, read:organization, read:repository, or read:user.
Anything else?
I have a working implementation with unit tests, validated against a live Gitea 1.27.2 instance: the no-label path returned the correct count in exactly one request, and the label path paginated and stopped at the cap as designed. Happy to open a PR.
Related: #6488 (closed by the stale bot), #6765, go-gitea/gitea#32862.
Proposal
Gitea Actions has no dedicated KEDA scaler. Today the options are the
forgejo-runnerscaler, which does not work against Gitea, or thegithub-runnerscaler, which does work but is expensive against a self-hosted instance.The
forgejo-runnerscaler calls/api/v1/admin/runners/jobs. Gitea has never implemented that endpoint — it returns 404 (verified against Gitea 1.27.2), and go-gitea/gitea#32862, which requested it, is still open. The response shapes also differ: Forgejo returns a bare array, Gitea returns{jobs, total_count}. Gitea also ignores thelabelsquery parameter the scaler relies on, so even a path fix would silently return the page cap rather than a real count.The
github-runnerscaler does work against Gitea (see #6765), because Gitea implements GitHub-compatible Actions endpoints. But it was written for an API with no instance-wide jobs endpoint, so it enumerates repos, then runs per repo, then jobs per run — roughly1 + 2R + Wrequests per poll. ItsenableEtagsmitigation does not help here either, as Gitea sends no ETag on these endpoints.Gitea exposes something GitHub does not:
/api/v1/admin/actions/jobs, instance-wide, wheretotal_counthonours a status filter and repeatedstatusparameters are OR-ed. That answers the scaling question in a single request.Scaler Source
Gitea Actions job queue —
/api/v1/admin/actions/jobs, plus the org, repo and user equivalents.Scaling Mechanics
Count jobs whose status is
queuedorin_progress— both, so that replicas are not torn down the moment their jobs start running. Gitea accepts both statuses in a single call.With no label filter, read
total_count: one request per poll regardless of queue size. With labels, Gitea has no server-side filter for this endpoint, so the scaler pages and matches client-side. Page size is capped byMAX_RESPONSE_ITEMS(50 by default) and pagination is bounded at 20 pages, logging a line when the bound is hit so the lower bound is never silent.Scopes:
global(admin),org,owner+repo, and the token owner's own jobs.Authentication Source
Gitea access token supplied via
TriggerAuthentication, scoped to match the level used:read:adminfor global,read:organization,read:repository, orread:user.Anything else?
I have a working implementation with unit tests, validated against a live Gitea 1.27.2 instance: the no-label path returned the correct count in exactly one request, and the label path paginated and stopped at the cap as designed. Happy to open a PR.
Related: #6488 (closed by the stale bot), #6765, go-gitea/gitea#32862.