0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-14 17:27:39 +02:00

Address review comments on workflow runs API

Fix false 404s from ActionsListWorkflowRuns: the previous check returned
404 whenever no runs existed, so a valid workflow that hadn't been
triggered yet was reported as missing. Accept either existing runs or a
workflow file on the default branch as proof of existence; run lookup
runs first since it's cheaper than parsing workflow YAML on every call.

Also use the HookEventPullRequest constant instead of a raw string
literal for the trigger_event filter, switch the new
exclude_pull_requests query param to ctx.FormBool, and add a test
asserting exclude_pull_requests filters out pull_request-event runs.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
silverwind 2026-04-21 01:10:44 +02:00
parent 65473f8e6e
commit 897e97ef6e
No known key found for this signature in database
GPG Key ID: 2E62B41C93869443
4 changed files with 30 additions and 12 deletions

View File

@ -85,7 +85,7 @@ func (opts FindRunOptions) ToConds() builder.Cond {
cond = cond.And(builder.Eq{"`action_run`.commit_sha": opts.CommitSHA})
}
if opts.ExcludePullRequests {
cond = cond.And(builder.Neq{"`action_run`.trigger_event": "pull_request"})
cond = cond.And(builder.Neq{"`action_run`.trigger_event": string(webhook_module.HookEventPullRequest)})
}
if len(opts.ConcurrencyGroup) > 0 {
if opts.RepoID == 0 {

View File

@ -1028,21 +1028,28 @@ func ActionsListWorkflowRuns(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
workflowID := ctx.PathParam("workflow_id")
runExists, err := db.GetEngine(ctx).
Where("repo_id = ? AND workflow_id = ?", ctx.Repo.Repository.ID, workflowID).
Exist(&actions_model.ActionRun{})
// Existing runs prove the workflow is/was valid and cover historical workflows
// whose file was later removed. Fall back to a git lookup for never-run workflows.
runExists, err := db.Exist[actions_model.ActionRun](ctx, actions_model.FindRunOptions{
RepoID: ctx.Repo.Repository.ID,
WorkflowID: workflowID,
}.ToConds())
if err != nil {
ctx.APIErrorInternal(err)
return
}
if !runExists {
ctx.APIError(http.StatusNotFound, util.NewNotExistErrorf("workflow %q not found", workflowID))
return
if _, err := convert.GetActionWorkflow(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository, workflowID); err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err)
} else {
ctx.APIErrorInternal(err)
}
return
}
}
repoID := ctx.Repo.Repository.ID
shared.ListRuns(ctx, 0, repoID, workflowID)
shared.ListRuns(ctx, 0, ctx.Repo.Repository.ID, workflowID)
}
func ActionsDisableWorkflow(ctx *context.APIContext) {

View File

@ -156,9 +156,7 @@ func ListRuns(ctx *context.APIContext, ownerID, repoID int64, workflowID string)
if headSHA := ctx.FormString("head_sha"); headSHA != "" {
opts.CommitSHA = headSHA
}
if ctx.FormString("exclude_pull_requests") == "true" {
opts.ExcludePullRequests = true
}
opts.ExcludePullRequests = ctx.FormBool("exclude_pull_requests")
runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts)
if err != nil {

View File

@ -58,6 +58,19 @@ func testAPIWorkflowRunsByWorkflowID(t *testing.T, owner, repo, workflowID, user
}
assert.True(t, found, "expected to find run with ID %d in workflow %s runs", expectedRunID, workflowID)
req = NewRequest(t, "GET", workflowRunsURL+"?exclude_pull_requests=true").AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
excludedList := api.ActionWorkflowRunsResponse{}
DecodeJSON(t, resp, &excludedList)
excludedFound := false
for _, run := range excludedList.Entries {
assert.NotEqual(t, "pull_request", run.Event)
if run.ID == expectedRunID {
excludedFound = true
}
}
assert.True(t, excludedFound, "expected to find run with ID %d when excluding pull requests", expectedRunID)
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/workflows/nonexistent.yaml/runs", owner, repo)).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}