aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/integration/actions_trigger_test.go14
-rw-r--r--tests/integration/api_packages_container_test.go16
-rw-r--r--tests/integration/repo_webhook_test.go205
-rw-r--r--tests/integration/workflow_run_api_check_test.go167
4 files changed, 389 insertions, 13 deletions
diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go
index 6461fe85f4..088491d570 100644
--- a/tests/integration/actions_trigger_test.go
+++ b/tests/integration/actions_trigger_test.go
@@ -720,7 +720,7 @@ func TestWorkflowDispatchPublicApi(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch
jobs:
@@ -800,7 +800,7 @@ func TestWorkflowDispatchPublicApiWithInputs(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
jobs:
@@ -891,7 +891,7 @@ func TestWorkflowDispatchPublicApiJSON(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
jobs:
@@ -977,7 +977,7 @@ func TestWorkflowDispatchPublicApiWithInputsJSON(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
jobs:
@@ -1071,7 +1071,7 @@ func TestWorkflowDispatchPublicApiWithInputsNonDefaultBranchJSON(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch
jobs:
@@ -1107,7 +1107,7 @@ jobs:
{
Operation: "update",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
jobs:
@@ -1209,7 +1209,7 @@ func TestWorkflowApi(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/dispatch.yml",
- ContentReader: strings.NewReader(`name: test
+ ContentReader: strings.NewReader(`
on:
workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
jobs:
diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go
index 8ae33dc35c..204f099bbe 100644
--- a/tests/integration/api_packages_container_test.go
+++ b/tests/integration/api_packages_container_test.go
@@ -297,11 +297,22 @@ func TestPackageContainer(t *testing.T) {
SetHeader("Content-Range", "1-10")
MakeRequest(t, req, http.StatusRequestedRangeNotSatisfiable)
- contentRange := fmt.Sprintf("0-%d", len(blobContent)-1)
- req.SetHeader("Content-Range", contentRange)
+ // first patch without Content-Range
+ req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent[:1])).
+ AddTokenAuth(userToken)
+ resp = MakeRequest(t, req, http.StatusAccepted)
+ assert.NotEmpty(t, resp.Header().Get("Location"))
+ assert.Equal(t, "0-0", resp.Header().Get("Range"))
+
+ // then send remaining content with Content-Range
+ req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent[1:])).
+ SetHeader("Content-Range", fmt.Sprintf("1-%d", len(blobContent)-1)).
+ AddTokenAuth(userToken)
resp = MakeRequest(t, req, http.StatusAccepted)
+ contentRange := fmt.Sprintf("0-%d", len(blobContent)-1)
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
+ assert.NotEmpty(t, resp.Header().Get("Location"))
assert.Equal(t, contentRange, resp.Header().Get("Range"))
uploadURL = resp.Header().Get("Location")
@@ -311,6 +322,7 @@ func TestPackageContainer(t *testing.T) {
resp = MakeRequest(t, req, http.StatusNoContent)
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
+ assert.Equal(t, uploadURL, resp.Header().Get("Location"))
assert.Equal(t, contentRange, resp.Header().Get("Range"))
pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid)
diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go
index 45a85552bd..5eb05f1fa3 100644
--- a/tests/integration/repo_webhook_test.go
+++ b/tests/integration/repo_webhook_test.go
@@ -910,8 +910,7 @@ jobs:
assert.Equal(t, commitID, payloads[3].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[3].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[3].Repo.FullName)
- assert.Contains(t, payloads[3].WorkflowJob.URL, fmt.Sprintf("/actions/runs/%d/jobs/%d", payloads[3].WorkflowJob.RunID, payloads[3].WorkflowJob.ID))
- assert.Contains(t, payloads[3].WorkflowJob.URL, payloads[3].WorkflowJob.RunURL)
+ assert.Contains(t, payloads[3].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[3].WorkflowJob.ID))
assert.Contains(t, payloads[3].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", 0))
assert.Len(t, payloads[3].WorkflowJob.Steps, 1)
@@ -947,9 +946,207 @@ jobs:
assert.Equal(t, commitID, payloads[6].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[6].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[6].Repo.FullName)
- assert.Contains(t, payloads[6].WorkflowJob.URL, fmt.Sprintf("/actions/runs/%d/jobs/%d", payloads[6].WorkflowJob.RunID, payloads[6].WorkflowJob.ID))
- assert.Contains(t, payloads[6].WorkflowJob.URL, payloads[6].WorkflowJob.RunURL)
+ assert.Contains(t, payloads[6].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[6].WorkflowJob.ID))
assert.Contains(t, payloads[6].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", 1))
assert.Len(t, payloads[6].WorkflowJob.Steps, 2)
})
}
+
+type workflowRunWebhook struct {
+ URL string
+ payloads []api.WorkflowRunPayload
+ triggeredEvent string
+}
+
+func Test_WebhookWorkflowRun(t *testing.T) {
+ webhookData := &workflowRunWebhook{}
+ provider := newMockWebhookProvider(func(r *http.Request) {
+ assert.Contains(t, r.Header["X-Github-Event-Type"], "workflow_run", "X-GitHub-Event-Type should contain workflow_run")
+ assert.Contains(t, r.Header["X-Gitea-Event-Type"], "workflow_run", "X-Gitea-Event-Type should contain workflow_run")
+ assert.Contains(t, r.Header["X-Gogs-Event-Type"], "workflow_run", "X-Gogs-Event-Type should contain workflow_run")
+ content, _ := io.ReadAll(r.Body)
+ var payload api.WorkflowRunPayload
+ err := json.Unmarshal(content, &payload)
+ assert.NoError(t, err)
+ webhookData.payloads = append(webhookData.payloads, payload)
+ webhookData.triggeredEvent = "workflow_run"
+ }, http.StatusOK)
+ defer provider.Close()
+ webhookData.URL = provider.URL()
+
+ tests := []struct {
+ name string
+ callback func(t *testing.T, webhookData *workflowRunWebhook)
+ }{
+ {
+ name: "WorkflowRun",
+ callback: testWebhookWorkflowRun,
+ },
+ {
+ name: "WorkflowRunDepthLimit",
+ callback: testWebhookWorkflowRunDepthLimit,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ webhookData.payloads = nil
+ webhookData.triggeredEvent = ""
+ onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
+ test.callback(t, webhookData)
+ })
+ })
+ }
+}
+
+func testWebhookWorkflowRun(t *testing.T, webhookData *workflowRunWebhook) {
+ // 1. create a new webhook with special webhook for repo1
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ session := loginUser(t, "user2")
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
+
+ testAPICreateWebhookForRepo(t, session, "user2", "repo1", webhookData.URL, "workflow_run")
+
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
+
+ gitRepo1, err := gitrepo.OpenRepository(t.Context(), repo1)
+ assert.NoError(t, err)
+
+ runner := newMockRunner()
+ runner.registerAsRepoRunner(t, "user2", "repo1", "mock-runner", []string{"ubuntu-latest"}, false)
+
+ // 2.1 add workflow_run workflow file to the repo
+
+ opts := getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, "create "+"dispatch.yml", `
+on:
+ workflow_run:
+ workflows: ["Push"]
+ types:
+ - completed
+jobs:
+ dispatch:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo 'test the webhook'
+`)
+ createWorkflowFile(t, token, "user2", "repo1", ".gitea/workflows/dispatch.yml", opts)
+
+ // 2.2 trigger the webhooks
+
+ // add workflow file to the repo
+ // init the workflow
+ wfTreePath := ".gitea/workflows/push.yml"
+ wfFileContent := `name: Push
+on: push
+jobs:
+ wf1-job:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo 'test the webhook'
+ wf2-job:
+ runs-on: ubuntu-latest
+ needs: wf1-job
+ steps:
+ - run: echo 'cmd 1'
+ - run: echo 'cmd 2'
+`
+ opts = getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, "create "+wfTreePath, wfFileContent)
+ createWorkflowFile(t, token, "user2", "repo1", wfTreePath, opts)
+
+ commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch)
+ assert.NoError(t, err)
+
+ // 3. validate the webhook is triggered
+ assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
+ assert.Len(t, webhookData.payloads, 1)
+ assert.Equal(t, "requested", webhookData.payloads[0].Action)
+ assert.Equal(t, "queued", webhookData.payloads[0].WorkflowRun.Status)
+ assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[0].WorkflowRun.HeadBranch)
+ assert.Equal(t, commitID, webhookData.payloads[0].WorkflowRun.HeadSha)
+ assert.Equal(t, "repo1", webhookData.payloads[0].Repo.Name)
+ assert.Equal(t, "user2/repo1", webhookData.payloads[0].Repo.FullName)
+
+ // 4. Execute two Jobs
+ task := runner.fetchTask(t)
+ outcome := &mockTaskOutcome{
+ result: runnerv1.Result_RESULT_SUCCESS,
+ }
+ runner.execTask(t, task, outcome)
+
+ task = runner.fetchTask(t)
+ outcome = &mockTaskOutcome{
+ result: runnerv1.Result_RESULT_FAILURE,
+ }
+ runner.execTask(t, task, outcome)
+
+ // 7. validate the webhook is triggered
+ assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
+ assert.Len(t, webhookData.payloads, 3)
+ assert.Equal(t, "completed", webhookData.payloads[1].Action)
+ assert.Equal(t, "push", webhookData.payloads[1].WorkflowRun.Event)
+
+ // 3. validate the webhook is triggered
+ assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
+ assert.Len(t, webhookData.payloads, 3)
+ assert.Equal(t, "requested", webhookData.payloads[2].Action)
+ assert.Equal(t, "queued", webhookData.payloads[2].WorkflowRun.Status)
+ assert.Equal(t, "workflow_run", webhookData.payloads[2].WorkflowRun.Event)
+ assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[2].WorkflowRun.HeadBranch)
+ assert.Equal(t, commitID, webhookData.payloads[2].WorkflowRun.HeadSha)
+ assert.Equal(t, "repo1", webhookData.payloads[2].Repo.Name)
+ assert.Equal(t, "user2/repo1", webhookData.payloads[2].Repo.FullName)
+}
+
+func testWebhookWorkflowRunDepthLimit(t *testing.T, webhookData *workflowRunWebhook) {
+ // 1. create a new webhook with special webhook for repo1
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ session := loginUser(t, "user2")
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
+
+ testAPICreateWebhookForRepo(t, session, "user2", "repo1", webhookData.URL, "workflow_run")
+
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
+
+ gitRepo1, err := gitrepo.OpenRepository(t.Context(), repo1)
+ assert.NoError(t, err)
+
+ // 2. trigger the webhooks
+
+ // add workflow file to the repo
+ // init the workflow
+ wfTreePath := ".gitea/workflows/push.yml"
+ wfFileContent := `name: Endless Loop
+on:
+ push:
+ workflow_run:
+ types:
+ - requested
+jobs:
+ dispatch:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo 'test the webhook'
+`
+ opts := getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, "create "+wfTreePath, wfFileContent)
+ createWorkflowFile(t, token, "user2", "repo1", wfTreePath, opts)
+
+ commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch)
+ assert.NoError(t, err)
+
+ // 3. validate the webhook is triggered
+ assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
+ // 1x push + 5x workflow_run requested chain
+ assert.Len(t, webhookData.payloads, 6)
+ for i := range 6 {
+ assert.Equal(t, "requested", webhookData.payloads[i].Action)
+ assert.Equal(t, "queued", webhookData.payloads[i].WorkflowRun.Status)
+ assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[i].WorkflowRun.HeadBranch)
+ assert.Equal(t, commitID, webhookData.payloads[i].WorkflowRun.HeadSha)
+ if i == 0 {
+ assert.Equal(t, "push", webhookData.payloads[i].WorkflowRun.Event)
+ } else {
+ assert.Equal(t, "workflow_run", webhookData.payloads[i].WorkflowRun.Event)
+ }
+ assert.Equal(t, "repo1", webhookData.payloads[i].Repo.Name)
+ assert.Equal(t, "user2/repo1", webhookData.payloads[i].Repo.FullName)
+ }
+}
diff --git a/tests/integration/workflow_run_api_check_test.go b/tests/integration/workflow_run_api_check_test.go
new file mode 100644
index 0000000000..6a80bb5118
--- /dev/null
+++ b/tests/integration/workflow_run_api_check_test.go
@@ -0,0 +1,167 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "testing"
+
+ auth_model "code.gitea.io/gitea/models/auth"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/tests"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAPIWorkflowRun(t *testing.T) {
+ t.Run("AdminRuns", func(t *testing.T) {
+ testAPIWorkflowRunBasic(t, "/api/v1/admin/actions", "User1", 802, auth_model.AccessTokenScopeReadAdmin, auth_model.AccessTokenScopeReadRepository)
+ })
+ t.Run("UserRuns", func(t *testing.T) {
+ testAPIWorkflowRunBasic(t, "/api/v1/user/actions", "User2", 803, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadRepository)
+ })
+ t.Run("OrgRuns", func(t *testing.T) {
+ testAPIWorkflowRunBasic(t, "/api/v1/orgs/org3/actions", "User1", 802, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadRepository)
+ })
+ t.Run("RepoRuns", func(t *testing.T) {
+ testAPIWorkflowRunBasic(t, "/api/v1/repos/org3/repo5/actions", "User2", 802, auth_model.AccessTokenScopeReadRepository)
+ })
+}
+
+func testAPIWorkflowRunBasic(t *testing.T, apiRootURL, userUsername string, runID int64, scope ...auth_model.AccessTokenScope) {
+ defer tests.PrepareTestEnv(t)()
+ token := getUserToken(t, userUsername, scope...)
+
+ 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)
+
+ foundRun := false
+
+ for _, run := range runnerList.Entries {
+ // Verify filtering works
+ 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, "")
+ verifyWorkflowRunCanbeFoundWithStatusFilter(t, apiRunsURL, token, run.ID, "", "", "", "", run.TriggerActor.UserName, run.HeadSha)
+
+ // Verify run url works
+ req := NewRequest(t, "GET", run.URL).AddTokenAuth(token)
+ runResp := MakeRequest(t, req, http.StatusOK)
+ apiRun := api.ActionWorkflowRun{}
+ DecodeJSON(t, runResp, &apiRun)
+ assert.Equal(t, run.ID, apiRun.ID)
+ assert.Equal(t, run.Status, apiRun.Status)
+ assert.Equal(t, run.Conclusion, apiRun.Conclusion)
+ assert.Equal(t, run.Event, apiRun.Event)
+
+ // Verify jobs list works
+ req = NewRequest(t, "GET", fmt.Sprintf("%s/%s", run.URL, "jobs")).AddTokenAuth(token)
+ jobsResp := MakeRequest(t, req, http.StatusOK)
+ jobList := api.ActionWorkflowJobsResponse{}
+ DecodeJSON(t, jobsResp, &jobList)
+
+ if run.ID == runID {
+ 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, "")
+
+ // Verify job url works
+ req := NewRequest(t, "GET", job.URL).AddTokenAuth(token)
+ jobsResp := MakeRequest(t, req, http.StatusOK)
+ apiJob := api.ActionWorkflowJob{}
+ DecodeJSON(t, jobsResp, &apiJob)
+ assert.Equal(t, job.ID, apiJob.ID)
+ assert.Equal(t, job.RunID, apiJob.RunID)
+ assert.Equal(t, job.Status, apiJob.Status)
+ assert.Equal(t, job.Conclusion, apiJob.Conclusion)
+ }
+ }
+ }
+ 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, actor, headSHA string) {
+ filter := url.Values{}
+ if conclusion != "" {
+ filter.Add("status", conclusion)
+ }
+ if status != "" {
+ filter.Add("status", status)
+ }
+ if event != "" {
+ filter.Set("event", event)
+ }
+ if branch != "" {
+ filter.Set("branch", branch)
+ }
+ if actor != "" {
+ filter.Set("actor", actor)
+ }
+ if headSHA != "" {
+ filter.Set("head_sha", headSHA)
+ }
+ req := NewRequest(t, "GET", runAPIURL+"?"+filter.Encode()).AddTokenAuth(token)
+ runResp := MakeRequest(t, req, http.StatusOK)
+ runList := api.ActionWorkflowRunsResponse{}
+ DecodeJSON(t, runResp, &runList)
+
+ found := false
+ for _, run := range runList.Entries {
+ if conclusion != "" {
+ assert.Equal(t, conclusion, run.Conclusion)
+ }
+ if status != "" {
+ assert.Equal(t, status, run.Status)
+ }
+ if event != "" {
+ assert.Equal(t, event, run.Event)
+ }
+ 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)
+}
+
+func verifyWorkflowJobCanbeFoundWithStatusFilter(t *testing.T, runAPIURL, token string, id int64, conclusion, status string) {
+ filter := conclusion
+ if filter == "" {
+ filter = status
+ }
+ if filter == "" {
+ return
+ }
+ req := NewRequest(t, "GET", runAPIURL+"?status="+filter).AddTokenAuth(token)
+ jobListResp := MakeRequest(t, req, http.StatusOK)
+ jobList := api.ActionWorkflowJobsResponse{}
+ DecodeJSON(t, jobListResp, &jobList)
+
+ found := false
+ for _, job := range jobList.Entries {
+ if conclusion != "" {
+ assert.Equal(t, conclusion, job.Conclusion)
+ } else {
+ assert.Equal(t, status, job.Status)
+ }
+ found = found || job.ID == id
+ }
+ assert.True(t, found, "Expected to find job with ID %d", id)
+}