forked from mirrors/forgejo
chore: document and test pagination of /runners API endpoint (#10551)
Document the pagination of all the `/runners` API endpoints and add tests for them. Follow-up of https://codeberg.org/forgejo/forgejo/pulls/10450. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10551 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Andreas Ahlenstorf <andreas@ahlenstorf.ch> Co-committed-by: Andreas Ahlenstorf <andreas@ahlenstorf.ch>
This commit is contained in:
parent
2db37153fb
commit
537a802125
11 changed files with 160 additions and 1 deletions
|
|
@ -50,6 +50,15 @@ func ListRunners(ctx *context.APIContext) {
|
|||
// summary: Get all runners, no matter whether they are global runners or scoped to an organization, user, or repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/ActionRunnerList"
|
||||
|
|
|
|||
|
|
@ -278,6 +278,14 @@ func (Action) ListRunners(ctx *context.APIContext) {
|
|||
// description: name of the organization
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/ActionRunnerList"
|
||||
|
|
|
|||
|
|
@ -523,6 +523,14 @@ func (Action) ListRunners(ctx *context.APIContext) {
|
|||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/ActionRunnerList"
|
||||
|
|
|
|||
|
|
@ -87,10 +87,12 @@ func ListRunners(ctx *context.APIContext, ownerID, repoID int64) {
|
|||
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("ownerID and repoID should not be both set: %d and %d", ownerID, repoID))
|
||||
return
|
||||
}
|
||||
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
runners, total, err := db.FindAndCount[actions_model.ActionRunner](ctx, &actions_model.FindRunnerOptions{
|
||||
OwnerID: ownerID,
|
||||
RepoID: repoID,
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
ListOptions: listOptions,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "FindCountRunners", map[string]string{})
|
||||
|
|
@ -106,6 +108,8 @@ func ListRunners(ctx *context.APIContext, ownerID, repoID int64) {
|
|||
}
|
||||
runnerList[i] = actionRunner
|
||||
}
|
||||
|
||||
ctx.SetLinkHeader(int(total), listOptions.PageSize)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, &runnerList)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,4 +69,10 @@ type swaggerActionRunner struct {
|
|||
type swaggerActionRunnerListResponse struct {
|
||||
// in:body
|
||||
Body []api.ActionRunner `json:"body"`
|
||||
|
||||
// Total number of runners matching the search criteria (excluding page and limit)
|
||||
TotalCount int64 `json:"X-Total-Count"`
|
||||
|
||||
// Links to other pages, if any
|
||||
Link string `json:"Link"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,15 @@ func ListRunners(ctx *context.APIContext) {
|
|||
// summary: Get the user's runners
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/ActionRunnerList"
|
||||
|
|
|
|||
63
templates/swagger/v1_json.tmpl
generated
63
templates/swagger/v1_json.tmpl
generated
|
|
@ -321,6 +321,20 @@
|
|||
],
|
||||
"summary": "Get all runners, no matter whether they are global runners or scoped to an organization, user, or repository",
|
||||
"operationId": "getAdminRunners",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/ActionRunnerList"
|
||||
|
|
@ -2627,6 +2641,18 @@
|
|||
"name": "org",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -5308,6 +5334,18 @@
|
|||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -18737,6 +18775,20 @@
|
|||
],
|
||||
"summary": "Get the user's runners",
|
||||
"operationId": "getUserRunners",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/ActionRunnerList"
|
||||
|
|
@ -29849,6 +29901,17 @@
|
|||
"items": {
|
||||
"$ref": "#/definitions/ActionRunner"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"Link": {
|
||||
"type": "string",
|
||||
"description": "Links to other pages, if any"
|
||||
},
|
||||
"X-Total-Count": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Total number of runners matching the search criteria (excluding page and limit)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ActionVariable": {
|
||||
|
|
|
|||
|
|
@ -177,6 +177,19 @@ func TestAPIGlobalActionsRunnerOperations(t *testing.T) {
|
|||
assert.Contains(t, runners, runnerThree)
|
||||
})
|
||||
|
||||
t.Run("GetRunnersPaginated", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/admin/actions/runners?page=1&limit=5")
|
||||
request.AddTokenAuth(readToken)
|
||||
response := MakeRequest(t, request, http.StatusOK)
|
||||
|
||||
var runners []*api.ActionRunner
|
||||
DecodeJSON(t, response, &runners)
|
||||
|
||||
assert.NotEmpty(t, response.Header().Get("Link"))
|
||||
assert.NotEmpty(t, response.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, runners, 5)
|
||||
})
|
||||
|
||||
t.Run("GetGlobalRunner", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/admin/actions/runners/130793")
|
||||
request.AddTokenAuth(readToken)
|
||||
|
|
|
|||
|
|
@ -147,6 +147,19 @@ func TestAPIOrgActionsRunnerOperations(t *testing.T) {
|
|||
assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners)
|
||||
})
|
||||
|
||||
t.Run("GetRunnersPaginated", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/orgs/org3/actions/runners?page=1&limit=1")
|
||||
request.AddTokenAuth(readToken)
|
||||
response := MakeRequest(t, request, http.StatusOK)
|
||||
|
||||
var runners []*api.ActionRunner
|
||||
DecodeJSON(t, response, &runners)
|
||||
|
||||
assert.NotEmpty(t, response.Header().Get("Link"))
|
||||
assert.NotEmpty(t, response.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, runners, 1)
|
||||
})
|
||||
|
||||
t.Run("GetRunner", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/orgs/org3/actions/runners/655691")
|
||||
request.AddTokenAuth(readToken)
|
||||
|
|
|
|||
|
|
@ -420,6 +420,19 @@ func TestAPIRepoActionsRunnerOperations(t *testing.T) {
|
|||
assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners)
|
||||
})
|
||||
|
||||
t.Run("GetRunnersPaginated", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/repos/user2/test_workflows/actions/runners?page=1&limit=1")
|
||||
request.AddTokenAuth(readToken)
|
||||
response := MakeRequest(t, request, http.StatusOK)
|
||||
|
||||
var runners []*api.ActionRunner
|
||||
DecodeJSON(t, response, &runners)
|
||||
|
||||
assert.NotEmpty(t, response.Header().Get("Link"))
|
||||
assert.NotEmpty(t, response.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, runners, 1)
|
||||
})
|
||||
|
||||
t.Run("GetRunner", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/repos/user2/test_workflows/actions/runners/899251")
|
||||
request.AddTokenAuth(readToken)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,19 @@ func TestAPIUserActionsRunnerOperations(t *testing.T) {
|
|||
assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners)
|
||||
})
|
||||
|
||||
t.Run("GetRunnersPaginated", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/user/actions/runners?page=1&limit=1")
|
||||
request.AddTokenAuth(readToken)
|
||||
response := MakeRequest(t, request, http.StatusOK)
|
||||
|
||||
var runners []*api.ActionRunner
|
||||
DecodeJSON(t, response, &runners)
|
||||
|
||||
assert.NotEmpty(t, response.Header().Get("Link"))
|
||||
assert.NotEmpty(t, response.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, runners, 1)
|
||||
})
|
||||
|
||||
t.Run("GetRunner", func(t *testing.T) {
|
||||
request := NewRequest(t, "GET", "/api/v1/user/actions/runners/71303")
|
||||
request.AddTokenAuth(readToken)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue