mirror of
https://github.com/go-gitea/gitea.git
synced 2024-05-09 03:26:19 +02:00
Compare commits
7 Commits
a93cdf24b6
...
03879c7a7f
Author | SHA1 | Date | |
---|---|---|---|
Yarden Shoham | 03879c7a7f | ||
GiteaBot | 27861d711b | ||
silverwind | c93eefb42b | ||
Bo-Yi Wu | 852547d0dc | ||
wxiaoguang | 993736d838 | ||
wxiaoguang | cd70ab31cd | ||
wxiaoguang | 1e749b80d7 |
|
@ -33,7 +33,6 @@ type ObjectFormat interface {
|
|||
ComputeHash(t ObjectType, content []byte) ObjectID
|
||||
}
|
||||
|
||||
/* SHA1 Type */
|
||||
type Sha1ObjectFormatImpl struct{}
|
||||
|
||||
var (
|
||||
|
@ -70,14 +69,10 @@ func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID
|
|||
_, _ = hasher.Write([]byte(" "))
|
||||
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
|
||||
_, _ = hasher.Write([]byte{0})
|
||||
|
||||
// HashSum generates a SHA1 for the provided hash
|
||||
var sha1 Sha1Hash
|
||||
copy(sha1[:], hasher.Sum(nil))
|
||||
return &sha1
|
||||
_, _ = hasher.Write(content)
|
||||
return h.MustID(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
/* SHA256 Type */
|
||||
type Sha256ObjectFormatImpl struct{}
|
||||
|
||||
var (
|
||||
|
@ -116,11 +111,8 @@ func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) Object
|
|||
_, _ = hasher.Write([]byte(" "))
|
||||
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
|
||||
_, _ = hasher.Write([]byte{0})
|
||||
|
||||
// HashSum generates a SHA256 for the provided hash
|
||||
var sha256 Sha1Hash
|
||||
copy(sha256[:], hasher.Sum(nil))
|
||||
return &sha256
|
||||
_, _ = hasher.Write(content)
|
||||
return h.MustID(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -16,7 +16,6 @@ type ObjectID interface {
|
|||
Type() ObjectFormat
|
||||
}
|
||||
|
||||
/* SHA1 */
|
||||
type Sha1Hash [20]byte
|
||||
|
||||
func (h *Sha1Hash) String() string {
|
||||
|
@ -40,7 +39,6 @@ func MustIDFromString(hexHash string) ObjectID {
|
|||
return id
|
||||
}
|
||||
|
||||
/* SHA256 */
|
||||
type Sha256Hash [32]byte
|
||||
|
||||
func (h *Sha256Hash) String() string {
|
||||
|
@ -54,7 +52,6 @@ func (h *Sha256Hash) IsZero() bool {
|
|||
func (h *Sha256Hash) RawValue() []byte { return h[:] }
|
||||
func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
|
||||
|
||||
/* utility */
|
||||
func NewIDFromString(hexHash string) (ObjectID, error) {
|
||||
var theObjectFormat ObjectFormat
|
||||
for _, objectFormat := range SupportedObjectFormats {
|
||||
|
|
|
@ -18,4 +18,8 @@ func TestIsValidSHAPattern(t *testing.T) {
|
|||
assert.False(t, h.IsValid("abc"))
|
||||
assert.False(t, h.IsValid("123g"))
|
||||
assert.False(t, h.IsValid("some random text"))
|
||||
assert.Equal(t, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", ComputeBlobHash(Sha1ObjectFormat, nil).String())
|
||||
assert.Equal(t, "2e65efe2a145dda7ee51d1741299f848e5bf752e", ComputeBlobHash(Sha1ObjectFormat, []byte("a")).String())
|
||||
assert.Equal(t, "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813", ComputeBlobHash(Sha256ObjectFormat, nil).String())
|
||||
assert.Equal(t, "eb337bcee2061c5313c9a1392116b6c76039e9e30d71467ae359b36277e17dc7", ComputeBlobHash(Sha256ObjectFormat, []byte("a")).String())
|
||||
}
|
||||
|
|
|
@ -436,6 +436,7 @@ oauth_signin_submit=Vincular conta
|
|||
oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contacte o administrador.
|
||||
oauth.signin.error.access_denied=O pedido de autorização foi negado.
|
||||
oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponĂvel. Tente mais tarde.
|
||||
oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso nĂŁo foi possĂvel criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sĂtio.
|
||||
openid_connect_submit=Estabelecer ligação
|
||||
openid_connect_title=Estabelecer ligação a uma conta existente
|
||||
openid_connect_desc=O URI do OpenID escolhido Ă© desconhecido. Associe-o a uma nova conta aqui.
|
||||
|
|
|
@ -93,6 +93,7 @@ import (
|
|||
"code.gitea.io/gitea/routers/api/v1/settings"
|
||||
"code.gitea.io/gitea/routers/api/v1/user"
|
||||
"code.gitea.io/gitea/routers/common"
|
||||
"code.gitea.io/gitea/services/actions"
|
||||
"code.gitea.io/gitea/services/auth"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
|
@ -835,6 +836,34 @@ func Routes() *web.Route {
|
|||
SignInRequired: setting.Service.RequireSignInView,
|
||||
}))
|
||||
|
||||
addActionsRoutes := func(
|
||||
m *web.Route,
|
||||
reqChecker func(ctx *context.APIContext),
|
||||
act actions.API,
|
||||
) {
|
||||
m.Group("/actions", func() {
|
||||
m.Group("/secrets", func() {
|
||||
m.Get("", reqToken(), reqChecker, act.ListActionsSecrets)
|
||||
m.Combo("/{secretname}").
|
||||
Put(reqToken(), reqChecker, bind(api.CreateOrUpdateSecretOption{}), act.CreateOrUpdateSecret).
|
||||
Delete(reqToken(), reqChecker, act.DeleteSecret)
|
||||
})
|
||||
|
||||
m.Group("/variables", func() {
|
||||
m.Get("", reqToken(), reqChecker, act.ListVariables)
|
||||
m.Combo("/{variablename}").
|
||||
Get(reqToken(), reqChecker, act.GetVariable).
|
||||
Delete(reqToken(), reqChecker, act.DeleteVariable).
|
||||
Post(reqToken(), reqChecker, bind(api.CreateVariableOption{}), act.CreateVariable).
|
||||
Put(reqToken(), reqChecker, bind(api.UpdateVariableOption{}), act.UpdateVariable)
|
||||
})
|
||||
|
||||
m.Group("/runners", func() {
|
||||
m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
m.Group("", func() {
|
||||
// Miscellaneous (no scope required)
|
||||
if setting.API.EnableSwagger {
|
||||
|
@ -1073,26 +1102,11 @@ func Routes() *web.Route {
|
|||
m.Post("/accept", repo.AcceptTransfer)
|
||||
m.Post("/reject", repo.RejectTransfer)
|
||||
}, reqToken())
|
||||
m.Group("/actions", func() {
|
||||
m.Group("/secrets", func() {
|
||||
m.Combo("/{secretname}").
|
||||
Put(reqToken(), reqOwner(), bind(api.CreateOrUpdateSecretOption{}), repo.CreateOrUpdateSecret).
|
||||
Delete(reqToken(), reqOwner(), repo.DeleteSecret)
|
||||
})
|
||||
|
||||
m.Group("/variables", func() {
|
||||
m.Get("", reqToken(), reqOwner(), repo.ListVariables)
|
||||
m.Combo("/{variablename}").
|
||||
Get(reqToken(), reqOwner(), repo.GetVariable).
|
||||
Delete(reqToken(), reqOwner(), repo.DeleteVariable).
|
||||
Post(reqToken(), reqOwner(), bind(api.CreateVariableOption{}), repo.CreateVariable).
|
||||
Put(reqToken(), reqOwner(), bind(api.UpdateVariableOption{}), repo.UpdateVariable)
|
||||
})
|
||||
|
||||
m.Group("/runners", func() {
|
||||
m.Get("/registration-token", reqToken(), reqOwner(), repo.GetRegistrationToken)
|
||||
})
|
||||
})
|
||||
addActionsRoutes(
|
||||
m,
|
||||
reqOwner(),
|
||||
repo.NewAction(),
|
||||
)
|
||||
m.Group("/hooks/git", func() {
|
||||
m.Combo("").Get(repo.ListGitHooks)
|
||||
m.Group("/{id}", func() {
|
||||
|
@ -1460,27 +1474,11 @@ func Routes() *web.Route {
|
|||
m.Combo("/{username}").Get(reqToken(), org.IsMember).
|
||||
Delete(reqToken(), reqOrgOwnership(), org.DeleteMember)
|
||||
})
|
||||
m.Group("/actions", func() {
|
||||
m.Group("/secrets", func() {
|
||||
m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets)
|
||||
m.Combo("/{secretname}").
|
||||
Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateSecret).
|
||||
Delete(reqToken(), reqOrgOwnership(), org.DeleteSecret)
|
||||
})
|
||||
|
||||
m.Group("/variables", func() {
|
||||
m.Get("", reqToken(), reqOrgOwnership(), org.ListVariables)
|
||||
m.Combo("/{variablename}").
|
||||
Get(reqToken(), reqOrgOwnership(), org.GetVariable).
|
||||
Delete(reqToken(), reqOrgOwnership(), org.DeleteVariable).
|
||||
Post(reqToken(), reqOrgOwnership(), bind(api.CreateVariableOption{}), org.CreateVariable).
|
||||
Put(reqToken(), reqOrgOwnership(), bind(api.UpdateVariableOption{}), org.UpdateVariable)
|
||||
})
|
||||
|
||||
m.Group("/runners", func() {
|
||||
m.Get("/registration-token", reqToken(), reqOrgOwnership(), org.GetRegistrationToken)
|
||||
})
|
||||
})
|
||||
addActionsRoutes(
|
||||
m,
|
||||
reqOrgOwnership(),
|
||||
org.NewAction(),
|
||||
)
|
||||
m.Group("/public_members", func() {
|
||||
m.Get("", org.ListPublicMembers)
|
||||
m.Combo("/{username}").Get(org.IsPublicMember).
|
||||
|
|
|
@ -9,16 +9,188 @@ import (
|
|||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/shared"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
actions_service "code.gitea.io/gitea/services/actions"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
secret_service "code.gitea.io/gitea/services/secrets"
|
||||
)
|
||||
|
||||
// ListActionsSecrets list an organization's actions secrets
|
||||
func (Action) ListActionsSecrets(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/secrets organization orgListActionsSecrets
|
||||
// ---
|
||||
// summary: List an organization's actions secrets
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// 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/SecretList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
opts := &secret_model.FindSecretsOptions{
|
||||
OwnerID: ctx.Org.Organization.ID,
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
}
|
||||
|
||||
secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
apiSecrets := make([]*api.Secret, len(secrets))
|
||||
for k, v := range secrets {
|
||||
apiSecrets[k] = &api.Secret{
|
||||
Name: v.Name,
|
||||
Created: v.CreatedUnix.AsTime(),
|
||||
}
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, apiSecrets)
|
||||
}
|
||||
|
||||
// create or update one secret of the organization
|
||||
func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret
|
||||
// ---
|
||||
// summary: Create or Update a secret value in an organization
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// description: name of organization
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: secretname
|
||||
// in: path
|
||||
// description: name of the secret
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/CreateOrUpdateSecretOption"
|
||||
// responses:
|
||||
// "201":
|
||||
// description: response when creating a secret
|
||||
// "204":
|
||||
// description: response when updating a secret
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
|
||||
|
||||
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"), opt.Data)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
|
||||
} else if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.Error(http.StatusNotFound, "CreateOrUpdateSecret", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if created {
|
||||
ctx.Status(http.StatusCreated)
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteSecret delete one secret of the organization
|
||||
func (Action) DeleteSecret(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /orgs/{org}/actions/secrets/{secretname} organization deleteOrgSecret
|
||||
// ---
|
||||
// summary: Delete a secret in an organization
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// description: name of organization
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: secretname
|
||||
// in: path
|
||||
// description: name of the secret
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// description: delete one secret of the organization
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
err := secret_service.DeleteSecretByName(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"))
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
|
||||
} else if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.Error(http.StatusNotFound, "DeleteSecret", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteSecret", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization
|
||||
// GetRegistrationToken returns the token to register org runners
|
||||
func (Action) GetRegistrationToken(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/runners/registration-token organization orgGetRunnerRegistrationToken
|
||||
// ---
|
||||
// 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
|
||||
func ListVariables(ctx *context.APIContext) {
|
||||
func (Action) ListVariables(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList
|
||||
// ---
|
||||
// summary: Get an org-level variables list
|
||||
|
@ -70,7 +242,7 @@ func ListVariables(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// GetVariable get an org-level variable
|
||||
func GetVariable(ctx *context.APIContext) {
|
||||
func (Action) GetVariable(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/variables/{variablename} organization getOrgVariable
|
||||
// ---
|
||||
// summary: Get an org-level variable
|
||||
|
@ -119,7 +291,7 @@ func GetVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// DeleteVariable delete an org-level variable
|
||||
func DeleteVariable(ctx *context.APIContext) {
|
||||
func (Action) DeleteVariable(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /orgs/{org}/actions/variables/{variablename} organization deleteOrgVariable
|
||||
// ---
|
||||
// summary: Delete an org-level variable
|
||||
|
@ -163,7 +335,7 @@ func DeleteVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// CreateVariable create an org-level variable
|
||||
func CreateVariable(ctx *context.APIContext) {
|
||||
func (Action) CreateVariable(ctx *context.APIContext) {
|
||||
// swagger:operation POST /orgs/{org}/actions/variables/{variablename} organization createOrgVariable
|
||||
// ---
|
||||
// summary: Create an org-level variable
|
||||
|
@ -227,7 +399,7 @@ func CreateVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// UpdateVariable update an org-level variable
|
||||
func UpdateVariable(ctx *context.APIContext) {
|
||||
func (Action) UpdateVariable(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /orgs/{org}/actions/variables/{variablename} organization updateOrgVariable
|
||||
// ---
|
||||
// summary: Update an org-level variable
|
||||
|
@ -289,3 +461,13 @@ func UpdateVariable(ctx *context.APIContext) {
|
|||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
var _ actions_service.API = new(Action)
|
||||
|
||||
// Action implements actions_service.API
|
||||
type Action struct{}
|
||||
|
||||
// NewAction creates a new Action service
|
||||
func NewAction() actions_service.API {
|
||||
return Action{}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package org
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/routers/api/v1/shared"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization
|
||||
|
||||
// GetRegistrationToken returns the token to register org runners
|
||||
func GetRegistrationToken(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/runners/registration-token organization orgGetRunnerRegistrationToken
|
||||
// ---
|
||||
// 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)
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package org
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
secret_service "code.gitea.io/gitea/services/secrets"
|
||||
)
|
||||
|
||||
// ListActionsSecrets list an organization's actions secrets
|
||||
func ListActionsSecrets(ctx *context.APIContext) {
|
||||
// swagger:operation GET /orgs/{org}/actions/secrets organization orgListActionsSecrets
|
||||
// ---
|
||||
// summary: List an organization's actions secrets
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// 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/SecretList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
opts := &secret_model.FindSecretsOptions{
|
||||
OwnerID: ctx.Org.Organization.ID,
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
}
|
||||
|
||||
secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
apiSecrets := make([]*api.Secret, len(secrets))
|
||||
for k, v := range secrets {
|
||||
apiSecrets[k] = &api.Secret{
|
||||
Name: v.Name,
|
||||
Created: v.CreatedUnix.AsTime(),
|
||||
}
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, apiSecrets)
|
||||
}
|
||||
|
||||
// create or update one secret of the organization
|
||||
func CreateOrUpdateSecret(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret
|
||||
// ---
|
||||
// summary: Create or Update a secret value in an organization
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// description: name of organization
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: secretname
|
||||
// in: path
|
||||
// description: name of the secret
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/CreateOrUpdateSecretOption"
|
||||
// responses:
|
||||
// "201":
|
||||
// description: response when creating a secret
|
||||
// "204":
|
||||
// description: response when updating a secret
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
|
||||
|
||||
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"), opt.Data)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
|
||||
} else if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.Error(http.StatusNotFound, "CreateOrUpdateSecret", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if created {
|
||||
ctx.Status(http.StatusCreated)
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteSecret delete one secret of the organization
|
||||
func DeleteSecret(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /orgs/{org}/actions/secrets/{secretname} organization deleteOrgSecret
|
||||
// ---
|
||||
// summary: Delete a secret in an organization
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: org
|
||||
// in: path
|
||||
// description: name of organization
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: secretname
|
||||
// in: path
|
||||
// description: name of the secret
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// description: delete one secret of the organization
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
err := secret_service.DeleteSecretByName(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"))
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
|
||||
} else if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.Error(http.StatusNotFound, "DeleteSecret", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteSecret", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
|
@ -9,17 +9,76 @@ import (
|
|||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/shared"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
actions_service "code.gitea.io/gitea/services/actions"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
secret_service "code.gitea.io/gitea/services/secrets"
|
||||
)
|
||||
|
||||
// ListActionsSecrets list an repo's actions secrets
|
||||
func (Action) ListActionsSecrets(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/actions/secrets repository repoListActionsSecrets
|
||||
// ---
|
||||
// summary: List an repo's actions secrets
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repository
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repository
|
||||
// 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/SecretList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
opts := &secret_model.FindSecretsOptions{
|
||||
RepoID: repo.ID,
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
}
|
||||
|
||||
secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
apiSecrets := make([]*api.Secret, len(secrets))
|
||||
for k, v := range secrets {
|
||||
apiSecrets[k] = &api.Secret{
|
||||
Name: v.Name,
|
||||
Created: v.CreatedUnix.AsTime(),
|
||||
}
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, apiSecrets)
|
||||
}
|
||||
|
||||
// create or update one secret of the repository
|
||||
func CreateOrUpdateSecret(ctx *context.APIContext) {
|
||||
func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /repos/{owner}/{repo}/actions/secrets/{secretname} repository updateRepoSecret
|
||||
// ---
|
||||
// summary: Create or Update a secret value in a repository
|
||||
|
@ -82,7 +141,7 @@ func CreateOrUpdateSecret(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// DeleteSecret delete one secret of the repository
|
||||
func DeleteSecret(ctx *context.APIContext) {
|
||||
func (Action) DeleteSecret(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/actions/secrets/{secretname} repository deleteRepoSecret
|
||||
// ---
|
||||
// summary: Delete a secret in a repository
|
||||
|
@ -133,7 +192,7 @@ func DeleteSecret(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// GetVariable get a repo-level variable
|
||||
func GetVariable(ctx *context.APIContext) {
|
||||
func (Action) GetVariable(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/actions/variables/{variablename} repository getRepoVariable
|
||||
// ---
|
||||
// summary: Get a repo-level variable
|
||||
|
@ -186,7 +245,7 @@ func GetVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// DeleteVariable delete a repo-level variable
|
||||
func DeleteVariable(ctx *context.APIContext) {
|
||||
func (Action) DeleteVariable(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/actions/variables/{variablename} repository deleteRepoVariable
|
||||
// ---
|
||||
// summary: Delete a repo-level variable
|
||||
|
@ -235,7 +294,7 @@ func DeleteVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// CreateVariable create a repo-level variable
|
||||
func CreateVariable(ctx *context.APIContext) {
|
||||
func (Action) CreateVariable(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/actions/variables/{variablename} repository createRepoVariable
|
||||
// ---
|
||||
// summary: Create a repo-level variable
|
||||
|
@ -302,7 +361,7 @@ func CreateVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// UpdateVariable update a repo-level variable
|
||||
func UpdateVariable(ctx *context.APIContext) {
|
||||
func (Action) UpdateVariable(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /repos/{owner}/{repo}/actions/variables/{variablename} repository updateRepoVariable
|
||||
// ---
|
||||
// summary: Update a repo-level variable
|
||||
|
@ -369,7 +428,7 @@ func UpdateVariable(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// ListVariables list repo-level variables
|
||||
func ListVariables(ctx *context.APIContext) {
|
||||
func (Action) ListVariables(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/actions/variables repository getRepoVariablesList
|
||||
// ---
|
||||
// summary: Get repo-level variables list
|
||||
|
@ -423,3 +482,38 @@ func ListVariables(ctx *context.APIContext) {
|
|||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, variables)
|
||||
}
|
||||
|
||||
// GetRegistrationToken returns the token to register repo runners
|
||||
func (Action) GetRegistrationToken(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/runners/registration-token repository repoGetRunnerRegistrationToken
|
||||
// ---
|
||||
// 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, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
|
||||
}
|
||||
|
||||
var _ actions_service.API = new(Action)
|
||||
|
||||
// Action implements actions_service.API
|
||||
type Action struct{}
|
||||
|
||||
// NewAction creates a new Action service
|
||||
func NewAction() actions_service.API {
|
||||
return Action{}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/routers/api/v1/shared"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
// GetRegistrationToken returns the token to register repo runners
|
||||
func GetRegistrationToken(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/runners/registration-token repository repoGetRunnerRegistrationToken
|
||||
// ---
|
||||
// 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, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
|
||||
}
|
|
@ -5,6 +5,7 @@ package routers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
||||
|
@ -25,6 +26,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/modules/web/routing"
|
||||
actions_router "code.gitea.io/gitea/routers/api/actions"
|
||||
packages_router "code.gitea.io/gitea/routers/api/packages"
|
||||
apiv1 "code.gitea.io/gitea/routers/api/v1"
|
||||
|
@ -202,5 +204,9 @@ func NormalRoutes() *web.Route {
|
|||
r.Mount(prefix, actions_router.ArtifactsV4Routes(prefix))
|
||||
}
|
||||
|
||||
r.NotFound(func(w http.ResponseWriter, req *http.Request) {
|
||||
routing.UpdateFuncInfo(req.Context(), routing.GetFuncInfo(http.NotFound, "GlobalNotFound"))
|
||||
http.NotFound(w, req)
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
|
|
@ -212,8 +212,6 @@ func SearchCommits(ctx *context.Context) {
|
|||
|
||||
// FileHistory show a file's reversions
|
||||
func FileHistory(ctx *context.Context) {
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
|
||||
fileName := ctx.Repo.TreePath
|
||||
if len(fileName) == 0 {
|
||||
Commits(ctx)
|
||||
|
|
|
@ -800,7 +800,6 @@ func CompareDiff(ctx *context.Context) {
|
|||
}
|
||||
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + separator + base.ShortSha(afterCommitID)
|
||||
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["IsDiffCompare"] = true
|
||||
_, templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates)
|
||||
|
||||
|
|
|
@ -1225,7 +1225,6 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
|||
ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
|
||||
ctx.Data["PageIsComparePull"] = true
|
||||
ctx.Data["IsDiffCompare"] = true
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
|
||||
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
|
||||
upload.AddUploadContext(ctx, "comment")
|
||||
|
|
|
@ -1612,7 +1612,7 @@ func registerRoutes(m *web.Route) {
|
|||
|
||||
m.NotFound(func(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := context.GetWebContext(req)
|
||||
routing.UpdateFuncInfo(ctx, routing.GetFuncInfo(ctx.NotFound, "GlobalNotFound"))
|
||||
routing.UpdateFuncInfo(ctx, routing.GetFuncInfo(ctx.NotFound, "WebNotFound"))
|
||||
ctx.NotFound("", nil)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import "code.gitea.io/gitea/services/context"
|
||||
|
||||
// API for actions of a repository or organization
|
||||
type API interface {
|
||||
// ListActionsSecrets list secrets
|
||||
ListActionsSecrets(*context.APIContext)
|
||||
// CreateOrUpdateSecret create or update a secret
|
||||
CreateOrUpdateSecret(*context.APIContext)
|
||||
// DeleteSecret delete a secret
|
||||
DeleteSecret(*context.APIContext)
|
||||
// ListVariables list variables
|
||||
ListVariables(*context.APIContext)
|
||||
// GetVariable get a variable
|
||||
GetVariable(*context.APIContext)
|
||||
// DeleteVariable delete a variable
|
||||
DeleteVariable(*context.APIContext)
|
||||
// CreateVariable create a variable
|
||||
CreateVariable(*context.APIContext)
|
||||
// UpdateVariable update a variable
|
||||
UpdateVariable(*context.APIContext)
|
||||
// GetRegistrationToken get registration token
|
||||
GetRegistrationToken(*context.APIContext)
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{{if $.IsSplitStyle}}
|
||||
{{range $k, $line := $.section.Lines}}
|
||||
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
|
||||
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}} line-expanded">
|
||||
{{if eq .GetType 4}}
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
|
||||
<div class="tw-flex">
|
||||
|
@ -26,17 +26,17 @@
|
|||
{{else}}
|
||||
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$.FileNameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||
<td class="blob-excerpt lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="blob-excerpt lines-code lines-code-old">{{/*
|
||||
<td class="lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="lines-code lines-code-old">{{/*
|
||||
*/}}{{if $line.LeftIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
|
||||
*/}}<code class="code-inner"></code>{{/*
|
||||
*/}}{{end}}{{/*
|
||||
*/}}</td>
|
||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
<td class="blob-excerpt lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="blob-excerpt lines-code lines-code-new">{{/*
|
||||
<td class="lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
|
||||
<td class="lines-code lines-code-new">{{/*
|
||||
*/}}{{if $line.RightIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
|
||||
*/}}<code class="code-inner"></code>{{/*
|
||||
*/}}{{end}}{{/*
|
||||
|
@ -46,7 +46,7 @@
|
|||
{{end}}
|
||||
{{else}}
|
||||
{{range $k, $line := $.section.Lines}}
|
||||
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
|
||||
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}} line-expanded">
|
||||
{{if eq .GetType 4}}
|
||||
<td colspan="2" class="lines-num">
|
||||
<div class="tw-flex">
|
||||
|
@ -72,9 +72,9 @@
|
|||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
{{end}}
|
||||
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
|
||||
<td class="blob-excerpt lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="blob-excerpt lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
|
||||
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
|
||||
<td class="lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
|
||||
<td class="lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
|
||||
<td class="lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -90,7 +90,16 @@
|
|||
{{ctx.Locale.Tr "repo.use_template"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if (not $isHomepage)}}
|
||||
{{if $isHomepage}}
|
||||
{{/* only show the "code search" on the repo home page, it only does global search,
|
||||
so do not show it when viewing file or directory to avoid misleading users (it doesn't search in a directory) */}}
|
||||
<form class="ignore-dirty" action="{{.RepoLink}}/search" method="get">
|
||||
<div class="ui small action input">
|
||||
<input name="q" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
|
||||
{{template "shared/search/button"}}
|
||||
</div>
|
||||
</form>
|
||||
{{else}}
|
||||
<span class="breadcrumb repo-path tw-ml-1">
|
||||
<a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
|
||||
{{- range $i, $v := .TreeNames -}}
|
||||
|
@ -103,13 +112,6 @@
|
|||
{{- end -}}
|
||||
</span>
|
||||
{{end}}
|
||||
|
||||
<form class="ignore-dirty" action="{{.RepoLink}}/search" method="get">
|
||||
<div class="ui small action input">
|
||||
<input name="q" value="{{.Keyword}}" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
|
||||
{{template "shared/search/button"}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
|
@ -136,7 +138,7 @@
|
|||
</div>
|
||||
{{template "repo/cite/cite_modal" .}}
|
||||
{{end}}
|
||||
{{if and (not $isHomepage) (not .IsViewFile) (not .IsBlame)}}
|
||||
{{if and (not $isHomepage) (not .IsViewFile) (not .IsBlame)}}{{/* IsViewDirectory (not home), TODO: split the templates, avoid using "if" tricks */}}
|
||||
<a class="ui button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">
|
||||
{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}}
|
||||
</a>
|
||||
|
@ -147,7 +149,7 @@
|
|||
{{template "repo/view_file" .}}
|
||||
{{else if .IsBlame}}
|
||||
{{template "repo/blame" .}}
|
||||
{{else}}
|
||||
{{else}}{{/* IsViewDirectory */}}
|
||||
{{template "repo/view_list" .}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -3843,6 +3843,54 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/actions/secrets": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "List an repo's actions secrets",
|
||||
"operationId": "repoListActionsSecrets",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repository",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repository",
|
||||
"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": {
|
||||
"200": {
|
||||
"$ref": "#/responses/SecretList"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/actions/secrets/{secretname}": {
|
||||
"put": {
|
||||
"consumes": [
|
||||
|
|
|
@ -24,6 +24,12 @@ func TestAPIRepoSecrets(t *testing.T) {
|
|||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/actions/secrets", repo.FullName())).
|
||||
AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
cases := []struct {
|
||||
Name string
|
||||
|
@ -31,7 +37,7 @@ func TestAPIRepoSecrets(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
Name: "",
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
ExpectedStatus: http.StatusMethodNotAllowed,
|
||||
},
|
||||
{
|
||||
Name: "-",
|
||||
|
|
|
@ -2377,7 +2377,7 @@ tbody.commit-list {
|
|||
|
||||
.tag-code,
|
||||
.tag-code td,
|
||||
.tag-code .blob-excerpt {
|
||||
.tag-code.line-expanded {
|
||||
background-color: var(--color-box-body-highlight);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -2393,8 +2393,8 @@ tbody.commit-list {
|
|||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.blob-excerpt {
|
||||
background-color: var(--color-secondary-alpha-30);
|
||||
.line-expanded {
|
||||
background-color: var(--color-secondary-alpha-20);
|
||||
}
|
||||
|
||||
.issue-keyword {
|
||||
|
@ -2553,11 +2553,9 @@ tbody.commit-list {
|
|||
|
||||
.code-diff-unified .add-code,
|
||||
.code-diff-unified .add-code td,
|
||||
.code-diff-split .add-code .lines-num-new,
|
||||
.code-diff-split .add-code .lines-type-marker-new,
|
||||
.code-diff-split .add-code .lines-escape-new,
|
||||
.code-diff-split .add-code .lines-code-new,
|
||||
.code-diff-split .del-code .add-code.lines-num-new,
|
||||
.code-diff-split .del-code .add-code.lines-type-marker-new,
|
||||
.code-diff-split .del-code .add-code.lines-escape-new,
|
||||
.code-diff-split .del-code .add-code.lines-code-new {
|
||||
|
@ -2565,17 +2563,33 @@ tbody.commit-list {
|
|||
border-color: var(--color-diff-added-row-border);
|
||||
}
|
||||
|
||||
.code-diff-split .del-code .lines-num-new,
|
||||
.code-diff-split .del-code .lines-type-marker-new,
|
||||
.code-diff-split .del-code .lines-code-new,
|
||||
.code-diff-split .del-code .lines-escape-new,
|
||||
.code-diff-split .add-code .lines-num-old,
|
||||
.code-diff-split .add-code .lines-escape-old,
|
||||
.code-diff-split .add-code .lines-type-marker-old,
|
||||
.code-diff-split .add-code .lines-code-old {
|
||||
background: var(--color-diff-inactive);
|
||||
}
|
||||
|
||||
.code-diff-split .add-code .lines-num.lines-num-old,
|
||||
.code-diff-split .del-code .lines-num.lines-num-new {
|
||||
background: var(--color-diff-inactive);
|
||||
}
|
||||
|
||||
.code-diff-unified .del-code .lines-num,
|
||||
.code-diff-split .del-code .lines-num {
|
||||
background: var(--color-diff-removed-linenum-bg);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.code-diff-unified .add-code .lines-num,
|
||||
.code-diff-split .add-code .lines-num,
|
||||
.code-diff-split .del-code .add-code.lines-num {
|
||||
background: var(--color-diff-added-linenum-bg);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.code-diff-split tbody tr td:nth-child(5),
|
||||
.code-diff-split tbody tr td.add-comment-right {
|
||||
border-left: 1px solid var(--color-secondary);
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
/* red/green colorblind-friendly colors */
|
||||
/* from GitHub: --diffBlob-addition-*, --diffBlob-deletion-*, etc */
|
||||
:root {
|
||||
--color-diff-added-word-bg: #388bfd66;
|
||||
--color-diff-added-row-bg: #388bfd26;
|
||||
|
||||
--color-diff-removed-word-bg: #db6d2866;
|
||||
--color-diff-removed-row-bg: #db6d2826;
|
||||
--color-diff-added-linenum-bg: #1979fd46;
|
||||
--color-diff-added-row-bg: #1979fd20;
|
||||
--color-diff-added-word-bg: #1979fd66;
|
||||
--color-diff-removed-linenum-bg: #c8622146;
|
||||
--color-diff-removed-row-bg: #c8622120;
|
||||
--color-diff-removed-word-bg: #c8622166;
|
||||
}
|
||||
|
|
|
@ -143,14 +143,16 @@
|
|||
--color-grey-light: #818f9e;
|
||||
--color-gold: #b1983b;
|
||||
--color-white: #ffffff;
|
||||
--color-diff-removed-word-bg: #6f3333;
|
||||
--color-diff-added-word-bg: #3c653c;
|
||||
--color-diff-removed-row-bg: #3c2626;
|
||||
--color-diff-moved-row-bg: #818044;
|
||||
--color-diff-added-row-bg: #283e2d;
|
||||
--color-diff-removed-row-border: #634343;
|
||||
--color-diff-moved-row-border: #bcca6f;
|
||||
--color-diff-added-linenum-bg: #274227;
|
||||
--color-diff-added-row-bg: #203224;
|
||||
--color-diff-added-row-border: #314a37;
|
||||
--color-diff-added-word-bg: #3c653c;
|
||||
--color-diff-moved-row-bg: #818044;
|
||||
--color-diff-moved-row-border: #bcca6f;
|
||||
--color-diff-removed-linenum-bg: #482121;
|
||||
--color-diff-removed-row-bg: #301e1e;
|
||||
--color-diff-removed-row-border: #634343;
|
||||
--color-diff-removed-word-bg: #6f3333;
|
||||
--color-diff-inactive: #22282d;
|
||||
--color-error-border: #a04141;
|
||||
--color-error-bg: #522;
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
/* red/green colorblind-friendly colors */
|
||||
/* from GitHub: --diffBlob-addition-*, --diffBlob-deletion-*, etc */
|
||||
:root {
|
||||
--color-diff-added-word-bg: #54aeff66;
|
||||
--color-diff-added-linenum-bg: #54aeff4d;
|
||||
--color-diff-added-row-bg: #ddf4ff80;
|
||||
|
||||
--color-diff-removed-word-bg: #ffb77c80;
|
||||
--color-diff-added-word-bg: #54aeff66;
|
||||
--color-diff-removed-linenum-bg: #ffb77c4d;
|
||||
--color-diff-removed-row-bg: #fff1e580;
|
||||
--color-diff-removed-word-bg: #ffb77c80;
|
||||
}
|
||||
|
|
|
@ -143,14 +143,16 @@
|
|||
--color-grey-light: #7c838a;
|
||||
--color-gold: #a1882b;
|
||||
--color-white: #ffffff;
|
||||
--color-diff-removed-word-bg: #fdb8c0;
|
||||
--color-diff-added-word-bg: #acf2bd;
|
||||
--color-diff-removed-row-bg: #ffeef0;
|
||||
--color-diff-moved-row-bg: #f1f8d1;
|
||||
--color-diff-added-linenum-bg: #d1f8d9;
|
||||
--color-diff-added-row-bg: #e6ffed;
|
||||
--color-diff-removed-row-border: #f1c0c0;
|
||||
--color-diff-moved-row-border: #d0e27f;
|
||||
--color-diff-added-row-border: #e6ffed;
|
||||
--color-diff-added-word-bg: #acf2bd;
|
||||
--color-diff-moved-row-bg: #f1f8d1;
|
||||
--color-diff-moved-row-border: #d0e27f;
|
||||
--color-diff-removed-linenum-bg: #ffcecb;
|
||||
--color-diff-removed-row-bg: #ffeef0;
|
||||
--color-diff-removed-row-border: #f1c0c0;
|
||||
--color-diff-removed-word-bg: #fdb8c0;
|
||||
--color-diff-inactive: #f0f2f4;
|
||||
--color-error-border: #e0b4b4;
|
||||
--color-error-bg: #fff6f6;
|
||||
|
|
Loading…
Reference in New Issue