introduced api endpoint for retrieving runner api tokens, defined by
Some checks failed
testing-integration / test-unit (push) Failing after 0s
testing-integration / test-sqlite (push) Failing after 0s
testing-integration / test-mariadb (v10.6) (push) Failing after 0s
testing-integration / test-mariadb (v11.8) (push) Failing after 0s
testing / backend-checks (push) Failing after 0s
testing / frontend-checks (push) Failing after 0s
testing / test-unit (push) Failing after 0s
testing / test-remote-cacher (garnet) (push) Failing after 0s
testing / test-remote-cacher (redict) (push) Failing after 0s
testing / security-check (push) Failing after 0s
testing / test-e2e (push) Failing after 0s
testing / test-mysql (push) Failing after 0s
testing / test-pgsql (push) Failing after 0s
testing / test-sqlite (push) Failing after 0s
testing / test-remote-cacher (redis) (push) Failing after 0s
testing / test-remote-cacher (valkey) (push) Failing after 0s
/ release (push) Has been cancelled
Some checks failed
testing-integration / test-unit (push) Failing after 0s
testing-integration / test-sqlite (push) Failing after 0s
testing-integration / test-mariadb (v10.6) (push) Failing after 0s
testing-integration / test-mariadb (v11.8) (push) Failing after 0s
testing / backend-checks (push) Failing after 0s
testing / frontend-checks (push) Failing after 0s
testing / test-unit (push) Failing after 0s
testing / test-remote-cacher (garnet) (push) Failing after 0s
testing / test-remote-cacher (redict) (push) Failing after 0s
testing / security-check (push) Failing after 0s
testing / test-e2e (push) Failing after 0s
testing / test-mysql (push) Failing after 0s
testing / test-pgsql (push) Failing after 0s
testing / test-sqlite (push) Failing after 0s
testing / test-remote-cacher (redis) (push) Failing after 0s
testing / test-remote-cacher (valkey) (push) Failing after 0s
/ release (push) Has been cancelled
github api spec
This commit is contained in:
parent
9d896028bd
commit
ffdda77325
10 changed files with 537 additions and 0 deletions
|
|
@ -235,3 +235,9 @@ func LoadSettingsForInstall() {
|
||||||
loadServiceFrom(CfgProvider)
|
loadServiceFrom(CfgProvider)
|
||||||
loadMailerFrom(CfgProvider)
|
loadMailerFrom(CfgProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PanicInDevOrTesting(msg string, a ...any) {
|
||||||
|
if !IsProd || IsInTesting {
|
||||||
|
panic(fmt.Sprintf(msg, a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,27 @@ type ActionTaskResponse struct {
|
||||||
Entries []*ActionTask `json:"workflow_runs"`
|
Entries []*ActionTask `json:"workflow_runs"`
|
||||||
TotalCount int64 `json:"total_count"`
|
TotalCount int64 `json:"total_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionRunnerLabel represents a Runner Label
|
||||||
|
type ActionRunnerLabel struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionRunner represents a Runner
|
||||||
|
type ActionRunner struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Busy bool `json:"busy"`
|
||||||
|
// currently unused as forgejo does not support ephemeral runners, but they are defined in gh api spec
|
||||||
|
Ephemeral bool `json:"ephemeral"`
|
||||||
|
Labels []*ActionRunnerLabel `json:"labels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionRunnersResponse returns Runners
|
||||||
|
type ActionRunnersResponse struct {
|
||||||
|
Entries []*ActionRunner `json:"runners"`
|
||||||
|
TotalCount int64 `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,81 @@ func SearchActionRunJobs(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
shared.GetActionRunJobs(ctx, 0, 0)
|
shared.GetActionRunJobs(ctx, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateRegistrationToken returns the token to register global runners
|
||||||
|
func CreateRegistrationToken(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /admin/actions/runners/registration-token admin adminCreateRunnerRegistrationToken
|
||||||
|
// ---
|
||||||
|
// summary: Get an global actions runner registration token
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/RegistrationToken"
|
||||||
|
|
||||||
|
shared.GetRegistrationToken(ctx, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRunners get all runners
|
||||||
|
func ListRunners(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /admin/actions/runners admin getAdminRunners
|
||||||
|
// ---
|
||||||
|
// summary: Get all runners
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.ListRunners(ctx, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRunner get an global runner
|
||||||
|
func GetRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /admin/actions/runners/{runner_id} admin getAdminRunner
|
||||||
|
// ---
|
||||||
|
// summary: Get an global runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunner"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.GetRunner(ctx, 0, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRunner delete an global runner
|
||||||
|
func DeleteRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /admin/actions/runners/{runner_id} admin deleteAdminRunner
|
||||||
|
// ---
|
||||||
|
// summary: Delete an global runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// description: runner has been deleted
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.DeleteRunner(ctx, 0, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -821,7 +821,11 @@ func Routes() *web.Route {
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Group("/runners", func() {
|
m.Group("/runners", func() {
|
||||||
|
m.Get("", reqToken(), reqChecker, act.ListRunners)
|
||||||
m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken)
|
m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken)
|
||||||
|
m.Post("/registration-token", reqToken(), reqChecker, act.CreateRegistrationToken)
|
||||||
|
m.Get("/{runner_id}", reqToken(), reqChecker, act.GetRunner)
|
||||||
|
m.Delete("/{runner_id}", reqToken(), reqChecker, act.DeleteRunner)
|
||||||
m.Get("/jobs", reqToken(), reqChecker, act.SearchActionRunJobs)
|
m.Get("/jobs", reqToken(), reqChecker, act.SearchActionRunJobs)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -979,7 +983,11 @@ func Routes() *web.Route {
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Group("/runners", func() {
|
m.Group("/runners", func() {
|
||||||
|
m.Get("", reqToken(), user.ListRunners)
|
||||||
m.Get("/registration-token", reqToken(), user.GetRegistrationToken)
|
m.Get("/registration-token", reqToken(), user.GetRegistrationToken)
|
||||||
|
m.Post("/registration-token", reqToken(), user.CreateRegistrationToken)
|
||||||
|
m.Get("/{runner_id}", reqToken(), user.GetRunner)
|
||||||
|
m.Delete("/{runner_id}", reqToken(), user.DeleteRunner)
|
||||||
m.Get("/jobs", reqToken(), user.SearchActionRunJobs)
|
m.Get("/jobs", reqToken(), user.SearchActionRunJobs)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -1653,6 +1661,12 @@ func Routes() *web.Route {
|
||||||
Patch(bind(api.EditHookOption{}), admin.EditHook).
|
Patch(bind(api.EditHookOption{}), admin.EditHook).
|
||||||
Delete(admin.DeleteHook)
|
Delete(admin.DeleteHook)
|
||||||
})
|
})
|
||||||
|
m.Group("/actions/runners", func() {
|
||||||
|
m.Get("", admin.ListRunners)
|
||||||
|
m.Post("/registration-token", admin.CreateRegistrationToken)
|
||||||
|
m.Get("/{runner_id}", admin.GetRunner)
|
||||||
|
m.Delete("/{runner_id}", admin.DeleteRunner)
|
||||||
|
})
|
||||||
m.Group("/runners", func() {
|
m.Group("/runners", func() {
|
||||||
m.Get("/registration-token", admin.GetRegistrationToken)
|
m.Get("/registration-token", admin.GetRegistrationToken)
|
||||||
m.Get("/jobs", admin.SearchActionRunJobs)
|
m.Get("/jobs", admin.SearchActionRunJobs)
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,27 @@ func (Action) SearchActionRunJobs(ctx *context.APIContext) {
|
||||||
shared.GetActionRunJobs(ctx, ctx.Org.Organization.ID, 0)
|
shared.GetActionRunJobs(ctx, ctx.Org.Organization.ID, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization
|
||||||
|
// CreateRegistrationToken returns the token to register org runners
|
||||||
|
func (Action) CreateRegistrationToken(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /orgs/{org}/actions/runners/registration-token organization orgCreateRunnerRegistrationToken
|
||||||
|
// ---
|
||||||
|
// summary: Get an organization's actions runner registration token
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/RegistrationToken"
|
||||||
|
|
||||||
|
shared.GetRegistrationToken(ctx, ctx.Org.Organization.ID, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// ListVariables list org-level variables
|
// ListVariables list org-level variables
|
||||||
func (Action) ListVariables(ctx *context.APIContext) {
|
func (Action) ListVariables(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList
|
// swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList
|
||||||
|
|
@ -266,6 +287,85 @@ func (Action) ListVariables(ctx *context.APIContext) {
|
||||||
ctx.JSON(http.StatusOK, variables)
|
ctx.JSON(http.StatusOK, variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRunners get org-level runners
|
||||||
|
func (Action) ListRunners(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /orgs/{org}/actions/runners organization getOrgRunners
|
||||||
|
// ---
|
||||||
|
// summary: Get org-level runners
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.ListRunners(ctx, ctx.Org.Organization.ID, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRunner get an org-level runner
|
||||||
|
func (Action) GetRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /orgs/{org}/actions/runners/{runner_id} organization getOrgRunner
|
||||||
|
// ---
|
||||||
|
// summary: Get an org-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunner"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.GetRunner(ctx, ctx.Org.Organization.ID, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRunner delete an org-level runner
|
||||||
|
func (Action) DeleteRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /orgs/{org}/actions/runners/{runner_id} organization deleteOrgRunner
|
||||||
|
// ---
|
||||||
|
// summary: Delete an org-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// description: runner has been deleted
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.DeleteRunner(ctx, ctx.Org.Organization.ID, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetVariable gives organization's variable
|
// GetVariable gives organization's variable
|
||||||
func (Action) GetVariable(ctx *context.APIContext) {
|
func (Action) GetVariable(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /orgs/{org}/actions/variables/{variablename} organization getOrgVariable
|
// swagger:operation GET /orgs/{org}/actions/variables/{variablename} organization getOrgVariable
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,125 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) {
|
||||||
shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID)
|
shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateRegistrationToken returns the token to register repo runners
|
||||||
|
func (Action) CreateRegistrationToken(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /repos/{owner}/{repo}/actions/runners/registration-token repository repoCreateRunnerRegistrationToken
|
||||||
|
// ---
|
||||||
|
// summary: Get a repository's actions runner registration token
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/RegistrationToken"
|
||||||
|
|
||||||
|
shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRunners get repo-level runners
|
||||||
|
func (Action) ListRunners(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runners repository getRepoRunners
|
||||||
|
// ---
|
||||||
|
// summary: Get repo-level runners
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.ListRunners(ctx, 0, ctx.Repo.Repository.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRunner get an repo-level runner
|
||||||
|
func (Action) GetRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runners/{runner_id} repository getRepoRunner
|
||||||
|
// ---
|
||||||
|
// summary: Get an repo-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunner"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.GetRunner(ctx, 0, ctx.Repo.Repository.ID, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRunner delete an repo-level runner
|
||||||
|
func (Action) DeleteRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /repos/{owner}/{repo}/actions/runners/{runner_id} repository deleteRepoRunner
|
||||||
|
// ---
|
||||||
|
// summary: Delete an repo-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// description: runner has been deleted
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.DeleteRunner(ctx, 0, ctx.Repo.Repository.ID, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
|
// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
|
||||||
func (Action) SearchActionRunJobs(ctx *context.APIContext) {
|
func (Action) SearchActionRunJobs(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/actions/runners/jobs repository repoSearchRunJobs
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runners/jobs repository repoSearchRunJobs
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ import (
|
||||||
"forgejo.org/modules/structs"
|
"forgejo.org/modules/structs"
|
||||||
"forgejo.org/modules/util"
|
"forgejo.org/modules/util"
|
||||||
"forgejo.org/services/context"
|
"forgejo.org/services/context"
|
||||||
|
|
||||||
|
"forgejo.org/modules/setting"
|
||||||
|
"forgejo.org/routers/api/v1/utils"
|
||||||
|
"forgejo.org/services/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegistrationToken is a string used to register a runner with a server
|
// RegistrationToken is a string used to register a runner with a server
|
||||||
|
|
@ -70,3 +74,84 @@ func fromRunJobModelToResponse(job []*actions_model.ActionRunJob, labels []strin
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRunners lists runners for api route validated ownerID and repoID
|
||||||
|
// ownerID == 0 and repoID == 0 means all runners including global runners, does not appear in sql where clause
|
||||||
|
// ownerID == 0 and repoID != 0 means all runners for the given repo
|
||||||
|
// ownerID != 0 and repoID == 0 means all runners for the given user/org
|
||||||
|
// ownerID != 0 and repoID != 0 undefined behavior
|
||||||
|
// Access rights are checked at the API route level
|
||||||
|
func ListRunners(ctx *context.APIContext, ownerID, repoID int64) {
|
||||||
|
if ownerID != 0 && repoID != 0 {
|
||||||
|
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
|
||||||
|
}
|
||||||
|
runners, total, err := db.FindAndCount[actions_model.ActionRunner](ctx, &actions_model.FindRunnerOptions{
|
||||||
|
OwnerID: ownerID,
|
||||||
|
RepoID: repoID,
|
||||||
|
ListOptions: utils.GetListOptions(ctx),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "FindCountRunners", map[string]string{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := new(structs.ActionRunnersResponse)
|
||||||
|
res.TotalCount = total
|
||||||
|
|
||||||
|
res.Entries = make([]*structs.ActionRunner, len(runners))
|
||||||
|
for i, runner := range runners {
|
||||||
|
res.Entries[i] = convert.ToActionRunner(ctx, runner)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, &res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRunner get the runner for api route validated ownerID and repoID
|
||||||
|
// ownerID == 0 and repoID == 0 means any runner including global runners
|
||||||
|
// ownerID == 0 and repoID != 0 means any runner for the given repo
|
||||||
|
// ownerID != 0 and repoID == 0 means any runner for the given user/org
|
||||||
|
// ownerID != 0 and repoID != 0 undefined behavior
|
||||||
|
// Access rights are checked at the API route level
|
||||||
|
func GetRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
|
||||||
|
if ownerID != 0 && repoID != 0 {
|
||||||
|
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
|
||||||
|
}
|
||||||
|
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(404, "GetRunnerByID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !runner.Editable(ownerID, repoID) {
|
||||||
|
ctx.Error(404, "RunnerEdit", "No permission to get this runner")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, convert.ToActionRunner(ctx, runner))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRunner deletes the runner for api route validated ownerID and repoID
|
||||||
|
// ownerID == 0 and repoID == 0 means any runner including global runners
|
||||||
|
// ownerID == 0 and repoID != 0 means any runner for the given repo
|
||||||
|
// ownerID != 0 and repoID == 0 means any runner for the given user/org
|
||||||
|
// ownerID != 0 and repoID != 0 undefined behavior
|
||||||
|
// Access rights are checked at the API route level
|
||||||
|
func DeleteRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
|
||||||
|
if ownerID != 0 && repoID != 0 {
|
||||||
|
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
|
||||||
|
}
|
||||||
|
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.InternalServerError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !runner.Editable(ownerID, repoID) {
|
||||||
|
ctx.Error(404, "EditRunner", "No permission to delete this runner")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = actions_model.DeleteRunner(ctx, runner)
|
||||||
|
if err != nil {
|
||||||
|
ctx.InternalServerError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,3 +50,81 @@ func SearchActionRunJobs(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
shared.GetActionRunJobs(ctx, ctx.Doer.ID, 0)
|
shared.GetActionRunJobs(ctx, ctx.Doer.ID, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateRegistrationToken returns the token to register user runners
|
||||||
|
func CreateRegistrationToken(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /user/actions/runners/registration-token user userCreateRunnerRegistrationToken
|
||||||
|
// ---
|
||||||
|
// summary: Get an user's actions runner registration token
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/RegistrationToken"
|
||||||
|
|
||||||
|
shared.GetRegistrationToken(ctx, ctx.Doer.ID, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRunners get user-level runners
|
||||||
|
func ListRunners(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /user/actions/runners user getUserRunners
|
||||||
|
// ---
|
||||||
|
// summary: Get user-level runners
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.ListRunners(ctx, ctx.Doer.ID, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRunner get an user-level runner
|
||||||
|
func GetRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /user/actions/runners/{runner_id} user getUserRunner
|
||||||
|
// ---
|
||||||
|
// summary: Get an user-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/definitions/ActionRunner"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.GetRunner(ctx, ctx.Doer.ID, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRunner delete an user-level runner
|
||||||
|
func DeleteRunner(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /user/actions/runners/{runner_id} user deleteUserRunner
|
||||||
|
// ---
|
||||||
|
// summary: Delete an user-level runner
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: runner_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the runner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// description: runner has been deleted
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
shared.DeleteRunner(ctx, ctx.Doer.ID, 0, ctx.ParamsInt64("runner_id"))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,12 @@ type API interface {
|
||||||
GetRegistrationToken(*context.APIContext)
|
GetRegistrationToken(*context.APIContext)
|
||||||
// SearchActionRunJobs get pending Action run jobs
|
// SearchActionRunJobs get pending Action run jobs
|
||||||
SearchActionRunJobs(*context.APIContext)
|
SearchActionRunJobs(*context.APIContext)
|
||||||
|
// CreateRegistrationToken get registration token
|
||||||
|
CreateRegistrationToken(*context.APIContext)
|
||||||
|
// ListRunners list runners
|
||||||
|
ListRunners(*context.APIContext)
|
||||||
|
// GetRunner get a runner
|
||||||
|
GetRunner(*context.APIContext)
|
||||||
|
// DeleteRunner delete runner
|
||||||
|
DeleteRunner(*context.APIContext)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
||||||
actions_model "forgejo.org/models/actions"
|
actions_model "forgejo.org/models/actions"
|
||||||
asymkey_model "forgejo.org/models/asymkey"
|
asymkey_model "forgejo.org/models/asymkey"
|
||||||
"forgejo.org/models/auth"
|
"forgejo.org/models/auth"
|
||||||
|
|
@ -508,3 +509,27 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri
|
||||||
|
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToActionRunner(ctx context.Context, runner *actions_model.ActionRunner) *api.ActionRunner {
|
||||||
|
status := runner.Status()
|
||||||
|
apiStatus := "offline"
|
||||||
|
if runner.IsOnline() {
|
||||||
|
apiStatus = "online"
|
||||||
|
}
|
||||||
|
labels := make([]*api.ActionRunnerLabel, len(runner.AgentLabels))
|
||||||
|
for i, label := range runner.AgentLabels {
|
||||||
|
labels[i] = &api.ActionRunnerLabel{
|
||||||
|
ID: int64(i),
|
||||||
|
Name: label,
|
||||||
|
Type: "custom",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &api.ActionRunner{
|
||||||
|
ID: runner.ID,
|
||||||
|
Name: runner.Name,
|
||||||
|
Status: apiStatus,
|
||||||
|
Busy: status == runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE,
|
||||||
|
// Ephemeral: runner.Ephemeral,
|
||||||
|
Labels: labels,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue