loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add API endpoints for getting action jobs status (#26673)

Sample of response, it is similar to Github actions

ref
https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository

``` json
{
"workflow_runs": [
{
"id": 3,
"name": "Explore-Gitea-Actions",
"head_branch": "main",
"head_sha": "6d8d29a9f7a01ded8f8aeb64341cb31ee1ab5f19",
"run_number": 3,
"event": "push",
"display_title": "More job",
"status": "success",
"workflow_id": "demo2.yaml",
"url": "/chester/test/actions/runs/3",
"created_at": "2023-08-22T13:41:33-04:00",
"updated_at": "2023-08-22T13:41:37-04:00",
"run_started_at": "2023-08-22T13:41:33-04:00"
},
{
"id": 2,
"name": "Explore-Gitea-Actions",
"head_branch": "main",
"head_sha": "6d8d29a9f7a01ded8f8aeb64341cb31ee1ab5f19",
"run_number": 2,
"event": "push",
"display_title": "More job",
"status": "success",
"workflow_id": "demo.yaml",
"url": "/chester/test/actions/runs/2",
"created_at": "2023-08-22T13:41:30-04:00",
"updated_at": "2023-08-22T13:41:33-04:00",
"run_started_at": "2023-08-22T13:41:30-04:00"
},
{
"id": 1,
"name": "Explore-Gitea-Actions",
"head_branch": "main",
"head_sha": "e5369ab054cae79899ba36e45ee82811a6e0acd5",
"run_number": 1,
"event": "push",
"display_title": "Add job",
"status": "failure",
"workflow_id": "demo.yaml",
"url": "/chester/test/actions/runs/1",
"created_at": "2023-08-22T13:15:21-04:00",
"updated_at": "2023-08-22T13:18:10-04:00",
"run_started_at": "2023-08-22T13:15:21-04:00"
}
],
"total_count": 3
}
```

---------

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: puni9869 <80308335+puni9869@users.noreply.github.com>
(cherry picked from commit 6709e28da78a0ea7e63f9fe4e32f620abdc88d14)

Conflicts:
routers/api/v1/swagger/repo.go
trivial context conflict

authored by

Chester
yp05327
puni9869
and committed by
Earl Warren
1a40fe54 9792a377

+300
+34
modules/structs/repo_actions.go
··· 1 + // Copyright 2023 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package structs 5 + 6 + import ( 7 + "time" 8 + ) 9 + 10 + // ActionTask represents a ActionTask 11 + type ActionTask struct { 12 + ID int64 `json:"id"` 13 + Name string `json:"name"` 14 + HeadBranch string `json:"head_branch"` 15 + HeadSHA string `json:"head_sha"` 16 + RunNumber int64 `json:"run_number"` 17 + Event string `json:"event"` 18 + DisplayTitle string `json:"display_title"` 19 + Status string `json:"status"` 20 + WorkflowID string `json:"workflow_id"` 21 + URL string `json:"url"` 22 + // swagger:strfmt date-time 23 + CreatedAt time.Time `json:"created_at"` 24 + // swagger:strfmt date-time 25 + UpdatedAt time.Time `json:"updated_at"` 26 + // swagger:strfmt date-time 27 + RunStartedAt time.Time `json:"run_started_at"` 28 + } 29 + 30 + // ActionTaskResponse returns a ActionTask 31 + type ActionTaskResponse struct { 32 + Entries []*ActionTask `json:"workflow_runs"` 33 + TotalCount int64 `json:"total_count"` 34 + }
+3
routers/api/v1/api.go
··· 1103 1103 m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateTagOption{}), repo.CreateTag) 1104 1104 m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteTag) 1105 1105 }, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true)) 1106 + m.Group("/actions", func() { 1107 + m.Get("/tasks", repo.ListActionTasks) 1108 + }, reqRepoReader(unit.TypeActions), context.ReferencesGitRepo(true)) 1106 1109 m.Group("/keys", func() { 1107 1110 m.Combo("").Get(repo.ListDeployKeys). 1108 1111 Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
+80
routers/api/v1/repo/actions.go
··· 1 + // Copyright 2023 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package repo 5 + 6 + import ( 7 + "net/http" 8 + 9 + actions_model "code.gitea.io/gitea/models/actions" 10 + "code.gitea.io/gitea/models/db" 11 + api "code.gitea.io/gitea/modules/structs" 12 + "code.gitea.io/gitea/routers/api/v1/utils" 13 + "code.gitea.io/gitea/services/context" 14 + "code.gitea.io/gitea/services/convert" 15 + ) 16 + 17 + // ListActionTasks list all the actions of a repository 18 + func ListActionTasks(ctx *context.APIContext) { 19 + // swagger:operation GET /repos/{owner}/{repo}/actions/tasks repository ListActionTasks 20 + // --- 21 + // summary: List a repository's action tasks 22 + // produces: 23 + // - application/json 24 + // parameters: 25 + // - name: owner 26 + // in: path 27 + // description: owner of the repo 28 + // type: string 29 + // required: true 30 + // - name: repo 31 + // in: path 32 + // description: name of the repo 33 + // type: string 34 + // required: true 35 + // - name: page 36 + // in: query 37 + // description: page number of results to return (1-based) 38 + // type: integer 39 + // - name: limit 40 + // in: query 41 + // description: page size of results, default maximum page size is 50 42 + // type: integer 43 + // responses: 44 + // "200": 45 + // "$ref": "#/responses/TasksList" 46 + // "400": 47 + // "$ref": "#/responses/error" 48 + // "403": 49 + // "$ref": "#/responses/forbidden" 50 + // "404": 51 + // "$ref": "#/responses/notFound" 52 + // "409": 53 + // "$ref": "#/responses/conflict" 54 + // "422": 55 + // "$ref": "#/responses/validationError" 56 + 57 + tasks, total, err := db.FindAndCount[actions_model.ActionTask](ctx, &actions_model.FindTaskOptions{ 58 + ListOptions: utils.GetListOptions(ctx), 59 + RepoID: ctx.Repo.Repository.ID, 60 + }) 61 + if err != nil { 62 + ctx.Error(http.StatusInternalServerError, "ListActionTasks", err) 63 + return 64 + } 65 + 66 + res := new(api.ActionTaskResponse) 67 + res.TotalCount = total 68 + 69 + res.Entries = make([]*api.ActionTask, len(tasks)) 70 + for i := range tasks { 71 + convertedTask, err := convert.ToActionTask(ctx, tasks[i]) 72 + if err != nil { 73 + ctx.Error(http.StatusInternalServerError, "ToActionTask", err) 74 + return 75 + } 76 + res.Entries[i] = convertedTask 77 + } 78 + 79 + ctx.JSON(http.StatusOK, &res) 80 + }
+7
routers/api/v1/swagger/repo.go
··· 422 422 Body []api.BlockedUser `json:"body"` 423 423 } 424 424 425 + // TasksList 426 + // swagger:response TasksList 427 + type swaggerRepoTasksList struct { 428 + // in:body 429 + Body api.ActionTaskResponse `json:"body"` 430 + } 431 + 425 432 // swagger:response Compare 426 433 type swaggerCompare struct { 427 434 // in:body
+27
services/convert/convert.go
··· 11 11 "strings" 12 12 "time" 13 13 14 + actions_model "code.gitea.io/gitea/models/actions" 14 15 asymkey_model "code.gitea.io/gitea/models/asymkey" 15 16 "code.gitea.io/gitea/models/auth" 16 17 git_model "code.gitea.io/gitea/models/git" ··· 24 25 "code.gitea.io/gitea/modules/container" 25 26 "code.gitea.io/gitea/modules/git" 26 27 "code.gitea.io/gitea/modules/log" 28 + "code.gitea.io/gitea/modules/setting" 27 29 api "code.gitea.io/gitea/modules/structs" 28 30 "code.gitea.io/gitea/modules/util" 29 31 "code.gitea.io/gitea/services/gitdiff" ··· 193 195 TarballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".tar.gz"), 194 196 ArchiveDownloadCount: t.ArchiveDownloadCount, 195 197 } 198 + } 199 + 200 + // ToActionTask convert a actions_model.ActionTask to an api.ActionTask 201 + func ToActionTask(ctx context.Context, t *actions_model.ActionTask) (*api.ActionTask, error) { 202 + if err := t.LoadAttributes(ctx); err != nil { 203 + return nil, err 204 + } 205 + 206 + url := strings.TrimSuffix(setting.AppURL, "/") + t.GetRunLink() 207 + 208 + return &api.ActionTask{ 209 + ID: t.ID, 210 + Name: t.Job.Name, 211 + HeadBranch: t.Job.Run.PrettyRef(), 212 + HeadSHA: t.Job.CommitSHA, 213 + RunNumber: t.Job.Run.Index, 214 + Event: t.Job.Run.TriggerEvent, 215 + DisplayTitle: t.Job.Run.Title, 216 + Status: t.Status.String(), 217 + WorkflowID: t.Job.Run.WorkflowID, 218 + URL: url, 219 + CreatedAt: t.Created.AsLocalTime(), 220 + UpdatedAt: t.Updated.AsLocalTime(), 221 + RunStartedAt: t.Started.AsLocalTime(), 222 + }, nil 196 223 } 197 224 198 225 // ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification
+149
templates/swagger/v1_json.tmpl
··· 3865 3865 } 3866 3866 } 3867 3867 }, 3868 + "/repos/{owner}/{repo}/actions/tasks": { 3869 + "get": { 3870 + "produces": [ 3871 + "application/json" 3872 + ], 3873 + "tags": [ 3874 + "repository" 3875 + ], 3876 + "summary": "List a repository's action tasks", 3877 + "operationId": "ListActionTasks", 3878 + "parameters": [ 3879 + { 3880 + "type": "string", 3881 + "description": "owner of the repo", 3882 + "name": "owner", 3883 + "in": "path", 3884 + "required": true 3885 + }, 3886 + { 3887 + "type": "string", 3888 + "description": "name of the repo", 3889 + "name": "repo", 3890 + "in": "path", 3891 + "required": true 3892 + }, 3893 + { 3894 + "type": "integer", 3895 + "description": "page number of results to return (1-based)", 3896 + "name": "page", 3897 + "in": "query" 3898 + }, 3899 + { 3900 + "type": "integer", 3901 + "description": "page size of results, default maximum page size is 50", 3902 + "name": "limit", 3903 + "in": "query" 3904 + } 3905 + ], 3906 + "responses": { 3907 + "200": { 3908 + "$ref": "#/responses/TasksList" 3909 + }, 3910 + "400": { 3911 + "$ref": "#/responses/error" 3912 + }, 3913 + "403": { 3914 + "$ref": "#/responses/forbidden" 3915 + }, 3916 + "404": { 3917 + "$ref": "#/responses/notFound" 3918 + }, 3919 + "409": { 3920 + "$ref": "#/responses/conflict" 3921 + }, 3922 + "422": { 3923 + "$ref": "#/responses/validationError" 3924 + } 3925 + } 3926 + } 3927 + }, 3868 3928 "/repos/{owner}/{repo}/actions/variables": { 3869 3929 "get": { 3870 3930 "produces": [ ··· 18253 18313 }, 18254 18314 "x-go-package": "code.gitea.io/gitea/modules/structs" 18255 18315 }, 18316 + "ActionTask": { 18317 + "description": "ActionTask represents a ActionTask", 18318 + "type": "object", 18319 + "properties": { 18320 + "created_at": { 18321 + "type": "string", 18322 + "format": "date-time", 18323 + "x-go-name": "CreatedAt" 18324 + }, 18325 + "display_title": { 18326 + "type": "string", 18327 + "x-go-name": "DisplayTitle" 18328 + }, 18329 + "event": { 18330 + "type": "string", 18331 + "x-go-name": "Event" 18332 + }, 18333 + "head_branch": { 18334 + "type": "string", 18335 + "x-go-name": "HeadBranch" 18336 + }, 18337 + "head_sha": { 18338 + "type": "string", 18339 + "x-go-name": "HeadSHA" 18340 + }, 18341 + "id": { 18342 + "type": "integer", 18343 + "format": "int64", 18344 + "x-go-name": "ID" 18345 + }, 18346 + "name": { 18347 + "type": "string", 18348 + "x-go-name": "Name" 18349 + }, 18350 + "run_number": { 18351 + "type": "integer", 18352 + "format": "int64", 18353 + "x-go-name": "RunNumber" 18354 + }, 18355 + "run_started_at": { 18356 + "type": "string", 18357 + "format": "date-time", 18358 + "x-go-name": "RunStartedAt" 18359 + }, 18360 + "status": { 18361 + "type": "string", 18362 + "x-go-name": "Status" 18363 + }, 18364 + "updated_at": { 18365 + "type": "string", 18366 + "format": "date-time", 18367 + "x-go-name": "UpdatedAt" 18368 + }, 18369 + "url": { 18370 + "type": "string", 18371 + "x-go-name": "URL" 18372 + }, 18373 + "workflow_id": { 18374 + "type": "string", 18375 + "x-go-name": "WorkflowID" 18376 + } 18377 + }, 18378 + "x-go-package": "code.gitea.io/gitea/modules/structs" 18379 + }, 18380 + "ActionTaskResponse": { 18381 + "description": "ActionTaskResponse returns a ActionTask", 18382 + "type": "object", 18383 + "properties": { 18384 + "total_count": { 18385 + "type": "integer", 18386 + "format": "int64", 18387 + "x-go-name": "TotalCount" 18388 + }, 18389 + "workflow_runs": { 18390 + "type": "array", 18391 + "items": { 18392 + "$ref": "#/definitions/ActionTask" 18393 + }, 18394 + "x-go-name": "Entries" 18395 + } 18396 + }, 18397 + "x-go-package": "code.gitea.io/gitea/modules/structs" 18398 + }, 18256 18399 "ActionVariable": { 18257 18400 "description": "ActionVariable return value of the query API", 18258 18401 "type": "object", ··· 25829 25972 "items": { 25830 25973 "$ref": "#/definitions/Tag" 25831 25974 } 25975 + } 25976 + }, 25977 + "TasksList": { 25978 + "description": "TasksList", 25979 + "schema": { 25980 + "$ref": "#/definitions/ActionTaskResponse" 25832 25981 } 25833 25982 }, 25834 25983 "Team": {