From c88e2ade343058577a8d45918fa579ddb4202cb9 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Sun, 23 Apr 2023 16:48:12 +0800 Subject: [PATCH 01/65] implements varibales --- models/migrations/migrations.go | 2 + models/migrations/v1_20/v255.go | 24 ++++++ models/variable/variable.go | 109 ++++++++++++++++++++++++++++ routers/api/actions/runner/utils.go | 27 +++++++ 4 files changed, 162 insertions(+) create mode 100644 models/migrations/v1_20/v255.go create mode 100644 models/variable/variable.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 9de5931d71468..c202c99eabb67 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -487,6 +487,8 @@ var migrations = []Migration{ NewMigration("Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam), // v254 -> v255 NewMigration("Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable), + // v255 -> v256 + NewMigration("Add varibale table", v1_20.CreateVariableTable), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_20/v255.go b/models/migrations/v1_20/v255.go new file mode 100644 index 0000000000000..b8a384a0f54e3 --- /dev/null +++ b/models/migrations/v1_20/v255.go @@ -0,0 +1,24 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_20 //nolint + +import ( + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func CreateVariableTable(x *xorm.Engine) error { + type Variable struct { + ID int64 `xorm:"pk autoincr"` + OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"` + RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"` + Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"` + Data string `xorm:"LONGTEXT NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + } + + return x.Sync(new(Variable)) +} diff --git a/models/variable/variable.go b/models/variable/variable.go new file mode 100644 index 0000000000000..c1ecc6d471663 --- /dev/null +++ b/models/variable/variable.go @@ -0,0 +1,109 @@ +package variable + +import ( + "fmt" + "regexp" + "strings" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + "golang.org/x/net/context" + "xorm.io/builder" +) + +type Variable struct { + ID int64 `xorm:"pk autoincr"` + OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"` + RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"` + Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"` + Data string `xorm:"LONGTEXT NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` +} + +func init() { + db.RegisterModel(new(Variable)) +} + +type ErrVariableUnbound struct{} + +func (err ErrVariableUnbound) Error() string { + return "variable is not bound to the repo or org" +} + +type ErrVariableInvalidValue struct { + Name *string + Data *string +} + +func (err ErrVariableInvalidValue) Error() string { + if err.Name != nil { + return fmt.Sprintf("varibale name %s is invalid", *err.Name) + } + if err.Data != nil { + return fmt.Sprintf("variable data %s is invalid", *err.Data) + } + return util.ErrInvalidArgument.Error() +} + +// some regular expression of `variables` +// reference to: https://docs.github.com/en/actions/learn-github-actions/variables#naming-conventions-for-configuration-variables +var ( + varibaleNameReg = regexp.MustCompile("(?i)^[A-Z_][A-Z0-9_]*$") + variableForbiddenPrefixReg = regexp.MustCompile("(?i)^GIT(EA|HUB)_") +) + +func (v *Variable) Validate() error { + switch { + case v.OwnerID == 0 && v.RepoID == 0: + return ErrVariableUnbound{} + case len(v.Name) == 0 || len(v.Name) > 50: + return ErrVariableInvalidValue{Name: &v.Name} + case len(v.Data) == 0: + return ErrVariableInvalidValue{Data: &v.Data} + case !varibaleNameReg.MatchString(v.Name) || variableForbiddenPrefixReg.MatchString(v.Name): + return ErrVariableInvalidValue{Name: &v.Name} + default: + return nil + } +} + +func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*Variable, error) { + variable := &Variable{ + OwnerID: ownerID, + RepoID: repoID, + Name: strings.ToUpper(name), + Data: data, + } + if err := variable.Validate(); err != nil { + return variable, err + } + return variable, db.Insert(ctx, variable) +} + +type FindVariablesOpts struct { + db.ListOptions + OwnerID int64 + RepoID int64 +} + +func (opts *FindVariablesOpts) toConds() builder.Cond { + cond := builder.NewCond() + if opts.OwnerID > 0 { + cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) + } + if opts.RepoID > 0 { + cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) + } + return cond +} + +func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*Variable, error) { + var variables []*Variable + sess := db.GetEngine(ctx) + if opts.PageSize != 0 { + sess = db.SetSessionPagination(sess, &opts.ListOptions) + } + return variables, sess.Where(opts.toConds()).Find(&variables) +} diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 705867a9b1067..5e7ba682f8021 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -9,6 +9,7 @@ import ( actions_model "code.gitea.io/gitea/models/actions" secret_model "code.gitea.io/gitea/models/secret" + variable_model "code.gitea.io/gitea/models/variable" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -36,6 +37,7 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv WorkflowPayload: t.Job.WorkflowPayload, Context: generateTaskContext(t), Secrets: getSecretsOfTask(ctx, t), + Vars: getVariablesOfTask(ctx, t), } if needs, err := findTaskNeeds(ctx, t); err != nil { @@ -88,6 +90,31 @@ func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[s return secrets } +func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { + variables := map[string]string{} + + // Org level + ownerVariables, err := variable_model.FindVariables(ctx, variable_model.FindVariablesOpts{OwnerID: task.Job.Run.Repo.OwnerID}) + if err != nil { + log.Error("find variables of org: %d, error: %v", task.Job.Run.Repo.OwnerID, err) + } + + // Repo level + repoVariables, err := variable_model.FindVariables(ctx, variable_model.FindVariablesOpts{RepoID: task.Job.Run.RepoID}) + if err != nil { + log.Error("find variables of repo: %d, error: %v", task.Job.Run.RepoID, err) + } + + //TODO: Env levl + + // Level precedence: ENV > REPO > ORG + for _, v := range append(ownerVariables, repoVariables...) { + variables[v.Name] = v.Data + } + + return variables +} + func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { event := map[string]interface{}{} _ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event) From 427dfa24ac84068de2d49308b4f0b3ae1c6a99d4 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Sun, 23 Apr 2023 17:11:13 +0800 Subject: [PATCH 02/65] typo --- routers/api/actions/runner/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 5e7ba682f8021..ee2ad76674185 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -105,7 +105,7 @@ func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map log.Error("find variables of repo: %d, error: %v", task.Job.Run.RepoID, err) } - //TODO: Env levl + // TODO: Env level // Level precedence: ENV > REPO > ORG for _, v := range append(ownerVariables, repoVariables...) { From 5edf8ae13a0be1b2324a50e711b8db221bc41df9 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Sun, 23 Apr 2023 23:01:37 +0800 Subject: [PATCH 03/65] fix context package --- models/variable/variable.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/variable/variable.go b/models/variable/variable.go index c1ecc6d471663..e45da66ed1893 100644 --- a/models/variable/variable.go +++ b/models/variable/variable.go @@ -1,6 +1,7 @@ package variable import ( + "context" "fmt" "regexp" "strings" @@ -8,7 +9,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "golang.org/x/net/context" "xorm.io/builder" ) From a438e97feed4c38cc3d21f4bd35b7a7292abe4ce Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Mon, 8 May 2023 09:39:06 +0800 Subject: [PATCH 04/65] update --- models/variable/variable.go | 24 ++++ options/locale/locale_en-US.ini | 20 ++++ routers/web/repo/setting/variables.go | 100 +++++++++++++++++ routers/web/shared/variables/variables.go | 104 ++++++++++++++++++ routers/web/web.go | 10 ++ services/forms/user_form.go | 10 ++ templates/repo/settings/actions.tmpl | 2 + templates/repo/settings/navbar.tmpl | 3 + templates/shared/variables/variable_list.tmpl | 96 ++++++++++++++++ web_src/js/features/repo-legacy.js | 3 +- web_src/js/features/repo-settings.js | 47 ++++++++ 11 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 routers/web/repo/setting/variables.go create mode 100644 routers/web/shared/variables/variables.go create mode 100644 templates/shared/variables/variable_list.tmpl diff --git a/models/variable/variable.go b/models/variable/variable.go index e45da66ed1893..1bbefdefda6b0 100644 --- a/models/variable/variable.go +++ b/models/variable/variable.go @@ -1,3 +1,6 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + package variable import ( @@ -107,3 +110,24 @@ func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*Variable, er } return variables, sess.Where(opts.toConds()).Find(&variables) } + +func GetVariableByID(ctx context.Context, variableID int64) (*Variable, error) { + var variable Variable + 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 UpdateVariable(ctx context.Context, variable *Variable) (bool, error) { + count, err := db.GetEngine(ctx).ID(variable.ID).Cols("name", "data"). + Where("owner_id = ? and repo_id = ?", variable.OwnerID, variable.RepoID). + Update(&Variable{ + Name: variable.Name, + Data: variable.Data, + }) + return count != 0, err +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ee8ec1a3adca5..efb7167a4cd9c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3445,6 +3445,26 @@ runs.no_matching_runner_helper = No matching runner: %s need_approval_desc = Need approval to run workflows for fork pull request. +variables = Variables +variables.management = Variables Management +variables.creation = Add Variable +variables.none = There are no variables yet. +variables.delete = Delete Variable "%s" +variables.edit_tooltip = Edit Variable "%s" +variables.deletion = Remove variable +variables.deletion.description = Removing a variable is permanent and cannot be undone. Continue? +variables.description = Variables will be passed to certain actions and cannot be read otherwise. +variables.name = Name +variables.value = Value +variables.id_not_exist = Variable with id %d not exists. +variables.edit = Edit Variable +variables.deletion.failed = Failed to remove variable. +variables.deletion.success = The variable has been removed. +variables.creation.failed = Failed to add variable. +variables.creation.success = The variable "%s" has been added. +variables.update.failed = Failed to edit variable. +variables.update.success = The variable has been edited. + [projects] type-1.display_name = Individual Project type-2.display_name = Repository Project diff --git a/routers/web/repo/setting/variables.go b/routers/web/repo/setting/variables.go new file mode 100644 index 0000000000000..98c7f3a372b99 --- /dev/null +++ b/routers/web/repo/setting/variables.go @@ -0,0 +1,100 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "errors" + "net/http" + + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + shared "code.gitea.io/gitea/routers/web/shared/variables" +) + +const ( + // TODO: Separate from runners when layout is ready + tplRepoVariables base.TplName = "repo/settings/actions" + tplOrgVaribales base.TplName = "org/settings/actions" +) + +type variablesCtx struct { + OwnerID int64 + RepoID int64 + IsRepo bool + IsOrg bool + VariablesTemplate base.TplName + RedirectLink string +} + +func getVariablesCtx(ctx *context.Context) (*variablesCtx, error) { + if ctx.Data["PageIsRepoSettings"] == true { + return &variablesCtx{ + RepoID: ctx.Repo.Repository.ID, + IsRepo: true, + VariablesTemplate: tplRepoVariables, + RedirectLink: ctx.Repo.RepoLink + "/settings/actions/variables", + }, nil + } + + if ctx.Data["PageIsOrgSettings"] == true { + return &variablesCtx{ + OwnerID: ctx.ContextUser.ID, + IsOrg: true, + VariablesTemplate: tplOrgVaribales, + RedirectLink: ctx.Org.OrgLink + "/settings/actions/variables", + }, nil + } + + return nil, errors.New("unable to set Variables context") +} + +func Variables(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("actions.variables") + ctx.Data["PageType"] = "variables" + ctx.Data["PageIsSharedSettingsVariables"] = true + + vCtx, err := getVariablesCtx(ctx) + if err != nil { + ctx.ServerError("getVariablesCtx", err) + return + } + + shared.SetVariablesContext(ctx, vCtx.OwnerID, vCtx.RepoID) + if ctx.Written() { + return + } + + ctx.HTML(http.StatusOK, vCtx.VariablesTemplate) +} + +func VariableDelete(ctx *context.Context) { + vCtx, err := getVariablesCtx(ctx) + if err != nil { + ctx.ServerError("getVariablesCtx", err) + return + } + shared.DeleteVariable(ctx, vCtx.OwnerID, vCtx.RepoID, vCtx.RedirectLink) +} + +func VariableCreate(ctx *context.Context) { + vCtx, err := getVariablesCtx(ctx) + if err != nil { + ctx.ServerError("getVariablesCtx", err) + return + } + shared.CreateVariable(ctx, vCtx.OwnerID, vCtx.RepoID, vCtx.RedirectLink) +} + +func VariableUpdate(ctx *context.Context) { + vCtx, err := getVariablesCtx(ctx) + if err != nil { + ctx.ServerError("getVariablesCtx", err) + return + } + shared.UpdateVariable(ctx, vCtx.OwnerID, vCtx.RepoID, vCtx.RedirectLink) +} + +func VariableByID(ctx *context.Context) { + shared.GetVariable(ctx) +} diff --git a/routers/web/shared/variables/variables.go b/routers/web/shared/variables/variables.go new file mode 100644 index 0000000000000..095c5df16525b --- /dev/null +++ b/routers/web/shared/variables/variables.go @@ -0,0 +1,104 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package varibales + +import ( + "net/http" + + "code.gitea.io/gitea/models/db" + variable_model "code.gitea.io/gitea/models/variable" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/private" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" +) + +func SetVariablesContext(ctx *context.Context, ownerID, repoID int64) { + variables, err := variable_model.FindVariables(ctx, variable_model.FindVariablesOpts{ + OwnerID: ownerID, + RepoID: repoID, + }) + if err != nil { + ctx.ServerError("FindVariables", err) + return + } + ctx.Data["Variables"] = variables +} + +func DeleteVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) { + id := ctx.ParamsInt64(":variableID") + + if _, err := db.DeleteByBean(ctx, &variable_model.Variable{ + ID: id, + OwnerID: ownerID, + RepoID: repoID, + }); err != nil { + log.Error("Delete variable [%d] failed: %v", id, err) + ctx.Flash.Error(ctx.Tr("actions.variables.deletion.failed")) + } else { + ctx.Flash.Success(ctx.Tr("actions.variables.deletion.success")) + } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": redirectURL, + }) +} + +func CreateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) { + form := web.GetForm(ctx).(*forms.EditVariableForm) + + v, err := variable_model.InsertVariable(ctx, ownerID, repoID, form.Name, form.Data) + if err != nil { + log.Error("InsertVariable error: %v", err) + ctx.Flash.Error(ctx.Tr("actions.variables.creation.failed")) + } else { + ctx.Flash.Success(ctx.Tr("actions.variables.creation.success", v.Name)) + } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": redirectURL, + }) +} + +func GetVariable(ctx *context.Context) { + id := ctx.ParamsInt64(":variableID") + + v, err := variable_model.GetVariableByID(ctx, id) + if err != nil { + log.Error("GetVariableByID error: %v", err) + ctx.JSON(http.StatusInternalServerError, private.Response{ + Err: err.Error(), + UserMsg: ctx.Tr("actions.variables.id_not_exist", id), + }) + return + } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "id": v.ID, + "name": v.Name, + "data": v.Data, + }) +} + +func UpdateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) { + id := ctx.ParamsInt64(":variableID") + form := web.GetForm(ctx).(*forms.EditVariableForm) + ok, err := variable_model.UpdateVariable(ctx, &variable_model.Variable{ + ID: id, + OwnerID: ownerID, + RepoID: repoID, + Name: form.Name, + Data: form.Data, + }) + if err != nil || !ok { + log.Error("UpdateVariable error: %v", err) + ctx.Flash.Error(ctx.Tr("actions.variables.update.failed")) + } else { + ctx.Flash.Success(ctx.Tr("actions.variables.update.success")) + } + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": redirectURL, + }) +} diff --git a/routers/web/web.go b/routers/web/web.go index e904db321d816..1bae249954af7 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -290,6 +290,15 @@ func registerRoutes(m *web.Route) { m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost) } + addSettingVariablesRoutes := func() { + m.Group("/variables", func() { + m.Get("", repo_setting.Variables) + m.Post("/new", web.Bind(forms.EditVariableForm{}), repo_setting.VariableCreate) + m.Post("/{variableID}/edit", web.Bind(forms.EditVariableForm{}), repo_setting.VariableUpdate) + m.Post("/{variableID}/delete", repo_setting.VariableDelete) + }) + } + addSettingsSecretsRoutes := func() { m.Group("/secrets", func() { m.Get("", repo_setting.Secrets) @@ -934,6 +943,7 @@ func registerRoutes(m *web.Route) { m.Get("", repo_setting.RedirectToDefaultSetting) addSettingsRunnersRoutes() addSettingsSecretsRoutes() + addSettingVariablesRoutes() }, actions.MustEnableActions) }, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer)) }, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef()) diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 285bc398b26c5..160180ed8770c 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -376,6 +376,16 @@ func (f *AddSecretForm) Validate(req *http.Request, errs binding.Errors) binding return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } +type EditVariableForm struct { + Name string `binding:"Required;MaxSize(50)"` + Data string `binding:"Required"` +} + +func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middleware.Validate(errs, ctx.Data, f, ctx.Locale) +} + // NewAccessTokenForm form for creating access token type NewAccessTokenForm struct { Name string `binding:"Required;MaxSize(255)"` diff --git a/templates/repo/settings/actions.tmpl b/templates/repo/settings/actions.tmpl index 72944234a3e8e..f38ab5b658412 100644 --- a/templates/repo/settings/actions.tmpl +++ b/templates/repo/settings/actions.tmpl @@ -4,6 +4,8 @@ {{template "shared/actions/runner_list" .}} {{else if eq .PageType "secrets"}} {{template "shared/secrets/add_list" .}} + {{else if eq .PageType "variables"}} + {{template "shared/variables/variable_list" .}} {{end}} {{template "repo/settings/layout_footer" .}} diff --git a/templates/repo/settings/navbar.tmpl b/templates/repo/settings/navbar.tmpl index b1beda7c944c1..a818810344123 100644 --- a/templates/repo/settings/navbar.tmpl +++ b/templates/repo/settings/navbar.tmpl @@ -43,6 +43,9 @@ {{.locale.Tr "secrets.secrets"}} + + {{.locale.Tr "actions.variables"}} + {{end}} diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl new file mode 100644 index 0000000000000..83d881ad7162e --- /dev/null +++ b/templates/shared/variables/variable_list.tmpl @@ -0,0 +1,96 @@ +

+ {{.locale.Tr "actions.variables.management"}} +
+ +
+

+
+ {{if .Variables}} +
+ {{range .Variables}} +
+
+ + {{$.locale.Tr "settings.add_on"}} + {{.CreatedUnix.FormatShort}} + + + +
+
+ {{.Name}} +
{{.Data}}
+
+
+ {{end}} +
+ {{else}} + {{.locale.Tr "actions.variables.none"}} + {{end}} +
+ + + + diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index c3bd0ccb760d4..9de6aafa8723d 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -19,7 +19,7 @@ import {initRepoDiffConversationNav} from './repo-diff.js'; import {createDropzone} from './dropzone.js'; import {initCommentContent, initMarkupContent} from '../markup/content.js'; import {initCompReactionSelector} from './comp/ReactionSelector.js'; -import {initRepoSettingBranches} from './repo-settings.js'; +import {initRepoSettingBranches, initRepoSettingVariables} from './repo-settings.js'; import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.js'; import {hideElem, showElem} from '../utils/dom.js'; import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js'; @@ -532,6 +532,7 @@ export function initRepository() { initCitationFileCopyContent(); initRepoCommonLanguageStats(); initRepoSettingBranches(); + initRepoSettingVariables(); // Issues if ($('.repository.view.issue').length > 0) { diff --git a/web_src/js/features/repo-settings.js b/web_src/js/features/repo-settings.js index 7105a14b30265..428a31a4c5652 100644 --- a/web_src/js/features/repo-settings.js +++ b/web_src/js/features/repo-settings.js @@ -82,3 +82,50 @@ export function initRepoSettingBranches() { if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable }); } + +export function initRepoSettingVariables() { + $('.show-variable-edit-modal').on('click', function () { + const target = $(this).attr('data-modal'); + const $modal = $(target); + // clear input/textarea value + $modal.find('input[name=name]').val(''); + $modal.find('textarea[name=data]').val(''); + // set dialog header + const $header = $modal.find('#variable-edit-header'); + $header.text($(this).attr('data-modal-header')); + + if ($(this).attr('data-is-new') === 'false') { + // edit variable dialog + const oldName = $(this).attr('data-old-name'); + const oldValue = $(this).attr('data-old-value'); + $modal.find('input[name=name]').val(oldName); + $modal.find('textarea[name=data]').val(oldValue); + } + + const url = $(this).attr('data-base-action') + const commitButton = $modal.find('.actions > .ok.button'); + $(commitButton).on('click', (e) => { + e.preventDefault(); + $.ajax({ + method: 'POST', + url: url, + headers: { + 'X-Csrf-Token': csrfToken, + }, + data: JSON.stringify({ + name: $modal.find('input[name=name]').val(), + data: $modal.find('textarea[name=data]').val(), + }), + contentType: 'application/json', + }).done((data) => { + if (data.redirect) { + window.location.href = data.redirect; + } else if (redirect) { + window.location.href = redirect; + } else { + window.location.reload(); + } + }); + }); + }); +} From b018fee166b456f9e30c399705690093f4e6d60b Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Mon, 8 May 2023 14:26:05 +0800 Subject: [PATCH 05/65] fix lint --- models/variable/variable.go | 3 + routers/web/shared/variables/variables.go | 3 +- templates/org/settings/actions.tmpl | 2 + templates/org/settings/navbar.tmpl | 3 + templates/shared/variables/variable_list.tmpl | 108 +++++++++--------- web_src/js/features/repo-settings.js | 28 ++--- 6 files changed, 73 insertions(+), 74 deletions(-) diff --git a/models/variable/variable.go b/models/variable/variable.go index 1bbefdefda6b0..e590830df946d 100644 --- a/models/variable/variable.go +++ b/models/variable/variable.go @@ -123,6 +123,9 @@ func GetVariableByID(ctx context.Context, variableID int64) (*Variable, error) { } func UpdateVariable(ctx context.Context, variable *Variable) (bool, error) { + if err := variable.Validate(); err != nil { + return false, err + } count, err := db.GetEngine(ctx).ID(variable.ID).Cols("name", "data"). Where("owner_id = ? and repo_id = ?", variable.OwnerID, variable.RepoID). Update(&Variable{ diff --git a/routers/web/shared/variables/variables.go b/routers/web/shared/variables/variables.go index 095c5df16525b..12976495556b0 100644 --- a/routers/web/shared/variables/variables.go +++ b/routers/web/shared/variables/variables.go @@ -5,6 +5,7 @@ package varibales import ( "net/http" + "strings" "code.gitea.io/gitea/models/db" variable_model "code.gitea.io/gitea/models/variable" @@ -89,7 +90,7 @@ func UpdateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL str ID: id, OwnerID: ownerID, RepoID: repoID, - Name: form.Name, + Name: strings.ToUpper(form.Name), Data: form.Data, }) if err != nil || !ok { diff --git a/templates/org/settings/actions.tmpl b/templates/org/settings/actions.tmpl index b3b24e05174cb..6ca0d7ff30137 100644 --- a/templates/org/settings/actions.tmpl +++ b/templates/org/settings/actions.tmpl @@ -4,6 +4,8 @@ {{template "shared/actions/runner_list" .}} {{else if eq .PageType "secrets"}} {{template "shared/secrets/add_list" .}} + {{else if eq .PageType "variables"}} + {{template "shared/variables/variable_list" .}} {{end}} {{template "org/settings/layout_footer" .}} diff --git a/templates/org/settings/navbar.tmpl b/templates/org/settings/navbar.tmpl index fcce43f914a21..e5bda312a532d 100644 --- a/templates/org/settings/navbar.tmpl +++ b/templates/org/settings/navbar.tmpl @@ -32,6 +32,9 @@ {{.locale.Tr "secrets.secrets"}} + + {{.locale.Tr "actions.variables"}} + {{end}} diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index 83d881ad7162e..b017811edaf14 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -2,58 +2,59 @@ {{.locale.Tr "actions.variables.management"}}
+ data-is-new="true" + data-base-action="{{.Link}}/new" + data-modal="#edit-variable-modal" + data-modal-header="{{.locale.Tr "actions.variables.creation"}}" + > + {{.locale.Tr "actions.variables.creation"}} +
- {{if .Variables}} -
- {{range .Variables}} -
-
- - {{$.locale.Tr "settings.add_on"}} - {{.CreatedUnix.FormatShort}} - - - -
-
+ {{if .Variables}} +
+ {{range .Variables}} +
+
+ + {{$.locale.Tr "settings.add_on"}} + {{.CreatedUnix.FormatShort}} + + + +
+
{{.Name}}
{{.Data}}
-
- {{end}} -
- {{else}} - {{.locale.Tr "actions.variables.none"}} - {{end}} +
+ {{end}} +
+ {{else}} + {{.locale.Tr "actions.variables.none"}} + {{end}}
+{{/** Edit Variable Dialog */}} {{template "base/modal_actions_confirm" (dict "locale" $.locale "ModalButtonTypes" "confirm")}}
+{{/** Delete Variable Confirm Dialog */}} {{end}} From 06eec8bcc2fdb6c63bb80af3f159fb7409b6689b Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Fri, 19 May 2023 16:53:51 +0800 Subject: [PATCH 18/65] use fetch request --- web_src/js/features/shared.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/web_src/js/features/shared.js b/web_src/js/features/shared.js index 7e9338425e21c..66a9b00b98c80 100644 --- a/web_src/js/features/shared.js +++ b/web_src/js/features/shared.js @@ -21,18 +21,24 @@ export function initSettingVariables() { $modal.find('textarea[name=data]').val(oldValue); } - const url = $(this).attr('data-base-action'); const commitButton = $modal.find('.actions > .ok.button'); - $(commitButton).on('click', (e) => { + $(commitButton).on('click', async (e) => { e.preventDefault(); - $.post(url, { - _csrf: csrfToken, - name: $modal.find('input[name=name]').val(), - data: $modal.find('textarea[name=data]').val(), - }, (data) => { - if (data.redirect) window.location.href = data.redirect; - else window.location.reload(); + const url = $(this).attr('data-base-action'); + const res = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Csrf-Token': csrfToken, + }, + body: JSON.stringify({ + name: $modal.find('input[name=name]').val(), + data: $modal.find('textarea[name=data]').val(), + }), }); + const data = res.json(); + if (data.redirect) window.location.href = data.redirect; + else window.location.reload(); }); }); } From ae965db7a1217e5d7e7ae47ad881ddfbc5aaaffe Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Fri, 19 May 2023 16:57:11 +0800 Subject: [PATCH 19/65] await json --- web_src/js/features/shared.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/shared.js b/web_src/js/features/shared.js index 66a9b00b98c80..3b848fb6a134a 100644 --- a/web_src/js/features/shared.js +++ b/web_src/js/features/shared.js @@ -36,7 +36,7 @@ export function initSettingVariables() { data: $modal.find('textarea[name=data]').val(), }), }); - const data = res.json(); + const data = await res.json(); if (data.redirect) window.location.href = data.redirect; else window.location.reload(); }); From e69f537d6fa7e421b885a941896fc63acdd4e3fe Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Mon, 22 May 2023 14:57:09 +0800 Subject: [PATCH 20/65] lint --- models/migrations/v1_20/v258.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/models/migrations/v1_20/v258.go b/models/migrations/v1_20/v258.go index f6f3ce20ccab3..d4fe1f94b2902 100644 --- a/models/migrations/v1_20/v258.go +++ b/models/migrations/v1_20/v258.go @@ -1,4 +1,7 @@ -package v1_20 +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_20 //nolint import ( "code.gitea.io/gitea/modules/timeutil" From e2a7327df5230e94e868f04d0e0429e44ea55a72 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Mon, 22 May 2023 15:03:29 +0800 Subject: [PATCH 21/65] make fmt --- models/migrations/v1_20/v258.go | 1 + 1 file changed, 1 insertion(+) diff --git a/models/migrations/v1_20/v258.go b/models/migrations/v1_20/v258.go index d4fe1f94b2902..6eef3546cd528 100644 --- a/models/migrations/v1_20/v258.go +++ b/models/migrations/v1_20/v258.go @@ -5,6 +5,7 @@ package v1_20 //nolint import ( "code.gitea.io/gitea/modules/timeutil" + "xorm.io/xorm" ) From 45165e4f5d6e66bfbb5daf341dc3c63de6248ed2 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 24 May 2023 10:35:44 +0800 Subject: [PATCH 22/65] rename filename and function name --- web_src/js/features/{shared.js => actions.js} | 2 +- web_src/js/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename web_src/js/features/{shared.js => actions.js} (97%) diff --git a/web_src/js/features/shared.js b/web_src/js/features/actions.js similarity index 97% rename from web_src/js/features/shared.js rename to web_src/js/features/actions.js index 3b848fb6a134a..65d9abdfeed13 100644 --- a/web_src/js/features/shared.js +++ b/web_src/js/features/actions.js @@ -2,7 +2,7 @@ import $ from 'jquery'; const {csrfToken} = window.config; -export function initSettingVariables() { +export function initActionsVariables() { $('.show-variable-edit-modal').on('click', function () { const target = $(this).attr('data-modal'); const $modal = $(target); diff --git a/web_src/js/index.js b/web_src/js/index.js index 1ad413e0d6bbd..0e0245dd605c6 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -82,7 +82,7 @@ import {initGiteaFomantic} from './modules/fomantic.js'; import {onDomReady} from './utils/dom.js'; import {initRepoIssueList} from './features/repo-issue-list.js'; import {initCommonIssueListQuickGoto} from './features/common-issue-list.js'; -import {initSettingVariables} from './features/shared.js'; +import {initActionsVariables} from './features/actions.js'; // Init Gitea's Fomantic settings initGiteaFomantic(); @@ -178,5 +178,5 @@ onDomReady(() => { initUserAuthWebAuthnRegister(); initUserSettings(); initRepoDiffView(); - initSettingVariables(); + initActionsVariables(); }); From fc9b3fa0cff8dd998587aead43f6e891f0d698a5 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 24 May 2023 10:48:42 +0800 Subject: [PATCH 23/65] delete comment --- routers/web/repo/setting/variables.go | 1 - 1 file changed, 1 deletion(-) diff --git a/routers/web/repo/setting/variables.go b/routers/web/repo/setting/variables.go index c6edc926bf381..ae3af8b2ec738 100644 --- a/routers/web/repo/setting/variables.go +++ b/routers/web/repo/setting/variables.go @@ -14,7 +14,6 @@ import ( ) const ( - // TODO: Separate from runners when layout is ready tplRepoVariables base.TplName = "repo/settings/actions" tplOrgVariables base.TplName = "org/settings/actions" tplUserVariables base.TplName = "user/settings/actions" From 3b9d874c6c77582cec9455723ead94caf2cd418d Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 24 May 2023 11:05:05 +0800 Subject: [PATCH 24/65] getValidateContext --- services/forms/user_form.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 01cda0021da86..ea2b71952ba3f 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -383,7 +383,7 @@ type EditVariableForm struct { } func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetContext(req) + ctx := context.GetValidateContext(req) return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } From c0552dd250715b1ce2a722fd983ba8b39dc7d370 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Thu, 25 May 2023 00:24:54 +0800 Subject: [PATCH 25/65] fix path param --- routers/web/shared/variables/variables.go | 6 +++--- routers/web/web.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/web/shared/variables/variables.go b/routers/web/shared/variables/variables.go index dfc18b541d824..a3bc9502b12ef 100644 --- a/routers/web/shared/variables/variables.go +++ b/routers/web/shared/variables/variables.go @@ -29,7 +29,7 @@ func SetVariablesContext(ctx *context.Context, ownerID, repoID int64) { } func DeleteVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) { - id := ctx.ParamsInt64(":variableID") + id := ctx.ParamsInt64(":variable_id") if _, err := db.DeleteByBean(ctx, &variable_model.ActionVariable{ ID: id, @@ -64,7 +64,7 @@ func CreateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL str } func GetVariable(ctx *context.Context) { - id := ctx.ParamsInt64(":variableID") + id := ctx.ParamsInt64(":variable_id") v, err := variable_model.GetVariableByID(ctx, id) if err != nil { @@ -84,7 +84,7 @@ func GetVariable(ctx *context.Context) { } func UpdateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) { - id := ctx.ParamsInt64(":variableID") + id := ctx.ParamsInt64(":variable_id") form := web.GetForm(ctx).(*forms.EditVariableForm) ok, err := variable_model.UpdateVariable(ctx, &variable_model.ActionVariable{ ID: id, diff --git a/routers/web/web.go b/routers/web/web.go index 42f8981034000..0fb0da1850506 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -316,8 +316,8 @@ func registerRoutes(m *web.Route) { m.Group("/variables", func() { m.Get("", repo_setting.Variables) m.Post("/new", web.Bind(forms.EditVariableForm{}), repo_setting.VariableCreate) - m.Post("/{variableID}/edit", web.Bind(forms.EditVariableForm{}), repo_setting.VariableUpdate) - m.Post("/{variableID}/delete", repo_setting.VariableDelete) + m.Post("/{variable_id}/edit", web.Bind(forms.EditVariableForm{}), repo_setting.VariableUpdate) + m.Post("/{variable_id}/delete", repo_setting.VariableDelete) }) } From 7c184d5cc2808193350f407d8b873a22347fa36d Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 28 May 2023 21:52:48 +0200 Subject: [PATCH 26/65] fix jquery.are-you-sure interference --- templates/shared/variables/variable_list.tmpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index 8edcb6616ac4e..0738a7697a6b0 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -69,6 +69,7 @@ value="{{.title}}" pattern="^[a-zA-Z_][a-zA-Z0-9_]*$" placeholder="{{.locale.Tr "secrets.creation.name_placeholder"}}" + data-ays-ignore="true" >
@@ -76,8 +77,9 @@ + placeholder="{{.locale.Tr "secrets.creation.value_placeholder"}}" + data-ays-ignore="true" + >
{{template "base/modal_actions_confirm" (dict "locale" $.locale "ModalButtonTypes" "confirm")}} From 238418d96db34baf0cd0a01ea9b3180d8841e441 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 28 May 2023 22:26:31 +0200 Subject: [PATCH 27/65] modal fixes --- templates/shared/variables/variable_list.tmpl | 2 +- web_src/js/features/actions.js | 55 +++++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index 0738a7697a6b0..e5fb1d4d3f9a0 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -55,7 +55,7 @@
-
+
{{.CsrfTokenHtml}}
diff --git a/web_src/js/features/actions.js b/web_src/js/features/actions.js index 65d9abdfeed13..7f9b20fe82de9 100644 --- a/web_src/js/features/actions.js +++ b/web_src/js/features/actions.js @@ -4,41 +4,50 @@ const {csrfToken} = window.config; export function initActionsVariables() { $('.show-variable-edit-modal').on('click', function () { - const target = $(this).attr('data-modal'); + const $btn = $(this); + const target = $btn.attr('data-modal'); const $modal = $(target); + const form = $modal.find('form')[0]; // clear input/textarea value $modal.find('input[name=name]').val(''); $modal.find('textarea[name=data]').val(''); // set dialog header const $header = $modal.find('#variable-edit-header'); - $header.text($(this).attr('data-modal-header')); + $header.text($btn.attr('data-modal-header')); - if ($(this).attr('data-is-new') === 'false') { + if ($btn.attr('data-is-new') === 'false') { // edit variable dialog - const oldName = $(this).attr('data-old-name'); - const oldValue = $(this).attr('data-old-value'); + const oldName = $btn.attr('data-old-name'); + const oldValue = $btn.attr('data-old-value'); $modal.find('input[name=name]').val(oldName); $modal.find('textarea[name=data]').val(oldValue); } - const commitButton = $modal.find('.actions > .ok.button'); - $(commitButton).on('click', async (e) => { - e.preventDefault(); - const url = $(this).attr('data-base-action'); - const res = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Csrf-Token': csrfToken, - }, - body: JSON.stringify({ - name: $modal.find('input[name=name]').val(), - data: $modal.find('textarea[name=data]').val(), - }), - }); - const data = await res.json(); - if (data.redirect) window.location.href = data.redirect; - else window.location.reload(); + $modal.find('.actions .ok.button').off('click').on('click', () => { + if (!form.checkValidity()) { + form.reportValidity(); + return false; + } + + (async () => { + const url = $(this).attr('data-base-action'); + const res = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Csrf-Token': csrfToken, + }, + body: JSON.stringify({ + name: $modal.find('input[name=name]').val(), + data: $modal.find('textarea[name=data]').val(), + }), + }); + const data = await res.json(); + if (data.redirect) window.location.href = data.redirect; + else window.location.reload(); + })(); + + return false; // tell fomantic to do not close the modal }); }); } From 0d07e9ccc62e7c872fa403902dff3b69c2738628 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 28 May 2023 23:05:09 +0200 Subject: [PATCH 28/65] rename field, use ignore-dirty --- templates/shared/variables/variable_list.tmpl | 14 ++++++-------- web_src/js/features/actions.js | 10 ++++------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index e5fb1d4d3f9a0..09f0528d0c6f1 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -55,30 +55,28 @@
- +
{{.CsrfTokenHtml}}
{{.locale.Tr "actions.variables.description"}}
- +
- +
diff --git a/web_src/js/features/actions.js b/web_src/js/features/actions.js index 7f9b20fe82de9..ea474a2380728 100644 --- a/web_src/js/features/actions.js +++ b/web_src/js/features/actions.js @@ -10,17 +10,15 @@ export function initActionsVariables() { const form = $modal.find('form')[0]; // clear input/textarea value $modal.find('input[name=name]').val(''); - $modal.find('textarea[name=data]').val(''); + $modal.find('textarea[name=value]').val(''); // set dialog header const $header = $modal.find('#variable-edit-header'); $header.text($btn.attr('data-modal-header')); if ($btn.attr('data-is-new') === 'false') { // edit variable dialog - const oldName = $btn.attr('data-old-name'); - const oldValue = $btn.attr('data-old-value'); - $modal.find('input[name=name]').val(oldName); - $modal.find('textarea[name=data]').val(oldValue); + $modal.find('input[name=name]').val($btn.attr('data-old-name')); + $modal.find('textarea[name=value]').val($btn.attr('data-old-value')); } $modal.find('.actions .ok.button').off('click').on('click', () => { @@ -39,7 +37,7 @@ export function initActionsVariables() { }, body: JSON.stringify({ name: $modal.find('input[name=name]').val(), - data: $modal.find('textarea[name=data]').val(), + data: $modal.find('textarea[name=value]').val(), }), }); const data = await res.json(); From 202946134ebd63bdeb168a7680e33d9943e32a67 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 28 May 2023 23:50:33 +0200 Subject: [PATCH 29/65] simplify form validation --- web_src/js/features/actions.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/web_src/js/features/actions.js b/web_src/js/features/actions.js index ea474a2380728..71347a7dc1eb9 100644 --- a/web_src/js/features/actions.js +++ b/web_src/js/features/actions.js @@ -22,10 +22,7 @@ export function initActionsVariables() { } $modal.find('.actions .ok.button').off('click').on('click', () => { - if (!form.checkValidity()) { - form.reportValidity(); - return false; - } + if (!form.reportValidity()) return false; (async () => { const url = $(this).attr('data-base-action'); From 2ba6a922730bf8974fb8ebf1d17361d5c81dd90a Mon Sep 17 00:00:00 2001 From: silverwind Date: Mon, 29 May 2023 00:01:49 +0200 Subject: [PATCH 30/65] use flexbox, fix border-radius --- templates/shared/variables/variable_list.tmpl | 20 +++++++++---------- web_src/css/repo.css | 4 ++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index 09f0528d0c6f1..67500379efd12 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -15,12 +15,16 @@ {{if .Variables}}
{{range $i, $v := .Variables}} -
-
- +
+
+ {{$v.Name}} +
{{$v.Data}}
+
+
+ {{$.locale.Tr "settings.added_on" (DateTime "short" $v.CreatedUnix) | Safe}} - - -
-
- {{$v.Name}} -
{{$v.Data}}
-
{{end}}
diff --git a/web_src/css/repo.css b/web_src/css/repo.css index dbf9bf79bd561..06eda15e25e87 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -2403,6 +2403,10 @@ margin: 16px -1rem -1rem; } +.settings .ui.attached.segment { + border-radius: 0 0 var(--border-radius) var(--border-radius); +} + .settings .list > .item > .svg { display: table-cell; } From 795cd09556283786364cfaf10f94c9be66e91484 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Thu, 8 Jun 2023 21:41:20 +0800 Subject: [PATCH 31/65] fix secrets list --- options/locale/locale_en-US.ini | 3 +- routers/web/shared/secrets/secrets.go | 4 +- templates/shared/secrets/add_list.tmpl | 101 +++++++++++------- templates/shared/variables/variable_list.tmpl | 4 +- web_src/js/features/actions.js | 36 +++++++ web_src/js/index.js | 3 +- 6 files changed, 107 insertions(+), 44 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0410064125088..652c9596d4d56 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3396,6 +3396,7 @@ deletion.description = Removing a secret is permanent and cannot be undone. Cont deletion.success = The secret has been removed. deletion.failed = Failed to remove secret. management = Secrets Management +deletion_with_key = Remove secrect "%s" [actions] actions = Actions @@ -3461,7 +3462,7 @@ variables = Variables variables.management = Variables Management variables.creation = Add Variable variables.none = There are no variables yet. -variables.delete = Delete Variable "%s" +variables.delete = Remove Variable "%s" variables.edit_tooltip = Edit Variable "%s" variables.deletion = Remove variable variables.deletion.description = Removing a variable is permanent and cannot be undone. Continue? diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go index a0d648f908fd4..457cd7d93819f 100644 --- a/routers/web/shared/secrets/secrets.go +++ b/routers/web/shared/secrets/secrets.go @@ -44,7 +44,9 @@ func PerformSecretsPost(ctx *context.Context, ownerID, repoID int64, redirectURL ctx.Flash.Success(ctx.Tr("secrets.creation.success", s.Name)) } - ctx.Redirect(redirectURL) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": redirectURL, + }) } func PerformSecretsDelete(ctx *context.Context, ownerID, repoID int64, redirectURL string) { diff --git a/templates/shared/secrets/add_list.tmpl b/templates/shared/secrets/add_list.tmpl index 8a6b7db9079e6..07086069a9697 100644 --- a/templates/shared/secrets/add_list.tmpl +++ b/templates/shared/secrets/add_list.tmpl @@ -1,52 +1,39 @@

{{.locale.Tr "secrets.management"}}
- +

-
- - {{.CsrfTokenHtml}} -
- {{.locale.Tr "secrets.description"}} -
-
- - -
-
- - -
- - - -
{{if .Secrets}}
- {{range .Secrets}} -
-
- -
-
- {{svg "octicon-key" 32}} + {{range $i, $v := .Secrets}} +
+
+
+ {{svg "octicon-key" 32}} +
+
+ {{$v.Name}} +
******
+
- {{.Name}} -
******
-
- - {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} - -
+ + {{$.locale.Tr "settings.added_on" (DateTime "short" $v.CreatedUnix) | Safe}} + +
{{end}} @@ -55,6 +42,42 @@ {{.locale.Tr "secrets.none"}} {{end}}
+ +{{/* Add secret dialog */}} + + +{{/* Detele secret confirm dialog */}}