mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-08 12:27:44 +00:00
feat(actions): add force-cancel workflow run API (#38756)
Add `POST /repos/{owner}/{repo}/actions/runs/{run}/force-cancel`, the
counterpart of [GitHub's force-cancel endpoint](https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2026-03-10#force-cancel-a-workflow-run).
It cancels a run like `POST .../cancel`, but bypasses the graceful
cancelling handshake with the runner and stops running tasks
immediately.
Permissions and responses match the `/cancel` endpoint.
References:
- https://github.blog/changelog/2023-09-21-github-actions-force-cancel-workflows/
- https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2026-03-10#force-cancel-a-workflow-run
- https://github.com/orgs/community/discussions/123240
This commit is contained in:
@@ -1363,6 +1363,7 @@ func Routes() *web.Router {
|
||||
m.Post("/rerun", reqToken(), reqRepoWriter(unit.TypeActions), repo.RerunWorkflowRun)
|
||||
m.Post("/rerun-failed-jobs", reqToken(), reqRepoWriter(unit.TypeActions), repo.RerunFailedWorkflowRun)
|
||||
m.Post("/cancel", reqToken(), reqRepoWriter(unit.TypeActions), repo.CancelWorkflowRun)
|
||||
m.Post("/force-cancel", reqToken(), reqRepoWriter(unit.TypeActions), repo.ForceCancelWorkflowRun)
|
||||
m.Post("/approve", reqToken(), reqRepoWriter(unit.TypeActions), repo.ApproveWorkflowRun)
|
||||
m.Group("/jobs", func() {
|
||||
m.Get("", repo.ListWorkflowRunJobs)
|
||||
|
||||
@@ -88,6 +88,51 @@ func CancelWorkflowRun(ctx *context.APIContext) {
|
||||
// "409":
|
||||
// "$ref": "#/responses/conflict"
|
||||
|
||||
cancelWorkflowRun(ctx, false)
|
||||
}
|
||||
|
||||
func ForceCancelWorkflowRun(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/actions/runs/{run}/force-cancel repository forceCancelWorkflowRun
|
||||
// ---
|
||||
// summary: Force-cancel a workflow run
|
||||
// description: |
|
||||
// Cancels a workflow run without waiting for its runners to acknowledge the cancellation.
|
||||
// The jobs are marked cancelled at once and anything a runner reports for them afterwards is discarded.
|
||||
// Only use this endpoint when the workflow run does not respond to `POST /repos/{owner}/{repo}/actions/runs/{run}/cancel`.
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repository
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: run
|
||||
// in: path
|
||||
// description: run ID
|
||||
// type: integer
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/WorkflowRun"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "409":
|
||||
// "$ref": "#/responses/conflict"
|
||||
|
||||
cancelWorkflowRun(ctx, true)
|
||||
}
|
||||
|
||||
func cancelWorkflowRun(ctx *context.APIContext, force bool) {
|
||||
run, jobs := getCurrentRepoActionRunJobsByID(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
@@ -99,7 +144,12 @@ func CancelWorkflowRun(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
run, err := actions_service.CancelRun(ctx, run, jobs)
|
||||
var err error
|
||||
if force {
|
||||
run, err = actions_service.ForceCancelRun(ctx, run, jobs)
|
||||
} else {
|
||||
run, err = actions_service.CancelRun(ctx, run, jobs)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.APIErrorAuto(err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user