Skip to content

Feature: Add per-runner “Disable/Pause” #36776

Merged
lunny merged 3 commits intogo-gitea:mainfrom
bircni:feature/per-runner-disable
Mar 16, 2026
Merged

Feature: Add per-runner “Disable/Pause” #36776
lunny merged 3 commits intogo-gitea:mainfrom
bircni:feature/per-runner-disable

Conversation

@bircni
Copy link
Copy Markdown
Member

@bircni bircni commented Feb 27, 2026

This PR adds per-runner disable/enable support for Gitea Actions so a registered runner can be paused from picking up new jobs without unregistering.

Disabled runners stay registered and online but are excluded from new task assignment; running tasks are allowed to finish. Re-enabling restores pickup, and runner list/get responses now expose disabled state.

Also added an endpoint for testing http://localhost:3000/devtest/runner-edit/enable

Bildschirmfoto 2026-02-27 um 22 13 24

Fixes: #36767

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Feb 27, 2026
@github-actions github-actions bot added modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/templates This PR modifies the template files modifies/migrations labels Feb 27, 2026
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Feb 28, 2026

Authorship: Reviewed by Codex (GPT-5.3)

I reviewed PR #36776 end-to-end (models, migrations, API/web routes, conversion layer, templates, and integration tests) and I did not find any blocking issues.

What I validated:

  • is_disabled persistence + migration path (models/migrations/v1_26/v326.go, test included)
  • API enable/disable coverage across admin/user/org/repo routes
  • Web enable/disable handlers and permission checks in shared runner settings
  • Scheduler behavior change to prevent disabled runners from receiving new work (services/actions/task.go, models/actions/task.go)
  • API response surface for disabled state (modules/structs/repo_actions.go, services/convert/convert.go)
  • Integration coverage for toggle behavior and scope checks

Local checks run:

  • go test -tags 'sqlite sqlite_unlock_notify' ./models/migrations/v1_26 -run Test_AddDisabledToActionRunner -count=1
  • go test -tags 'sqlite sqlite_unlock_notify' ./services/actions -run TestNonExistent -count=1 (compile check)

@silverwind - first review with codex 5.3 😄

@bircni bircni marked this pull request as ready for review February 28, 2026 11:42
@silverwind silverwind requested a review from Copilot February 28, 2026 13:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a per-runner disable/pause feature for Gitea Actions, allowing admins to stop a registered runner from picking up new jobs without unregistering it. Disabled runners remain registered and online but are excluded from new task assignment; running tasks finish normally. Re-enabling a runner restores task pickup. The feature is exposed via REST API endpoints for all runner scopes (global/admin, org, user, repo) and through the existing web UI runner edit page.

Changes:

  • DB migration (#326) adding is_disabled column to action_runner table, with model field IsDisabled, and SetRunnerDisabled() function that updates the field and bumps the task version inside a transaction
  • New DisableRunner/EnableRunner API endpoints at all four scopes (admin/org/user/repo), with updated ActionRunner API struct exposing a disabled field and corresponding swagger documentation
  • Web UI changes adding an enable/disable toggle button to the runner edit page, with a new actions.runners.availability status indicator and locale strings

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
models/actions/runner.go Adds IsDisabled field and SetRunnerDisabled with transactional update + task version bump
models/actions/task.go Adds IsDisabled guard in CreateTaskForRunner (defense-in-depth)
models/migrations/v1_26/v326.go + v326_test.go DB migration adds is_disabled NOT NULL DEFAULT false column
models/migrations/migrations.go Registers migration 326
modules/structs/repo_actions.go Adds Disabled bool to ActionRunner API struct
services/actions/task.go Adds IsDisabled early-exit guard in PickTask
services/actions/interface.go Adds DisableRunner/EnableRunner to the API interface
services/convert/convert.go Maps runner.IsDisabled to Disabled in API response
routers/api/v1/shared/runners.go Implements shared updateRunnerDisabled, DisableRunner, EnableRunner
routers/api/v1/admin/runners.go + org/action.go + repo/action.go + user/runners.go Scope-specific handler wrappers with swagger comments
routers/api/v1/api.go Registers PUT /{runner_id}/disable and /{runner_id}/enable routes
routers/web/shared/actions/runners.go Implements web RunnerDisablePost/RunnerEnablePost handlers
routers/web/web.go Registers POST disable/enable web routes; adds devtest runner-edit routes
routers/web/devtest/runner_edit.go Devtest handler for previewing enable/disable UI states
templates/shared/actions/runner_edit.tmpl Adds availability status indicator and enable/disable toggle button
templates/devtest/runner-edit.tmpl Devtest page for UI verification
templates/swagger/v1_json.tmpl Adds swagger definitions for all new endpoints and disabled field in ActionRunner definition; fixes "an" → "a" article in repo/user endpoint summaries
options/locale/locale_en-US.json Adds locale strings for availability label and enable/disable actions
tests/integration/api_actions_runner_test.go Integration tests for disable/enable API at all scopes, including idempotency and scope-enforcement
tests/integration/actions_runner_modify_test.go Web integration tests for disable/enable in runner modify flow
tests/integration/actions_job_test.go End-to-end test verifying disabled runner does not pick up tasks but re-enabled runner does

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bircni bircni force-pushed the feature/per-runner-disable branch from 9d903da to 678ae44 Compare February 28, 2026 13:59
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 3, 2026

@silverwind fixed copilots comments

@lunny lunny added the type/enhancement An improvement of existing functionality label Mar 3, 2026
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 5, 2026

anyone who can review? :-)

@lunny
Copy link
Copy Markdown
Member

lunny commented Mar 5, 2026

anyone who can review? :-)

I will take care of that, but it may take some time since the task is relatively large.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 6, 2026

Found some issues fixing them

@bircni bircni force-pushed the feature/per-runner-disable branch from d5f0054 to 5bf5c62 Compare March 7, 2026 21:25
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 7, 2026

@lunny should be ready for a review now - rebased and fixed some stuff 😄

@bircni bircni force-pushed the feature/per-runner-disable branch from 5bf5c62 to a53dde2 Compare March 7, 2026 21:35
Copy link
Copy Markdown
Member

@silverwind silverwind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. fetchTaskOnce will panic on error (tests/integration/actions_runner_test.go): Uses assert.NoError which records the failure but continues execution. If FetchTask returns an error, resp is nil and resp.Msg.Task panics. Should use require.NoError to fail fast.

  2. Consider a single toggle endpoint: Separate /disable and /enable endpoints result in 8 route registrations + 8 swagger handler functions for a boolean toggle. A single PATCH .../runners/{runner_id} with {"disabled": true/false} would halve the API surface and be more conventional REST. Though I understand this may be intentional for simplicity.

  1. Redundant early-return in API handler: updateRunnerDisabled in routers/api/v1/shared/runners.go checks runner.IsDisabled == isDisabled before calling SetRunnerDisabled, but SetRunnerDisabled already has this exact same check. The API handler check just saves one function call — not worth the duplicated logic.

silverwind

This comment was marked as duplicate.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 8, 2026

@silverwind which of these comments do you want fixed?

@silverwind
Copy link
Copy Markdown
Member

silverwind commented Mar 8, 2026

1 and 3 at least. And don't ask me questions like that, it's your job to judge these comments :)

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 8, 2026

@silverwind is there something wrong with CI?
I didn't touch the part which raises errors now :-(

@bircni bircni force-pushed the feature/per-runner-disable branch from dbda9f6 to c1d40c4 Compare March 8, 2026 20:58
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 8, 2026

ig I found it: #36858

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 8, 2026

It was a lie :-( whyyyyy

@silverwind
Copy link
Copy Markdown
Member

silverwind commented Mar 8, 2026

int64-related issues may be coming from #36858. Also I think you need to run make tidy.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 9, 2026

@silverwind @lunny fixed and ready for review again

@bircni bircni force-pushed the feature/per-runner-disable branch from 1dff406 to a312d98 Compare March 13, 2026 20:38
@bircni bircni requested a review from lunny March 13, 2026 20:38
@wxiaoguang
Copy link
Copy Markdown
Contributor

Don't force-push or rebase after review starts. It makes it very difficult to review new changes.

image

lunny
lunny previously approved these changes Mar 14, 2026
@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Mar 14, 2026
@lunny
Copy link
Copy Markdown
Member

lunny commented Mar 14, 2026

It's better if @Zettat123 could have a review.

@lunny lunny dismissed their stale review March 14, 2026 20:37
  • When a runner was disabled, it will become offline after a while.
  • When a runner was converted from disable to enable, the pending tasks will not be picked
@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. labels Mar 14, 2026
@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Mar 14, 2026
@lunny lunny added this to the 1.26.0 milestone Mar 14, 2026
@lunny lunny added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Mar 14, 2026
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 16, 2026

Merge queue not working?

@lunny lunny merged commit b3b2d11 into go-gitea:main Mar 16, 2026
26 checks passed
@GiteaBot GiteaBot removed the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Mar 16, 2026
@lunny
Copy link
Copy Markdown
Member

lunny commented Mar 16, 2026

Merge queue not working?

Merged manually.

@bircni bircni deleted the feature/per-runner-disable branch March 16, 2026 17:27
silverwind added a commit to silverwind/gitea that referenced this pull request Mar 17, 2026
* origin/main:
  Update Nix flake (go-gitea#36902)
  Migrate fomantic `search` and `modal` CSS to first-party modules (go-gitea#36869)
  Feature: Add per-runner “Disable/Pause” (go-gitea#36776)

# Conflicts:
#	webpack.config.ts
zjjhot added a commit to zjjhot/gitea that referenced this pull request Mar 18, 2026
* giteaofficial/main:
  [skip ci] Updated translations via Crowdin
  Update Nix flake (go-gitea#36902)
  Migrate fomantic `search` and `modal` CSS to first-party modules (go-gitea#36869)
  Feature: Add per-runner “Disable/Pause” (go-gitea#36776)
  Enable native dark mode for swagger-ui (go-gitea#36899)
  Front port changelog for 1.25.5 (go-gitea#36892)
  Fix typos in code comments: doesnt, dont, wont (go-gitea#36890)
  Vendor relative-time-element as local web component (go-gitea#36853)
@bircni bircni mentioned this pull request Mar 22, 2026
lunny pushed a commit that referenced this pull request Mar 22, 2026
I'd like to apply as a maintainer.

Thanks to @TheFox0x7 for the suggestion.

Merged PRs:
- #36441
- #36571
- #36603
- #36768
- #36776
- #36783
- #36876
- #36883
- #36924

Ongoing work:
- #36514
- #36752
- #36912
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/migrations modifies/templates This PR modifies the template files type/enhancement An improvement of existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add per-runner “Disable/Pause” so a registered runner can stop picking up jobs (without unregistering)

7 participants