gitea源码

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "encoding/base64"
  6. "fmt"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "testing"
  11. "time"
  12. actions_model "code.gitea.io/gitea/models/actions"
  13. auth_model "code.gitea.io/gitea/models/auth"
  14. "code.gitea.io/gitea/models/db"
  15. git_model "code.gitea.io/gitea/models/git"
  16. issues_model "code.gitea.io/gitea/models/issues"
  17. "code.gitea.io/gitea/models/perm"
  18. repo_model "code.gitea.io/gitea/models/repo"
  19. "code.gitea.io/gitea/models/unittest"
  20. user_model "code.gitea.io/gitea/models/user"
  21. actions_module "code.gitea.io/gitea/modules/actions"
  22. "code.gitea.io/gitea/modules/commitstatus"
  23. "code.gitea.io/gitea/modules/git"
  24. "code.gitea.io/gitea/modules/gitrepo"
  25. "code.gitea.io/gitea/modules/json"
  26. "code.gitea.io/gitea/modules/setting"
  27. api "code.gitea.io/gitea/modules/structs"
  28. "code.gitea.io/gitea/modules/test"
  29. "code.gitea.io/gitea/modules/timeutil"
  30. "code.gitea.io/gitea/modules/util"
  31. issue_service "code.gitea.io/gitea/services/issue"
  32. pull_service "code.gitea.io/gitea/services/pull"
  33. release_service "code.gitea.io/gitea/services/release"
  34. repo_service "code.gitea.io/gitea/services/repository"
  35. commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
  36. files_service "code.gitea.io/gitea/services/repository/files"
  37. "github.com/stretchr/testify/assert"
  38. )
  39. func TestPullRequestTargetEvent(t *testing.T) {
  40. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  41. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo
  42. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of the forked repo
  43. // create the base repo
  44. baseRepo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  45. Name: "repo-pull-request-target",
  46. Description: "test pull-request-target event",
  47. AutoInit: true,
  48. Gitignores: "Go",
  49. License: "MIT",
  50. Readme: "Default",
  51. DefaultBranch: "main",
  52. IsPrivate: false,
  53. })
  54. assert.NoError(t, err)
  55. assert.NotEmpty(t, baseRepo)
  56. // add user4 as the collaborator
  57. ctx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository)
  58. t.Run("AddUser4AsCollaboratorWithReadAccess", doAPIAddCollaborator(ctx, "user4", perm.AccessModeRead))
  59. // create the forked repo
  60. forkedRepo, err := repo_service.ForkRepository(t.Context(), user2, user4, repo_service.ForkRepoOptions{
  61. BaseRepo: baseRepo,
  62. Name: "forked-repo-pull-request-target",
  63. Description: "test pull-request-target event",
  64. })
  65. assert.NoError(t, err)
  66. assert.NotEmpty(t, forkedRepo)
  67. // add workflow file to the base repo
  68. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), baseRepo, user2, &files_service.ChangeRepoFilesOptions{
  69. Files: []*files_service.ChangeRepoFile{
  70. {
  71. Operation: "create",
  72. TreePath: ".gitea/workflows/pr.yml",
  73. ContentReader: strings.NewReader(`name: test
  74. on:
  75. pull_request_target:
  76. paths:
  77. - 'file_*.txt'
  78. jobs:
  79. test:
  80. runs-on: ubuntu-latest
  81. steps:
  82. - run: echo helloworld
  83. `),
  84. },
  85. },
  86. Message: "add workflow",
  87. OldBranch: "main",
  88. NewBranch: "main",
  89. Author: &files_service.IdentityOptions{
  90. GitUserName: user2.Name,
  91. GitUserEmail: user2.Email,
  92. },
  93. Committer: &files_service.IdentityOptions{
  94. GitUserName: user2.Name,
  95. GitUserEmail: user2.Email,
  96. },
  97. Dates: &files_service.CommitDateOptions{
  98. Author: time.Now(),
  99. Committer: time.Now(),
  100. },
  101. })
  102. assert.NoError(t, err)
  103. assert.NotEmpty(t, addWorkflowToBaseResp)
  104. // add a new file to the forked repo
  105. addFileToForkedResp, err := files_service.ChangeRepoFiles(t.Context(), forkedRepo, user4, &files_service.ChangeRepoFilesOptions{
  106. Files: []*files_service.ChangeRepoFile{
  107. {
  108. Operation: "create",
  109. TreePath: "file_1.txt",
  110. ContentReader: strings.NewReader("file1"),
  111. },
  112. },
  113. Message: "add file1",
  114. OldBranch: "main",
  115. NewBranch: "fork-branch-1",
  116. Author: &files_service.IdentityOptions{
  117. GitUserName: user4.Name,
  118. GitUserEmail: user4.Email,
  119. },
  120. Committer: &files_service.IdentityOptions{
  121. GitUserName: user4.Name,
  122. GitUserEmail: user4.Email,
  123. },
  124. Dates: &files_service.CommitDateOptions{
  125. Author: time.Now(),
  126. Committer: time.Now(),
  127. },
  128. })
  129. assert.NoError(t, err)
  130. assert.NotEmpty(t, addFileToForkedResp)
  131. // create Pull
  132. pullIssue := &issues_model.Issue{
  133. RepoID: baseRepo.ID,
  134. Title: "Test pull-request-target-event",
  135. PosterID: user4.ID,
  136. Poster: user4,
  137. IsPull: true,
  138. }
  139. pullRequest := &issues_model.PullRequest{
  140. HeadRepoID: forkedRepo.ID,
  141. BaseRepoID: baseRepo.ID,
  142. HeadBranch: "fork-branch-1",
  143. BaseBranch: "main",
  144. HeadRepo: forkedRepo,
  145. BaseRepo: baseRepo,
  146. Type: issues_model.PullRequestGitea,
  147. }
  148. prOpts := &pull_service.NewPullRequestOptions{Repo: baseRepo, Issue: pullIssue, PullRequest: pullRequest}
  149. err = pull_service.NewPullRequest(t.Context(), prOpts)
  150. assert.NoError(t, err)
  151. // load and compare ActionRun
  152. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}))
  153. actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID})
  154. assert.Equal(t, addFileToForkedResp.Commit.SHA, actionRun.CommitSHA)
  155. assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent)
  156. // add another file whose name cannot match the specified path
  157. addFileToForkedResp, err = files_service.ChangeRepoFiles(t.Context(), forkedRepo, user4, &files_service.ChangeRepoFilesOptions{
  158. Files: []*files_service.ChangeRepoFile{
  159. {
  160. Operation: "create",
  161. TreePath: "foo.txt",
  162. ContentReader: strings.NewReader("foo"),
  163. },
  164. },
  165. Message: "add foo.txt",
  166. OldBranch: "main",
  167. NewBranch: "fork-branch-2",
  168. Author: &files_service.IdentityOptions{
  169. GitUserName: user4.Name,
  170. GitUserEmail: user4.Email,
  171. },
  172. Committer: &files_service.IdentityOptions{
  173. GitUserName: user4.Name,
  174. GitUserEmail: user4.Email,
  175. },
  176. Dates: &files_service.CommitDateOptions{
  177. Author: time.Now(),
  178. Committer: time.Now(),
  179. },
  180. })
  181. assert.NoError(t, err)
  182. assert.NotEmpty(t, addFileToForkedResp)
  183. // create Pull
  184. pullIssue = &issues_model.Issue{
  185. RepoID: baseRepo.ID,
  186. Title: "A mismatched path cannot trigger pull-request-target-event",
  187. PosterID: user4.ID,
  188. Poster: user4,
  189. IsPull: true,
  190. }
  191. pullRequest = &issues_model.PullRequest{
  192. HeadRepoID: forkedRepo.ID,
  193. BaseRepoID: baseRepo.ID,
  194. HeadBranch: "fork-branch-2",
  195. BaseBranch: "main",
  196. HeadRepo: forkedRepo,
  197. BaseRepo: baseRepo,
  198. Type: issues_model.PullRequestGitea,
  199. }
  200. prOpts = &pull_service.NewPullRequestOptions{Repo: baseRepo, Issue: pullIssue, PullRequest: pullRequest}
  201. err = pull_service.NewPullRequest(t.Context(), prOpts)
  202. assert.NoError(t, err)
  203. // the new pull request cannot trigger actions, so there is still only 1 record
  204. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}))
  205. })
  206. }
  207. func TestSkipCI(t *testing.T) {
  208. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  209. session := loginUser(t, "user2")
  210. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  211. // create the repo
  212. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  213. Name: "skip-ci",
  214. Description: "test skip ci functionality",
  215. AutoInit: true,
  216. Gitignores: "Go",
  217. License: "MIT",
  218. Readme: "Default",
  219. DefaultBranch: "master",
  220. IsPrivate: false,
  221. })
  222. assert.NoError(t, err)
  223. assert.NotEmpty(t, repo)
  224. // add workflow file to the repo
  225. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  226. Files: []*files_service.ChangeRepoFile{
  227. {
  228. Operation: "create",
  229. TreePath: ".gitea/workflows/pr.yml",
  230. ContentReader: strings.NewReader(`name: test
  231. on:
  232. push:
  233. branches: [master]
  234. pull_request:
  235. jobs:
  236. test:
  237. runs-on: ubuntu-latest
  238. steps:
  239. - run: echo helloworld
  240. `),
  241. },
  242. },
  243. Message: "add workflow",
  244. OldBranch: "master",
  245. NewBranch: "master",
  246. Author: &files_service.IdentityOptions{
  247. GitUserName: user2.Name,
  248. GitUserEmail: user2.Email,
  249. },
  250. Committer: &files_service.IdentityOptions{
  251. GitUserName: user2.Name,
  252. GitUserEmail: user2.Email,
  253. },
  254. Dates: &files_service.CommitDateOptions{
  255. Author: time.Now(),
  256. Committer: time.Now(),
  257. },
  258. })
  259. assert.NoError(t, err)
  260. assert.NotEmpty(t, addWorkflowToBaseResp)
  261. // a run has been created
  262. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
  263. // add a file with a configured skip-ci string in commit message
  264. addFileResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  265. Files: []*files_service.ChangeRepoFile{
  266. {
  267. Operation: "create",
  268. TreePath: "bar.txt",
  269. ContentReader: strings.NewReader("bar"),
  270. },
  271. },
  272. Message: setting.Actions.SkipWorkflowStrings[0] + " add bar",
  273. OldBranch: "master",
  274. NewBranch: "master",
  275. Author: &files_service.IdentityOptions{
  276. GitUserName: user2.Name,
  277. GitUserEmail: user2.Email,
  278. },
  279. Committer: &files_service.IdentityOptions{
  280. GitUserName: user2.Name,
  281. GitUserEmail: user2.Email,
  282. },
  283. Dates: &files_service.CommitDateOptions{
  284. Author: time.Now(),
  285. Committer: time.Now(),
  286. },
  287. })
  288. assert.NoError(t, err)
  289. assert.NotEmpty(t, addFileResp)
  290. // the commit message contains a configured skip-ci string, so there is still only 1 record
  291. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
  292. // add file to new branch
  293. addFileToBranchResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  294. Files: []*files_service.ChangeRepoFile{
  295. {
  296. Operation: "create",
  297. TreePath: "test-skip-ci",
  298. ContentReader: strings.NewReader("test-skip-ci"),
  299. },
  300. },
  301. Message: "add test file",
  302. OldBranch: "master",
  303. NewBranch: "test-skip-ci",
  304. Author: &files_service.IdentityOptions{
  305. GitUserName: user2.Name,
  306. GitUserEmail: user2.Email,
  307. },
  308. Committer: &files_service.IdentityOptions{
  309. GitUserName: user2.Name,
  310. GitUserEmail: user2.Email,
  311. },
  312. Dates: &files_service.CommitDateOptions{
  313. Author: time.Now(),
  314. Committer: time.Now(),
  315. },
  316. })
  317. assert.NoError(t, err)
  318. assert.NotEmpty(t, addFileToBranchResp)
  319. resp := testPullCreate(t, session, "user2", "skip-ci", true, "master", "test-skip-ci", "[skip ci] test-skip-ci")
  320. // check the redirected URL
  321. url := test.RedirectURL(resp)
  322. assert.Regexp(t, "^/user2/skip-ci/pulls/[0-9]*$", url)
  323. // the pr title contains a configured skip-ci string, so there is still only 1 record
  324. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
  325. })
  326. }
  327. func TestCreateDeleteRefEvent(t *testing.T) {
  328. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  329. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  330. // create the repo
  331. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  332. Name: "create-delete-ref-event",
  333. Description: "test create delete ref ci event",
  334. AutoInit: true,
  335. Gitignores: "Go",
  336. License: "MIT",
  337. Readme: "Default",
  338. DefaultBranch: "main",
  339. IsPrivate: false,
  340. })
  341. assert.NoError(t, err)
  342. assert.NotEmpty(t, repo)
  343. // add workflow file to the repo
  344. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  345. Files: []*files_service.ChangeRepoFile{
  346. {
  347. Operation: "create",
  348. TreePath: ".gitea/workflows/createdelete.yml",
  349. ContentReader: strings.NewReader(`name: test
  350. on:
  351. [create,delete]
  352. jobs:
  353. test:
  354. runs-on: ubuntu-latest
  355. steps:
  356. - run: echo helloworld
  357. `),
  358. },
  359. },
  360. Message: "add workflow",
  361. OldBranch: "main",
  362. NewBranch: "main",
  363. Author: &files_service.IdentityOptions{
  364. GitUserName: user2.Name,
  365. GitUserEmail: user2.Email,
  366. },
  367. Committer: &files_service.IdentityOptions{
  368. GitUserName: user2.Name,
  369. GitUserEmail: user2.Email,
  370. },
  371. Dates: &files_service.CommitDateOptions{
  372. Author: time.Now(),
  373. Committer: time.Now(),
  374. },
  375. })
  376. assert.NoError(t, err)
  377. assert.NotEmpty(t, addWorkflowToBaseResp)
  378. // Get the commit ID of the default branch
  379. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  380. assert.NoError(t, err)
  381. defer gitRepo.Close()
  382. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  383. assert.NoError(t, err)
  384. // create a branch
  385. err = repo_service.CreateNewBranchFromCommit(t.Context(), user2, repo, gitRepo, branch.CommitID, "test-create-branch")
  386. assert.NoError(t, err)
  387. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  388. Title: "add workflow",
  389. RepoID: repo.ID,
  390. Event: "create",
  391. Ref: "refs/heads/test-create-branch",
  392. WorkflowID: "createdelete.yml",
  393. CommitSHA: branch.CommitID,
  394. })
  395. assert.NotNil(t, run)
  396. // create a tag
  397. err = release_service.CreateNewTag(t.Context(), user2, repo, branch.CommitID, "test-create-tag", "test create tag event")
  398. assert.NoError(t, err)
  399. run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  400. Title: "add workflow",
  401. RepoID: repo.ID,
  402. Event: "create",
  403. Ref: "refs/tags/test-create-tag",
  404. WorkflowID: "createdelete.yml",
  405. CommitSHA: branch.CommitID,
  406. })
  407. assert.NotNil(t, run)
  408. // delete the branch
  409. err = repo_service.DeleteBranch(t.Context(), user2, repo, gitRepo, "test-create-branch", nil)
  410. assert.NoError(t, err)
  411. run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  412. Title: "add workflow",
  413. RepoID: repo.ID,
  414. Event: "delete",
  415. Ref: "refs/heads/main",
  416. WorkflowID: "createdelete.yml",
  417. CommitSHA: branch.CommitID,
  418. })
  419. assert.NotNil(t, run)
  420. // delete the tag
  421. tag, err := repo_model.GetRelease(t.Context(), repo.ID, "test-create-tag")
  422. assert.NoError(t, err)
  423. err = release_service.DeleteReleaseByID(t.Context(), repo, tag, user2, true)
  424. assert.NoError(t, err)
  425. run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  426. Title: "add workflow",
  427. RepoID: repo.ID,
  428. Event: "delete",
  429. Ref: "refs/heads/main",
  430. WorkflowID: "createdelete.yml",
  431. CommitSHA: branch.CommitID,
  432. })
  433. assert.NotNil(t, run)
  434. })
  435. }
  436. func TestPullRequestCommitStatusEvent(t *testing.T) {
  437. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  438. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo
  439. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // contributor of the repo
  440. // create a repo
  441. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  442. Name: "repo-pull-request",
  443. Description: "test pull-request event",
  444. AutoInit: true,
  445. Gitignores: "Go",
  446. License: "MIT",
  447. Readme: "Default",
  448. DefaultBranch: "main",
  449. IsPrivate: false,
  450. })
  451. assert.NoError(t, err)
  452. assert.NotEmpty(t, repo)
  453. // add user4 as the collaborator
  454. ctx := NewAPITestContext(t, repo.OwnerName, repo.Name, auth_model.AccessTokenScopeWriteRepository)
  455. t.Run("AddUser4AsCollaboratorWithReadAccess", doAPIAddCollaborator(ctx, "user4", perm.AccessModeRead))
  456. // add the workflow file to the repo
  457. addWorkflow, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  458. Files: []*files_service.ChangeRepoFile{
  459. {
  460. Operation: "create",
  461. TreePath: ".gitea/workflows/pr.yml",
  462. ContentReader: strings.NewReader(`name: test
  463. on:
  464. pull_request:
  465. types: [assigned, unassigned, labeled, unlabeled, opened, edited, closed, reopened, synchronize, milestoned, demilestoned, review_requested, review_request_removed]
  466. jobs:
  467. test:
  468. runs-on: ubuntu-latest
  469. steps:
  470. - run: echo helloworld
  471. `),
  472. },
  473. },
  474. Message: "add workflow",
  475. OldBranch: "main",
  476. NewBranch: "main",
  477. Author: &files_service.IdentityOptions{
  478. GitUserName: user2.Name,
  479. GitUserEmail: user2.Email,
  480. },
  481. Committer: &files_service.IdentityOptions{
  482. GitUserName: user2.Name,
  483. GitUserEmail: user2.Email,
  484. },
  485. Dates: &files_service.CommitDateOptions{
  486. Author: time.Now(),
  487. Committer: time.Now(),
  488. },
  489. })
  490. assert.NoError(t, err)
  491. assert.NotEmpty(t, addWorkflow)
  492. sha := addWorkflow.Commit.SHA
  493. // create a new branch
  494. testBranch := "test-branch"
  495. gitRepo, err := git.OpenRepository(t.Context(), ".")
  496. assert.NoError(t, err)
  497. err = repo_service.CreateNewBranch(t.Context(), user2, repo, gitRepo, "main", testBranch)
  498. assert.NoError(t, err)
  499. // create Pull
  500. pullIssue := &issues_model.Issue{
  501. RepoID: repo.ID,
  502. Title: "A test PR",
  503. PosterID: user2.ID,
  504. Poster: user2,
  505. IsPull: true,
  506. }
  507. pullRequest := &issues_model.PullRequest{
  508. HeadRepoID: repo.ID,
  509. BaseRepoID: repo.ID,
  510. HeadBranch: testBranch,
  511. BaseBranch: "main",
  512. HeadRepo: repo,
  513. BaseRepo: repo,
  514. Type: issues_model.PullRequestGitea,
  515. }
  516. prOpts := &pull_service.NewPullRequestOptions{Repo: repo, Issue: pullIssue, PullRequest: pullRequest}
  517. err = pull_service.NewPullRequest(t.Context(), prOpts)
  518. assert.NoError(t, err)
  519. // opened
  520. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  521. // edited
  522. err = issue_service.ChangeContent(t.Context(), pullIssue, user2, "test", 0)
  523. assert.NoError(t, err)
  524. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  525. // closed
  526. err = issue_service.CloseIssue(t.Context(), pullIssue, user2, "")
  527. assert.NoError(t, err)
  528. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  529. // reopened
  530. err = issue_service.ReopenIssue(t.Context(), pullIssue, user2, "")
  531. assert.NoError(t, err)
  532. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  533. // assign
  534. removed, _, err := issue_service.ToggleAssigneeWithNotify(t.Context(), pullIssue, user2, user4.ID)
  535. assert.False(t, removed)
  536. assert.NoError(t, err)
  537. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  538. // unassign
  539. removed, _, err = issue_service.ToggleAssigneeWithNotify(t.Context(), pullIssue, user2, user4.ID)
  540. assert.True(t, removed)
  541. assert.NoError(t, err)
  542. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  543. // labeled
  544. label := &issues_model.Label{
  545. RepoID: repo.ID,
  546. Name: "test",
  547. Exclusive: false,
  548. Description: "test",
  549. Color: "#e11d21",
  550. }
  551. err = issues_model.NewLabel(t.Context(), label)
  552. assert.NoError(t, err)
  553. err = issue_service.AddLabel(t.Context(), pullIssue, user2, label)
  554. assert.NoError(t, err)
  555. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  556. // unlabeled
  557. err = issue_service.RemoveLabel(t.Context(), pullIssue, user2, label)
  558. assert.NoError(t, err)
  559. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  560. // synchronize
  561. addFileResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  562. Files: []*files_service.ChangeRepoFile{
  563. {
  564. Operation: "create",
  565. TreePath: "test.txt",
  566. ContentReader: strings.NewReader("test"),
  567. },
  568. },
  569. Message: "add file",
  570. OldBranch: testBranch,
  571. NewBranch: testBranch,
  572. Author: &files_service.IdentityOptions{
  573. GitUserName: user2.Name,
  574. GitUserEmail: user2.Email,
  575. },
  576. Committer: &files_service.IdentityOptions{
  577. GitUserName: user2.Name,
  578. GitUserEmail: user2.Email,
  579. },
  580. Dates: &files_service.CommitDateOptions{
  581. Author: time.Now(),
  582. Committer: time.Now(),
  583. },
  584. })
  585. assert.NoError(t, err)
  586. assert.NotEmpty(t, addFileResp)
  587. sha = addFileResp.Commit.SHA
  588. assert.Eventually(t, func() bool {
  589. latestCommitStatuses, err := git_model.GetLatestCommitStatus(t.Context(), repo.ID, sha, db.ListOptionsAll)
  590. assert.NoError(t, err)
  591. if len(latestCommitStatuses) == 0 {
  592. return false
  593. }
  594. if latestCommitStatuses[0].State == commitstatus.CommitStatusPending {
  595. insertFakeStatus(t, repo, sha, latestCommitStatuses[0].TargetURL, latestCommitStatuses[0].Context)
  596. return true
  597. }
  598. return false
  599. }, 1*time.Second, 100*time.Millisecond)
  600. // milestoned
  601. milestone := &issues_model.Milestone{
  602. RepoID: repo.ID,
  603. Name: "test",
  604. Content: "test",
  605. DeadlineUnix: timeutil.TimeStampNow(),
  606. }
  607. err = issues_model.NewMilestone(t.Context(), milestone)
  608. assert.NoError(t, err)
  609. err = issue_service.ChangeMilestoneAssign(t.Context(), pullIssue, user2, milestone.ID)
  610. assert.NoError(t, err)
  611. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  612. // demilestoned
  613. err = issue_service.ChangeMilestoneAssign(t.Context(), pullIssue, user2, milestone.ID)
  614. assert.NoError(t, err)
  615. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  616. // review_requested
  617. _, err = issue_service.ReviewRequest(t.Context(), pullIssue, user2, nil, user4, true)
  618. assert.NoError(t, err)
  619. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  620. // review_request_removed
  621. _, err = issue_service.ReviewRequest(t.Context(), pullIssue, user2, nil, user4, false)
  622. assert.NoError(t, err)
  623. checkCommitStatusAndInsertFakeStatus(t, repo, sha)
  624. })
  625. }
  626. func checkCommitStatusAndInsertFakeStatus(t *testing.T, repo *repo_model.Repository, sha string) {
  627. latestCommitStatuses, err := git_model.GetLatestCommitStatus(t.Context(), repo.ID, sha, db.ListOptionsAll)
  628. assert.NoError(t, err)
  629. assert.Len(t, latestCommitStatuses, 1)
  630. assert.Equal(t, commitstatus.CommitStatusPending, latestCommitStatuses[0].State)
  631. insertFakeStatus(t, repo, sha, latestCommitStatuses[0].TargetURL, latestCommitStatuses[0].Context)
  632. }
  633. func insertFakeStatus(t *testing.T, repo *repo_model.Repository, sha, targetURL, context string) {
  634. err := commitstatus_service.CreateCommitStatus(t.Context(), repo, user_model.NewActionsUser(), sha, &git_model.CommitStatus{
  635. State: commitstatus.CommitStatusSuccess,
  636. TargetURL: targetURL,
  637. Context: context,
  638. })
  639. assert.NoError(t, err)
  640. }
  641. func TestWorkflowDispatchPublicApi(t *testing.T) {
  642. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  643. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  644. session := loginUser(t, user2.Name)
  645. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  646. // create the repo
  647. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  648. Name: "workflow-dispatch-event",
  649. Description: "test workflow-dispatch ci event",
  650. AutoInit: true,
  651. Gitignores: "Go",
  652. License: "MIT",
  653. Readme: "Default",
  654. DefaultBranch: "main",
  655. IsPrivate: false,
  656. })
  657. assert.NoError(t, err)
  658. assert.NotEmpty(t, repo)
  659. // add workflow file to the repo
  660. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  661. Files: []*files_service.ChangeRepoFile{
  662. {
  663. Operation: "create",
  664. TreePath: ".gitea/workflows/dispatch.yml",
  665. ContentReader: strings.NewReader(`
  666. on:
  667. workflow_dispatch
  668. jobs:
  669. test:
  670. runs-on: ubuntu-latest
  671. steps:
  672. - run: echo helloworld
  673. `),
  674. },
  675. },
  676. Message: "add workflow",
  677. OldBranch: "main",
  678. NewBranch: "main",
  679. Author: &files_service.IdentityOptions{
  680. GitUserName: user2.Name,
  681. GitUserEmail: user2.Email,
  682. },
  683. Committer: &files_service.IdentityOptions{
  684. GitUserName: user2.Name,
  685. GitUserEmail: user2.Email,
  686. },
  687. Dates: &files_service.CommitDateOptions{
  688. Author: time.Now(),
  689. Committer: time.Now(),
  690. },
  691. })
  692. assert.NoError(t, err)
  693. assert.NotEmpty(t, addWorkflowToBaseResp)
  694. // Get the commit ID of the default branch
  695. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  696. assert.NoError(t, err)
  697. defer gitRepo.Close()
  698. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  699. assert.NoError(t, err)
  700. values := url.Values{}
  701. values.Set("ref", "main")
  702. req := NewRequestWithURLValues(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), values).
  703. AddTokenAuth(token)
  704. _ = MakeRequest(t, req, http.StatusNoContent)
  705. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  706. Title: "add workflow",
  707. RepoID: repo.ID,
  708. Event: "workflow_dispatch",
  709. Ref: "refs/heads/main",
  710. WorkflowID: "dispatch.yml",
  711. CommitSHA: branch.CommitID,
  712. })
  713. assert.NotNil(t, run)
  714. })
  715. }
  716. func TestWorkflowDispatchPublicApiWithInputs(t *testing.T) {
  717. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  718. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  719. session := loginUser(t, user2.Name)
  720. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  721. // create the repo
  722. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  723. Name: "workflow-dispatch-event",
  724. Description: "test workflow-dispatch ci event",
  725. AutoInit: true,
  726. Gitignores: "Go",
  727. License: "MIT",
  728. Readme: "Default",
  729. DefaultBranch: "main",
  730. IsPrivate: false,
  731. })
  732. assert.NoError(t, err)
  733. assert.NotEmpty(t, repo)
  734. // add workflow file to the repo
  735. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  736. Files: []*files_service.ChangeRepoFile{
  737. {
  738. Operation: "create",
  739. TreePath: ".gitea/workflows/dispatch.yml",
  740. ContentReader: strings.NewReader(`
  741. on:
  742. workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
  743. jobs:
  744. test:
  745. runs-on: ubuntu-latest
  746. steps:
  747. - run: echo helloworld
  748. `),
  749. },
  750. },
  751. Message: "add workflow",
  752. OldBranch: "main",
  753. NewBranch: "main",
  754. Author: &files_service.IdentityOptions{
  755. GitUserName: user2.Name,
  756. GitUserEmail: user2.Email,
  757. },
  758. Committer: &files_service.IdentityOptions{
  759. GitUserName: user2.Name,
  760. GitUserEmail: user2.Email,
  761. },
  762. Dates: &files_service.CommitDateOptions{
  763. Author: time.Now(),
  764. Committer: time.Now(),
  765. },
  766. })
  767. assert.NoError(t, err)
  768. assert.NotEmpty(t, addWorkflowToBaseResp)
  769. // Get the commit ID of the default branch
  770. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  771. assert.NoError(t, err)
  772. defer gitRepo.Close()
  773. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  774. assert.NoError(t, err)
  775. values := url.Values{}
  776. values.Set("ref", "main")
  777. values.Set("inputs[myinput]", "val0")
  778. values.Set("inputs[myinput3]", "true")
  779. req := NewRequestWithURLValues(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), values).
  780. AddTokenAuth(token)
  781. _ = MakeRequest(t, req, http.StatusNoContent)
  782. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  783. Title: "add workflow",
  784. RepoID: repo.ID,
  785. Event: "workflow_dispatch",
  786. Ref: "refs/heads/main",
  787. WorkflowID: "dispatch.yml",
  788. CommitSHA: branch.CommitID,
  789. })
  790. assert.NotNil(t, run)
  791. dispatchPayload := &api.WorkflowDispatchPayload{}
  792. err = json.Unmarshal([]byte(run.EventPayload), dispatchPayload)
  793. assert.NoError(t, err)
  794. assert.Contains(t, dispatchPayload.Inputs, "myinput")
  795. assert.Contains(t, dispatchPayload.Inputs, "myinput2")
  796. assert.Contains(t, dispatchPayload.Inputs, "myinput3")
  797. assert.Equal(t, "val0", dispatchPayload.Inputs["myinput"])
  798. assert.Equal(t, "def2", dispatchPayload.Inputs["myinput2"])
  799. assert.Equal(t, "true", dispatchPayload.Inputs["myinput3"])
  800. })
  801. }
  802. func TestWorkflowDispatchPublicApiJSON(t *testing.T) {
  803. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  804. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  805. session := loginUser(t, user2.Name)
  806. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  807. // create the repo
  808. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  809. Name: "workflow-dispatch-event",
  810. Description: "test workflow-dispatch ci event",
  811. AutoInit: true,
  812. Gitignores: "Go",
  813. License: "MIT",
  814. Readme: "Default",
  815. DefaultBranch: "main",
  816. IsPrivate: false,
  817. })
  818. assert.NoError(t, err)
  819. assert.NotEmpty(t, repo)
  820. // add workflow file to the repo
  821. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  822. Files: []*files_service.ChangeRepoFile{
  823. {
  824. Operation: "create",
  825. TreePath: ".gitea/workflows/dispatch.yml",
  826. ContentReader: strings.NewReader(`
  827. on:
  828. workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
  829. jobs:
  830. test:
  831. runs-on: ubuntu-latest
  832. steps:
  833. - run: echo helloworld
  834. `),
  835. },
  836. },
  837. Message: "add workflow",
  838. OldBranch: "main",
  839. NewBranch: "main",
  840. Author: &files_service.IdentityOptions{
  841. GitUserName: user2.Name,
  842. GitUserEmail: user2.Email,
  843. },
  844. Committer: &files_service.IdentityOptions{
  845. GitUserName: user2.Name,
  846. GitUserEmail: user2.Email,
  847. },
  848. Dates: &files_service.CommitDateOptions{
  849. Author: time.Now(),
  850. Committer: time.Now(),
  851. },
  852. })
  853. assert.NoError(t, err)
  854. assert.NotEmpty(t, addWorkflowToBaseResp)
  855. // Get the commit ID of the default branch
  856. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  857. assert.NoError(t, err)
  858. defer gitRepo.Close()
  859. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  860. assert.NoError(t, err)
  861. inputs := &api.CreateActionWorkflowDispatch{
  862. Ref: "main",
  863. Inputs: map[string]string{
  864. "myinput": "val0",
  865. "myinput3": "true",
  866. },
  867. }
  868. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), inputs).
  869. AddTokenAuth(token)
  870. _ = MakeRequest(t, req, http.StatusNoContent)
  871. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  872. Title: "add workflow",
  873. RepoID: repo.ID,
  874. Event: "workflow_dispatch",
  875. Ref: "refs/heads/main",
  876. WorkflowID: "dispatch.yml",
  877. CommitSHA: branch.CommitID,
  878. })
  879. assert.NotNil(t, run)
  880. })
  881. }
  882. func TestWorkflowDispatchPublicApiWithInputsJSON(t *testing.T) {
  883. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  884. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  885. session := loginUser(t, user2.Name)
  886. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  887. // create the repo
  888. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  889. Name: "workflow-dispatch-event",
  890. Description: "test workflow-dispatch ci event",
  891. AutoInit: true,
  892. Gitignores: "Go",
  893. License: "MIT",
  894. Readme: "Default",
  895. DefaultBranch: "main",
  896. IsPrivate: false,
  897. })
  898. assert.NoError(t, err)
  899. assert.NotEmpty(t, repo)
  900. // add workflow file to the repo
  901. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  902. Files: []*files_service.ChangeRepoFile{
  903. {
  904. Operation: "create",
  905. TreePath: ".gitea/workflows/dispatch.yml",
  906. ContentReader: strings.NewReader(`
  907. on:
  908. workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
  909. jobs:
  910. test:
  911. runs-on: ubuntu-latest
  912. steps:
  913. - run: echo helloworld
  914. `),
  915. },
  916. },
  917. Message: "add workflow",
  918. OldBranch: "main",
  919. NewBranch: "main",
  920. Author: &files_service.IdentityOptions{
  921. GitUserName: user2.Name,
  922. GitUserEmail: user2.Email,
  923. },
  924. Committer: &files_service.IdentityOptions{
  925. GitUserName: user2.Name,
  926. GitUserEmail: user2.Email,
  927. },
  928. Dates: &files_service.CommitDateOptions{
  929. Author: time.Now(),
  930. Committer: time.Now(),
  931. },
  932. })
  933. assert.NoError(t, err)
  934. assert.NotEmpty(t, addWorkflowToBaseResp)
  935. // Get the commit ID of the default branch
  936. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  937. assert.NoError(t, err)
  938. defer gitRepo.Close()
  939. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  940. assert.NoError(t, err)
  941. inputs := &api.CreateActionWorkflowDispatch{
  942. Ref: "main",
  943. Inputs: map[string]string{
  944. "myinput": "val0",
  945. "myinput3": "true",
  946. },
  947. }
  948. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), inputs).
  949. AddTokenAuth(token)
  950. _ = MakeRequest(t, req, http.StatusNoContent)
  951. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  952. Title: "add workflow",
  953. RepoID: repo.ID,
  954. Event: "workflow_dispatch",
  955. Ref: "refs/heads/main",
  956. WorkflowID: "dispatch.yml",
  957. CommitSHA: branch.CommitID,
  958. })
  959. assert.NotNil(t, run)
  960. dispatchPayload := &api.WorkflowDispatchPayload{}
  961. err = json.Unmarshal([]byte(run.EventPayload), dispatchPayload)
  962. assert.NoError(t, err)
  963. assert.Contains(t, dispatchPayload.Inputs, "myinput")
  964. assert.Contains(t, dispatchPayload.Inputs, "myinput2")
  965. assert.Contains(t, dispatchPayload.Inputs, "myinput3")
  966. assert.Equal(t, "val0", dispatchPayload.Inputs["myinput"])
  967. assert.Equal(t, "def2", dispatchPayload.Inputs["myinput2"])
  968. assert.Equal(t, "true", dispatchPayload.Inputs["myinput3"])
  969. })
  970. }
  971. func TestWorkflowDispatchPublicApiWithInputsNonDefaultBranchJSON(t *testing.T) {
  972. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  973. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  974. session := loginUser(t, user2.Name)
  975. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  976. // create the repo
  977. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  978. Name: "workflow-dispatch-event",
  979. Description: "test workflow-dispatch ci event",
  980. AutoInit: true,
  981. Gitignores: "Go",
  982. License: "MIT",
  983. Readme: "Default",
  984. DefaultBranch: "main",
  985. IsPrivate: false,
  986. })
  987. assert.NoError(t, err)
  988. assert.NotEmpty(t, repo)
  989. // add workflow file to the repo
  990. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  991. Files: []*files_service.ChangeRepoFile{
  992. {
  993. Operation: "create",
  994. TreePath: ".gitea/workflows/dispatch.yml",
  995. ContentReader: strings.NewReader(`
  996. on:
  997. workflow_dispatch
  998. jobs:
  999. test:
  1000. runs-on: ubuntu-latest
  1001. steps:
  1002. - run: echo helloworld
  1003. `),
  1004. },
  1005. },
  1006. Message: "add workflow",
  1007. OldBranch: "main",
  1008. NewBranch: "main",
  1009. Author: &files_service.IdentityOptions{
  1010. GitUserName: user2.Name,
  1011. GitUserEmail: user2.Email,
  1012. },
  1013. Committer: &files_service.IdentityOptions{
  1014. GitUserName: user2.Name,
  1015. GitUserEmail: user2.Email,
  1016. },
  1017. Dates: &files_service.CommitDateOptions{
  1018. Author: time.Now(),
  1019. Committer: time.Now(),
  1020. },
  1021. })
  1022. assert.NoError(t, err)
  1023. assert.NotEmpty(t, addWorkflowToBaseResp)
  1024. // add workflow file to the repo
  1025. addWorkflowToBaseResp, err = files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  1026. Files: []*files_service.ChangeRepoFile{
  1027. {
  1028. Operation: "update",
  1029. TreePath: ".gitea/workflows/dispatch.yml",
  1030. ContentReader: strings.NewReader(`
  1031. on:
  1032. workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
  1033. jobs:
  1034. test:
  1035. runs-on: ubuntu-latest
  1036. steps:
  1037. - run: echo helloworld
  1038. `),
  1039. },
  1040. },
  1041. Message: "add workflow",
  1042. OldBranch: "main",
  1043. NewBranch: "dispatch",
  1044. Author: &files_service.IdentityOptions{
  1045. GitUserName: user2.Name,
  1046. GitUserEmail: user2.Email,
  1047. },
  1048. Committer: &files_service.IdentityOptions{
  1049. GitUserName: user2.Name,
  1050. GitUserEmail: user2.Email,
  1051. },
  1052. Dates: &files_service.CommitDateOptions{
  1053. Author: time.Now(),
  1054. Committer: time.Now(),
  1055. },
  1056. })
  1057. assert.NoError(t, err)
  1058. assert.NotEmpty(t, addWorkflowToBaseResp)
  1059. // Get the commit ID of the dispatch branch
  1060. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  1061. assert.NoError(t, err)
  1062. defer gitRepo.Close()
  1063. commit, err := gitRepo.GetBranchCommit("dispatch")
  1064. assert.NoError(t, err)
  1065. inputs := &api.CreateActionWorkflowDispatch{
  1066. Ref: "refs/heads/dispatch",
  1067. Inputs: map[string]string{
  1068. "myinput": "val0",
  1069. "myinput3": "true",
  1070. },
  1071. }
  1072. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), inputs).
  1073. AddTokenAuth(token)
  1074. _ = MakeRequest(t, req, http.StatusNoContent)
  1075. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  1076. Title: "add workflow",
  1077. RepoID: repo.ID,
  1078. Repo: repo,
  1079. Event: "workflow_dispatch",
  1080. Ref: "refs/heads/dispatch",
  1081. WorkflowID: "dispatch.yml",
  1082. CommitSHA: commit.ID.String(),
  1083. })
  1084. assert.NotNil(t, run)
  1085. dispatchPayload := &api.WorkflowDispatchPayload{}
  1086. err = json.Unmarshal([]byte(run.EventPayload), dispatchPayload)
  1087. assert.NoError(t, err)
  1088. assert.Contains(t, dispatchPayload.Inputs, "myinput")
  1089. assert.Contains(t, dispatchPayload.Inputs, "myinput2")
  1090. assert.Contains(t, dispatchPayload.Inputs, "myinput3")
  1091. assert.Equal(t, "val0", dispatchPayload.Inputs["myinput"])
  1092. assert.Equal(t, "def2", dispatchPayload.Inputs["myinput2"])
  1093. assert.Equal(t, "true", dispatchPayload.Inputs["myinput3"])
  1094. })
  1095. }
  1096. func TestWorkflowApi(t *testing.T) {
  1097. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  1098. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  1099. session := loginUser(t, user2.Name)
  1100. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  1101. // create the repo
  1102. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  1103. Name: "workflow-api",
  1104. Description: "test workflow apis",
  1105. AutoInit: true,
  1106. Gitignores: "Go",
  1107. License: "MIT",
  1108. Readme: "Default",
  1109. DefaultBranch: "main",
  1110. IsPrivate: false,
  1111. })
  1112. assert.NoError(t, err)
  1113. assert.NotEmpty(t, repo)
  1114. req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/actions/workflows", repo.FullName())).
  1115. AddTokenAuth(token)
  1116. resp := MakeRequest(t, req, http.StatusOK)
  1117. workflows := &api.ActionWorkflowResponse{}
  1118. json.NewDecoder(resp.Body).Decode(workflows)
  1119. assert.Empty(t, workflows.Workflows)
  1120. // add workflow file to the repo
  1121. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  1122. Files: []*files_service.ChangeRepoFile{
  1123. {
  1124. Operation: "create",
  1125. TreePath: ".gitea/workflows/dispatch.yml",
  1126. ContentReader: strings.NewReader(`
  1127. on:
  1128. workflow_dispatch: { inputs: { myinput: { default: def }, myinput2: { default: def2 }, myinput3: { type: boolean, default: false } } }
  1129. jobs:
  1130. test:
  1131. runs-on: ubuntu-latest
  1132. steps:
  1133. - run: echo helloworld
  1134. `),
  1135. },
  1136. },
  1137. Message: "add workflow",
  1138. OldBranch: "main",
  1139. NewBranch: "main",
  1140. Author: &files_service.IdentityOptions{
  1141. GitUserName: user2.Name,
  1142. GitUserEmail: user2.Email,
  1143. },
  1144. Committer: &files_service.IdentityOptions{
  1145. GitUserName: user2.Name,
  1146. GitUserEmail: user2.Email,
  1147. },
  1148. Dates: &files_service.CommitDateOptions{
  1149. Author: time.Now(),
  1150. Committer: time.Now(),
  1151. },
  1152. })
  1153. assert.NoError(t, err)
  1154. assert.NotEmpty(t, addWorkflowToBaseResp)
  1155. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/actions/workflows", repo.FullName())).
  1156. AddTokenAuth(token)
  1157. resp = MakeRequest(t, req, http.StatusOK)
  1158. json.NewDecoder(resp.Body).Decode(workflows)
  1159. assert.Len(t, workflows.Workflows, 1)
  1160. assert.Equal(t, "dispatch.yml", workflows.Workflows[0].Name)
  1161. assert.Equal(t, ".gitea/workflows/dispatch.yml", workflows.Workflows[0].Path)
  1162. assert.Equal(t, ".gitea/workflows/dispatch.yml", workflows.Workflows[0].Path)
  1163. assert.Equal(t, "active", workflows.Workflows[0].State)
  1164. // Use a hardcoded api path
  1165. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/%s", repo.FullName(), workflows.Workflows[0].ID)).
  1166. AddTokenAuth(token)
  1167. resp = MakeRequest(t, req, http.StatusOK)
  1168. workflow := &api.ActionWorkflow{}
  1169. json.NewDecoder(resp.Body).Decode(workflow)
  1170. assert.Equal(t, workflows.Workflows[0].ID, workflow.ID)
  1171. assert.Equal(t, workflows.Workflows[0].Path, workflow.Path)
  1172. assert.Equal(t, workflows.Workflows[0].URL, workflow.URL)
  1173. assert.Equal(t, workflows.Workflows[0].HTMLURL, workflow.HTMLURL)
  1174. assert.Equal(t, workflows.Workflows[0].Name, workflow.Name)
  1175. assert.Equal(t, workflows.Workflows[0].State, workflow.State)
  1176. // Use the provided url instead of the hardcoded one
  1177. req = NewRequest(t, "GET", workflows.Workflows[0].URL).
  1178. AddTokenAuth(token)
  1179. resp = MakeRequest(t, req, http.StatusOK)
  1180. workflow = &api.ActionWorkflow{}
  1181. json.NewDecoder(resp.Body).Decode(workflow)
  1182. assert.Equal(t, workflows.Workflows[0].ID, workflow.ID)
  1183. assert.Equal(t, workflows.Workflows[0].Path, workflow.Path)
  1184. assert.Equal(t, workflows.Workflows[0].URL, workflow.URL)
  1185. assert.Equal(t, workflows.Workflows[0].HTMLURL, workflow.HTMLURL)
  1186. assert.Equal(t, workflows.Workflows[0].Name, workflow.Name)
  1187. assert.Equal(t, workflows.Workflows[0].State, workflow.State)
  1188. // Disable the workflow
  1189. req = NewRequest(t, "PUT", workflows.Workflows[0].URL+"/disable").
  1190. AddTokenAuth(token)
  1191. _ = MakeRequest(t, req, http.StatusNoContent)
  1192. // Use the provided url instead of the hardcoded one
  1193. req = NewRequest(t, "GET", workflows.Workflows[0].URL).
  1194. AddTokenAuth(token)
  1195. resp = MakeRequest(t, req, http.StatusOK)
  1196. workflow = &api.ActionWorkflow{}
  1197. json.NewDecoder(resp.Body).Decode(workflow)
  1198. assert.Equal(t, workflows.Workflows[0].ID, workflow.ID)
  1199. assert.Equal(t, workflows.Workflows[0].Path, workflow.Path)
  1200. assert.Equal(t, workflows.Workflows[0].URL, workflow.URL)
  1201. assert.Equal(t, workflows.Workflows[0].HTMLURL, workflow.HTMLURL)
  1202. assert.Equal(t, workflows.Workflows[0].Name, workflow.Name)
  1203. assert.Equal(t, "disabled_manually", workflow.State)
  1204. inputs := &api.CreateActionWorkflowDispatch{
  1205. Ref: "main",
  1206. Inputs: map[string]string{
  1207. "myinput": "val0",
  1208. "myinput3": "true",
  1209. },
  1210. }
  1211. // Since the workflow is disabled, so the response code is 403 forbidden
  1212. req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), inputs).
  1213. AddTokenAuth(token)
  1214. _ = MakeRequest(t, req, http.StatusForbidden)
  1215. // Enable the workflow again
  1216. req = NewRequest(t, "PUT", workflows.Workflows[0].URL+"/enable").
  1217. AddTokenAuth(token)
  1218. _ = MakeRequest(t, req, http.StatusNoContent)
  1219. // Use the provided url instead of the hardcoded one
  1220. req = NewRequest(t, "GET", workflows.Workflows[0].URL).
  1221. AddTokenAuth(token)
  1222. resp = MakeRequest(t, req, http.StatusOK)
  1223. workflow = &api.ActionWorkflow{}
  1224. json.NewDecoder(resp.Body).Decode(workflow)
  1225. assert.Equal(t, workflows.Workflows[0].ID, workflow.ID)
  1226. assert.Equal(t, workflows.Workflows[0].Path, workflow.Path)
  1227. assert.Equal(t, workflows.Workflows[0].URL, workflow.URL)
  1228. assert.Equal(t, workflows.Workflows[0].HTMLURL, workflow.HTMLURL)
  1229. assert.Equal(t, workflows.Workflows[0].Name, workflow.Name)
  1230. assert.Equal(t, workflows.Workflows[0].State, workflow.State)
  1231. req = NewRequest(t, "GET", workflows.Workflows[0].URL).
  1232. AddTokenAuth(token)
  1233. resp = MakeRequest(t, req, http.StatusOK)
  1234. workflow = &api.ActionWorkflow{}
  1235. json.NewDecoder(resp.Body).Decode(workflow)
  1236. assert.Equal(t, workflows.Workflows[0].ID, workflow.ID)
  1237. assert.Equal(t, workflows.Workflows[0].Path, workflow.Path)
  1238. assert.Equal(t, workflows.Workflows[0].URL, workflow.URL)
  1239. assert.Equal(t, workflows.Workflows[0].HTMLURL, workflow.HTMLURL)
  1240. assert.Equal(t, workflows.Workflows[0].Name, workflow.Name)
  1241. assert.Equal(t, workflows.Workflows[0].State, workflow.State)
  1242. // Get the commit ID of the default branch
  1243. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  1244. assert.NoError(t, err)
  1245. defer gitRepo.Close()
  1246. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  1247. assert.NoError(t, err)
  1248. inputs = &api.CreateActionWorkflowDispatch{
  1249. Ref: "main",
  1250. Inputs: map[string]string{
  1251. "myinput": "val0",
  1252. "myinput3": "true",
  1253. },
  1254. }
  1255. req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), inputs).
  1256. AddTokenAuth(token)
  1257. _ = MakeRequest(t, req, http.StatusNoContent)
  1258. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  1259. Title: "add workflow",
  1260. RepoID: repo.ID,
  1261. Event: "workflow_dispatch",
  1262. Ref: "refs/heads/main",
  1263. WorkflowID: "dispatch.yml",
  1264. CommitSHA: branch.CommitID,
  1265. })
  1266. assert.NotNil(t, run)
  1267. dispatchPayload := &api.WorkflowDispatchPayload{}
  1268. err = json.Unmarshal([]byte(run.EventPayload), dispatchPayload)
  1269. assert.NoError(t, err)
  1270. assert.Contains(t, dispatchPayload.Inputs, "myinput")
  1271. assert.Contains(t, dispatchPayload.Inputs, "myinput2")
  1272. assert.Contains(t, dispatchPayload.Inputs, "myinput3")
  1273. assert.Equal(t, "val0", dispatchPayload.Inputs["myinput"])
  1274. assert.Equal(t, "def2", dispatchPayload.Inputs["myinput2"])
  1275. assert.Equal(t, "true", dispatchPayload.Inputs["myinput3"])
  1276. })
  1277. }
  1278. func TestClosePullRequestWithPath(t *testing.T) {
  1279. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  1280. // user2 is the owner of the base repo
  1281. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  1282. user2Token := getTokenForLoggedInUser(t, loginUser(t, user2.Name), auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
  1283. // user4 is the owner of the fork repo
  1284. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  1285. user4Token := getTokenForLoggedInUser(t, loginUser(t, user4.Name), auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
  1286. // create the base repo
  1287. apiBaseRepo := createActionsTestRepo(t, user2Token, "close-pull-request-with-path", false)
  1288. baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiBaseRepo.ID})
  1289. user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository)
  1290. // init the workflow
  1291. wfTreePath := ".gitea/workflows/pull.yml"
  1292. wfFileContent := `name: Pull Request
  1293. on:
  1294. pull_request:
  1295. types:
  1296. - closed
  1297. paths:
  1298. - 'app/**'
  1299. jobs:
  1300. echo:
  1301. runs-on: ubuntu-latest
  1302. steps:
  1303. - run: echo 'Hello World'
  1304. `
  1305. opts1 := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create "+wfTreePath, wfFileContent)
  1306. createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wfTreePath, opts1)
  1307. // user4 forks the repo
  1308. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks", baseRepo.OwnerName, baseRepo.Name),
  1309. &api.CreateForkOption{
  1310. Name: util.ToPointer("close-pull-request-with-path-fork"),
  1311. }).AddTokenAuth(user4Token)
  1312. resp := MakeRequest(t, req, http.StatusAccepted)
  1313. var apiForkRepo api.Repository
  1314. DecodeJSON(t, resp, &apiForkRepo)
  1315. forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiForkRepo.ID})
  1316. user4APICtx := NewAPITestContext(t, user4.Name, forkRepo.Name, auth_model.AccessTokenScopeWriteRepository)
  1317. // user4 creates a pull request to add file "app/main.go"
  1318. doAPICreateFile(user4APICtx, "app/main.go", &api.CreateFileOptions{
  1319. FileOptions: api.FileOptions{
  1320. NewBranchName: "user4/add-main",
  1321. Message: "create main.go",
  1322. Author: api.Identity{
  1323. Name: user4.Name,
  1324. Email: user4.Email,
  1325. },
  1326. Committer: api.Identity{
  1327. Name: user4.Name,
  1328. Email: user4.Email,
  1329. },
  1330. Dates: api.CommitDateOptions{
  1331. Author: time.Now(),
  1332. Committer: time.Now(),
  1333. },
  1334. },
  1335. ContentBase64: base64.StdEncoding.EncodeToString([]byte("// main.go")),
  1336. })(t)
  1337. apiPull, err := doAPICreatePullRequest(user4APICtx, baseRepo.OwnerName, baseRepo.Name, baseRepo.DefaultBranch, user4.Name+":user4/add-main")(t)
  1338. assert.NoError(t, err)
  1339. doAPIMergePullRequest(user2APICtx, baseRepo.OwnerName, baseRepo.Name, apiPull.Index)(t)
  1340. pullRequest := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: apiPull.ID})
  1341. // load and compare ActionRun
  1342. assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}))
  1343. actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID})
  1344. assert.Equal(t, actions_module.GithubEventPullRequest, actionRun.TriggerEvent)
  1345. assert.Equal(t, pullRequest.MergedCommitID, actionRun.CommitSHA)
  1346. })
  1347. }
  1348. func TestActionRunNameWithContextVariables(t *testing.T) {
  1349. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  1350. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  1351. // create the repo
  1352. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  1353. Name: "action-run-name-with-variables",
  1354. Description: "test action run name",
  1355. AutoInit: true,
  1356. Gitignores: "Go",
  1357. License: "MIT",
  1358. Readme: "Default",
  1359. DefaultBranch: "main",
  1360. IsPrivate: false,
  1361. })
  1362. assert.NoError(t, err)
  1363. assert.NotEmpty(t, repo)
  1364. // add workflow file to the repo
  1365. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  1366. Files: []*files_service.ChangeRepoFile{
  1367. {
  1368. Operation: "create",
  1369. TreePath: ".gitea/workflows/runname.yml",
  1370. ContentReader: strings.NewReader(`name: test
  1371. on:
  1372. [create,delete]
  1373. run-name: ${{ gitea.actor }} is running this workflow
  1374. jobs:
  1375. test:
  1376. runs-on: ubuntu-latest
  1377. steps:
  1378. - run: echo helloworld
  1379. `),
  1380. },
  1381. },
  1382. Message: "add workflow with run-name",
  1383. OldBranch: "main",
  1384. NewBranch: "main",
  1385. Author: &files_service.IdentityOptions{
  1386. GitUserName: user2.Name,
  1387. GitUserEmail: user2.Email,
  1388. },
  1389. Committer: &files_service.IdentityOptions{
  1390. GitUserName: user2.Name,
  1391. GitUserEmail: user2.Email,
  1392. },
  1393. Dates: &files_service.CommitDateOptions{
  1394. Author: time.Now(),
  1395. Committer: time.Now(),
  1396. },
  1397. })
  1398. assert.NoError(t, err)
  1399. assert.NotEmpty(t, addWorkflowToBaseResp)
  1400. // Get the commit ID of the default branch
  1401. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  1402. assert.NoError(t, err)
  1403. defer gitRepo.Close()
  1404. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  1405. assert.NoError(t, err)
  1406. // create a branch
  1407. err = repo_service.CreateNewBranchFromCommit(t.Context(), user2, repo, gitRepo, branch.CommitID, "test-action-run-name-with-variables")
  1408. assert.NoError(t, err)
  1409. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  1410. Title: user2.LoginName + " is running this workflow",
  1411. RepoID: repo.ID,
  1412. Event: "create",
  1413. Ref: "refs/heads/test-action-run-name-with-variables",
  1414. WorkflowID: "runname.yml",
  1415. CommitSHA: branch.CommitID,
  1416. })
  1417. assert.NotNil(t, run)
  1418. })
  1419. }
  1420. func TestActionRunName(t *testing.T) {
  1421. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  1422. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  1423. // create the repo
  1424. repo, err := repo_service.CreateRepository(t.Context(), user2, user2, repo_service.CreateRepoOptions{
  1425. Name: "action-run-name",
  1426. Description: "test action run-name",
  1427. AutoInit: true,
  1428. Gitignores: "Go",
  1429. License: "MIT",
  1430. Readme: "Default",
  1431. DefaultBranch: "main",
  1432. IsPrivate: false,
  1433. })
  1434. assert.NoError(t, err)
  1435. assert.NotEmpty(t, repo)
  1436. // add workflow file to the repo
  1437. addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(t.Context(), repo, user2, &files_service.ChangeRepoFilesOptions{
  1438. Files: []*files_service.ChangeRepoFile{
  1439. {
  1440. Operation: "create",
  1441. TreePath: ".gitea/workflows/runname.yml",
  1442. ContentReader: strings.NewReader(`name: test
  1443. on:
  1444. [create,delete]
  1445. run-name: run name without variables
  1446. jobs:
  1447. test:
  1448. runs-on: ubuntu-latest
  1449. steps:
  1450. - run: echo helloworld
  1451. `),
  1452. },
  1453. },
  1454. Message: "add workflow with run name",
  1455. OldBranch: "main",
  1456. NewBranch: "main",
  1457. Author: &files_service.IdentityOptions{
  1458. GitUserName: user2.Name,
  1459. GitUserEmail: user2.Email,
  1460. },
  1461. Committer: &files_service.IdentityOptions{
  1462. GitUserName: user2.Name,
  1463. GitUserEmail: user2.Email,
  1464. },
  1465. Dates: &files_service.CommitDateOptions{
  1466. Author: time.Now(),
  1467. Committer: time.Now(),
  1468. },
  1469. })
  1470. assert.NoError(t, err)
  1471. assert.NotEmpty(t, addWorkflowToBaseResp)
  1472. // Get the commit ID of the default branch
  1473. gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
  1474. assert.NoError(t, err)
  1475. defer gitRepo.Close()
  1476. branch, err := git_model.GetBranch(t.Context(), repo.ID, repo.DefaultBranch)
  1477. assert.NoError(t, err)
  1478. // create a branch
  1479. err = repo_service.CreateNewBranchFromCommit(t.Context(), user2, repo, gitRepo, branch.CommitID, "test-action-run-name")
  1480. assert.NoError(t, err)
  1481. run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
  1482. Title: "run name without variables",
  1483. RepoID: repo.ID,
  1484. Event: "create",
  1485. Ref: "refs/heads/test-action-run-name",
  1486. WorkflowID: "runname.yml",
  1487. CommitSHA: branch.CommitID,
  1488. })
  1489. assert.NotNil(t, run)
  1490. })
  1491. }