diff --git a/modules/structs/actions.go b/modules/structs/actions.go new file mode 100644 index 0000000000000..12c45c74da4e0 --- /dev/null +++ b/modules/structs/actions.go @@ -0,0 +1,11 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs // import "code.gitea.io/gitea/modules/structs" + +// ActionRunnerToken represents an action runner token +// swagger:model +type ActionRunnerToken struct { + ID int64 `json:"id"` + Token string `json:"token"` +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index a67a5420ac66e..1db631d44c202 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1184,6 +1184,11 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/issue_config/validate", context.ReferencesGitRepo(), repo.ValidateIssueConfig) m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages) m.Get("/activities/feeds", repo.ListRepoActivityFeeds) + + // TODO: list runners + // TODO: update runner + // TODO: delete runner + m.Put("/runners", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeActions), repo.GenerateRunnerToken) }, repoAssignment()) }) diff --git a/routers/api/v1/repo/runners.go b/routers/api/v1/repo/runners.go new file mode 100644 index 0000000000000..28072841bcc6c --- /dev/null +++ b/routers/api/v1/repo/runners.go @@ -0,0 +1,52 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "errors" + "net/http" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/convert" +) + +// GenerateRunnerToken generate a new runner token for a repository. +func GenerateRunnerToken(ctx *context.APIContext) { + // swagger:operation PUT /repos/{owner}/{repo}/runners repository repoGenerateRunnerToken + // --- + // summary: Generate a new runner token for a repository. + // 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/ActionRunnerToken" + // "404": + // "$ref": "#/responses/notFound" + + token, err := actions_model.GetUnactivatedRunnerToken(ctx, ctx.Repo.Owner.ID, ctx.Repo.Repository.ID) + if errors.Is(err, util.ErrNotExist) { + token, err = actions_model.NewRunnerToken(ctx, ctx.Repo.Owner.ID, ctx.Repo.Repository.ID) + if err != nil { + ctx.ServerError("CreateRunnerToken", err) + return + } + } else if err != nil { + ctx.ServerError("GetUnactivatedRunnerToken", err) + return + } + ctx.JSON(http.StatusOK, convert.ToAPIActionRunnerToken(token)) +} diff --git a/services/convert/actions.go b/services/convert/actions.go new file mode 100644 index 0000000000000..e567d936e6f07 --- /dev/null +++ b/services/convert/actions.go @@ -0,0 +1,16 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package convert + +import ( + actions_model "code.gitea.io/gitea/models/actions" + api "code.gitea.io/gitea/modules/structs" +) + +func ToAPIActionRunnerToken(token *actions_model.ActionRunnerToken) *api.ActionRunnerToken { + return &api.ActionRunnerToken{ + ID: token.ID, + Token: token.Token, + } +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 3859eb5567a86..f15f0cf0e0529 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -11237,6 +11237,42 @@ } } }, + "/repos/{owner}/{repo}/runners": { + "put": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Generate a new runner token for a repository.", + "operationId": "repoGenerateRunnerToken", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionRunnerToken" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, "/repos/{owner}/{repo}/signing-key.gpg": { "get": { "produces": [