diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9f9f6f27d1..ab30e1789d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "Gitea DevContainer", - "image": "mcr.microsoft.com/devcontainers/go:1.23-bookworm", + "image": "mcr.microsoft.com/devcontainers/go:1.24-bookworm", "features": { // installs nodejs into container "ghcr.io/devcontainers/features/node:1": { diff --git a/models/actions/variable.go b/models/actions/variable.go index 1929cffbd8..7154843c17 100644 --- a/models/actions/variable.go +++ b/models/actions/variable.go @@ -6,10 +6,12 @@ package actions import ( "context" "strings" + "unicode/utf8" "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" ) @@ -32,26 +34,39 @@ type ActionVariable struct { RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name)"` Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"` Data string `xorm:"LONGTEXT NOT NULL"` + Description string `xorm:"TEXT"` CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` } +const ( + VariableDataMaxLength = 65536 + VariableDescriptionMaxLength = 4096 +) + func init() { db.RegisterModel(new(ActionVariable)) } -func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) { +func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data, description string) (*ActionVariable, error) { if ownerID != 0 && repoID != 0 { // It's trying to create a variable that belongs to a repository, but OwnerID has been set accidentally. // Remove OwnerID to avoid confusion; it's not worth returning an error here. ownerID = 0 } + if utf8.RuneCountInString(data) > VariableDataMaxLength { + return nil, util.NewInvalidArgumentErrorf("data too long") + } + + description = util.TruncateRunes(description, VariableDescriptionMaxLength) + variable := &ActionVariable{ - OwnerID: ownerID, - RepoID: repoID, - Name: strings.ToUpper(name), - Data: data, + OwnerID: ownerID, + RepoID: repoID, + Name: strings.ToUpper(name), + Data: data, + Description: description, } return variable, db.Insert(ctx, variable) } @@ -96,6 +111,12 @@ func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*ActionVariab } func UpdateVariableCols(ctx context.Context, variable *ActionVariable, cols ...string) (bool, error) { + if utf8.RuneCountInString(variable.Data) > VariableDataMaxLength { + return false, util.NewInvalidArgumentErrorf("data too long") + } + + variable.Description = util.TruncateRunes(variable.Description, VariableDescriptionMaxLength) + variable.Name = strings.ToUpper(variable.Name) count, err := db.GetEngine(ctx). ID(variable.ID). diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index f9ab993abf..297c50a267 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -376,6 +376,7 @@ func prepareMigrationTasks() []*migration { newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin), newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables), newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner), + newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables), } return preparedMigrations } diff --git a/models/migrations/v1_24/v316.go b/models/migrations/v1_24/v316.go new file mode 100644 index 0000000000..0378133e53 --- /dev/null +++ b/models/migrations/v1_24/v316.go @@ -0,0 +1,20 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "xorm.io/xorm" +) + +func AddDescriptionForSecretsAndVariables(x *xorm.Engine) error { + type Secret struct { + Description string `xorm:"TEXT"` + } + + type ActionVariable struct { + Description string `xorm:"TEXT"` + } + + return x.Sync(new(Secret), new(ActionVariable)) +} diff --git a/models/repo/repo.go b/models/repo/repo.go index 13473699f3..a8732f60bf 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -215,12 +215,24 @@ func init() { db.RegisterModel(new(Repository)) } -func (repo *Repository) GetName() string { - return repo.Name +func RelativePath(ownerName, repoName string) string { + return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".git" } -func (repo *Repository) GetOwnerName() string { - return repo.OwnerName +// RelativePath should be an unix style path like username/reponame.git +func (repo *Repository) RelativePath() string { + return RelativePath(repo.OwnerName, repo.Name) +} + +type StorageRepo string + +// RelativePath should be an unix style path like username/reponame.git +func (sr StorageRepo) RelativePath() string { + return string(sr) +} + +func (repo *Repository) WikiStorageRepo() StorageRepo { + return StorageRepo(strings.ToLower(repo.OwnerName) + "/" + strings.ToLower(repo.Name) + ".wiki.git") } // SanitizedOriginalURL returns a sanitized OriginalURL diff --git a/models/secret/secret.go b/models/secret/secret.go index eab9cf0712..10a0287dfd 100644 --- a/models/secret/secret.go +++ b/models/secret/secret.go @@ -40,9 +40,15 @@ type Secret struct { 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"` // encrypted data + Description string `xorm:"TEXT"` CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` } +const ( + SecretDataMaxLength = 65536 + SecretDescriptionMaxLength = 4096 +) + // ErrSecretNotFound represents a "secret not found" error. type ErrSecretNotFound struct { Name string @@ -57,7 +63,7 @@ func (err ErrSecretNotFound) Unwrap() error { } // InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database -func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) { +func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data, description string) (*Secret, error) { if ownerID != 0 && repoID != 0 { // It's trying to create a secret that belongs to a repository, but OwnerID has been set accidentally. // Remove OwnerID to avoid confusion; it's not worth returning an error here. @@ -67,15 +73,23 @@ func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, dat return nil, fmt.Errorf("%w: ownerID and repoID cannot be both zero, global secrets are not supported", util.ErrInvalidArgument) } + if len(data) > SecretDataMaxLength { + return nil, util.NewInvalidArgumentErrorf("data too long") + } + + description = util.TruncateRunes(description, SecretDescriptionMaxLength) + encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data) if err != nil { return nil, err } + secret := &Secret{ - OwnerID: ownerID, - RepoID: repoID, - Name: strings.ToUpper(name), - Data: encrypted, + OwnerID: ownerID, + RepoID: repoID, + Name: strings.ToUpper(name), + Data: encrypted, + Description: description, } return secret, db.Insert(ctx, secret) } @@ -114,16 +128,23 @@ func (opts FindSecretsOptions) ToConds() builder.Cond { } // UpdateSecret changes org or user reop secret. -func UpdateSecret(ctx context.Context, secretID int64, data string) error { +func UpdateSecret(ctx context.Context, secretID int64, data, description string) error { + if len(data) > SecretDataMaxLength { + return util.NewInvalidArgumentErrorf("data too long") + } + + description = util.TruncateRunes(description, SecretDescriptionMaxLength) + encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data) if err != nil { return err } s := &Secret{ - Data: encrypted, + Data: encrypted, + Description: description, } - affected, err := db.GetEngine(ctx).ID(secretID).Cols("data").Update(s) + affected, err := db.GetEngine(ctx).ID(secretID).Cols("data", "description").Update(s) if affected != 1 { return ErrSecretNotFound{} } diff --git a/modules/git/command.go b/modules/git/command.go index f46fbea9b5..d85a91804a 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -46,6 +46,7 @@ type Command struct { args []string globalArgsLength int brokenArgs []string + cmd *exec.Cmd // for debug purpose only } func logArgSanitize(arg string) string { @@ -314,6 +315,7 @@ func (c *Command) run(ctx context.Context, skip int, opts *RunOpts) error { startTime := time.Now() cmd := exec.CommandContext(ctx, c.prog, c.args...) + c.cmd = cmd // for debug purpose only if opts.Env == nil { cmd.Env = os.Environ() } else { diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index 1b6be0a3fa..89101e5af3 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -9,6 +9,8 @@ import ( "fmt" "io" "os" + "path/filepath" + "time" "code.gitea.io/gitea/modules/log" ) @@ -102,7 +104,7 @@ type CheckAttributeReader struct { stdinReader io.ReadCloser stdinWriter *os.File - stdOut attributeWriter + stdOut *nulSeparatedAttributeWriter cmd *Command env []string ctx context.Context @@ -152,7 +154,6 @@ func (c *CheckAttributeReader) Init(ctx context.Context) error { return nil } -// Run run cmd func (c *CheckAttributeReader) Run() error { defer func() { _ = c.stdinReader.Close() @@ -176,7 +177,7 @@ func (c *CheckAttributeReader) Run() error { func (c *CheckAttributeReader) CheckPath(path string) (rs map[string]string, err error) { defer func() { if err != nil && err != c.ctx.Err() { - log.Error("Unexpected error when checking path %s in %s. Error: %v", path, c.Repo.Path, err) + log.Error("Unexpected error when checking path %s in %s, error: %v", path, filepath.Base(c.Repo.Path), err) } }() @@ -191,9 +192,31 @@ func (c *CheckAttributeReader) CheckPath(path string) (rs map[string]string, err return nil, err } + reportTimeout := func() error { + stdOutClosed := false + select { + case <-c.stdOut.closed: + stdOutClosed = true + default: + } + debugMsg := fmt.Sprintf("check path %q in repo %q", path, filepath.Base(c.Repo.Path)) + debugMsg += fmt.Sprintf(", stdOut: tmp=%q, pos=%d, closed=%v", string(c.stdOut.tmp), c.stdOut.pos, stdOutClosed) + if c.cmd.cmd != nil { + debugMsg += fmt.Sprintf(", process state: %q", c.cmd.cmd.ProcessState.String()) + } + _ = c.Close() + return fmt.Errorf("CheckPath timeout: %s", debugMsg) + } + rs = make(map[string]string) for range c.Attributes { select { + case <-time.After(5 * time.Second): + // There is a strange "hang" problem in gitdiff.GetDiff -> CheckPath + // So add a timeout here to mitigate the problem, and output more logs for debug purpose + // In real world, if CheckPath runs long than seconds, it blocks the end user's operation, + // and at the moment the CheckPath result is not so important, so we can just ignore it. + return nil, reportTimeout() case attr, ok := <-c.stdOut.ReadAttribute(): if !ok { return nil, c.ctx.Err() @@ -206,18 +229,12 @@ func (c *CheckAttributeReader) CheckPath(path string) (rs map[string]string, err return rs, nil } -// Close close pip after use func (c *CheckAttributeReader) Close() error { c.cancel() err := c.stdinWriter.Close() return err } -type attributeWriter interface { - io.WriteCloser - ReadAttribute() <-chan attributeTriple -} - type attributeTriple struct { Filename string Attribute string @@ -281,7 +298,7 @@ func (wr *nulSeparatedAttributeWriter) Close() error { return nil } -// Create a check attribute reader for the current repository and provided commit ID +// CheckAttributeReader creates a check attribute reader for the current repository and provided commit ID func (repo *Repository) CheckAttributeReader(commitID string) (*CheckAttributeReader, context.CancelFunc) { indexFilename, worktree, deleteTemporaryFile, err := repo.ReadTreeToTemporaryIndex(commitID) if err != nil { @@ -303,21 +320,21 @@ func (repo *Repository) CheckAttributeReader(commitID string) (*CheckAttributeRe } ctx, cancel := context.WithCancel(repo.Ctx) if err := checker.Init(ctx); err != nil { - log.Error("Unable to open checker for %s. Error: %v", commitID, err) + log.Error("Unable to open attribute checker for commit %s, error: %v", commitID, err) } else { go func() { err := checker.Run() - if err != nil && err != ctx.Err() { - log.Error("Unable to open checker for %s. Error: %v", commitID, err) + if err != nil && !IsErrCanceledOrKilled(err) { + log.Error("Attribute checker for commit %s exits with error: %v", commitID, err) } cancel() }() } - deferable := func() { + deferrable := func() { _ = checker.Close() cancel() deleteTemporaryFile() } - return checker, deferable + return checker, deferrable } diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go index 0fcd94b4c7..e0bde146f6 100644 --- a/modules/git/repo_attribute_test.go +++ b/modules/git/repo_attribute_test.go @@ -4,10 +4,16 @@ package git import ( + "context" + mathRand "math/rand/v2" + "path/filepath" + "slices" + "sync" "testing" "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { @@ -95,3 +101,57 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { Value: "unspecified", }, attr) } + +func TestAttributeReader(t *testing.T) { + t.Skip() // for debug purpose only, do not run in CI + + ctx := t.Context() + + timeout := 1 * time.Second + repoPath := filepath.Join(testReposDir, "language_stats_repo") + commitRef := "HEAD" + + oneRound := func(t *testing.T, roundIdx int) { + ctx, cancel := context.WithTimeout(ctx, timeout) + _ = cancel + gitRepo, err := OpenRepository(ctx, repoPath) + require.NoError(t, err) + defer gitRepo.Close() + + commit, err := gitRepo.GetCommit(commitRef) + require.NoError(t, err) + + files, err := gitRepo.LsFiles() + require.NoError(t, err) + + randomFiles := slices.Clone(files) + randomFiles = append(randomFiles, "any-file-1", "any-file-2") + + t.Logf("Round %v with %d files", roundIdx, len(randomFiles)) + + attrReader, deferrable := gitRepo.CheckAttributeReader(commit.ID.String()) + defer deferrable() + + wg := sync.WaitGroup{} + wg.Add(1) + + go func() { + for { + file := randomFiles[mathRand.IntN(len(randomFiles))] + _, err := attrReader.CheckPath(file) + if err != nil { + for i := 0; i < 10; i++ { + _, _ = attrReader.CheckPath(file) + } + break + } + } + wg.Done() + }() + wg.Wait() + } + + for i := 0; i < 100; i++ { + oneRound(t, i) + } +} diff --git a/modules/gitrepo/branch.go b/modules/gitrepo/branch.go index 9c4bdc5bdf..25ea5abfca 100644 --- a/modules/gitrepo/branch.go +++ b/modules/gitrepo/branch.go @@ -44,24 +44,12 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) { return git.GetDefaultBranch(ctx, repoPath(repo)) } -func GetWikiDefaultBranch(ctx context.Context, repo Repository) (string, error) { - return git.GetDefaultBranch(ctx, wikiPath(repo)) -} - // IsReferenceExist returns true if given reference exists in the repository. func IsReferenceExist(ctx context.Context, repo Repository, name string) bool { return git.IsReferenceExist(ctx, repoPath(repo), name) } -func IsWikiReferenceExist(ctx context.Context, repo Repository, name string) bool { - return git.IsReferenceExist(ctx, wikiPath(repo), name) -} - // IsBranchExist returns true if given branch exists in the repository. func IsBranchExist(ctx context.Context, repo Repository, name string) bool { return IsReferenceExist(ctx, repo, git.BranchPrefix+name) } - -func IsWikiBranchExist(ctx context.Context, repo Repository, name string) bool { - return IsWikiReferenceExist(ctx, repo, git.BranchPrefix+name) -} diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go index f3b2c7a349..5da65e2452 100644 --- a/modules/gitrepo/gitrepo.go +++ b/modules/gitrepo/gitrepo.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "path/filepath" - "strings" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/reqctx" @@ -16,17 +15,15 @@ import ( "code.gitea.io/gitea/modules/util" ) +// Repository represents a git repository which stored in a disk type Repository interface { - GetName() string - GetOwnerName() string -} - -func absPath(owner, name string) string { - return filepath.Join(setting.RepoRootPath, strings.ToLower(owner), strings.ToLower(name)+".git") + RelativePath() string // We don't assume how the directory structure of the repository is, so we only need the relative path } +// RelativePath should be an unix style path like username/reponame.git +// This method should change it according to the current OS. func repoPath(repo Repository) string { - return absPath(repo.GetOwnerName(), repo.GetName()) + return filepath.Join(setting.RepoRootPath, filepath.FromSlash(repo.RelativePath())) } // OpenRepository opens the repository at the given relative path with the provided context. @@ -78,9 +75,8 @@ func DeleteRepository(ctx context.Context, repo Repository) error { } // RenameRepository renames a repository's name on disk -func RenameRepository(ctx context.Context, repo Repository, newName string) error { - newRepoPath := absPath(repo.GetOwnerName(), newName) - if err := util.Rename(repoPath(repo), newRepoPath); err != nil { +func RenameRepository(ctx context.Context, repo, newRepo Repository) error { + if err := util.Rename(repoPath(repo), repoPath(newRepo)); err != nil { return fmt.Errorf("rename repository directory: %w", err) } return nil diff --git a/modules/gitrepo/hooks.go b/modules/gitrepo/hooks.go index cf44f792c6..d9d4a88ff1 100644 --- a/modules/gitrepo/hooks.go +++ b/modules/gitrepo/hooks.go @@ -106,16 +106,11 @@ done return hookNames, hookTpls, giteaHookTpls } -// CreateDelegateHooksForRepo creates all the hooks scripts for the repo -func CreateDelegateHooksForRepo(_ context.Context, repo Repository) (err error) { +// CreateDelegateHooks creates all the hooks scripts for the repo +func CreateDelegateHooks(_ context.Context, repo Repository) (err error) { return createDelegateHooks(filepath.Join(repoPath(repo), "hooks")) } -// CreateDelegateHooksForWiki creates all the hooks scripts for the wiki repo -func CreateDelegateHooksForWiki(_ context.Context, repo Repository) (err error) { - return createDelegateHooks(filepath.Join(wikiPath(repo), "hooks")) -} - func createDelegateHooks(hookDir string) (err error) { hookNames, hookTpls, giteaHookTpls := getHookTemplates() @@ -178,16 +173,11 @@ func ensureExecutable(filename string) error { return os.Chmod(filename, mode) } -// CheckDelegateHooksForRepo checks the hooks scripts for the repo -func CheckDelegateHooksForRepo(_ context.Context, repo Repository) ([]string, error) { +// CheckDelegateHooks checks the hooks scripts for the repo +func CheckDelegateHooks(_ context.Context, repo Repository) ([]string, error) { return checkDelegateHooks(filepath.Join(repoPath(repo), "hooks")) } -// CheckDelegateHooksForWiki checks the hooks scripts for the repo -func CheckDelegateHooksForWiki(_ context.Context, repo Repository) ([]string, error) { - return checkDelegateHooks(filepath.Join(wikiPath(repo), "hooks")) -} - func checkDelegateHooks(hookDir string) ([]string, error) { hookNames, hookTpls, giteaHookTpls := getHookTemplates() diff --git a/modules/repository/init.go b/modules/repository/init.go index 3fc1261baa..ace21254ba 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -138,7 +138,7 @@ func CheckInitRepository(ctx context.Context, repo *repo_model.Repository) (err // Init git bare new repository. if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { return fmt.Errorf("git.InitRepository: %w", err) - } else if err = gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { + } else if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } return nil diff --git a/modules/structs/secret.go b/modules/structs/secret.go index a0673ca08c..2afb41ec43 100644 --- a/modules/structs/secret.go +++ b/modules/structs/secret.go @@ -10,6 +10,8 @@ import "time" type Secret struct { // the secret's name Name string `json:"name"` + // the secret's description + Description string `json:"description"` // swagger:strfmt date-time Created time.Time `json:"created_at"` } @@ -21,4 +23,9 @@ type CreateOrUpdateSecretOption struct { // // required: true Data string `json:"data" binding:"Required"` + + // Description of the secret to update + // + // required: false + Description string `json:"description"` } diff --git a/modules/structs/variable.go b/modules/structs/variable.go index cc846cf0ec..5198937303 100644 --- a/modules/structs/variable.go +++ b/modules/structs/variable.go @@ -10,6 +10,11 @@ type CreateVariableOption struct { // // required: true Value string `json:"value" binding:"Required"` + + // Description of the variable to create + // + // required: false + Description string `json:"description"` } // UpdateVariableOption the option when updating variable @@ -21,6 +26,11 @@ type UpdateVariableOption struct { // // required: true Value string `json:"value" binding:"Required"` + + // Description of the variable to update + // + // required: false + Description string `json:"description"` } // ActionVariable return value of the query API @@ -34,4 +44,6 @@ type ActionVariable struct { Name string `json:"name"` // the value of the variable Data string `json:"data"` + // the description of the variable + Description string `json:"description"` } diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index c66258b386..41c770452f 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -3679,6 +3679,7 @@ secrets=Tajné klíče description=Tejné klíče budou předány určitým akcím a nelze je přečíst jinak. none=Zatím zde nejsou žádné tajné klíče. creation=Přidat tajný klíč +creation.description=Popis creation.name_placeholder=nerozlišovat velká a malá písmena, pouze alfanumerické znaky nebo podtržítka, nemohou začínat na GITEA_ nebo GITHUB_ creation.value_placeholder=Vložte jakýkoliv obsah. Mezery na začátku a konci budou vynechány. creation.success=Tajný klíč „%s“ byl přidán. diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 513ce39137..c9e7f5edab 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -3670,6 +3670,7 @@ secrets=Secrets description=Secrets werden an bestimmte Aktionen weitergegeben und können nicht anderweitig ausgelesen werden. none=Noch keine Secrets vorhanden. creation=Secret hinzufügen +creation.description=Beschreibung creation.name_placeholder=Groß-/Kleinschreibung wird ignoriert, nur alphanumerische Zeichen oder Unterstriche, darf nicht mit GITEA_ oder GITHUB_ beginnen creation.value_placeholder=Beliebigen Inhalt eingeben. Leerzeichen am Anfang und Ende werden weggelassen. creation.success=Das Secret "%s" wurde hinzugefügt. diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index df5e5e9553..09ae6f5a87 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -3338,6 +3338,7 @@ secrets=Μυστικά description=Τα μυστικά θα περάσουν σε ορισμένες δράσεις και δεν μπορούν να αναγνωστούν αλλού. none=Δεν υπάρχουν ακόμα μυστικά. creation=Προσθήκη Μυστικού +creation.description=Περιγραφή creation.name_placeholder=αλφαριθμητικοί χαρακτήρες ή κάτω παύλες μόνο, δεν μπορούν να ξεκινούν με GITEA_ ή GITHUB_ creation.value_placeholder=Εισάγετε οποιοδήποτε περιεχόμενο. Τα κενά στην αρχή παραλείπονται. creation.success=Το μυστικό "%s" προστέθηκε. diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 3ee7c8818c..876e135b22 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3712,8 +3712,10 @@ secrets = Secrets description = Secrets will be passed to certain actions and cannot be read otherwise. none = There are no secrets yet. creation = Add Secret +creation.description = Description creation.name_placeholder = case-insensitive, alphanumeric characters or underscores only, cannot start with GITEA_ or GITHUB_ creation.value_placeholder = Input any content. Whitespace at the start and end will be omitted. +creation.description_placeholder = Enter short description (optional). creation.success = The secret "%s" has been added. creation.failed = Failed to add secret. deletion = Remove secret diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index f856eaebd6..1a0ee9be8e 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -3318,6 +3318,7 @@ secrets=Secretos description=Los secretos pasarán a ciertas acciones y no se podrán leer de otro modo. none=Todavía no hay secretos. creation=Añadir secreto +creation.description=Descripción creation.name_placeholder=sin distinción de mayúsculas, solo carácteres alfanuméricos o guiones bajos, no puede empezar por GITEA_ o GITHUB_ creation.value_placeholder=Introduce cualquier contenido. Se omitirá el espacio en blanco en el inicio y el final. creation.success=El secreto "%s" ha sido añadido. diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index c82cfc61bd..147c570ca0 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -2513,6 +2513,7 @@ conan.details.repository=مخزن owner.settings.cleanuprules.enabled=فعال شده [secrets] +creation.description=شرح [actions] diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index d78a06ae20..e853273375 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -1694,6 +1694,7 @@ conan.details.repository=Repo owner.settings.cleanuprules.enabled=Käytössä [secrets] +creation.description=Kuvaus [actions] diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 11a7960bc9..9964bcc077 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -3705,6 +3705,7 @@ secrets=Secrets description=Les secrets seront transmis à certaines actions et ne pourront pas être lus autrement. none=Il n'y a pas encore de secrets. creation=Ajouter un secret +creation.description=Description creation.name_placeholder=Caractères alphanumériques ou tirets bas uniquement, insensibles à la casse, ne peut commencer par GITEA_ ou GITHUB_. creation.value_placeholder=Entrez n’importe quoi. Les blancs cernant seront taillés. creation.success=Le secret "%s" a été ajouté. diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 2371e807e2..aa79a03a3a 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -3705,6 +3705,7 @@ secrets=Rúin description=Cuirfear rúin ar aghaidh chuig gníomhartha áirithe agus ní féidir iad a léamh ar mhalairt. none=Níl aon rúin ann fós. creation=Cuir Rúnda leis +creation.description=Cur síos creation.name_placeholder=carachtair alfanumair nó íoslaghda amháin nach féidir a thosú le GITEA_ nó GITHUB_ creation.value_placeholder=Ionchur ábhar ar bith. Fágfar spás bán ag tús agus ag deireadh ar lár. creation.success=Tá an rún "%s" curtha leis. diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index 08a71c27d2..f4f0bed24c 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -1598,6 +1598,7 @@ conan.details.repository=Tároló owner.settings.cleanuprules.enabled=Engedélyezett [secrets] +creation.description=Leírás [actions] diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 2beade34ad..10d8c43c5b 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -1398,6 +1398,7 @@ conan.details.repository=Repositori owner.settings.cleanuprules.enabled=Aktif [secrets] +creation.description=Deskripsi [actions] diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 98a8615130..ee5eb4a7dd 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -1326,6 +1326,7 @@ npm.details.tag=Merki pypi.requires=Þarfnast Python [secrets] +creation.description=Lýsing [actions] diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 48a43210bf..b3564eb8f7 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -2790,6 +2790,7 @@ settings.delete.error=Impossibile eliminare il pacchetto. owner.settings.cleanuprules.enabled=Attivo [secrets] +creation.description=Descrizione [actions] diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index b33f794bdb..dd88f3eeaa 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -3699,6 +3699,7 @@ secrets=シークレット description=シークレットは特定のActionsに渡されます。 それ以外で読み出されることはありません。 none=シークレットはまだありません。 creation=シークレットを追加 +creation.description=説明 creation.name_placeholder=大文字小文字の区別なし、英数字とアンダースコアのみ、GITEA_ や GITHUB_ で始まるものは不可 creation.value_placeholder=内容を入力してください。前後の空白は除去されます。 creation.success=シークレット "%s" を追加しました。 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index a570a05274..601c203aba 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -1547,6 +1547,7 @@ conan.details.repository=저장소 owner.settings.cleanuprules.enabled=활성화됨 [secrets] +creation.description=설명 [actions] diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index bc8cab4781..975943ec91 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -3341,6 +3341,7 @@ secrets=Noslēpumi description=Noslēpumi tiks padoti atsevišķām darbībām un citādi nevar tikt nolasīti. none=Pagaidām nav neviena noslēpuma. creation=Pievienot noslēpumu +creation.description=Apraksts creation.name_placeholder=reģistr-nejūtīgs, tikai burti, cipari un apakšsvītras, nevar sākties ar GITEA_ vai GITHUB_ creation.value_placeholder=Ievadiet jebkādu saturu. Atstarpes sākumā un beigā tiks noņemtas. creation.success=Noslēpums "%s" tika pievienots. diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 650e8d4e23..efea6b82df 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -2523,6 +2523,7 @@ settings.link.button=Repository link bijwerken owner.settings.cleanuprules.enabled=Ingeschakeld [secrets] +creation.description=Omschrijving [actions] diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 55a82e9629..1e6268e2be 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -2412,6 +2412,7 @@ conan.details.repository=Repozytorium owner.settings.cleanuprules.enabled=Włączone [secrets] +creation.description=Opis [actions] diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index f4b479344d..b23e45088d 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -2194,7 +2194,7 @@ settings.protect_check_status_contexts_list=Verificações de status encontradas settings.protect_required_approvals=Aprovações necessárias: settings.dismiss_stale_approvals=Descartar aprovações obsoletas settings.dismiss_stale_approvals_desc=Quando novos commits que mudam o conteúdo do pull request são enviados para o branch, as antigas aprovações serão descartadas. -settings.require_signed_commits=Exibir commits assinados +settings.require_signed_commits=Exigir commits assinados settings.require_signed_commits_desc=Rejeitar pushes para este branch se não estiverem assinados ou não forem validáveis. settings.protect_branch_name_pattern=Padrão de Nome de Branch Protegida settings.protect_patterns=Padrões @@ -3278,6 +3278,7 @@ secrets=Segredos description=Os segredos serão passados a certas ações e não poderão ser lidos de outra forma. none=Não há segredos ainda. creation=Adicionar Segredo +creation.description=Descrição creation.name_placeholder=apenas caracteres alfanuméricos ou underline (_), não pode começar com GITEA_ ou GITHUB_ creation.value_placeholder=Insira qualquer conteúdo. Espaços em branco no início e no fim serão omitidos. creation.success=O segredo "%s" foi adicionado. diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 26a1d7708e..5b6672c266 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -113,6 +113,7 @@ copy_type_unsupported=Este tipo de ficheiro não pode ser copiado write=Escrever preview=Pré-visualizar loading=Carregando… +files=Ficheiros error=Erro error404=A página que pretende aceder não existe ou não tem autorização para a ver. @@ -3710,8 +3711,10 @@ secrets=Segredos description=Os segredos serão transmitidos a certas operações e não poderão ser lidos de outra forma. none=Ainda não há segredos. creation=Adicionar segredo +creation.description=Descrição creation.name_placeholder=Só sublinhados ou alfanuméricos sem distinguir maiúsculas, sem começar com GITEA_ nem GITHUB_ creation.value_placeholder=Insira um conteúdo qualquer. Espaços em branco no início ou no fim serão omitidos. +creation.description_placeholder=Escreva uma descrição curta (opcional). creation.success=O segredo "%s" foi adicionado. creation.failed=Falhou ao adicionar o segredo. deletion=Remover segredo diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index b8126089e9..6b08ec9e5c 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -3275,6 +3275,7 @@ secrets=Секреты description=Секреты будут передаваться определенным действиям и не могут быть прочитаны иначе. none=Секретов пока нет. creation=Добавить секрет +creation.description=Описание creation.name_placeholder=регистр не важен, только алфавитно-цифровые символы и подчёркивания, не может начинаться с GITEA_ или GITHUB_ creation.value_placeholder=Введите любое содержимое. Пробельные символы в начале и конце будут опущены. creation.success=Секрет «%s» добавлен. diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 4857fa8d88..0f5ae91e40 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -2454,6 +2454,7 @@ conan.details.repository=කෝෂ්ඨය owner.settings.cleanuprules.enabled=සබල කර ඇත [secrets] +creation.description=සවිස්තරය [actions] diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 0d3d0f5fc4..d79d751ea3 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -1989,6 +1989,7 @@ conan.details.repository=Utvecklingskatalog owner.settings.cleanuprules.enabled=Aktiv [secrets] +creation.description=Beskrivning [actions] diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index b420e562c4..d00cce5006 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -3534,6 +3534,7 @@ secrets=Gizlilikler description=Gizlilikler belirli işlemlere aktarılacaktır, bunun dışında okunamaz. none=Henüz gizlilik yok. creation=Gizlilik Ekle +creation.description=Açıklama creation.name_placeholder=küçük-büyük harfe duyarlı değil, alfanümerik karakterler veya sadece alt tire, GITEA_ veya GITHUB_ ile başlayamaz creation.value_placeholder=Herhangi bir içerik girin. Baştaki ve sondaki boşluklar ihmal edilecektir. creation.success=Gizlilik "%s" eklendi. diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 4071659304..3b3017a127 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -2524,6 +2524,7 @@ conan.details.repository=Репозиторій owner.settings.cleanuprules.enabled=Увімкнено [secrets] +creation.description=Опис [actions] diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 74dfa57a01..d6ef36dede 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -96,8 +96,8 @@ edit=编辑 view=查看 test=测试 -enabled=启用 -disabled=禁用 +enabled=已启用 +disabled=已禁用 locked=已锁定 copy=复制 @@ -148,7 +148,7 @@ name=名称 value=值 readme=自述文档 -filter=过滤 +filter=筛选 filter.clear=清除筛选器 filter.is_archived=已归档 filter.not_archived=非存档 @@ -159,7 +159,7 @@ filter.not_mirror=非镜像 filter.is_template=模板 filter.not_template=非模板 filter.public=公开 -filter.private=私有库 +filter.private=私有 no_results_found=未找到结果 internal_error_skipped=发生内部错误,但已被跳过: %s @@ -245,6 +245,7 @@ license_desc=所有的代码都开源在 官方文档 后再对本页面进行填写。 require_db_desc=Gitea 需要使用 MySQL、PostgreSQL、MSSQL、SQLite3 或 TiDB (MySQL协议) 等数据库 @@ -2870,7 +2871,7 @@ authentication=认证源 emails=用户邮件 config=应用配置 config_summary=摘要 -config_settings=组织设置 +config_settings=设置 notices=系统提示 monitor=监控面板 first_page=首页 @@ -3349,6 +3350,7 @@ monitor.previous=上次执行时间 monitor.execute_times=执行次数 monitor.process=运行中进程 monitor.stacktrace=调用栈踪迹 +monitor.performance_logs=性能日志 monitor.processes_count=%d 个进程 monitor.download_diagnosis_report=下载诊断报告 monitor.desc=进程描述 @@ -3529,12 +3531,12 @@ alpine.registry.info=从下面的列表中选择 $branch 和 $repository。 alpine.install=要安装包,请运行以下命令: alpine.repository=仓库信息 alpine.repository.branches=分支 -alpine.repository.repositories=仓库管理 +alpine.repository.repositories=仓库 alpine.repository.architectures=架构 arch.registry=添加具有相关仓库和架构的服务器到 /etc/pacman.conf 中: arch.install=使用 pacman 同步软件包: arch.repository=仓库信息 -arch.repository.repositories=仓库管理 +arch.repository.repositories=仓库 arch.repository.architectures=架构 cargo.registry=在 Cargo 配置文件中设置此注册中心(例如:~/.cargo/config.toml): cargo.install=要使用 Cargo 安装软件包,请运行以下命令: @@ -3552,6 +3554,7 @@ conda.install=要使用 Conda 安装软件包,请运行以下命令: container.details.type=镜像类型 container.details.platform=平台 container.pull=从命令行拉取镜像: +container.images=镜像 container.multi_arch=OS / Arch container.layers=镜像层 container.labels=标签 @@ -3655,6 +3658,7 @@ secrets=密钥 description=Secrets 将被传给特定的 Actions,其它情况将不能读取 none=还没有密钥。 creation=添加密钥 +creation.description=组织描述 creation.name_placeholder=不区分大小写,字母数字或下划线不能以GITEA_ 或 GITHUB_ 开头。 creation.value_placeholder=输入任何内容,开头和结尾的空白都会被省略 creation.success=您的密钥 '%s' 添加成功。 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 3733d95ec8..b924faba09 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -963,6 +963,7 @@ conan.details.repository=儲存庫 owner.settings.cleanuprules.enabled=已啟用 [secrets] +creation.description=組織描述 [actions] diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 4bc3259586..8b6dc3afcb 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -3646,6 +3646,7 @@ secrets=Secret description=Secret 會被傳給特定的 Action,其他情況無法讀取。 none=還沒有 Secret。 creation=加入 Secret +creation.description=描述 creation.name_placeholder=不區分大小寫,只能包含英文字母、數字、底線 ('_'),不能以 GITEA_ 或 GITHUB_ 開頭。 creation.value_placeholder=輸入任何內容,頭尾的空白都會被忽略。 creation.success=已新增 Secret「%s」。 diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index d9bdb3ab48..b1cd2f0c3c 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -61,8 +61,9 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) { apiSecrets := make([]*api.Secret, len(secrets)) for k, v := range secrets { apiSecrets[k] = &api.Secret{ - Name: v.Name, - Created: v.CreatedUnix.AsTime(), + Name: v.Name, + Description: v.Description, + Created: v.CreatedUnix.AsTime(), } } @@ -106,7 +107,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) - _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data) + _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) @@ -230,10 +231,11 @@ func (Action) ListVariables(ctx *context.APIContext) { variables := make([]*api.ActionVariable, len(vars)) for i, v := range vars { variables[i] = &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, - Data: v.Data, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } } @@ -281,10 +283,11 @@ func (Action) GetVariable(ctx *context.APIContext) { } variable := &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, - Data: v.Data, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } ctx.JSON(http.StatusOK, variable) @@ -386,7 +389,7 @@ func (Action) CreateVariable(ctx *context.APIContext) { return } - if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil { + if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) } else { @@ -453,6 +456,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { v.Name = opt.Name v.Data = opt.Value + v.Description = opt.Description if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 6b4ce37fcf..2ace9fa295 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -84,8 +84,9 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) { apiSecrets := make([]*api.Secret, len(secrets)) for k, v := range secrets { apiSecrets[k] = &api.Secret{ - Name: v.Name, - Created: v.CreatedUnix.AsTime(), + Name: v.Name, + Description: v.Description, + Created: v.CreatedUnix.AsTime(), } } @@ -136,7 +137,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) - _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data) + _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) @@ -249,10 +250,11 @@ func (Action) GetVariable(ctx *context.APIContext) { } variable := &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, - Data: v.Data, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } ctx.JSON(http.StatusOK, variable) @@ -362,7 +364,7 @@ func (Action) CreateVariable(ctx *context.APIContext) { return } - if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value); err != nil { + if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) } else { @@ -432,6 +434,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { v.Name = opt.Name v.Data = opt.Value + v.Description = opt.Description if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { @@ -491,9 +494,11 @@ func (Action) ListVariables(ctx *context.APIContext) { variables := make([]*api.ActionVariable, len(vars)) for i, v := range vars { variables[i] = &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } } diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 8d73383f76..67dd6c913d 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -476,7 +476,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) // findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error. // The caller is responsible for closing the returned repo again func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) { - wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) + wikiRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) if err != nil { if git.IsErrNotExist(err) || err.Error() == "no such file or directory" { ctx.APIErrorNotFound(err) diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go index 1c8e3b6e71..04097fcc95 100644 --- a/routers/api/v1/user/action.go +++ b/routers/api/v1/user/action.go @@ -49,7 +49,7 @@ func CreateOrUpdateSecret(ctx *context.APIContext) { opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) - _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data) + _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) @@ -153,7 +153,7 @@ func CreateVariable(ctx *context.APIContext) { return } - if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil { + if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.APIError(http.StatusBadRequest, err) } else { @@ -215,6 +215,7 @@ func UpdateVariable(ctx *context.APIContext) { v.Name = opt.Name v.Data = opt.Value + v.Description = opt.Description if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { @@ -300,10 +301,11 @@ func GetVariable(ctx *context.APIContext) { } variable := &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, - Data: v.Data, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } ctx.JSON(http.StatusOK, variable) @@ -345,10 +347,11 @@ func ListVariables(ctx *context.APIContext) { variables := make([]*api.ActionVariable, len(vars)) for i, v := range vars { variables[i] = &api.ActionVariable{ - OwnerID: v.OwnerID, - RepoID: v.RepoID, - Name: v.Name, - Data: v.Data, + OwnerID: v.OwnerID, + RepoID: v.RepoID, + Name: v.Name, + Data: v.Data, + Description: v.Description, } } diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index bbdcf9875e..3fd1eacb58 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -284,7 +284,7 @@ func Diff(ctx *context.Context) { ) if ctx.Data["PageIsWiki"] != nil { - gitRepo, err = gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) + gitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) if err != nil { ctx.ServerError("Repo.GitRepo.GetCommit", err) return @@ -417,7 +417,7 @@ func Diff(ctx *context.Context) { func RawDiff(ctx *context.Context) { var gitRepo *git.Repository if ctx.Data["PageIsWiki"] != nil { - wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) + wikiRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) if err != nil { ctx.ServerError("OpenRepository", err) return diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 6cea95e387..3e9cdb5df8 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -885,7 +885,7 @@ func ExcerptBlob(ctx *context.Context) { gitRepo := ctx.Repo.GitRepo if ctx.Data["PageIsWiki"] == true { var err error - gitRepo, err = gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) + gitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) if err != nil { ctx.ServerError("OpenRepository", err) return diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 0a34e0bcbf..dbdf64ac51 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -96,7 +96,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) } func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) { - wikiGitRepo, errGitRepo := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) + wikiGitRepo, errGitRepo := gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) if errGitRepo != nil { ctx.ServerError("OpenRepository", errGitRepo) return nil, nil, errGitRepo @@ -105,7 +105,7 @@ func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, err commit, errCommit := wikiGitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultWikiBranch) if git.IsErrNotExist(errCommit) { // if the default branch recorded in database is out of sync, then re-sync it - gitRepoDefaultBranch, errBranch := gitrepo.GetWikiDefaultBranch(ctx, ctx.Repo.Repository) + gitRepoDefaultBranch, errBranch := gitrepo.GetDefaultBranch(ctx, ctx.Repo.Repository.WikiStorageRepo()) if errBranch != nil { return wikiGitRepo, nil, errBranch } diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index 23f59777f6..51b38b46bc 100644 --- a/routers/web/repo/wiki_test.go +++ b/routers/web/repo/wiki_test.go @@ -29,7 +29,7 @@ const ( ) func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry { - wikiRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) + wikiRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) assert.NoError(t, err) defer wikiRepo.Close() commit, err := wikiRepo.GetBranchCommit("master") diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go index 7e8100b948..9cc1676d7b 100644 --- a/routers/web/shared/actions/variables.go +++ b/routers/web/shared/actions/variables.go @@ -106,7 +106,8 @@ func Variables(ctx *context.Context) { return } ctx.Data["Variables"] = variables - + ctx.Data["DataMaxLength"] = actions_model.VariableDataMaxLength + ctx.Data["DescriptionMaxLength"] = actions_model.VariableDescriptionMaxLength ctx.HTML(http.StatusOK, vCtx.VariablesTemplate) } @@ -124,7 +125,7 @@ func VariableCreate(ctx *context.Context) { form := web.GetForm(ctx).(*forms.EditVariableForm) - v, err := actions_service.CreateVariable(ctx, vCtx.OwnerID, vCtx.RepoID, form.Name, form.Data) + v, err := actions_service.CreateVariable(ctx, vCtx.OwnerID, vCtx.RepoID, form.Name, form.Data, form.Description) if err != nil { log.Error("CreateVariable: %v", err) ctx.JSONError(ctx.Tr("actions.variables.creation.failed")) @@ -157,6 +158,7 @@ func VariableUpdate(ctx *context.Context) { form := web.GetForm(ctx).(*forms.EditVariableForm) variable.Name = form.Name variable.Data = form.Data + variable.Description = form.Description if ok, err := actions_service.UpdateVariableNameData(ctx, variable); err != nil || !ok { log.Error("UpdateVariable: %v", err) diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go index 3bd421f86a..c8b80ebb26 100644 --- a/routers/web/shared/secrets/secrets.go +++ b/routers/web/shared/secrets/secrets.go @@ -22,12 +22,14 @@ func SetSecretsContext(ctx *context.Context, ownerID, repoID int64) { } ctx.Data["Secrets"] = secrets + ctx.Data["DataMaxLength"] = secret_model.SecretDataMaxLength + ctx.Data["DescriptionMaxLength"] = secret_model.SecretDescriptionMaxLength } func PerformSecretsPost(ctx *context.Context, ownerID, repoID int64, redirectURL string) { form := web.GetForm(ctx).(*forms.AddSecretForm) - s, _, err := secret_service.CreateOrUpdateSecret(ctx, ownerID, repoID, form.Name, util.ReserveLineBreakForTextarea(form.Data)) + s, _, err := secret_service.CreateOrUpdateSecret(ctx, ownerID, repoID, form.Name, util.ReserveLineBreakForTextarea(form.Data), form.Description) if err != nil { log.Error("CreateOrUpdateSecret failed: %v", err) ctx.JSONError(ctx.Tr("secrets.creation.failed")) diff --git a/services/actions/variables.go b/services/actions/variables.go index 95f088dbd3..2603f1d461 100644 --- a/services/actions/variables.go +++ b/services/actions/variables.go @@ -13,7 +13,7 @@ import ( secret_service "code.gitea.io/gitea/services/secrets" ) -func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*actions_model.ActionVariable, error) { +func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data, description string) (*actions_model.ActionVariable, error) { if err := secret_service.ValidateName(name); err != nil { return nil, err } @@ -22,7 +22,7 @@ func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data strin return nil, err } - v, err := actions_model.InsertVariable(ctx, ownerID, repoID, name, util.ReserveLineBreakForTextarea(data)) + v, err := actions_model.InsertVariable(ctx, ownerID, repoID, name, util.ReserveLineBreakForTextarea(data), description) if err != nil { return nil, err } @@ -41,7 +41,7 @@ func UpdateVariableNameData(ctx context.Context, variable *actions_model.ActionV variable.Data = util.ReserveLineBreakForTextarea(variable.Data) - return actions_model.UpdateVariableCols(ctx, variable, "name", "data") + return actions_model.UpdateVariableCols(ctx, variable, "name", "data", "description") } func DeleteVariableByID(ctx context.Context, variableID int64) error { diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go index da265dec27..2216bca54a 100644 --- a/services/asymkey/sign.go +++ b/services/asymkey/sign.go @@ -204,7 +204,7 @@ Loop: return false, "", nil, &ErrWontSign{twofa} } case parentSigned: - gitRepo, err := gitrepo.OpenWikiRepository(ctx, repo) + gitRepo, err := gitrepo.OpenRepository(ctx, repo.WikiStorageRepo()) if err != nil { return false, "", nil, err } diff --git a/services/doctor/misc.go b/services/doctor/misc.go index 260a28ec4c..d934640af5 100644 --- a/services/doctor/misc.go +++ b/services/doctor/misc.go @@ -49,14 +49,14 @@ func checkScriptType(ctx context.Context, logger log.Logger, autofix bool) error func checkHooks(ctx context.Context, logger log.Logger, autofix bool) error { if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { - results, err := gitrepo.CheckDelegateHooksForRepo(ctx, repo) + results, err := gitrepo.CheckDelegateHooks(ctx, repo) if err != nil { logger.Critical("Unable to check delegate hooks for repo %-v. ERROR: %v", repo, err) return fmt.Errorf("Unable to check delegate hooks for repo %-v. ERROR: %w", repo, err) } if len(results) > 0 && autofix { logger.Warn("Regenerated hooks for %s", repo.FullName()) - if err := gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { + if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { logger.Critical("Unable to recreate delegate hooks for %-v. ERROR: %v", repo, err) return fmt.Errorf("Unable to recreate delegate hooks for %-v. ERROR: %w", repo, err) } diff --git a/services/forms/user_form.go b/services/forms/user_form.go index c9ce71e886..ddf2bd09b0 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -323,8 +323,9 @@ func (f *AddKeyForm) Validate(req *http.Request, errs binding.Errors) binding.Er // AddSecretForm for adding secrets type AddSecretForm struct { - Name string `binding:"Required;MaxSize(255)"` - Data string `binding:"Required;MaxSize(65535)"` + Name string `binding:"Required;MaxSize(255)"` + Data string `binding:"Required;MaxSize(65535)"` + Description string `binding:"MaxSize(65535)"` } // Validate validates the fields @@ -334,8 +335,9 @@ func (f *AddSecretForm) Validate(req *http.Request, errs binding.Errors) binding } type EditVariableForm struct { - Name string `binding:"Required;MaxSize(255)"` - Data string `binding:"Required;MaxSize(65535)"` + Name string `binding:"Required;MaxSize(255)"` + Data string `binding:"Required;MaxSize(65535)"` + Description string `binding:"MaxSize(65535)"` } func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 7208e1fb96..b9781cf8d0 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1253,6 +1253,8 @@ func GetDiffForRender(ctx context.Context, gitRepo *git.Repository, opts *DiffOp if language.Has() { diffFile.Language = language.Value() } + } else { + checker = nil // CheckPath fails, it's not impossible to "check" anymore } } diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index f8dfc2f622..ae8cd3b4fd 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -151,7 +151,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { var gitRepo *git.Repository if isWiki { - gitRepo, err = gitrepo.OpenWikiRepository(ctx, repo) + gitRepo, err = gitrepo.OpenRepository(ctx, repo.WikiStorageRepo()) } else { gitRepo, err = gitrepo.OpenRepository(ctx, repo) } diff --git a/services/repository/adopt.go b/services/repository/adopt.go index ea4f9a1920..b7321156d9 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -115,7 +115,7 @@ func adoptRepository(ctx context.Context, repo *repo_model.Repository, defaultBr return fmt.Errorf("adoptRepository: path does not already exist: %s", repo.FullName()) } - if err := gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { + if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } diff --git a/services/repository/fork.go b/services/repository/fork.go index 7f7364acfc..5b1ba7a418 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -170,7 +170,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork return fmt.Errorf("git update-server-info: %w", err) } - if err = gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { + if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } diff --git a/services/repository/hooks.go b/services/repository/hooks.go index d2144501e7..a6b6102877 100644 --- a/services/repository/hooks.go +++ b/services/repository/hooks.go @@ -31,16 +31,16 @@ func SyncRepositoryHooks(ctx context.Context) error { default: } - if err := gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { - return fmt.Errorf("SyncRepositoryHook: %w", err) + if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { + return fmt.Errorf("CreateDelegateHooks: %w", err) } - exist, err := gitrepo.IsWikiRepositoryExist(ctx, repo) + exist, err := gitrepo.IsRepositoryExist(ctx, repo.WikiStorageRepo()) if err != nil { - return fmt.Errorf("SyncRepositoryHook: %w", err) + return fmt.Errorf("IsRepositoryExist: %w", err) } if exist { - if err := gitrepo.CreateDelegateHooksForWiki(ctx, repo); err != nil { - return fmt.Errorf("SyncRepositoryHook: %w", err) + if err := gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { + return fmt.Errorf("CreateDelegateHooks: %w", err) } } return nil diff --git a/services/repository/migrate.go b/services/repository/migrate.go index 2284e2c722..5d911b52d8 100644 --- a/services/repository/migrate.go +++ b/services/repository/migrate.go @@ -265,16 +265,16 @@ func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { // CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors. func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) { - if err := gitrepo.CreateDelegateHooksForRepo(ctx, repo); err != nil { + if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return repo, fmt.Errorf("createDelegateHooks: %w", err) } - hasWiki, err := gitrepo.IsWikiRepositoryExist(ctx, repo) + hasWiki, err := gitrepo.IsRepositoryExist(ctx, repo.WikiStorageRepo()) if err != nil { return repo, fmt.Errorf("IsWikiRepositoryExist: %w", err) } if hasWiki { - if err := gitrepo.CreateDelegateHooksForWiki(ctx, repo); err != nil { + if err := gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { return repo, fmt.Errorf("createDelegateHooks.(wiki): %w", err) } } diff --git a/services/repository/transfer.go b/services/repository/transfer.go index 427f8acde1..cf0cba0b76 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -331,12 +331,13 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR return fmt.Errorf("IsRepositoryExist: %w", err) } else if has { return repo_model.ErrRepoAlreadyExist{ - Uname: repo.Owner.Name, + Uname: repo.OwnerName, Name: newRepoName, } } - if err = gitrepo.RenameRepository(ctx, repo, newRepoName); err != nil { + if err = gitrepo.RenameRepository(ctx, repo, + repo_model.StorageRepo(repo_model.RelativePath(repo.OwnerName, newRepoName))); err != nil { return fmt.Errorf("rename repository directory: %w", err) } diff --git a/services/secrets/secrets.go b/services/secrets/secrets.go index 031c474dd7..ec6a3cb062 100644 --- a/services/secrets/secrets.go +++ b/services/secrets/secrets.go @@ -10,7 +10,7 @@ import ( secret_model "code.gitea.io/gitea/models/secret" ) -func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*secret_model.Secret, bool, error) { +func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data, description string) (*secret_model.Secret, bool, error) { if err := ValidateName(name); err != nil { return nil, false, err } @@ -25,14 +25,14 @@ func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data } if len(s) == 0 { - s, err := secret_model.InsertEncryptedSecret(ctx, ownerID, repoID, name, data) + s, err := secret_model.InsertEncryptedSecret(ctx, ownerID, repoID, name, data, description) if err != nil { return nil, false, err } return s, true, nil } - if err := secret_model.UpdateSecret(ctx, s[0].ID, data); err != nil { + if err := secret_model.UpdateSecret(ctx, s[0].ID, data, description); err != nil { return nil, false, err } diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 568004aaf4..0bbe0c6b50 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -43,7 +43,7 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error { if err := git.InitRepository(ctx, repo.WikiPath(), true, repo.ObjectFormatName); err != nil { return fmt.Errorf("InitRepository: %w", err) - } else if err = gitrepo.CreateDelegateHooksForWiki(ctx, repo); err != nil { + } else if err = gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } else if _, _, err = git.NewCommand("symbolic-ref", "HEAD").AddDynamicArguments(git.BranchPrefix+repo.DefaultWikiBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.WikiPath()}); err != nil { return fmt.Errorf("unable to set default wiki branch to %q: %w", repo.DefaultWikiBranch, err) @@ -102,7 +102,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model return fmt.Errorf("InitWiki: %w", err) } - hasDefaultBranch := gitrepo.IsWikiBranchExist(ctx, repo, repo.DefaultWikiBranch) + hasDefaultBranch := gitrepo.IsBranchExist(ctx, repo.WikiStorageRepo(), repo.DefaultWikiBranch) basePath, err := repo_module.CreateTemporaryPath("update-wiki") if err != nil { @@ -392,7 +392,7 @@ func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, n return nil } - oldDefBranch, err := gitrepo.GetWikiDefaultBranch(ctx, repo) + oldDefBranch, err := gitrepo.GetDefaultBranch(ctx, repo.WikiStorageRepo()) if err != nil { return fmt.Errorf("unable to get default branch: %w", err) } @@ -400,7 +400,7 @@ func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, n return nil } - gitRepo, err := gitrepo.OpenWikiRepository(ctx, repo) + gitRepo, err := gitrepo.OpenRepository(ctx, repo.WikiStorageRepo()) if errors.Is(err, util.ErrNotExist) { return nil // no git repo on storage, no need to do anything else } else if err != nil { diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 3c4fd501d8..9fe464bf48 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -168,7 +168,7 @@ func TestRepository_AddWikiPage(t *testing.T) { webPath := UserTitleToWebPath("", userTitle) assert.NoError(t, AddWikiPage(git.DefaultContext, doer, repo, webPath, wikiContent, commitMsg)) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() @@ -215,7 +215,7 @@ func TestRepository_EditWikiPage(t *testing.T) { assert.NoError(t, EditWikiPage(git.DefaultContext, doer, repo, "Home", webPath, newWikiContent, commitMsg)) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) assert.NoError(t, err) masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch) assert.NoError(t, err) @@ -239,7 +239,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) { assert.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, "Home")) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() @@ -253,7 +253,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) { func TestPrepareWikiFileName(t *testing.T) { unittest.PrepareTestEnv(t) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() diff --git a/templates/package/content/container.tmpl b/templates/package/content/container.tmpl index a88ebec3bc..7d89f8c6e2 100644 --- a/templates/package/content/container.tmpl +++ b/templates/package/content/container.tmpl @@ -82,7 +82,7 @@ {{range $key, $value := .PackageDescriptor.Metadata.Labels}} - {{$key}} + {{$key}} {{$value}} {{end}} diff --git a/templates/repo/issue/labels/label_list.tmpl b/templates/repo/issue/labels/label_list.tmpl index 822567301e..cdbcc456f0 100644 --- a/templates/repo/issue/labels/label_list.tmpl +++ b/templates/repo/issue/labels/label_list.tmpl @@ -63,13 +63,11 @@ {{if and (not .PageIsOrgSettingsLabels) (.OrgLabels)}}
  • -
    -
    - {{ctx.Locale.Tr "repo.org_labels_desc"}} - {{if .IsOrganizationOwner}} - ({{ctx.Locale.Tr "repo.org_labels_desc_manage"}}): - {{end}} -
    +
    {{/* parent is flex, so use block here to keep sentence spaces */}} + {{ctx.Locale.Tr "repo.org_labels_desc"}} + {{if .IsOrganizationOwner}} + ({{ctx.Locale.Tr "repo.org_labels_desc_manage"}}): + {{end}}
  • diff --git a/templates/repo/issue/sidebar/reference_link.tmpl b/templates/repo/issue/sidebar/reference_link.tmpl index 6b8f120c7b..ad7c0f6bc0 100644 --- a/templates/repo/issue/sidebar/reference_link.tmpl +++ b/templates/repo/issue/sidebar/reference_link.tmpl @@ -1,8 +1,6 @@
    -
    - {{$issueReferenceLink := printf "%s#%d" .Issue.Repo.FullName .Issue.Index}} -
    - {{ctx.Locale.Tr "repo.issues.reference_link" $issueReferenceLink}} - -
    +{{$issueReferenceLink := printf "%s#%d" .Issue.Repo.FullName .Issue.Index}} +
    + {{ctx.Locale.Tr "repo.issues.reference_link" $issueReferenceLink}} +
    diff --git a/templates/repo/view_file_tree.tmpl b/templates/repo/view_file_tree.tmpl index ce9b2e4d11..8aed05f346 100644 --- a/templates/repo/view_file_tree.tmpl +++ b/templates/repo/view_file_tree.tmpl @@ -1,5 +1,5 @@ -
    -
    {{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}} diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl index 7a0ab48cef..2edca431c1 100644 --- a/templates/shared/variables/variable_list.tmpl +++ b/templates/shared/variables/variable_list.tmpl @@ -7,6 +7,7 @@ data-modal-header="{{ctx.Locale.Tr "actions.variables.creation"}}" data-modal-dialog-variable-name="" data-modal-dialog-variable-data="" + data-modal-dialog-variable-description="" > {{ctx.Locale.Tr "actions.variables.creation"}} @@ -24,6 +25,9 @@
    {{.Name}}
    +
    + {{if .Description}}{{.Description}}{{else}}-{{end}} +
    {{.Data}}
    @@ -39,6 +43,7 @@ data-modal-header="{{ctx.Locale.Tr "actions.variables.edit"}}" data-modal-dialog-variable-name="{{.Name}}" data-modal-dialog-variable-data="{{.Data}}" + data-modal-dialog-variable-description="{{.Description}}" > {{svg "octicon-pencil"}} @@ -82,9 +87,20 @@
    +
    + + +
    {{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 48ed958ca2..1efaf1a875 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -19325,6 +19325,11 @@ "type": "string", "x-go-name": "Data" }, + "description": { + "description": "the description of the variable", + "type": "string", + "x-go-name": "Description" + }, "name": { "description": "the name of the variable", "type": "string", @@ -20988,6 +20993,11 @@ "description": "Data of the secret to update", "type": "string", "x-go-name": "Data" + }, + "description": { + "description": "Description of the secret to update", + "type": "string", + "x-go-name": "Description" } }, "x-go-package": "code.gitea.io/gitea/modules/structs" @@ -21498,6 +21508,11 @@ "value" ], "properties": { + "description": { + "description": "Description of the variable to create", + "type": "string", + "x-go-name": "Description" + }, "value": { "description": "Value of the variable to create", "type": "string", @@ -25459,6 +25474,11 @@ "format": "date-time", "x-go-name": "Created" }, + "description": { + "description": "the secret's description", + "type": "string", + "x-go-name": "Description" + }, "name": { "description": "the secret's name", "type": "string", @@ -26034,6 +26054,11 @@ "value" ], "properties": { + "description": { + "description": "Description of the variable to update", + "type": "string", + "x-go-name": "Description" + }, "name": { "description": "New name for the variable. If the field is empty, the variable name won't be updated.", "type": "string", diff --git a/templates/user/auth/captcha.tmpl b/templates/user/auth/captcha.tmpl index 8dd4d1cc51..6779948da5 100644 --- a/templates/user/auth/captcha.tmpl +++ b/templates/user/auth/captcha.tmpl @@ -10,12 +10,12 @@
    - + {{else if eq .CaptchaType "hcaptcha"}}
    - + {{else if eq .CaptchaType "mcaptcha"}}
    @@ -25,5 +25,5 @@
    - + {{end}}{{end}} diff --git a/templates/user/settings/repos.tmpl b/templates/user/settings/repos.tmpl index a50fb586c7..4aed8070de 100644 --- a/templates/user/settings/repos.tmpl +++ b/templates/user/settings/repos.tmpl @@ -81,7 +81,7 @@ {{end}} {{else}} {{if .Repos}} -
    +
    {{range .Repos}}
    diff --git a/tests/integration/actions_variables_test.go b/tests/integration/actions_variables_test.go index 1fd3294109..c0d0bd371b 100644 --- a/tests/integration/actions_variables_test.go +++ b/tests/integration/actions_variables_test.go @@ -27,21 +27,21 @@ func TestActionsVariables(t *testing.T) { require.NoError(t, db.DeleteAllRecords("action_variable")) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - _, _ = actions_model.InsertVariable(ctx, user2.ID, 0, "VAR", "user2-var") + _, _ = actions_model.InsertVariable(ctx, user2.ID, 0, "VAR", "user2-var", "user2-var-description") user2Var := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionVariable{OwnerID: user2.ID, Name: "VAR"}) userWebURL := "/user/settings/actions/variables" org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3, Type: user_model.UserTypeOrganization}) - _, _ = actions_model.InsertVariable(ctx, org3.ID, 0, "VAR", "org3-var") + _, _ = actions_model.InsertVariable(ctx, org3.ID, 0, "VAR", "org3-var", "org3-var-description") org3Var := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionVariable{OwnerID: org3.ID, Name: "VAR"}) orgWebURL := "/org/org3/settings/actions/variables" repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - _, _ = actions_model.InsertVariable(ctx, 0, repo1.ID, "VAR", "repo1-var") + _, _ = actions_model.InsertVariable(ctx, 0, repo1.ID, "VAR", "repo1-var", "repo1-var-description") repo1Var := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionVariable{RepoID: repo1.ID, Name: "VAR"}) repoWebURL := "/user2/repo1/settings/actions/variables" - _, _ = actions_model.InsertVariable(ctx, 0, 0, "VAR", "global-var") + _, _ = actions_model.InsertVariable(ctx, 0, 0, "VAR", "global-var", "global-var-description") globalVar := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionVariable{Name: "VAR", Data: "global-var"}) adminWebURL := "/-/admin/actions/variables" diff --git a/tests/integration/api_repo_secrets_test.go b/tests/integration/api_repo_secrets_test.go index c3074d9ece..2059aff484 100644 --- a/tests/integration/api_repo_secrets_test.go +++ b/tests/integration/api_repo_secrets_test.go @@ -73,6 +73,33 @@ func TestAPIRepoSecrets(t *testing.T) { } }) + t.Run("CreateWithDescription", func(t *testing.T) { + cases := []struct { + Name string + Description string + ExpectedStatus int + }{ + { + Name: "no_description", + Description: "", + ExpectedStatus: http.StatusCreated, + }, + { + Name: "description", + Description: "some description", + ExpectedStatus: http.StatusCreated, + }, + } + + for _, c := range cases { + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s", repo.FullName(), c.Name), api.CreateOrUpdateSecretOption{ + Data: "data", + Description: c.Description, + }).AddTokenAuth(token) + MakeRequest(t, req, c.ExpectedStatus) + } + }) + t.Run("Update", func(t *testing.T) { name := "update_secret" url := fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s", repo.FullName(), name) diff --git a/web_src/css/markup/content.css b/web_src/css/markup/content.css index fabf5b3a8f..865ac0536a 100644 --- a/web_src/css/markup/content.css +++ b/web_src/css/markup/content.css @@ -285,7 +285,6 @@ .markup table { display: block; width: 100%; - width: max-content; max-width: 100%; overflow: auto; } diff --git a/web_src/css/modules/grid.css b/web_src/css/modules/grid.css index 05e28c513f..b4f4e16105 100644 --- a/web_src/css/modules/grid.css +++ b/web_src/css/modules/grid.css @@ -393,28 +393,6 @@ margin-right: 2.5rem; } -.ui[class*="middle aligned"].grid > .column:not(.row), -.ui[class*="middle aligned"].grid > .row > .column, -.ui.grid > [class*="middle aligned"].row > .column, -.ui.grid > [class*="middle aligned"].column:not(.row), -.ui.grid > .row > [class*="middle aligned"].column { - flex-direction: column; - vertical-align: middle; - align-self: center !important; -} - -.ui[class*="equal width"].grid > .column:not(.row), -.ui[class*="equal width"].grid > .row > .column, -.ui.grid > [class*="equal width"].row > .column { - display: inline-block; - flex-grow: 1; -} -.ui[class*="equal width"].grid > .wide.column, -.ui[class*="equal width"].grid > .row > .wide.column, -.ui.grid > [class*="equal width"].row > .wide.column { - flex-grow: 0; -} - @media only screen and (max-width: 767.98px) { .ui[class*="mobile reversed"].grid, .ui[class*="mobile reversed"].grid > .row, diff --git a/web_src/css/modules/table.css b/web_src/css/modules/table.css index 844675b5ae..eabca31a17 100644 --- a/web_src/css/modules/table.css +++ b/web_src/css/modules/table.css @@ -152,16 +152,6 @@ } } -.ui.table[class*="top aligned"], -.ui.table [class*="top aligned"] { - vertical-align: top; -} - -.ui.table[class*="middle aligned"], -.ui.table [class*="middle aligned"] { - vertical-align: middle; -} - .ui.table th.collapsing, .ui.table td.collapsing { width: 1px; diff --git a/web_src/css/repo/home-file-list.css b/web_src/css/repo/home-file-list.css index 189b6406d4..46128457ed 100644 --- a/web_src/css/repo/home-file-list.css +++ b/web_src/css/repo/home-file-list.css @@ -14,10 +14,6 @@ } } -#repo-files-table .repo-file-cell.name .svg { - margin-right: 2px; -} - #repo-files-table .svg.octicon-file-directory-fill, #repo-files-table .svg.octicon-file-submodule { color: var(--color-primary); @@ -70,11 +66,25 @@ } #repo-files-table .repo-file-cell.name { + display: flex; + align-items: center; + gap: 0.5em; + overflow: hidden; +} + +#repo-files-table .repo-file-cell.name > a, +#repo-files-table .repo-file-cell.name > span { + flex-shrink: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +#repo-files-table .repo-file-cell.name .entry-name { + flex-shrink: 1; + min-width: 3em; +} + @media (max-width: 767.98px) { #repo-files-table .repo-file-cell.name { max-width: 35vw; diff --git a/web_src/css/repo/home.css b/web_src/css/repo/home.css index 219be77adb..69c454d611 100644 --- a/web_src/css/repo/home.css +++ b/web_src/css/repo/home.css @@ -55,7 +55,7 @@ } .repo-view-container .repo-view-file-tree-container { - flex: 0 1 15%; + flex: 0 0 15%; min-width: 0; max-height: 100vh; } diff --git a/web_src/fomantic/build/components/form.css b/web_src/fomantic/build/components/form.css index 66ccedf29a..0124e2d6b5 100644 --- a/web_src/fomantic/build/components/form.css +++ b/web_src/fomantic/build/components/form.css @@ -1499,16 +1499,6 @@ width: 100%; } -/*-------------------- - Equal Width ----------------------*/ - -.ui[class*="equal width"].form .fields > .field, -.ui.form [class*="equal width"].fields > .field { - width: 100%; - flex: 1 1 auto; -} - /*-------------------- Inline Fields ---------------------*/ diff --git a/web_src/fomantic/build/components/modal.css b/web_src/fomantic/build/components/modal.css index 87a7989510..7da015cfd0 100644 --- a/web_src/fomantic/build/components/modal.css +++ b/web_src/fomantic/build/components/modal.css @@ -116,12 +116,7 @@ align-self: start; max-width: 100%; } -.ui.modal > [class*="top aligned"] { - align-self: start; -} -.ui.modal > [class*="middle aligned"] { - align-self: center; -} + .ui.modal > [class*="stretched"] { align-self: stretch; } @@ -258,7 +253,7 @@ padding: 1rem 0 !important; box-shadow: none; } - + /* Let Buttons Stack */ .ui.modal > .actions { padding: 1rem 1rem 0rem !important; diff --git a/web_src/js/webcomponents/absolute-date.test.ts b/web_src/js/webcomponents/absolute-date.test.ts index a3866829a7..bf591358bd 100644 --- a/web_src/js/webcomponents/absolute-date.test.ts +++ b/web_src/js/webcomponents/absolute-date.test.ts @@ -20,7 +20,7 @@ test('toAbsoluteLocaleDate', () => { // test different timezone const oldTZ = process.env.TZ; process.env.TZ = 'America/New_York'; - expect(new Date('2024-03-15').toLocaleString()).toEqual('3/14/2024, 8:00:00 PM'); - expect(toAbsoluteLocaleDate('2024-03-15')).toEqual('3/15/2024, 12:00:00 AM'); + expect(new Date('2024-03-15').toLocaleString('en-US')).toEqual('3/14/2024, 8:00:00 PM'); + expect(toAbsoluteLocaleDate('2024-03-15', 'en-US')).toEqual('3/15/2024, 12:00:00 AM'); process.env.TZ = oldTZ; });