From 5be456b05b8d621d89f74af525341935499a9c59 Mon Sep 17 00:00:00 2001 From: Christopher Homberger Date: Sat, 3 May 2025 18:29:11 +0200 Subject: [PATCH] add actor and triggerActor --- modules/structs/repo_actions.go | 2 ++ routers/api/v1/shared/runners.go | 2 +- services/convert/convert.go | 5 ++- .../workflow_run_api_check_test.go | 34 +++++++++++++------ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/modules/structs/repo_actions.go b/modules/structs/repo_actions.go index b19db3cbdb..9a486cd1d6 100644 --- a/modules/structs/repo_actions.go +++ b/modules/structs/repo_actions.go @@ -98,6 +98,8 @@ type ActionWorkflowRun struct { HeadSha string `json:"head_sha"` HeadBranch string `json:"head_branch,omitempty"` Status string `json:"status"` + Actor *User `json:"actor,omitempty"` + TriggerActor *User `json:"trigger_actor,omitempty"` Repository *Repository `json:"repository,omitempty"` HeadRepository *Repository `json:"head_repository,omitempty"` Conclusion string `json:"conclusion,omitempty"` diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index dd9b92155d..5f392a290e 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -167,7 +167,7 @@ func ListJobs(ctx *context.APIContext, ownerID, repoID, runID int64) { if isRepoLevel { repository = ctx.Repo.Repository } else { - repository, err = repo_model.GetRepositoryByID(ctx, repoID) + repository, err = repo_model.GetRepositoryByID(ctx, jobs[i].RepoID) if err != nil { ctx.APIErrorInternal(err) return diff --git a/services/convert/convert.go b/services/convert/convert.go index a30ab7b658..e6a1b12cf9 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -248,7 +248,7 @@ func ToActionTask(ctx context.Context, t *actions_model.ActionTask) (*api.Action } func ToActionWorkflowRun(ctx context.Context, repo *repo_model.Repository, run *actions_model.ActionRun) (*api.ActionWorkflowRun, error) { - err := run.LoadRepo(ctx) + err := run.LoadAttributes(ctx) if err != nil { return nil, err } @@ -268,6 +268,9 @@ func ToActionWorkflowRun(ctx context.Context, repo *repo_model.Repository, run * Conclusion: conclusion, Path: fmt.Sprintf("%s@%s", run.WorkflowID, run.Ref), Repository: ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeNone}), + TriggerActor: ToUser(ctx, run.TriggerUser, nil), + // We do not have a way to get a different User for the actor than the trigger user + Actor: ToUser(ctx, run.TriggerUser, nil), }, nil } diff --git a/tests/integration/workflow_run_api_check_test.go b/tests/integration/workflow_run_api_check_test.go index cd6d49d622..60808c25bd 100644 --- a/tests/integration/workflow_run_api_check_test.go +++ b/tests/integration/workflow_run_api_check_test.go @@ -18,24 +18,25 @@ import ( func TestAPIWorkflowRun(t *testing.T) { t.Run("AdminRunner", func(t *testing.T) { - testAPIWorkflowRunBasic(t, "/api/v1/admin/actions/runs", 6, "User1", 802, auth_model.AccessTokenScopeReadAdmin, auth_model.AccessTokenScopeReadRepository) + testAPIWorkflowRunBasic(t, "/api/v1/admin/actions", 6, "User1", 802, auth_model.AccessTokenScopeReadAdmin, auth_model.AccessTokenScopeReadRepository) }) t.Run("UserRunner", func(t *testing.T) { - testAPIWorkflowRunBasic(t, "/api/v1/user/actions/runs", 1, "User2", 803, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadRepository) + testAPIWorkflowRunBasic(t, "/api/v1/user/actions", 1, "User2", 803, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadRepository) }) t.Run("OrgRuns", func(t *testing.T) { - testAPIWorkflowRunBasic(t, "/api/v1/orgs/org3/actions/runs", 1, "User1", 802, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadRepository) + testAPIWorkflowRunBasic(t, "/api/v1/orgs/org3/actions", 1, "User1", 802, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadRepository) }) t.Run("RepoRuns", func(t *testing.T) { - testAPIWorkflowRunBasic(t, "/api/v1/repos/org3/repo5/actions/runs", 1, "User2", 802, auth_model.AccessTokenScopeReadRepository) + testAPIWorkflowRunBasic(t, "/api/v1/repos/org3/repo5/actions", 1, "User2", 802, auth_model.AccessTokenScopeReadRepository) }) } -func testAPIWorkflowRunBasic(t *testing.T, runAPIURL string, itemCount int, userUsername string, runID int64, scope ...auth_model.AccessTokenScope) { +func testAPIWorkflowRunBasic(t *testing.T, apiRootURL string, itemCount int, userUsername string, runID int64, scope ...auth_model.AccessTokenScope) { defer tests.PrepareTestEnv(t)() token := getUserToken(t, userUsername, scope...) - req := NewRequest(t, "GET", runAPIURL).AddTokenAuth(token) + apiRunsURL := fmt.Sprintf("%s/%s", apiRootURL, "runs") + req := NewRequest(t, "GET", apiRunsURL).AddTokenAuth(token) runnerListResp := MakeRequest(t, req, http.StatusOK) runnerList := api.ActionWorkflowRunsResponse{} DecodeJSON(t, runnerListResp, &runnerList) @@ -45,10 +46,11 @@ func testAPIWorkflowRunBasic(t *testing.T, runAPIURL string, itemCount int, user foundRun := false for _, run := range runnerList.Entries { - verifyWorkflowRunCanbeFoundWithStatusFilter(t, runAPIURL, token, run.ID, "", run.Status, "", "") - verifyWorkflowRunCanbeFoundWithStatusFilter(t, runAPIURL, token, run.ID, run.Conclusion, "", "", "") - verifyWorkflowRunCanbeFoundWithStatusFilter(t, runAPIURL, token, run.ID, "", "", "", run.HeadBranch) - verifyWorkflowRunCanbeFoundWithStatusFilter(t, runAPIURL, token, run.ID, "", "", run.Event, "") + verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, "", run.Status, "", "", "") + verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, run.Conclusion, "", "", "", "") + verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, "", "", "", run.HeadBranch, "") + verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, "", "", run.Event, "", "") + verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, "", "", "", "", run.TriggerActor.UserName) req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", run.URL, "jobs")).AddTokenAuth(token) jobsResp := MakeRequest(t, req, http.StatusOK) @@ -59,8 +61,12 @@ func testAPIWorkflowRunBasic(t *testing.T, runAPIURL string, itemCount int, user foundRun = true assert.Len(t, jobList.Entries, 1) for _, job := range jobList.Entries { + // Check the jobs list of the run verifyWorkflowJobCanbeFoundWithStatusFilter(t, fmt.Sprintf("%s/%s", run.URL, "jobs"), token, job.ID, "", job.Status) verifyWorkflowJobCanbeFoundWithStatusFilter(t, fmt.Sprintf("%s/%s", run.URL, "jobs"), token, job.ID, job.Conclusion, "") + // Check the run independent job list + verifyWorkflowJobCanbeFoundWithStatusFilter(t, fmt.Sprintf("%s/%s", apiRootURL, "jobs"), token, job.ID, "", job.Status) + verifyWorkflowJobCanbeFoundWithStatusFilter(t, fmt.Sprintf("%s/%s", apiRootURL, "jobs"), token, job.ID, job.Conclusion, "") req := NewRequest(t, "GET", job.URL).AddTokenAuth(token) jobsResp := MakeRequest(t, req, http.StatusOK) @@ -76,7 +82,7 @@ func testAPIWorkflowRunBasic(t *testing.T, runAPIURL string, itemCount int, user assert.True(t, foundRun, "Expected to find run with ID %d", runID) } -func verifyWorkflowRunCanbeFoundWithStatusFilter(t *testing.T, runAPIURL, token string, id int64, conclusion, status, event, branch string) { +func verifyWorkflowRunCanbeFoundWithStatusFilter(t *testing.T, runAPIURL, token string, id int64, conclusion, status, event, branch, actor string) { filter := url.Values{} if conclusion != "" { filter.Add("status", conclusion) @@ -90,6 +96,9 @@ func verifyWorkflowRunCanbeFoundWithStatusFilter(t *testing.T, runAPIURL, token if branch != "" { filter.Set("branch", branch) } + if actor != "" { + filter.Set("actor", actor) + } req := NewRequest(t, "GET", runAPIURL+"?"+filter.Encode()).AddTokenAuth(token) runResp := MakeRequest(t, req, http.StatusOK) runList := api.ActionWorkflowRunsResponse{} @@ -109,6 +118,9 @@ func verifyWorkflowRunCanbeFoundWithStatusFilter(t *testing.T, runAPIURL, token if branch != "" { assert.Equal(t, branch, run.HeadBranch) } + if actor != "" { + assert.Equal(t, actor, run.Actor.UserName) + } found = found || run.ID == id } assert.True(t, found, "Expected to find run with ID %d", id)