mirror of
https://github.com/go-gitea/gitea
synced 2025-07-28 05:08:37 +00:00
Add workflow_run api + webhook (#33964)
Implements - https://docs.github.com/en/rest/actions/workflow-jobs?apiVersion=2022-11-28#list-jobs-for-a-workflow-run--code-samples - https://docs.github.com/en/rest/actions/workflow-jobs?apiVersion=2022-11-28#get-a-job-for-a-workflow-run--code-samples - https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository - https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#get-a-workflow-run - `/actions/runs` for global + user + org (Gitea only) - `/actions/jobs` for global + user + org + repository (Gitea only) - workflow_run webhook + action trigger - limitations - workflow id is assigned to a string, this may result into problems in strongly typed clients Fixes - workflow_job webhook url to no longer contain the `runs/<run>` part to align with api - workflow instance does now use it's name inside the file instead of filename if set Refactoring - Moved a lot of logic from workflows/workflow_job into a shared module used by both webhook and api TODO - [x] Verify Keda Compatibility - [x] Edit Webhook API bug is resolved Closes https://github.com/go-gitea/gitea/issues/23670 Closes https://github.com/go-gitea/gitea/issues/23796 Closes https://github.com/go-gitea/gitea/issues/24898 Replaces https://github.com/go-gitea/gitea/pull/28047 and is much more complete --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -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:
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
167
tests/integration/workflow_run_api_check_test.go
Normal file
167
tests/integration/workflow_run_api_check_test.go
Normal file
@@ -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)
|
||||
}
|
Reference in New Issue
Block a user