| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719 |
- // Copyright 2024 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package integration
-
- import (
- "fmt"
- "io"
- "net/http"
- "net/http/httptest"
- "net/url"
- "path"
- "strings"
- "testing"
- "time"
-
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/commitstatus"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/test"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/tests"
-
- runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
- "github.com/PuerkitoBio/goquery"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
-
- func TestNewWebHookLink(t *testing.T) {
- defer tests.PrepareTestEnv(t)()
- session := loginUser(t, "user2")
-
- baseurl := "/user2/repo1/settings/hooks"
- tests := []string{
- // webhook list page
- baseurl,
- // new webhook page
- baseurl + "/gitea/new",
- // edit webhook page
- baseurl + "/1",
- }
-
- for _, url := range tests {
- resp := session.MakeRequest(t, NewRequest(t, "GET", url), http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
- menus := htmlDoc.doc.Find(".ui.top.attached.header .ui.dropdown .menu a")
- menus.Each(func(i int, menu *goquery.Selection) {
- url, exist := menu.Attr("href")
- assert.True(t, exist)
- assert.True(t, strings.HasPrefix(url, baseurl))
- })
- }
- }
-
- func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string, branchFilter ...string) {
- token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
- var branchFilterString string
- if len(branchFilter) > 0 {
- branchFilterString = branchFilter[0]
- }
- req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+userName+"/"+repoName+"/hooks", api.CreateHookOption{
- Type: "gitea",
- Config: api.CreateHookOptionConfig{
- "content_type": "json",
- "url": url,
- },
- Events: []string{event},
- Active: true,
- BranchFilter: branchFilterString,
- }).AddTokenAuth(token)
- MakeRequest(t, req, http.StatusCreated)
- }
-
- func testCreateWebhookForRepo(t *testing.T, session *TestSession, webhookType, userName, repoName, url, eventKind string) {
- csrf := GetUserCSRFToken(t, session)
- req := NewRequestWithValues(t, "POST", "/"+userName+"/"+repoName+"/settings/hooks/"+webhookType+"/new", map[string]string{
- "_csrf": csrf,
- "payload_url": url,
- "events": eventKind,
- "active": "true",
- "content_type": fmt.Sprintf("%d", webhook.ContentTypeJSON),
- "http_method": "POST",
- })
- session.MakeRequest(t, req, http.StatusSeeOther)
- }
-
- func testAPICreateWebhookForOrg(t *testing.T, session *TestSession, userName, url, event string) {
- token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
- req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/"+userName+"/hooks", api.CreateHookOption{
- Type: "gitea",
- Config: api.CreateHookOptionConfig{
- "content_type": "json",
- "url": url,
- },
- Events: []string{event},
- Active: true,
- }).AddTokenAuth(token)
- MakeRequest(t, req, http.StatusCreated)
- }
-
- type mockWebhookProvider struct {
- server *httptest.Server
- }
-
- func newMockWebhookProvider(callback func(r *http.Request), status int) *mockWebhookProvider {
- m := &mockWebhookProvider{}
- m.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- callback(r)
- w.WriteHeader(status)
- }))
- return m
- }
-
- func (m *mockWebhookProvider) URL() string {
- if m.server == nil {
- return ""
- }
- return m.server.URL
- }
-
- // Close closes the mock webhook http server
- func (m *mockWebhookProvider) Close() {
- if m.server != nil {
- m.server.Close()
- m.server = nil
- }
- }
-
- func Test_WebhookCreate(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.CreatePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.CreatePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = string(webhook_module.HookEventCreate)
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "create")
-
- // 2. trigger the webhook
- testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated)
-
- // 3. validate the webhook is triggered
- assert.Len(t, payloads, 1)
- assert.Equal(t, string(webhook_module.HookEventCreate), triggeredEvent)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Equal(t, "master2", payloads[0].Ref)
- assert.Equal(t, "branch", payloads[0].RefType)
- })
- }
-
- func Test_WebhookDelete(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.DeletePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.DeletePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "delete"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "delete")
-
- // 2. trigger the webhook
- testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated)
- testAPIDeleteBranch(t, "master2", http.StatusNoContent)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "delete", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Equal(t, "master2", payloads[0].Ref)
- assert.Equal(t, "branch", payloads[0].RefType)
- })
- }
-
- func Test_WebhookFork(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.ForkPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.ForkPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "fork"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user1")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "fork")
-
- // 2. trigger the webhook
- testRepoFork(t, session, "user2", "repo1", "user1", "repo1-fork", "master")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "fork", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "repo1-fork", payloads[0].Repo.Name)
- assert.Equal(t, "user1/repo1-fork", payloads[0].Repo.FullName)
- assert.Equal(t, "repo1", payloads[0].Forkee.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Forkee.FullName)
- })
- }
-
- func Test_WebhookIssueComment(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.IssueCommentPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.IssueCommentPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "issue_comment"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_comment")
-
- t.Run("create comment", func(t *testing.T) {
- // 2. trigger the webhook
- issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2")
- testIssueAddComment(t, session, issueURL, "issue title2 comment1", "")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "issue_comment", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "created", payloads[0].Action)
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "Title2", payloads[0].Issue.Title)
- assert.Equal(t, "Description2", payloads[0].Issue.Body)
- assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body)
- })
-
- t.Run("update comment", func(t *testing.T) {
- payloads = make([]api.IssueCommentPayload, 0, 2)
- triggeredEvent = ""
-
- // 2. trigger the webhook
- issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3")
- commentID := testIssueAddComment(t, session, issueURL, "issue title3 comment1", "")
- modifiedContent := "issue title2 comment1 - modified"
- req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
- "_csrf": GetUserCSRFToken(t, session),
- "content": modifiedContent,
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "issue_comment", triggeredEvent)
- assert.Len(t, payloads, 2)
- assert.EqualValues(t, "edited", payloads[1].Action)
- assert.Equal(t, "repo1", payloads[1].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[1].Issue.Repo.FullName)
- assert.Equal(t, "Title3", payloads[1].Issue.Title)
- assert.Equal(t, "Description3", payloads[1].Issue.Body)
- assert.Equal(t, modifiedContent, payloads[1].Comment.Body)
- })
-
- t.Run("Update comment with no content change", func(t *testing.T) {
- payloads = make([]api.IssueCommentPayload, 0, 2)
- triggeredEvent = ""
- commentContent := "issue title3 comment1"
-
- // 2. trigger the webhook
- issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3")
- commentID := testIssueAddComment(t, session, issueURL, commentContent, "")
-
- payloads = make([]api.IssueCommentPayload, 0, 2)
- triggeredEvent = ""
- req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
- "_csrf": GetUserCSRFToken(t, session),
- "content": commentContent,
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- // 3. validate the webhook is not triggered because no content change
- assert.Empty(t, triggeredEvent)
- assert.Empty(t, payloads)
- })
- })
- }
-
- func Test_WebhookRelease(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.ReleasePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.ReleasePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "release"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "release")
-
- // 2. trigger the webhook
- createNewRelease(t, session, "/user2/repo1", "v0.0.99", "v0.0.99", false, false)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "release", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "repo1", payloads[0].Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repository.FullName)
- assert.Equal(t, "v0.0.99", payloads[0].Release.TagName)
- assert.False(t, payloads[0].Release.IsDraft)
- assert.False(t, payloads[0].Release.IsPrerelease)
- })
- }
-
- func Test_WebhookPush(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.PushPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PushPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "push"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push")
-
- // 2. trigger the webhook
- testCreateFile(t, session, "user2", "repo1", "master", "", "test_webhook_push.md", "# a test file for webhook push")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "push", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Len(t, payloads[0].Commits, 1)
- assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added)
- })
- }
-
- func Test_WebhookPushDevBranch(t *testing.T) {
- var payloads []api.PushPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PushPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "push"
- }, http.StatusOK)
- defer provider.Close()
-
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- // only for dev branch
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push", "develop")
-
- // 2. this should not trigger the webhook
- testCreateFile(t, session, "user2", "repo1", "master", "", "test_webhook_push.md", "# a test file for webhook push")
- assert.Empty(t, triggeredEvent)
- assert.Empty(t, payloads)
-
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- gitRepo, err := gitrepo.OpenRepository(t.Context(), repo1)
- assert.NoError(t, err)
- defer gitRepo.Close()
-
- beforeCommitID, err := gitRepo.GetBranchCommitID("develop")
- assert.NoError(t, err)
-
- // 3. trigger the webhook
- testCreateFile(t, session, "user2", "repo1", "develop", "", "test_webhook_push.md", "# a test file for webhook push")
-
- afterCommitID, err := gitRepo.GetBranchCommitID("develop")
- assert.NoError(t, err)
-
- // 4. validate the webhook is triggered
- assert.Equal(t, "push", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "refs/heads/develop", payloads[0].Ref)
- assert.Equal(t, beforeCommitID, payloads[0].Before)
- assert.Equal(t, afterCommitID, payloads[0].After)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "develop", payloads[0].Branch())
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Len(t, payloads[0].Commits, 1)
- assert.Equal(t, afterCommitID, payloads[0].Commits[0].ID)
- assert.Equal(t, setting.AppURL+"user2/repo1/compare/"+beforeCommitID+"..."+afterCommitID, payloads[0].CompareURL)
- assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added)
- assert.Empty(t, payloads[0].Commits[0].Removed)
- })
- }
-
- func Test_WebhookPushToNewBranch(t *testing.T) {
- var payloads []api.PushPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PushPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "push"
- }, http.StatusOK)
- defer provider.Close()
-
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- // only for dev branch
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push", "new_branch")
-
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- gitRepo, err := gitrepo.OpenRepository(t.Context(), repo1)
- assert.NoError(t, err)
- defer gitRepo.Close()
-
- beforeCommitID, err := gitRepo.GetBranchCommitID("master")
- assert.NoError(t, err)
-
- // 2. trigger the webhook
- testCreateFile(t, session, "user2", "repo1", "master", "new_branch", "test_webhook_push.md", "# a new push from new branch")
-
- afterCommitID, err := gitRepo.GetBranchCommitID("new_branch")
- assert.NoError(t, err)
- emptyCommitID := git.Sha1ObjectFormat.EmptyObjectID().String()
-
- // 4. validate the webhook is triggered
- assert.Equal(t, "push", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "refs/heads/new_branch", payloads[0].Ref)
- assert.Equal(t, emptyCommitID, payloads[0].Before)
- assert.Equal(t, afterCommitID, payloads[0].After)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "new_branch", payloads[0].Branch())
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Len(t, payloads[0].Commits, 1)
- assert.Equal(t, afterCommitID, payloads[0].Commits[0].ID)
- assert.Equal(t, setting.AppURL+"user2/repo1/compare/"+beforeCommitID+"..."+afterCommitID, payloads[0].CompareURL)
- assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added)
- assert.Empty(t, payloads[0].Commits[0].Removed)
- })
- }
-
- func Test_WebhookIssue(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.IssuePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.IssuePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "issues"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issues")
-
- // 2. trigger the webhook
- testNewIssue(t, session, "user2", "repo1", "Title1", "Description1")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "issues", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "opened", payloads[0].Action)
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "Title1", payloads[0].Issue.Title)
- assert.Equal(t, "Description1", payloads[0].Issue.Body)
- assert.Positive(t, payloads[0].Issue.Created.Unix())
- assert.Positive(t, payloads[0].Issue.Updated.Unix())
- })
- }
-
- func Test_WebhookIssueDelete(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.IssuePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.IssuePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "issue"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issues")
- issueURL := testNewIssue(t, session, "user2", "repo1", "Title1", "Description1")
-
- // 2. trigger the webhook
- testIssueDelete(t, session, issueURL)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "issue", triggeredEvent)
- require.Len(t, payloads, 2)
- assert.EqualValues(t, "deleted", payloads[1].Action)
- assert.Equal(t, "repo1", payloads[1].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[1].Issue.Repo.FullName)
- assert.Equal(t, "Title1", payloads[1].Issue.Title)
- assert.Equal(t, "Description1", payloads[1].Issue.Body)
- })
- }
-
- func Test_WebhookIssueAssign(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.PullRequestPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PullRequestPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "pull_request_assign"
- }, http.StatusOK)
- defer provider.Close()
-
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request_assign")
-
- // 2. trigger the webhook, issue 2 is a pull request
- testIssueAssign(t, session, repo1.Link(), 2, user2.ID)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "pull_request_assign", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "assigned", payloads[0].Action)
- assert.Equal(t, "repo1", payloads[0].PullRequest.Base.Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[0].PullRequest.Base.Repository.FullName)
- assert.Equal(t, "issue2", payloads[0].PullRequest.Title)
- assert.Equal(t, "content for the second issue", payloads[0].PullRequest.Body)
- assert.Equal(t, user2.ID, payloads[0].PullRequest.Assignee.ID)
- })
- }
-
- func Test_WebhookIssueMilestone(t *testing.T) {
- var payloads []api.IssuePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.IssuePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "issues"
- }, http.StatusOK)
- defer provider.Close()
-
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- // create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_milestone")
-
- t.Run("assign a milestone", func(t *testing.T) {
- // trigger the webhook
- testIssueChangeMilestone(t, session, repo1.Link(), 1, 1)
-
- // validate the webhook is triggered
- assert.Equal(t, "issues", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "milestoned", string(payloads[0].Action))
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "issue1", payloads[0].Issue.Title)
- assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
- assert.EqualValues(t, 1, payloads[0].Issue.Milestone.ID)
- })
-
- t.Run("change a milestong", func(t *testing.T) {
- // trigger the webhook again
- triggeredEvent = ""
- payloads = make([]api.IssuePayload, 0, 1)
- // change milestone to 2
- testIssueChangeMilestone(t, session, repo1.Link(), 1, 2)
-
- // validate the webhook is triggered
- assert.Equal(t, "issues", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "milestoned", string(payloads[0].Action))
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "issue1", payloads[0].Issue.Title)
- assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
- assert.EqualValues(t, 2, payloads[0].Issue.Milestone.ID)
- })
-
- t.Run("remove a milestone", func(t *testing.T) {
- // trigger the webhook again
- triggeredEvent = ""
- payloads = make([]api.IssuePayload, 0, 1)
- // change milestone to 0
- testIssueChangeMilestone(t, session, repo1.Link(), 1, 0)
-
- // validate the webhook is triggered
- assert.Equal(t, "issues", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, "demilestoned", string(payloads[0].Action))
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "issue1", payloads[0].Issue.Title)
- assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
- assert.Nil(t, payloads[0].Issue.Milestone)
- })
- })
- }
-
- func Test_WebhookPullRequest(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.PullRequestPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PullRequestPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "pull_request"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request")
-
- testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated)
- // 2. trigger the webhook
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "pull_request", triggeredEvent)
- require.Len(t, payloads, 1)
- assert.Equal(t, "repo1", payloads[0].PullRequest.Base.Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[0].PullRequest.Base.Repository.FullName)
- assert.Equal(t, "repo1", payloads[0].PullRequest.Head.Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[0].PullRequest.Head.Repository.FullName)
- assert.Equal(t, 0, *payloads[0].PullRequest.Additions)
- assert.Equal(t, 0, *payloads[0].PullRequest.ChangedFiles)
- assert.Equal(t, 0, *payloads[0].PullRequest.Deletions)
- })
- }
-
- func Test_WebhookPullRequestDelete(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.PullRequestPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PullRequestPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "pull_request"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request")
-
- testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated)
-
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- issueURL := testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request")
-
- // 2. trigger the webhook
- testIssueDelete(t, session, path.Join(repo1.Link(), "pulls", issueURL))
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "pull_request", triggeredEvent)
- require.Len(t, payloads, 2)
- assert.EqualValues(t, "deleted", payloads[1].Action)
- assert.Equal(t, "repo1", payloads[1].PullRequest.Base.Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[1].PullRequest.Base.Repository.FullName)
- assert.Equal(t, 0, *payloads[1].PullRequest.Additions)
- assert.Equal(t, 0, *payloads[1].PullRequest.ChangedFiles)
- assert.Equal(t, 0, *payloads[1].PullRequest.Deletions)
- })
- }
-
- func Test_WebhookPullRequestComment(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.IssueCommentPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.IssueCommentPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "pull_request_comment"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request_comment")
-
- // 2. trigger the webhook
- testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated)
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
- prID := testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request")
-
- testIssueAddComment(t, session, "/user2/repo1/pulls/"+prID, "pull title2 comment1", "")
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "pull_request_comment", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "created", payloads[0].Action)
- assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
- assert.Equal(t, "first pull request", payloads[0].Issue.Title)
- assert.Empty(t, payloads[0].Issue.Body)
- assert.Equal(t, "pull title2 comment1", payloads[0].Comment.Body)
- })
- }
-
- func Test_WebhookWiki(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.WikiPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.WikiPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "wiki"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "wiki")
-
- // 2. trigger the webhook
- testAPICreateWikiPage(t, session, "user2", "repo1", "Test Wiki Page", http.StatusCreated)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "wiki", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "created", payloads[0].Action)
- assert.Equal(t, "repo1", payloads[0].Repository.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repository.FullName)
- assert.Equal(t, "Test-Wiki-Page", payloads[0].Page)
- })
- }
-
- func Test_WebhookRepository(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.RepositoryPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.RepositoryPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "repository"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user1")
-
- testAPICreateWebhookForOrg(t, session, "org3", provider.URL(), "repository")
-
- // 2. trigger the webhook
- testAPIOrgCreateRepo(t, session, "org3", "repo_new", http.StatusCreated)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "repository", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "created", payloads[0].Action)
- assert.Equal(t, "org3", payloads[0].Organization.UserName)
- assert.Equal(t, "repo_new", payloads[0].Repository.Name)
- assert.Equal(t, "org3/repo_new", payloads[0].Repository.FullName)
- })
- }
-
- func Test_WebhookPackage(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.PackagePayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- content, _ := io.ReadAll(r.Body)
- var payload api.PackagePayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "package"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user1")
-
- testAPICreateWebhookForOrg(t, session, "org3", provider.URL(), "package")
-
- // 2. trigger the webhook
- token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
- url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", "org3", "gitea", "v1.24.0")
- req := NewRequestWithBody(t, "PUT", url+"/gitea", strings.NewReader("This is a dummy file")).
- AddTokenAuth(token)
- MakeRequest(t, req, http.StatusCreated)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "package", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.EqualValues(t, "created", payloads[0].Action)
- assert.Equal(t, "gitea", payloads[0].Package.Name)
- assert.Equal(t, "generic", payloads[0].Package.Type)
- assert.Equal(t, "org3", payloads[0].Organization.UserName)
- assert.Equal(t, "v1.24.0", payloads[0].Package.Version)
- })
- }
-
- func Test_WebhookStatus(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.CommitStatusPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- assert.Contains(t, r.Header["X-Github-Event-Type"], "status", "X-GitHub-Event-Type should contain status")
- assert.Contains(t, r.Header["X-Github-Hook-Installation-Target-Type"], "repository", "X-GitHub-Hook-Installation-Target-Type should contain repository")
- assert.Contains(t, r.Header["X-Gitea-Event-Type"], "status", "X-Gitea-Event-Type should contain status")
- assert.Contains(t, r.Header["X-Gitea-Hook-Installation-Target-Type"], "repository", "X-Gitea-Hook-Installation-Target-Type should contain repository")
- assert.Contains(t, r.Header["X-Gogs-Event-Type"], "status", "X-Gogs-Event-Type should contain status")
- content, _ := io.ReadAll(r.Body)
- var payload api.CommitStatusPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "status"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "status")
-
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
-
- gitRepo1, err := gitrepo.OpenRepository(t.Context(), repo1)
- assert.NoError(t, err)
- commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch)
- assert.NoError(t, err)
-
- // 2. trigger the webhook
- testCtx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeAll)
-
- // update a status for a commit via API
- doAPICreateCommitStatus(testCtx, commitID, api.CreateStatusOption{
- State: commitstatus.CommitStatusSuccess,
- TargetURL: "http://test.ci/",
- Description: "",
- Context: "testci",
- })(t)
-
- // 3. validate the webhook is triggered
- assert.Equal(t, "status", triggeredEvent)
- assert.Len(t, payloads, 1)
- assert.Equal(t, commitID, payloads[0].Commit.ID)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
- assert.Equal(t, "testci", payloads[0].Context)
- assert.Equal(t, commitID, payloads[0].SHA)
- })
- }
-
- func Test_WebhookStatus_NoWrongTrigger(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var trigger string
- provider := newMockWebhookProvider(func(r *http.Request) {
- assert.NotContains(t, r.Header["X-Github-Event-Type"], "status", "X-GitHub-Event-Type should not contain status")
- assert.NotContains(t, r.Header["X-Gitea-Event-Type"], "status", "X-Gitea-Event-Type should not contain status")
- assert.NotContains(t, r.Header["X-Gogs-Event-Type"], "status", "X-Gogs-Event-Type should not contain status")
- trigger = "push"
- }, http.StatusOK)
- defer provider.Close()
-
- // 1. create a new webhook with special webhook for repo1
- session := loginUser(t, "user2")
-
- // create a push_only webhook from web UI
- testCreateWebhookForRepo(t, session, "gitea", "user2", "repo1", provider.URL(), "push_only")
-
- // 2. trigger the webhook with a push action
- testCreateFile(t, session, "user2", "repo1", "master", "", "test_webhook_push.md", "# a test file for webhook push")
-
- // 3. validate the webhook is triggered with right event
- assert.Equal(t, "push", trigger)
- })
- }
-
- func Test_WebhookWorkflowJob(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- var payloads []api.WorkflowJobPayload
- var triggeredEvent string
- provider := newMockWebhookProvider(func(r *http.Request) {
- assert.Contains(t, r.Header["X-Github-Event-Type"], "workflow_job", "X-GitHub-Event-Type should contain workflow_job")
- assert.Contains(t, r.Header["X-Gitea-Event-Type"], "workflow_job", "X-Gitea-Event-Type should contain workflow_job")
- assert.Contains(t, r.Header["X-Gogs-Event-Type"], "workflow_job", "X-Gogs-Event-Type should contain workflow_job")
- content, _ := io.ReadAll(r.Body)
- var payload api.WorkflowJobPayload
- err := json.Unmarshal(content, &payload)
- assert.NoError(t, err)
- payloads = append(payloads, payload)
- triggeredEvent = "workflow_job"
- }, http.StatusOK)
- defer provider.Close()
-
- // 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", provider.URL(), "workflow_job")
-
- 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. 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_job", triggeredEvent)
- assert.Len(t, payloads, 2)
- assert.Equal(t, "queued", payloads[0].Action)
- assert.Equal(t, "queued", payloads[0].WorkflowJob.Status)
- assert.Equal(t, []string{"ubuntu-latest"}, payloads[0].WorkflowJob.Labels)
- assert.Equal(t, commitID, payloads[0].WorkflowJob.HeadSha)
- assert.Equal(t, "repo1", payloads[0].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
-
- assert.Equal(t, "waiting", payloads[1].Action)
- assert.Equal(t, "waiting", payloads[1].WorkflowJob.Status)
- assert.Equal(t, commitID, payloads[1].WorkflowJob.HeadSha)
- assert.Equal(t, "repo1", payloads[1].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[1].Repo.FullName)
-
- // 4. Execute a single Job
- task := runner.fetchTask(t)
- outcome := &mockTaskOutcome{
- result: runnerv1.Result_RESULT_SUCCESS,
- }
- runner.execTask(t, task, outcome)
-
- // 5. validate the webhook is triggered
- assert.Equal(t, "workflow_job", triggeredEvent)
- assert.Len(t, payloads, 5)
- assert.Equal(t, "in_progress", payloads[2].Action)
- assert.Equal(t, "in_progress", payloads[2].WorkflowJob.Status)
- assert.Equal(t, "mock-runner", payloads[2].WorkflowJob.RunnerName)
- assert.Equal(t, commitID, payloads[2].WorkflowJob.HeadSha)
- assert.Equal(t, "repo1", payloads[2].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[2].Repo.FullName)
-
- assert.Equal(t, "completed", payloads[3].Action)
- assert.Equal(t, "completed", payloads[3].WorkflowJob.Status)
- assert.Equal(t, "mock-runner", payloads[3].WorkflowJob.RunnerName)
- assert.Equal(t, "success", payloads[3].WorkflowJob.Conclusion)
- 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/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)
-
- assert.Equal(t, "queued", payloads[4].Action)
- assert.Equal(t, "queued", payloads[4].WorkflowJob.Status)
- assert.Equal(t, []string{"ubuntu-latest"}, payloads[4].WorkflowJob.Labels)
- assert.Equal(t, commitID, payloads[4].WorkflowJob.HeadSha)
- assert.Equal(t, "repo1", payloads[4].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[4].Repo.FullName)
-
- // 6. Execute a single Job
- 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_job", triggeredEvent)
- assert.Len(t, payloads, 7)
- assert.Equal(t, "in_progress", payloads[5].Action)
- assert.Equal(t, "in_progress", payloads[5].WorkflowJob.Status)
- assert.Equal(t, "mock-runner", payloads[5].WorkflowJob.RunnerName)
-
- assert.Equal(t, commitID, payloads[5].WorkflowJob.HeadSha)
- assert.Equal(t, "repo1", payloads[5].Repo.Name)
- assert.Equal(t, "user2/repo1", payloads[5].Repo.FullName)
-
- assert.Equal(t, "completed", payloads[6].Action)
- assert.Equal(t, "completed", payloads[6].WorkflowJob.Status)
- assert.Equal(t, "failure", payloads[6].WorkflowJob.Conclusion)
- assert.Equal(t, "mock-runner", payloads[6].WorkflowJob.RunnerName)
- 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/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) {
- testCases := []struct {
- name string
- testFunc func(t *testing.T, webhookData *workflowRunWebhook)
- }{
- {
- name: "WorkflowRun",
- testFunc: testWebhookWorkflowRun,
- },
- {
- name: "WorkflowRunDepthLimit",
- testFunc: testWebhookWorkflowRunDepthLimit,
- },
- {
- name: "WorkflowRunEvents",
- testFunc: testWorkflowRunEvents,
- },
- {
- name: "WorkflowRunEventsOnRerun",
- testFunc: testWorkflowRunEventsOnRerun,
- },
- {
- name: "WorkflowRunEventsOnCancellingAbandonedRunAllJobsAbandoned",
- testFunc: func(t *testing.T, webhookData *workflowRunWebhook) {
- testWorkflowRunEventsOnCancellingAbandonedRun(t, webhookData, true)
- },
- },
- {
- name: "WorkflowRunEventsOnCancellingAbandonedRunPartiallyAbandoned",
- testFunc: func(t *testing.T, webhookData *workflowRunWebhook) {
- testWorkflowRunEventsOnCancellingAbandonedRun(t, webhookData, false)
- },
- },
- }
- for _, obj := range testCases {
- t.Run(obj.name, func(t *testing.T) {
- onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- 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()
- webhookData.payloads = nil
- webhookData.triggeredEvent = ""
- obj.testFunc(t, webhookData)
- })
- })
- }
- }
-
- func testWorkflowRunEvents(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.2 trigger the webhooks
-
- // add workflow file to the repo
- // init the workflow
- wfTreePath := ".gitea/workflows/push.yml"
- wfFileContent := `on:
- push:
- workflow_dispatch:
-
- jobs:
- test:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test2:
- needs: [test]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test3:
- needs: [test, test2]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test4:
- needs: [test, test2, test3]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test5:
- needs: [test, test2, test4]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test6:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
- needs: [test, test2, test3]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test7:
- needs: test6
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test8:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test9:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, ubuntu-25.04, windows-2022, windows-2025, macos-13, macos-14, macos-15]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test10:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0`
- 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)
-
- // Call cancel ui api
- // Only a web UI API exists for cancelling workflow runs, so use the UI endpoint.
- cancelURL := fmt.Sprintf("/user2/repo1/actions/runs/%d/cancel", webhookData.payloads[0].WorkflowRun.RunNumber)
- req := NewRequestWithValues(t, "POST", cancelURL, map[string]string{
- "_csrf": GetUserCSRFToken(t, session),
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- assert.Len(t, webhookData.payloads, 2)
-
- // 4. Validate the second webhook payload
- assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
- assert.Equal(t, "completed", webhookData.payloads[1].Action)
- assert.Equal(t, "push", webhookData.payloads[1].WorkflowRun.Event)
- assert.Equal(t, "completed", webhookData.payloads[1].WorkflowRun.Status)
- assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[1].WorkflowRun.HeadBranch)
- assert.Equal(t, commitID, webhookData.payloads[1].WorkflowRun.HeadSha)
- assert.Equal(t, "repo1", webhookData.payloads[1].Repo.Name)
- assert.Equal(t, "user2/repo1", webhookData.payloads[1].Repo.FullName)
- }
-
- func testWorkflowRunEventsOnRerun(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)
-
- runners := make([]*mockRunner, 2)
- for i := range runners {
- runners[i] = newMockRunner()
- runners[i].registerAsRepoRunner(t, "user2", "repo1", fmt.Sprintf("mock-runner-%d", i), []string{"ubuntu-latest"}, false)
- }
-
- 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.2 trigger the webhooks
-
- // add workflow file to the repo
- // init the workflow
- wfTreePath := ".gitea/workflows/push.yml"
- wfFileContent := `on:
- push:
- workflow_dispatch:
-
- jobs:
- test:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test2:
- needs: [test]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test3:
- needs: [test, test2]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test4:
- needs: [test, test2, test3]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test5:
- needs: [test, test2, test4]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test6:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
- needs: [test, test2, test3]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test7:
- needs: test6
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test8:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test9:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, ubuntu-25.04, windows-2022, windows-2025, macos-13, macos-14, macos-15]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test10:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0`
- 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)
-
- for _, runner := range runners {
- task := runner.fetchTask(t)
- runner.execTask(t, task, &mockTaskOutcome{
- result: runnerv1.Result_RESULT_SUCCESS,
- })
- }
-
- // Call cancel ui api
- // Only a web UI API exists for cancelling workflow runs, so use the UI endpoint.
- cancelURL := fmt.Sprintf("/user2/repo1/actions/runs/%d/cancel", webhookData.payloads[0].WorkflowRun.RunNumber)
- req := NewRequestWithValues(t, "POST", cancelURL, map[string]string{
- "_csrf": GetUserCSRFToken(t, session),
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- assert.Len(t, webhookData.payloads, 2)
-
- // 4. Validate the second webhook payload
- assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
- assert.Equal(t, "completed", webhookData.payloads[1].Action)
- assert.Equal(t, "push", webhookData.payloads[1].WorkflowRun.Event)
- assert.Equal(t, "completed", webhookData.payloads[1].WorkflowRun.Status)
- assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[1].WorkflowRun.HeadBranch)
- assert.Equal(t, commitID, webhookData.payloads[1].WorkflowRun.HeadSha)
- assert.Equal(t, "repo1", webhookData.payloads[1].Repo.Name)
- assert.Equal(t, "user2/repo1", webhookData.payloads[1].Repo.FullName)
-
- // Call rerun ui api
- // Only a web UI API exists for cancelling workflow runs, so use the UI endpoint.
- rerunURL := fmt.Sprintf("/user2/repo1/actions/runs/%d/rerun", webhookData.payloads[0].WorkflowRun.RunNumber)
- req = NewRequestWithValues(t, "POST", rerunURL, map[string]string{
- "_csrf": GetUserCSRFToken(t, session),
- })
- session.MakeRequest(t, req, http.StatusOK)
-
- assert.Len(t, webhookData.payloads, 3)
- }
-
- func testWorkflowRunEventsOnCancellingAbandonedRun(t *testing.T, webhookData *workflowRunWebhook, allJobsAbandoned bool) {
- defer test.MockVariableValue(&setting.Actions.AbandonedJobTimeout, 0*time.Nanosecond)()
-
- // 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)
-
- repoName := "test-workflow-run-cancelling-abandoned-run"
- testRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: createActionsTestRepo(t, token, repoName, false).ID})
-
- runners := make([]*mockRunner, 2)
- for i := range runners {
- runners[i] = newMockRunner()
- runners[i].registerAsRepoRunner(t, "user2", repoName,
- fmt.Sprintf("mock-runner-%d", i), []string{"ubuntu-latest"}, false)
- }
-
- testAPICreateWebhookForRepo(t, session, "user2", repoName, webhookData.URL, "workflow_run")
-
- ctx := t.Context()
- gitRepo, err := gitrepo.OpenRepository(ctx, testRepo)
- assert.NoError(t, err)
-
- // 2.2 trigger the webhooks
-
- // add workflow file to the repo
- // init the workflow
- wfilename := "push.yml"
- wfTreePath := ".gitea/workflows/" + wfilename
- wfFileContent := `on:
- push:
- workflow_dispatch:
-
- jobs:
- test:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test2:
- needs: [test]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test3:
- needs: [test, test2]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test4:
- needs: [test, test2, test3]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test5:
- needs: [test, test2, test4]
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test6:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
- needs: [test, test2, test3]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test7:
- needs: test6
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test8:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0
-
- test9:
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, ubuntu-25.04, windows-2022, windows-2025, macos-13, macos-14, macos-15]
- runs-on: ${{ matrix.os }}
- steps:
- - run: exit 0
-
- test10:
- runs-on: ubuntu-latest
- steps:
- - run: exit 0`
-
- opts := getWorkflowCreateFileOptions(user2, testRepo.DefaultBranch, "create "+wfTreePath, wfFileContent)
- createWorkflowFile(t, token, "user2", repoName, wfTreePath, opts)
-
- commitID, err := gitRepo.GetBranchCommitID(testRepo.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, testRepo.DefaultBranch, webhookData.payloads[0].WorkflowRun.HeadBranch)
- assert.Equal(t, commitID, webhookData.payloads[0].WorkflowRun.HeadSha)
- assert.Equal(t, repoName, webhookData.payloads[0].Repo.Name)
- assert.Equal(t, "user2/"+repoName, webhookData.payloads[0].Repo.FullName)
-
- if !allJobsAbandoned {
- for _, runner := range runners {
- task := runner.fetchTask(t)
- runner.execTask(t, task, &mockTaskOutcome{
- result: runnerv1.Result_RESULT_SUCCESS,
- })
- }
- }
-
- // Add this sleep to ensure the func can find the tasks by timestamp.
- time.Sleep(time.Second)
-
- err = actions.CancelAbandonedJobs(ctx)
- assert.NoError(t, err)
- assert.Len(t, webhookData.payloads, 2)
- assert.Equal(t, "completed", webhookData.payloads[1].Action)
- assert.Equal(t, "completed", webhookData.payloads[1].WorkflowRun.Status)
- assert.Equal(t, testRepo.DefaultBranch, webhookData.payloads[1].WorkflowRun.HeadBranch)
- assert.Equal(t, commitID, webhookData.payloads[1].WorkflowRun.HeadSha)
- assert.Equal(t, repoName, webhookData.payloads[1].Repo.Name)
- assert.Equal(t, "user2/"+repoName, webhookData.payloads[1].Repo.FullName)
- }
-
- 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)
- }
- }
|