Skip to content

Commit

Permalink
Add API for Variables (#29520)
Browse files Browse the repository at this point in the history
close #27801

---------

Co-authored-by: silverwind <me@silverwind.io>
  • Loading branch information
sillyguodong and silverwind authored Mar 28, 2024
1 parent 6103623 commit 62b073e
Show file tree
Hide file tree
Showing 16 changed files with 2,137 additions and 109 deletions.
27 changes: 16 additions & 11 deletions models/actions/variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ package actions
import (
"context"
"errors"
"fmt"
"strings"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"xorm.io/builder"
)
Expand Down Expand Up @@ -55,24 +53,24 @@ type FindVariablesOpts struct {
db.ListOptions
OwnerID int64
RepoID int64
Name string
}

func (opts FindVariablesOpts) ToConds() builder.Cond {
cond := builder.NewCond()
// Since we now support instance-level variables,
// there is no need to check for null values for `owner_id` and `repo_id`
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})

if opts.Name != "" {
cond = cond.And(builder.Eq{"name": strings.ToUpper(opts.Name)})
}
return cond
}

func GetVariableByID(ctx context.Context, variableID int64) (*ActionVariable, error) {
var variable ActionVariable
has, err := db.GetEngine(ctx).Where("id=?", variableID).Get(&variable)
if err != nil {
return nil, err
} else if !has {
return nil, fmt.Errorf("variable with id %d: %w", variableID, util.ErrNotExist)
}
return &variable, nil
func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*ActionVariable, error) {
return db.Find[ActionVariable](ctx, opts)
}

func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error) {
Expand All @@ -84,6 +82,13 @@ func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error)
return count != 0, err
}

func DeleteVariable(ctx context.Context, id int64) error {
if _, err := db.DeleteByID[ActionVariable](ctx, id); err != nil {
return err
}
return nil
}

func GetVariablesOfRun(ctx context.Context, run *ActionRun) (map[string]string, error) {
variables := map[string]string{}

Expand Down
37 changes: 37 additions & 0 deletions modules/structs/variable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package structs

// CreateVariableOption the option when creating variable
// swagger:model
type CreateVariableOption struct {
// Value of the variable to create
//
// required: true
Value string `json:"value" binding:"Required"`
}

// UpdateVariableOption the option when updating variable
// swagger:model
type UpdateVariableOption struct {
// New name for the variable. If the field is empty, the variable name won't be updated.
Name string `json:"name"`
// Value of the variable to update
//
// required: true
Value string `json:"value" binding:"Required"`
}

// ActionVariable return value of the query API
// swagger:model
type ActionVariable struct {
// the owner to which the variable belongs
OwnerID int64 `json:"owner_id"`
// the repository to which the variable belongs
RepoID int64 `json:"repo_id"`
// the name of the variable
Name string `json:"name"`
// the value of the variable
Data string `json:"data"`
}
9 changes: 9 additions & 0 deletions modules/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,12 @@ func IfZero[T comparable](v, def T) T {
}
return v
}

func ReserveLineBreakForTextarea(input string) string {
// Since the content is from a form which is a textarea, the line endings are \r\n.
// It's a standard behavior of HTML.
// But we want to store them as \n like what GitHub does.
// And users are unlikely to really need to keep the \r.
// Other than this, we should respect the original content, even leading or trailing spaces.
return strings.ReplaceAll(input, "\r\n", "\n")
}
5 changes: 5 additions & 0 deletions modules/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,8 @@ func TestToPointer(t *testing.T) {
val123 := 123
assert.False(t, &val123 == ToPointer(val123))
}

func TestReserveLineBreakForTextarea(t *testing.T) {
assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata"), "test\ndata")
assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata\r\n"), "test\ndata\n")
}
27 changes: 27 additions & 0 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,15 @@ func Routes() *web.Route {
Delete(user.DeleteSecret)
})

m.Group("/variables", func() {
m.Get("", user.ListVariables)
m.Combo("/{variablename}").
Get(user.GetVariable).
Delete(user.DeleteVariable).
Post(bind(api.CreateVariableOption{}), user.CreateVariable).
Put(bind(api.UpdateVariableOption{}), user.UpdateVariable)
})

m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), user.GetRegistrationToken)
})
Expand Down Expand Up @@ -1073,6 +1082,15 @@ func Routes() *web.Route {
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)
})
Expand Down Expand Up @@ -1452,6 +1470,15 @@ func Routes() *web.Route {
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)
})
Expand Down
Loading

0 comments on commit 62b073e

Please sign in to comment.