Skip to content

Commit 6735dcd

Browse files
committed
Basic support description field for secrets and variables (go-gitea#33484)
1 parent a52720b commit 6735dcd

File tree

18 files changed

+179
-64
lines changed

18 files changed

+179
-64
lines changed

models/actions/variable.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type ActionVariable struct {
3232
RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name)"`
3333
Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"`
3434
Data string `xorm:"LONGTEXT NOT NULL"`
35+
Description string `xorm:"TEXT"`
3536
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
3637
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
3738
}
@@ -40,18 +41,19 @@ func init() {
4041
db.RegisterModel(new(ActionVariable))
4142
}
4243

43-
func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) {
44+
func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data, description string) (*ActionVariable, error) {
4445
if ownerID != 0 && repoID != 0 {
4546
// It's trying to create a variable that belongs to a repository, but OwnerID has been set accidentally.
4647
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
4748
ownerID = 0
4849
}
4950

5051
variable := &ActionVariable{
51-
OwnerID: ownerID,
52-
RepoID: repoID,
53-
Name: strings.ToUpper(name),
54-
Data: data,
52+
OwnerID: ownerID,
53+
RepoID: repoID,
54+
Name: strings.ToUpper(name),
55+
Data: data,
56+
Description: description,
5557
}
5658
return variable, db.Insert(ctx, variable)
5759
}
@@ -86,10 +88,11 @@ func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*ActionVariab
8688
}
8789

8890
func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error) {
89-
count, err := db.GetEngine(ctx).ID(variable.ID).Cols("name", "data").
91+
count, err := db.GetEngine(ctx).ID(variable.ID).Cols("name", "data", "description").
9092
Update(&ActionVariable{
91-
Name: variable.Name,
92-
Data: variable.Data,
93+
Name: variable.Name,
94+
Data: variable.Data,
95+
Description: variable.Description,
9396
})
9497
return count != 0, err
9598
}

models/migrations/migrations.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ func prepareMigrationTasks() []*migration {
373373

374374
// Gitea 1.23.0-rc0 ends at migration ID number 311 (database version 312)
375375
newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge),
376+
newMigration(313, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
376377
}
377378
return preparedMigrations
378379
}

models/migrations/v1_24/v313.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_24 //nolint
5+
6+
import (
7+
"xorm.io/xorm"
8+
)
9+
10+
func AddDescriptionForSecretsAndVariables(x *xorm.Engine) error {
11+
type Secret struct {
12+
Description string `xorm:"TEXT"`
13+
}
14+
15+
type ActionVariable struct {
16+
Description string `xorm:"TEXT"`
17+
}
18+
19+
return x.Sync(new(Secret), new(ActionVariable))
20+
}

models/secret/secret.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type Secret struct {
4040
RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"`
4141
Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"`
4242
Data string `xorm:"LONGTEXT"` // encrypted data
43+
Description string `xorm:"TEXT"`
4344
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
4445
}
4546

@@ -57,7 +58,7 @@ func (err ErrSecretNotFound) Unwrap() error {
5758
}
5859

5960
// InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database
60-
func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) {
61+
func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data, description string) (*Secret, error) {
6162
if ownerID != 0 && repoID != 0 {
6263
// It's trying to create a secret that belongs to a repository, but OwnerID has been set accidentally.
6364
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
@@ -72,10 +73,11 @@ func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, dat
7273
return nil, err
7374
}
7475
secret := &Secret{
75-
OwnerID: ownerID,
76-
RepoID: repoID,
77-
Name: strings.ToUpper(name),
78-
Data: encrypted,
76+
OwnerID: ownerID,
77+
RepoID: repoID,
78+
Name: strings.ToUpper(name),
79+
Data: encrypted,
80+
Description: description,
7981
}
8082
return secret, db.Insert(ctx, secret)
8183
}

modules/structs/secret.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import "time"
1010
type Secret struct {
1111
// the secret's name
1212
Name string `json:"name"`
13+
// the secret's description
14+
Description string `json:"description"`
1315
// swagger:strfmt date-time
1416
Created time.Time `json:"created_at"`
1517
}
@@ -21,4 +23,9 @@ type CreateOrUpdateSecretOption struct {
2123
//
2224
// required: true
2325
Data string `json:"data" binding:"Required"`
26+
27+
// Description of the secret to update
28+
//
29+
// required: false
30+
Description string `json:"description"`
2431
}

modules/structs/variable.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ type CreateVariableOption struct {
1010
//
1111
// required: true
1212
Value string `json:"value" binding:"Required"`
13+
14+
// Description of the variable to create
15+
//
16+
// required: false
17+
Description string `json:"description"`
1318
}
1419

1520
// UpdateVariableOption the option when updating variable
@@ -21,6 +26,11 @@ type UpdateVariableOption struct {
2126
//
2227
// required: true
2328
Value string `json:"value" binding:"Required"`
29+
30+
// Description of the variable to update
31+
//
32+
// required: false
33+
Description string `json:"description"`
2434
}
2535

2636
// ActionVariable return value of the query API
@@ -34,4 +44,6 @@ type ActionVariable struct {
3444
Name string `json:"name"`
3545
// the value of the variable
3646
Data string `json:"data"`
47+
// the description of the variable
48+
Description string `json:"description"`
3749
}

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3694,8 +3694,10 @@ secrets = Secrets
36943694
description = Secrets will be passed to certain actions and cannot be read otherwise.
36953695
none = There are no secrets yet.
36963696
creation = Add Secret
3697+
creation.description = Description
36973698
creation.name_placeholder = case-insensitive, alphanumeric characters or underscores only, cannot start with GITEA_ or GITHUB_
36983699
creation.value_placeholder = Input any content. Whitespace at the start and end will be omitted.
3700+
creation.description_placeholder = Enter short description (optional).
36993701
creation.success = The secret "%s" has been added.
37003702
creation.failed = Failed to add secret.
37013703
deletion = Remove secret

routers/api/v1/org/action.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) {
6161
apiSecrets := make([]*api.Secret, len(secrets))
6262
for k, v := range secrets {
6363
apiSecrets[k] = &api.Secret{
64-
Name: v.Name,
65-
Created: v.CreatedUnix.AsTime(),
64+
Name: v.Name,
65+
Description: v.Description,
66+
Created: v.CreatedUnix.AsTime(),
6667
}
6768
}
6869

@@ -106,7 +107,8 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
106107

107108
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
108109

109-
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data)
110+
_, created, err := secret_service.CreateOrUpdateSecret(
111+
ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description)
110112
if err != nil {
111113
if errors.Is(err, util.ErrInvalidArgument) {
112114
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -230,10 +232,11 @@ func (Action) ListVariables(ctx *context.APIContext) {
230232
variables := make([]*api.ActionVariable, len(vars))
231233
for i, v := range vars {
232234
variables[i] = &api.ActionVariable{
233-
OwnerID: v.OwnerID,
234-
RepoID: v.RepoID,
235-
Name: v.Name,
236-
Data: v.Data,
235+
OwnerID: v.OwnerID,
236+
RepoID: v.RepoID,
237+
Name: v.Name,
238+
Data: v.Data,
239+
Description: v.Description,
237240
}
238241
}
239242

@@ -281,10 +284,11 @@ func (Action) GetVariable(ctx *context.APIContext) {
281284
}
282285

283286
variable := &api.ActionVariable{
284-
OwnerID: v.OwnerID,
285-
RepoID: v.RepoID,
286-
Name: v.Name,
287-
Data: v.Data,
287+
OwnerID: v.OwnerID,
288+
RepoID: v.RepoID,
289+
Name: v.Name,
290+
Data: v.Data,
291+
Description: v.Description,
288292
}
289293

290294
ctx.JSON(http.StatusOK, variable)
@@ -386,7 +390,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
386390
return
387391
}
388392

389-
if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil {
393+
if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil {
390394
if errors.Is(err, util.ErrInvalidArgument) {
391395
ctx.Error(http.StatusBadRequest, "CreateVariable", err)
392396
} else {
@@ -450,7 +454,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
450454
if opt.Name == "" {
451455
opt.Name = ctx.PathParam("variablename")
452456
}
453-
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
457+
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value, opt.Description); err != nil {
454458
if errors.Is(err, util.ErrInvalidArgument) {
455459
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
456460
} else {

routers/api/v1/repo/action.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) {
6969
apiSecrets := make([]*api.Secret, len(secrets))
7070
for k, v := range secrets {
7171
apiSecrets[k] = &api.Secret{
72-
Name: v.Name,
73-
Created: v.CreatedUnix.AsTime(),
72+
Name: v.Name,
73+
Description: v.Description,
74+
Created: v.CreatedUnix.AsTime(),
7475
}
7576
}
7677

@@ -121,7 +122,8 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
121122

122123
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
123124

124-
_, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data)
125+
_, created, err := secret_service.CreateOrUpdateSecret(
126+
ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data, opt.Description)
125127
if err != nil {
126128
if errors.Is(err, util.ErrInvalidArgument) {
127129
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -234,10 +236,11 @@ func (Action) GetVariable(ctx *context.APIContext) {
234236
}
235237

236238
variable := &api.ActionVariable{
237-
OwnerID: v.OwnerID,
238-
RepoID: v.RepoID,
239-
Name: v.Name,
240-
Data: v.Data,
239+
OwnerID: v.OwnerID,
240+
RepoID: v.RepoID,
241+
Name: v.Name,
242+
Data: v.Data,
243+
Description: v.Description,
241244
}
242245

243246
ctx.JSON(http.StatusOK, variable)
@@ -347,7 +350,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
347350
return
348351
}
349352

350-
if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value); err != nil {
353+
if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value, opt.Description); err != nil {
351354
if errors.Is(err, util.ErrInvalidArgument) {
352355
ctx.Error(http.StatusBadRequest, "CreateVariable", err)
353356
} else {
@@ -414,7 +417,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
414417
if opt.Name == "" {
415418
opt.Name = ctx.PathParam("variablename")
416419
}
417-
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
420+
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value, opt.Description); err != nil {
418421
if errors.Is(err, util.ErrInvalidArgument) {
419422
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
420423
} else {
@@ -472,9 +475,11 @@ func (Action) ListVariables(ctx *context.APIContext) {
472475
variables := make([]*api.ActionVariable, len(vars))
473476
for i, v := range vars {
474477
variables[i] = &api.ActionVariable{
475-
OwnerID: v.OwnerID,
476-
RepoID: v.RepoID,
477-
Name: v.Name,
478+
OwnerID: v.OwnerID,
479+
RepoID: v.RepoID,
480+
Name: v.Name,
481+
Data: v.Data,
482+
Description: v.Description,
478483
}
479484
}
480485

routers/api/v1/user/action.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ func CreateOrUpdateSecret(ctx *context.APIContext) {
4949

5050
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
5151

52-
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data)
52+
_, created, err := secret_service.CreateOrUpdateSecret(
53+
ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description)
5354
if err != nil {
5455
if errors.Is(err, util.ErrInvalidArgument) {
5556
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -153,7 +154,7 @@ func CreateVariable(ctx *context.APIContext) {
153154
return
154155
}
155156

156-
if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil {
157+
if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil {
157158
if errors.Is(err, util.ErrInvalidArgument) {
158159
ctx.Error(http.StatusBadRequest, "CreateVariable", err)
159160
} else {
@@ -212,7 +213,7 @@ func UpdateVariable(ctx *context.APIContext) {
212213
if opt.Name == "" {
213214
opt.Name = ctx.PathParam("variablename")
214215
}
215-
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
216+
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value, opt.Description); err != nil {
216217
if errors.Is(err, util.ErrInvalidArgument) {
217218
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
218219
} else {
@@ -296,10 +297,11 @@ func GetVariable(ctx *context.APIContext) {
296297
}
297298

298299
variable := &api.ActionVariable{
299-
OwnerID: v.OwnerID,
300-
RepoID: v.RepoID,
301-
Name: v.Name,
302-
Data: v.Data,
300+
OwnerID: v.OwnerID,
301+
RepoID: v.RepoID,
302+
Name: v.Name,
303+
Data: v.Data,
304+
Description: v.Description,
303305
}
304306

305307
ctx.JSON(http.StatusOK, variable)
@@ -341,10 +343,11 @@ func ListVariables(ctx *context.APIContext) {
341343
variables := make([]*api.ActionVariable, len(vars))
342344
for i, v := range vars {
343345
variables[i] = &api.ActionVariable{
344-
OwnerID: v.OwnerID,
345-
RepoID: v.RepoID,
346-
Name: v.Name,
347-
Data: v.Data,
346+
OwnerID: v.OwnerID,
347+
RepoID: v.RepoID,
348+
Name: v.Name,
349+
Data: v.Data,
350+
Description: v.Description,
348351
}
349352
}
350353

routers/web/shared/actions/variables.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func SetVariablesContext(ctx *context.Context, ownerID, repoID int64) {
2828
func CreateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) {
2929
form := web.GetForm(ctx).(*forms.EditVariableForm)
3030

31-
v, err := actions_service.CreateVariable(ctx, ownerID, repoID, form.Name, form.Data)
31+
v, err := actions_service.CreateVariable(ctx, ownerID, repoID, form.Name, form.Data, form.Description)
3232
if err != nil {
3333
log.Error("CreateVariable: %v", err)
3434
ctx.JSONError(ctx.Tr("actions.variables.creation.failed"))
@@ -43,7 +43,7 @@ func UpdateVariable(ctx *context.Context, redirectURL string) {
4343
id := ctx.PathParamInt64("variable_id")
4444
form := web.GetForm(ctx).(*forms.EditVariableForm)
4545

46-
if ok, err := actions_service.UpdateVariable(ctx, id, form.Name, form.Data); err != nil || !ok {
46+
if ok, err := actions_service.UpdateVariable(ctx, id, form.Name, form.Data, form.Description); err != nil || !ok {
4747
log.Error("UpdateVariable: %v", err)
4848
ctx.JSONError(ctx.Tr("actions.variables.update.failed"))
4949
return

0 commit comments

Comments
 (0)