diff --git a/.github/workflows/files-changed.yml b/.github/workflows/files-changed.yml index f9156d668d5cb..b9277d3109d38 100644 --- a/.github/workflows/files-changed.yml +++ b/.github/workflows/files-changed.yml @@ -43,6 +43,8 @@ jobs: - "go.mod" - "go.sum" - "Makefile" + - ".golangci.yml" + - ".editorconfig" frontend: - "**/*.js" @@ -51,16 +53,21 @@ jobs: - "package.json" - "package-lock.json" - "Makefile" + - ".eslintrc.yaml" + - ".stylelintrc.yaml" + - ".npmrc" docs: - "**/*.md" - "docs/**" + - ".markdownlint.yaml" actions: - ".github/workflows/*" templates: - "templates/**/*.tmpl" + - "pyproject.toml" - "poetry.lock" docker: @@ -72,3 +79,6 @@ jobs: swagger: - "templates/swagger/v1_json.tmpl" - "Makefile" + - "package.json" + - "package-lock.json" + - ".spectral.yml" diff --git a/.golangci.yml b/.golangci.yml index 7c35bdd2a8dad..069dc13c991e6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,7 +29,7 @@ linters: fast: false run: - go: "1.20" + go: "1.21" timeout: 10m skip-dirs: - node_modules @@ -75,7 +75,7 @@ linters-settings: - name: modifies-value-receiver gofumpt: extra-rules: true - lang-version: "1.20" + lang-version: "1.21" depguard: rules: main: diff --git a/README.md b/README.md index ff9bcc0659cd1..767a7858e423f 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,10 @@ or if SQLite support is required: The `build` target is split into two sub-targets: -- `make backend` which requires [Go Stable](https://go.dev/dl/), required version is defined in [go.mod](/go.mod). -- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies. +- `make backend` which requires [Go Stable](https://go.dev/dl/), the required version is defined in [go.mod](/go.mod). +- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater. -When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity. +Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js. Parallelism (`make -j `) is not supported. diff --git a/build/backport-locales.go b/build/backport-locales.go index 0346215348596..d112dd72bd56e 100644 --- a/build/backport-locales.go +++ b/build/backport-locales.go @@ -12,6 +12,7 @@ import ( "path/filepath" "strings" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/setting" ) @@ -58,7 +59,7 @@ func main() { // use old en-US as the base, and copy the new translations to the old locales enUsOld := inisOld["options/locale/locale_en-US.ini"] - brokenWarned := map[string]bool{} + brokenWarned := make(container.Set[string]) for path, iniOld := range inisOld { if iniOld == enUsOld { continue @@ -77,7 +78,7 @@ func main() { broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%") broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n") if broken { - brokenWarned[secOld.Name()+"."+keyEnUs.Name()] = true + brokenWarned.Add(secOld.Name() + "." + keyEnUs.Name()) fmt.Println("----") fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name()) fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n")) @@ -103,7 +104,7 @@ func main() { broken = broken || strings.HasPrefix(str, "`\"") broken = broken || strings.Count(str, `"`)%2 == 1 broken = broken || strings.Count(str, "`")%2 == 1 - if broken && !brokenWarned[sec.Name()+"."+key.Name()] { + if broken && !brokenWarned.Contains(sec.Name()+"."+key.Name()) { fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name()) fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n")) fmt.Println("----") diff --git a/build/generate-go-licenses.go b/build/generate-go-licenses.go index c3b40c226f4de..84ba39025c4cd 100644 --- a/build/generate-go-licenses.go +++ b/build/generate-go-licenses.go @@ -15,6 +15,8 @@ import ( "regexp" "sort" "strings" + + "code.gitea.io/gitea/modules/container" ) // regexp is based on go-license, excluding README and NOTICE @@ -55,20 +57,14 @@ func main() { // yml // // It could be removed once we have a better regex. - excludedExt := map[string]bool{ - ".gitignore": true, - ".go": true, - ".mod": true, - ".sum": true, - ".toml": true, - ".yml": true, - } + excludedExt := container.SetOf(".gitignore", ".go", ".mod", ".sum", ".toml", ".yml") + var paths []string err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error { if err != nil { return err } - if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt[filepath.Ext(entry.Name())] { + if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt.Contains(filepath.Ext(entry.Name())) { return nil } paths = append(paths, path) diff --git a/models/fixtures/email_address.yml b/models/fixtures/email_address.yml index e7df5fdc5f01c..1c32379b60d94 100644 --- a/models/fixtures/email_address.yml +++ b/models/fixtures/email_address.yml @@ -276,4 +276,12 @@ email: user2-2@example.com lower_email: user2-2@example.com is_activated: false - is_primary: false \ No newline at end of file + is_primary: false + +- + id: 36 + uid: 36 + email: abcde@gitea.com + lower_email: abcde@gitea.com + is_activated: true + is_primary: false diff --git a/models/fixtures/gpg_key.yml b/models/fixtures/gpg_key.yml index ca780a73aa0c1..2d54313fdf1c7 100644 --- a/models/fixtures/gpg_key.yml +++ b/models/fixtures/gpg_key.yml @@ -1 +1,23 @@ -[] # empty +- + id: 5 + owner_id: 36 + key_id: B15431642629B826 + primary_key_id: + content: xsDNBGTrY3UBDAC2HLBqmMplAV15qSnC7g1c4dV406f5EHNhFr95Nup2My6b2eafTlvedv77s8PT/I7F3fy4apOZs5A7w2SsPlLMcQ3ev4uGOsxRtkq5RLy1Yb6SNueX0Da2UVKR5KTC5Q6BWaqxwS0IjKOLZ/xz0Pbe/ClV3bZSKBEY2omkVo3Z0HZ771vB2clPRvGJ/IdeKOsZ3ZytSFXfyiJBdARmeSPmydXLil8+Ibq5iLAeow5PK8hK1TCOnKHzLWNqcNq70tyjoHvcGi70iGjoVEEUgPCLLuU8WmzTJwlvA3BuDzjtaO7TLo/jdE6iqkHtMSS8x+43sAH6hcFRCWAVh/0Uq7n36uGDfNxGnX3YrmX3LR9x5IsBES1rGGWbpxio4o5GIf/Xd+JgDd9rzJCqRuZ3/sW/TxK38htWaVNZV0kMkHUCTc1ctzWpCm635hbFCHBhPYIp+/z206khkAKDbz/CNuU91Wazsh7KO07wrwDtxfDDbInJ8TfHE2TGjzjQzgChfmcAEQEAAQ== + verified: true + can_sign: true + can_encrypt_comms: true + can_encrypt_storage: true + can_certify: true + +- + id: 6 + owner_id: 36 + key_id: EE3AF48454AFD619 + primary_key_id: B15431642629B826 + content: zsDNBGTrY3UBDADsHrzuOicQaPdUQm0+0UNrs92cESm/j/4yBBUk+sfLZAo6J99c4eh4nAQzzZ7al080rYKB0G+7xoRz1eHcQH6zrVcqB8KYtf/sdY47WaMiMyxM+kTSvzp7tsv7QuSQZ0neUEXRyYMz5ttBfIjWUd+3NDItuHyB+MtNWlS3zXgaUbe5VifqKaNmzN0Ye4yXTKcpypE3AOqPVz+iIFv3c6TmsqLHJaR4VoicCleAqLyF/28WsJO7M9dDW+EM3MZVnsVpycTURyHAJGfSk10waQZAaRwmarCN/q0KEJ+aEAK/SRliUneBZoMO5hY5iBeG432tofwaQqAahPv9uXIb1n2JEMKwnMlMA9UGD1AcDbywfj1m/ZGBBw95i4Ekkfn43RvV3THr7uJU/dRqqP+iic4MwpUrOxqELW/kmeHXlBcNbZZhEEvwRoW7U2/9eeuog4nRleRJ0pi/xOP9wmxkKjaIPIK3phdBtEpVk4w/UTAWNdyIIrFggukeAnZFyGJwlm8AEQEAAQ== + verified: true + can_sign: true + can_encrypt_comms: true + can_encrypt_storage: true + can_certify: true diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index c7c5c024be89a..f24d098a7ed7b 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -1301,7 +1301,7 @@ lower_name: limited_org36 name: limited_org36 full_name: Limited Org 36 - email: limited_org36@example.com + email: abcde@gitea.com keep_email_private: false email_notifications_preference: enabled passwd: ZogKvWdyEx:password @@ -1320,7 +1320,7 @@ allow_create_organization: true prohibit_login: false avatar: avatar22 - avatar_email: limited_org36@example.com + avatar_email: abcde@gitea.com use_custom_avatar: false num_followers: 0 num_following: 0 diff --git a/models/migrations/v1_16/v210.go b/models/migrations/v1_16/v210.go index 4e55afccc1302..533bb4bf8055f 100644 --- a/models/migrations/v1_16/v210.go +++ b/models/migrations/v1_16/v210.go @@ -4,7 +4,6 @@ package v1_16 //nolint import ( - "crypto/elliptic" "encoding/base32" "fmt" "strings" @@ -123,13 +122,17 @@ func RemigrateU2FCredentials(x *xorm.Engine) error { if err != nil { continue } + pubKey, err := parsed.PubKey.ECDH() + if err != nil { + continue + } remigrated := &webauthnCredential{ ID: reg.ID, Name: reg.Name, LowerName: strings.ToLower(reg.Name), UserID: reg.UserID, CredentialID: base32.HexEncoding.EncodeToString(parsed.KeyHandle), - PublicKey: elliptic.Marshal(elliptic.P256(), parsed.PubKey.X, parsed.PubKey.Y), + PublicKey: pubKey.Bytes(), AttestationType: "fido-u2f", AAGUID: []byte{}, SignCount: reg.Counter, diff --git a/models/secret/secret.go b/models/secret/secret.go index 410cb3770ebdf..1cb816e9db273 100644 --- a/models/secret/secret.go +++ b/models/secret/secret.go @@ -160,3 +160,31 @@ func DeleteSecret(ctx context.Context, orgID, repoID int64, name string) error { return nil } + +// CreateOrUpdateSecret creates or updates a secret and returns true if it was created +func CreateOrUpdateSecret(ctx context.Context, orgID, repoID int64, name, data string) (bool, error) { + sc := new(Secret) + name = strings.ToUpper(name) + has, err := db.GetEngine(ctx). + Where("owner_id=?", orgID). + And("repo_id=?", repoID). + And("name=?", name). + Get(sc) + if err != nil { + return false, err + } + + if !has { + _, err = InsertEncryptedSecret(ctx, orgID, repoID, name, data) + if err != nil { + return false, err + } + return true, nil + } + + if err := UpdateSecret(ctx, orgID, repoID, name, data); err != nil { + return false, err + } + + return false, nil +} diff --git a/models/unit/unit.go b/models/unit/unit.go index 5f5e20de1e0e0..ca3e7f999d2c0 100644 --- a/models/unit/unit.go +++ b/models/unit/unit.go @@ -9,6 +9,7 @@ import ( "strings" "code.gitea.io/gitea/models/perm" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -318,14 +319,13 @@ var ( // FindUnitTypes give the unit key names and return valid unique units and invalid keys func FindUnitTypes(nameKeys ...string) (res []Type, invalidKeys []string) { - m := map[Type]struct{}{} + m := make(container.Set[Type]) for _, key := range nameKeys { t := TypeFromKey(key) if t == TypeInvalid { invalidKeys = append(invalidKeys, key) - } else if _, ok := m[t]; !ok { + } else if m.Add(t) { res = append(res, t) - m[t] = struct{}{} } } return res, invalidKeys diff --git a/modules/assetfs/layered.go b/modules/assetfs/layered.go index d69732f81be6b..9678d23ad675f 100644 --- a/modules/assetfs/layered.go +++ b/modules/assetfs/layered.go @@ -14,6 +14,7 @@ import ( "sort" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/util" @@ -130,7 +131,7 @@ func readDir(layer *Layer, name string) ([]fs.FileInfo, error) { // * false: only directories will be returned. // The returned files are sorted by name. func (l *LayeredFS) ListFiles(name string, fileMode ...bool) ([]string, error) { - fileMap := map[string]bool{} + fileSet := make(container.Set[string]) for _, layer := range l.layers { infos, err := readDir(layer, name) if err != nil { @@ -138,14 +139,11 @@ func (l *LayeredFS) ListFiles(name string, fileMode ...bool) ([]string, error) { } for _, info := range infos { if shouldInclude(info, fileMode...) { - fileMap[info.Name()] = true + fileSet.Add(info.Name()) } } } - files := make([]string, 0, len(fileMap)) - for file := range fileMap { - files = append(files, file) - } + files := fileSet.Values() sort.Strings(files) return files, nil } @@ -161,7 +159,7 @@ func (l *LayeredFS) ListAllFiles(name string, fileMode ...bool) ([]string, error } func listAllFiles(layers []*Layer, name string, fileMode ...bool) ([]string, error) { - fileMap := map[string]bool{} + fileSet := make(container.Set[string]) var list func(dir string) error list = func(dir string) error { for _, layer := range layers { @@ -172,7 +170,7 @@ func listAllFiles(layers []*Layer, name string, fileMode ...bool) ([]string, err for _, info := range infos { path := util.PathJoinRelX(dir, info.Name()) if shouldInclude(info, fileMode...) { - fileMap[path] = true + fileSet.Add(path) } if info.IsDir() { if err = list(path); err != nil { @@ -186,10 +184,7 @@ func listAllFiles(layers []*Layer, name string, fileMode ...bool) ([]string, err if err := list(name); err != nil { return nil, err } - var files []string - for file := range fileMap { - files = append(files, file) - } + files := fileSet.Values() sort.Strings(files) return files, nil } diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go index 70f6ef9dbb9e6..7519e32b90027 100644 --- a/modules/git/log_name_status.go +++ b/modules/git/log_name_status.go @@ -374,27 +374,25 @@ heaploop: break heaploop } parentRemaining.Remove(current.CommitID) - if current.Paths != nil { - for i, found := range current.Paths { - if !found { - continue + for i, found := range current.Paths { + if !found { + continue + } + changed[i] = false + if results[i] == "" { + results[i] = current.CommitID + if err := repo.LastCommitCache.Put(headRef, path.Join(treepath, paths[i]), current.CommitID); err != nil { + return nil, err } - changed[i] = false - if results[i] == "" { - results[i] = current.CommitID - if err := repo.LastCommitCache.Put(headRef, path.Join(treepath, paths[i]), current.CommitID); err != nil { + delete(path2idx, paths[i]) + remaining-- + if results[0] == "" { + results[0] = current.CommitID + if err := repo.LastCommitCache.Put(headRef, treepath, current.CommitID); err != nil { return nil, err } - delete(path2idx, paths[i]) + delete(path2idx, "") remaining-- - if results[0] == "" { - results[0] = current.CommitID - if err := repo.LastCommitCache.Put(headRef, treepath, current.CommitID); err != nil { - return nil, err - } - delete(path2idx, "") - remaining-- - } } } } diff --git a/modules/setting/service.go b/modules/setting/service.go index 595ea6528f886..74a7e90f7c880 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -223,7 +223,7 @@ func loadServiceFrom(rootCfg ConfigProvider) { Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) sec.Key("VALID_SITE_URL_SCHEMES").MustString("http,https") Service.ValidSiteURLSchemes = sec.Key("VALID_SITE_URL_SCHEMES").Strings(",") - schemes := make([]string, len(Service.ValidSiteURLSchemes)) + schemes := make([]string, 0, len(Service.ValidSiteURLSchemes)) for _, scheme := range Service.ValidSiteURLSchemes { scheme = strings.ToLower(strings.TrimSpace(scheme)) if scheme != "" { diff --git a/modules/templates/util_dict.go b/modules/templates/util_dict.go index 79c307b68d9a0..8d6376b522e56 100644 --- a/modules/templates/util_dict.go +++ b/modules/templates/util_dict.go @@ -9,6 +9,7 @@ import ( "html/template" "reflect" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" ) @@ -51,7 +52,7 @@ func dict(args ...any) (map[string]any, error) { return m, nil } -func dumpVarMarshalable(v any, dumped map[uintptr]bool) (ret any, ok bool) { +func dumpVarMarshalable(v any, dumped container.Set[uintptr]) (ret any, ok bool) { if v == nil { return nil, true } @@ -61,11 +62,10 @@ func dumpVarMarshalable(v any, dumped map[uintptr]bool) (ret any, ok bool) { } if e.CanAddr() { addr := e.UnsafeAddr() - if dumped[addr] { + if !dumped.Add(addr) { return "[dumped]", false } - dumped[addr] = true - defer delete(dumped, addr) + defer dumped.Remove(addr) } switch e.Kind() { case reflect.Bool, reflect.String, @@ -107,7 +107,7 @@ func dumpVar(v any) template.HTML { if setting.IsProd { return "
dumpVar: only available in dev mode
" } - m, ok := dumpVarMarshalable(v, map[uintptr]bool{}) + m, ok := dumpVarMarshalable(v, make(container.Set[uintptr])) var dumpStr string jsonBytes, err := json.MarshalIndent(m, "", " ") if err != nil { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 31d47ad6af202..f8e068fe19706 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -970,6 +970,7 @@ trust_model_helper_collaborator_committer = Collaborator+Committer: Trust signat trust_model_helper_default = Default: Use the default trust model for this installation create_repo = Create Repository default_branch = Default Branch +default_branch_label = default default_branch_helper = The default branch is the base branch for pull requests and code commits. mirror_prune = Prune mirror_prune_desc = Remove obsolete remote-tracking references diff --git a/package-lock.json b/package-lock.json index 4def61f7072f6..0aa87bdbe1ea2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,21 +17,21 @@ "@primer/octicons": "19.6.0", "@webcomponents/custom-elements": "1.6.0", "add-asset-webpack-plugin": "2.0.1", - "ansi_up": "6.0.0", + "ansi_up": "6.0.2", "asciinema-player": "3.5.0", "clippie": "4.0.6", "css-loader": "6.8.1", "dropzone": "6.0.0-beta.2", "easymde": "2.18.0", - "esbuild-loader": "4.0.0", + "esbuild-loader": "4.0.2", "escape-goat": "4.0.0", "fast-glob": "3.3.1", - "jquery": "3.7.0", + "jquery": "3.7.1", "jquery.are-you-sure": "1.9.0", "katex": "0.16.8", "license-checker-webpack-plugin": "0.2.1", "lightningcss-loader": "2.1.0", - "mermaid": "10.3.1", + "mermaid": "10.4.0", "mini-css-extract-plugin": "2.7.6", "minimatch": "9.0.3", "monaco-editor": "0.41.0", @@ -58,16 +58,16 @@ "@eslint-community/eslint-plugin-eslint-comments": "4.1.0", "@playwright/test": "1.37.1", "@stoplight/spectral-cli": "6.10.1", - "@vitejs/plugin-vue": "4.3.1", - "eslint": "8.47.0", + "@vitejs/plugin-vue": "4.3.4", + "eslint": "8.48.0", "eslint-plugin-array-func": "3.1.8", "eslint-plugin-custom-elements": "0.0.8", - "eslint-plugin-import": "2.28.0", + "eslint-plugin-import": "2.28.1", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-regexp": "1.15.0", - "eslint-plugin-sonarjs": "0.20.0", + "eslint-plugin-sonarjs": "0.21.0", "eslint-plugin-unicorn": "48.0.1", "eslint-plugin-vue": "9.17.0", "eslint-plugin-vue-scoped-css": "2.5.0", @@ -80,9 +80,9 @@ "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.3", "svgo": "3.0.2", - "updates": "14.3.5", + "updates": "14.4.0", "vite-string-plugin": "1.1.2", - "vitest": "0.34.2" + "vitest": "0.34.3" }, "engines": { "node": ">= 16.0.0" @@ -992,9 +992,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1146,9 +1146,9 @@ } }, "node_modules/@jest/schemas": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -2030,9 +2030,9 @@ "dev": true }, "node_modules/@vitejs/plugin-vue": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.1.tgz", - "integrity": "sha512-tUBEtWcF7wFtII7ayNiLNDTCE1X1afySEo+XNVMNkFXaThENyCowIEX095QqbJZGTgoOcSVDJGlnde2NG4jtbQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz", + "integrity": "sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==", "dev": true, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -2043,13 +2043,13 @@ } }, "node_modules/@vitest/expect": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.2.tgz", - "integrity": "sha512-EZm2dMNlLyIfDMha17QHSQcg2KjeAZaXd65fpPzXY5bvnfx10Lcaz3N55uEe8PhF+w4pw+hmrlHLLlRn9vkBJg==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.3.tgz", + "integrity": "sha512-F8MTXZUYRBVsYL1uoIft1HHWhwDbSzwAU9Zgh8S6WFC3YgVb4AnFV2GXO3P5Em8FjEYaZtTnQYoNwwBrlOMXgg==", "dev": true, "dependencies": { - "@vitest/spy": "0.34.2", - "@vitest/utils": "0.34.2", + "@vitest/spy": "0.34.3", + "@vitest/utils": "0.34.3", "chai": "^4.3.7" }, "funding": { @@ -2057,12 +2057,12 @@ } }, "node_modules/@vitest/runner": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.2.tgz", - "integrity": "sha512-8ydGPACVX5tK3Dl0SUwxfdg02h+togDNeQX3iXVFYgzF5odxvaou7HnquALFZkyVuYskoaHUOqOyOLpOEj5XTA==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.3.tgz", + "integrity": "sha512-lYNq7N3vR57VMKMPLVvmJoiN4bqwzZ1euTW+XXYH5kzr3W/+xQG3b41xJn9ChJ3AhYOSoweu974S1V3qDcFESA==", "dev": true, "dependencies": { - "@vitest/utils": "0.34.2", + "@vitest/utils": "0.34.3", "p-limit": "^4.0.0", "pathe": "^1.1.1" }, @@ -2098,9 +2098,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.2.tgz", - "integrity": "sha512-qhQ+xy3u4mwwLxltS4Pd4SR+XHv4EajiTPNY3jkIBLUApE6/ce72neJPSUQZ7bL3EBuKI+NhvzhGj3n5baRQUQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.3.tgz", + "integrity": "sha512-QyPaE15DQwbnIBp/yNJ8lbvXTZxS00kRly0kfFgAD5EYmCbYcA+1EEyRalc93M0gosL/xHeg3lKAClIXYpmUiQ==", "dev": true, "dependencies": { "magic-string": "^0.30.1", @@ -2112,9 +2112,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", + "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -2124,9 +2124,9 @@ } }, "node_modules/@vitest/spy": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.2.tgz", - "integrity": "sha512-yd4L9OhfH6l0Av7iK3sPb3MykhtcRN5c5K5vm1nTbuN7gYn+yvUVVsyvzpHrjqS7EWqn9WsPJb7+0c3iuY60tA==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.3.tgz", + "integrity": "sha512-N1V0RFQ6AI7CPgzBq9kzjRdPIgThC340DGjdKdPSE8r86aUSmeliTUgkTqLSgtEwWWsGfBQ+UetZWhK0BgJmkQ==", "dev": true, "dependencies": { "tinyspy": "^2.1.1" @@ -2136,9 +2136,9 @@ } }, "node_modules/@vitest/utils": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.2.tgz", - "integrity": "sha512-Lzw+kAsTPubhoQDp1uVAOP6DhNia1GMDsI9jgB0yMn+/nDaPieYQ88lKqz/gGjSHL4zwOItvpehec9OY+rS73w==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.3.tgz", + "integrity": "sha512-kiSnzLG6m/tiT0XEl4U2H8JDBjFtwVlaE8I3QfGiMFR0QvnRDfYfdP3YvTBWM/6iJDAyaPY6yVQiCTUc7ZzTHA==", "dev": true, "dependencies": { "diff-sequences": "^29.4.3", @@ -2607,9 +2607,9 @@ } }, "node_modules/ansi_up": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.0.tgz", - "integrity": "sha512-3lnYPwXYbCSXQw52OWemps5mgfYuNsX3R5fgkHXoUDpRe8Ex/ivir1AdQLUWkdpQLyQZS/v3ofY8JGQDORwuLQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.2.tgz", + "integrity": "sha512-3G3vKvl1ilEp7J1u6BmULpMA0xVoW/f4Ekqhl8RTrJrhEBkonKn5k3bUc5Xt+qDayA6iDX0jyUh3AbZjB/l0tw==", "engines": { "node": "*" } @@ -3088,9 +3088,9 @@ ] }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", + "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -4222,9 +4222,9 @@ } }, "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4596,12 +4596,12 @@ } }, "node_modules/esbuild-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.0.tgz", - "integrity": "sha512-J7TJWyHV2YHmflZaXLZ0Vf4wYmixDyGTw26bt4Ok+XOqSyYA4VWAVt2zJGqIfCA7TwZRDKN8hvus4akN2yAbmA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.2.tgz", + "integrity": "sha512-kj88m0yrtTEJDeUEF+3TZsq7t9VPzQQj7UmXAzUbIaipoYSrd0UxKAcg4l9CBgP8uVoploiw+nKr8DIv6Y9gXw==", "dependencies": { "esbuild": "^0.19.0", - "get-tsconfig": "^4.6.2", + "get-tsconfig": "^4.7.0", "loader-utils": "^2.0.4", "webpack-sources": "^1.4.3" }, @@ -4644,15 +4644,15 @@ } }, "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4765,9 +4765,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz", - "integrity": "sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "dependencies": { "array-includes": "^3.1.6", @@ -4779,13 +4779,12 @@ "eslint-import-resolver-node": "^0.3.7", "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.12.1", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.6", "object.groupby": "^1.0.0", "object.values": "^1.1.6", - "resolve": "^1.22.3", "semver": "^6.3.1", "tsconfig-paths": "^3.14.2" }, @@ -4904,9 +4903,9 @@ } }, "node_modules/eslint-plugin-sonarjs": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.20.0.tgz", - "integrity": "sha512-BRhZ7BY/oTr6DDaxvx58ReTg7R+J8T+Y2ZVGgShgpml25IHBTIG7EudUtHuJD1zhtMgUEt59x3VNvUQRo2LV6w==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.21.0.tgz", + "integrity": "sha512-oezUDfFT5S6j3rQheZ4DLPrbetPmMS7zHIKWGHr0CM3g5JgyZroz1FpIKa4jV83NsGpmgIeagpokWDKIJzRQmw==", "dev": true, "engines": { "node": ">=14" @@ -6463,9 +6462,9 @@ } }, "node_modules/jquery": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", - "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" }, "node_modules/jquery.are-you-sure": { "version": "1.9.0", @@ -7417,9 +7416,9 @@ } }, "node_modules/mermaid": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.3.1.tgz", - "integrity": "sha512-hkenh7WkuRWPcob3oJtrN3W+yzrrIYuWF1OIfk/d0xGE8UWlvDhfexaHmDwwe8DKQgqMLI8DWEPwGprxkumjuw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz", + "integrity": "sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw==", "dependencies": { "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", @@ -7969,15 +7968,15 @@ } }, "node_modules/mlly": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz", - "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.1.tgz", + "integrity": "sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.10.0", "pathe": "^1.1.1", "pkg-types": "^1.0.3", - "ufo": "^1.1.2" + "ufo": "^1.3.0" } }, "node_modules/monaco-editor": { @@ -8797,12 +8796,12 @@ } }, "node_modules/pretty-format": { - "version": "29.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", - "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", + "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.6.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -10511,9 +10510,9 @@ "dev": true }, "node_modules/ufo": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.2.0.tgz", - "integrity": "sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", + "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==", "dev": true }, "node_modules/uint8-to-base64": { @@ -10587,9 +10586,9 @@ } }, "node_modules/updates": { - "version": "14.3.5", - "resolved": "https://registry.npmjs.org/updates/-/updates-14.3.5.tgz", - "integrity": "sha512-kx1sm2RXd9guF3lAmAaC8mpfAlG5iSPHiPkSJtEC5d/Gaa+NoxwxcuySb0c5pBFlzuGGU8ZxxQ0qRl9HLfwRRg==", + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/updates/-/updates-14.4.0.tgz", + "integrity": "sha512-fAB49LEq46XlJfQmLDWHt3Yt7XpSAxj1GwO6MxgEMHlGbhyGLSNu2hPYuSzipNRhO7phJNp8UDi0kikn/RAwwQ==", "dev": true, "bin": { "updates": "bin/updates.js" @@ -10736,9 +10735,9 @@ } }, "node_modules/vite-node": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.2.tgz", - "integrity": "sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.3.tgz", + "integrity": "sha512-+0TzJf1g0tYXj6tR2vEyiA42OPq68QkRZCu/ERSo2PtsDJfBpDyEfuKbRvLmZqi/CgC7SCBtyC+WjTGNMRIaig==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -11173,19 +11172,19 @@ } }, "node_modules/vitest": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.2.tgz", - "integrity": "sha512-WgaIvBbjsSYMq/oiMlXUI7KflELmzM43BEvkdC/8b5CAod4ryAiY2z8uR6Crbi5Pjnu5oOmhKa9sy7uk6paBxQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.3.tgz", + "integrity": "sha512-7+VA5Iw4S3USYk+qwPxHl8plCMhA5rtfwMjgoQXMT7rO5ldWcdsdo3U1QD289JgglGK4WeOzgoLTsGFu6VISyQ==", "dev": true, "dependencies": { "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.34.2", - "@vitest/runner": "0.34.2", - "@vitest/snapshot": "0.34.2", - "@vitest/spy": "0.34.2", - "@vitest/utils": "0.34.2", + "@vitest/expect": "0.34.3", + "@vitest/runner": "0.34.3", + "@vitest/snapshot": "0.34.3", + "@vitest/spy": "0.34.3", + "@vitest/utils": "0.34.3", "acorn": "^8.9.0", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -11200,7 +11199,7 @@ "tinybench": "^2.5.0", "tinypool": "^0.7.0", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.34.2", + "vite-node": "0.34.3", "why-is-node-running": "^2.2.2" }, "bin": { diff --git a/package.json b/package.json index fd3c46c8684a4..e4f1743febd82 100644 --- a/package.json +++ b/package.json @@ -16,21 +16,21 @@ "@primer/octicons": "19.6.0", "@webcomponents/custom-elements": "1.6.0", "add-asset-webpack-plugin": "2.0.1", - "ansi_up": "6.0.0", + "ansi_up": "6.0.2", "asciinema-player": "3.5.0", "clippie": "4.0.6", "css-loader": "6.8.1", "dropzone": "6.0.0-beta.2", "easymde": "2.18.0", - "esbuild-loader": "4.0.0", + "esbuild-loader": "4.0.2", "escape-goat": "4.0.0", "fast-glob": "3.3.1", - "jquery": "3.7.0", + "jquery": "3.7.1", "jquery.are-you-sure": "1.9.0", "katex": "0.16.8", "license-checker-webpack-plugin": "0.2.1", "lightningcss-loader": "2.1.0", - "mermaid": "10.3.1", + "mermaid": "10.4.0", "mini-css-extract-plugin": "2.7.6", "minimatch": "9.0.3", "monaco-editor": "0.41.0", @@ -57,16 +57,16 @@ "@eslint-community/eslint-plugin-eslint-comments": "4.1.0", "@playwright/test": "1.37.1", "@stoplight/spectral-cli": "6.10.1", - "@vitejs/plugin-vue": "4.3.1", - "eslint": "8.47.0", + "@vitejs/plugin-vue": "4.3.4", + "eslint": "8.48.0", "eslint-plugin-array-func": "3.1.8", "eslint-plugin-custom-elements": "0.0.8", - "eslint-plugin-import": "2.28.0", + "eslint-plugin-import": "2.28.1", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-regexp": "1.15.0", - "eslint-plugin-sonarjs": "0.20.0", + "eslint-plugin-sonarjs": "0.21.0", "eslint-plugin-unicorn": "48.0.1", "eslint-plugin-vue": "9.17.0", "eslint-plugin-vue-scoped-css": "2.5.0", @@ -79,9 +79,9 @@ "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.3", "svgo": "3.0.2", - "updates": "14.3.5", + "updates": "14.4.0", "vite-string-plugin": "1.1.2", - "vitest": "0.34.2" + "vitest": "0.34.3" }, "browserslist": [ "defaults", diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index e95df7a00fa80..24432ab6b202d 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -10,6 +10,7 @@ import ( actions_model "code.gitea.io/gitea/models/actions" secret_model "code.gitea.io/gitea/models/secret" actions_module "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -55,8 +56,12 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { secrets := map[string]string{} + + secrets["GITHUB_TOKEN"] = task.Token + secrets["GITEA_TOKEN"] = task.Token + if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { - // ignore secrets for fork pull request + // ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated. // for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target return secrets @@ -82,13 +87,6 @@ func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[s } } - if _, ok := secrets["GITHUB_TOKEN"]; !ok { - secrets["GITHUB_TOKEN"] = task.Token - } - if _, ok := secrets["GITEA_TOKEN"]; !ok { - secrets["GITEA_TOKEN"] = task.Token - } - return secrets } @@ -200,10 +198,7 @@ func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str if len(task.Job.Needs) == 0 { return nil, nil } - needs := map[string]struct{}{} - for _, v := range task.Job.Needs { - needs[v] = struct{}{} - } + needs := container.SetOf(task.Job.Needs...) jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: task.Job.RunID}) if err != nil { @@ -212,7 +207,7 @@ func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str ret := make(map[string]*runnerv1.TaskNeed, len(needs)) for _, job := range jobs { - if _, ok := needs[job.JobID]; !ok { + if !needs.Contains(job.JobID) { continue } if job.TaskID == 0 || !job.Status.IsDone() { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 6424931a47342..32e5a10bbe78d 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -933,6 +933,10 @@ func Routes() *web.Route { m.Post("/accept", repo.AcceptTransfer) m.Post("/reject", repo.RejectTransfer) }, reqToken()) + m.Group("/actions/secrets", func() { + m.Combo("/{secretname}"). + Put(reqToken(), reqOwner(), bind(api.CreateOrUpdateSecretOption{}), repo.CreateOrUpdateSecret) + }) m.Group("/hooks/git", func() { m.Combo("").Get(repo.ListGitHooks) m.Group("/{id}", func() { @@ -1301,7 +1305,7 @@ func Routes() *web.Route { m.Group("/actions/secrets", func() { m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets) m.Combo("/{secretname}"). - Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateOrgSecret). + Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateSecret). Delete(reqToken(), reqOrgOwnership(), org.DeleteOrgSecret) }) m.Group("/public_members", func() { diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index ee18cca26de73..0bf741e8256db 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -74,7 +74,7 @@ func listActionsSecrets(ctx *context.APIContext) { } // create or update one secret of the organization -func CreateOrUpdateOrgSecret(ctx *context.APIContext) { +func CreateOrUpdateSecret(ctx *context.APIContext) { // swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret // --- // summary: Create or Update a secret value in an organization @@ -108,26 +108,17 @@ func CreateOrUpdateOrgSecret(ctx *context.APIContext) { // "$ref": "#/responses/forbidden" secretName := ctx.Params(":secretname") if err := actions.NameRegexMatch(secretName); err != nil { - ctx.Error(http.StatusBadRequest, "CreateOrUpdateOrgSecret", err) + ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) return } opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) - err := secret_model.UpdateSecret( - ctx, ctx.Org.Organization.ID, 0, secretName, opt.Data, - ) - if secret_model.IsErrSecretNotFound(err) { - _, err := secret_model.InsertEncryptedSecret( - ctx, ctx.Org.Organization.ID, 0, secretName, actions.ReserveLineBreakForTextarea(opt.Data), - ) - if err != nil { - ctx.Error(http.StatusInternalServerError, "InsertEncryptedSecret", err) - return - } - ctx.Status(http.StatusCreated) + isCreated, err := secret_model.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, secretName, opt.Data) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err) return } - if err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateSecret", err) + if isCreated { + ctx.Status(http.StatusCreated) return } diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go new file mode 100644 index 0000000000000..015c731a75d22 --- /dev/null +++ b/routers/api/v1/repo/action.go @@ -0,0 +1,75 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "net/http" + + secret_model "code.gitea.io/gitea/models/secret" + "code.gitea.io/gitea/modules/context" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers/web/shared/actions" +) + +// create or update one secret of the repository +func CreateOrUpdateSecret(ctx *context.APIContext) { + // swagger:operation PUT /repos/{owner}/{repo}/actions/secrets/{secretname} repository updateRepoSecret + // --- + // summary: Create or Update a secret value in a repository + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repository + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repository + // type: string + // required: true + // - name: secretname + // in: path + // description: name of the secret + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/CreateOrUpdateSecretOption" + // responses: + // "201": + // description: response when creating a secret + // "204": + // description: response when updating a secret + // "400": + // "$ref": "#/responses/error" + // "403": + // "$ref": "#/responses/forbidden" + + owner := ctx.Repo.Owner + repo := ctx.Repo.Repository + + secretName := ctx.Params(":secretname") + if err := actions.NameRegexMatch(secretName); err != nil { + ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) + return + } + opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) + isCreated, err := secret_model.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, secretName, opt.Data) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err) + return + } + if isCreated { + ctx.Status(http.StatusCreated) + return + } + + ctx.Status(http.StatusNoContent) +} diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index a507c1f44d171..58f2fc69cea8e 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -326,11 +326,9 @@ func CreatePullRequest(ctx *context.APIContext) { return } - labelIDs = make([]int64, len(form.Labels)) - orgLabelIDs := make([]int64, len(form.Labels)) - - for i := range labels { - labelIDs[i] = labels[i].ID + labelIDs = make([]int64, 0, len(labels)) + for _, label := range labels { + labelIDs = append(labelIDs, label.ID) } if ctx.Repo.Owner.IsOrganization() { @@ -340,12 +338,12 @@ func CreatePullRequest(ctx *context.APIContext) { return } - for i := range orgLabels { - orgLabelIDs[i] = orgLabels[i].ID + orgLabelIDs := make([]int64, 0, len(orgLabels)) + for _, orgLabel := range orgLabels { + orgLabelIDs = append(orgLabelIDs, orgLabel.ID) } + labelIDs = append(labelIDs, orgLabelIDs...) } - - labelIDs = append(labelIDs, orgLabelIDs...) } if form.Milestone > 0 { diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go index caf3874ec3030..8604789529a6e 100644 --- a/routers/private/hook_verification.go +++ b/routers/private/hook_verification.go @@ -28,23 +28,31 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env [] _ = stdoutWriter.Close() }() + var command *git.Command + if oldCommitID == git.EmptySHA { + // When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all": + // List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits + // So, it only lists the new commits received, doesn't list the commits already present in the receiving repository + command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all") + } else { + command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID) + } // This is safe as force pushes are already forbidden - err = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID). - Run(&git.RunOpts{ - Env: env, - Dir: repo.Path, - Stdout: stdoutWriter, - PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { - _ = stdoutWriter.Close() - err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env) - if err != nil { - log.Error("%v", err) - cancel() - } - _ = stdoutReader.Close() - return err - }, - }) + err = command.Run(&git.RunOpts{ + Env: env, + Dir: repo.Path, + Stdout: stdoutWriter, + PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { + _ = stdoutWriter.Close() + err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env) + if err != nil { + log.Error("%v", err) + cancel() + } + _ = stdoutReader.Close() + return err + }, + }) if err != nil && !isErrUnverifiedCommit(err) { log.Error("Unable to check commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err) } diff --git a/routers/private/hook_verification_test.go b/routers/private/hook_verification_test.go new file mode 100644 index 0000000000000..cd0c05ff50a71 --- /dev/null +++ b/routers/private/hook_verification_test.go @@ -0,0 +1,43 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package private + +import ( + "context" + "testing" + + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/git" + + "github.com/stretchr/testify/assert" +) + +var testReposDir = "tests/repos/" + +func TestVerifyCommits(t *testing.T) { + unittest.PrepareTestEnv(t) + + gitRepo, err := git.OpenRepository(context.Background(), testReposDir+"repo1_hook_verification") + defer gitRepo.Close() + assert.NoError(t, err) + + testCases := []struct { + base, head string + verified bool + }{ + {"72920278f2f999e3005801e5d5b8ab8139d3641c", "d766f2917716d45be24bfa968b8409544941be32", true}, + {git.EmptySHA, "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit + {"9779d17a04f1e2640583d35703c62460b2d86e0a", "72920278f2f999e3005801e5d5b8ab8139d3641c", false}, + {git.EmptySHA, "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit + } + + for _, tc := range testCases { + err = verifyCommits(tc.base, tc.head, gitRepo, nil) + if tc.verified { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + } +} diff --git a/routers/private/main_test.go b/routers/private/main_test.go new file mode 100644 index 0000000000000..700af6ec8d413 --- /dev/null +++ b/routers/private/main_test.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package private + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models/unittest" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: filepath.Join("..", ".."), + }) +} diff --git a/routers/private/tests/repos/repo1_hook_verification/HEAD b/routers/private/tests/repos/repo1_hook_verification/HEAD new file mode 100644 index 0000000000000..b870d82622c1a --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/routers/private/tests/repos/repo1_hook_verification/config b/routers/private/tests/repos/repo1_hook_verification/config new file mode 100644 index 0000000000000..64280b806c976 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = true + symlinks = false + ignorecase = true diff --git a/routers/private/tests/repos/repo1_hook_verification/info/refs b/routers/private/tests/repos/repo1_hook_verification/info/refs new file mode 100644 index 0000000000000..ee593c4db2647 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/info/refs @@ -0,0 +1 @@ +d766f2917716d45be24bfa968b8409544941be32 refs/heads/main diff --git a/routers/private/tests/repos/repo1_hook_verification/logs/HEAD b/routers/private/tests/repos/repo1_hook_verification/logs/HEAD new file mode 100644 index 0000000000000..5c549b9b4ea66 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 d766f2917716d45be24bfa968b8409544941be32 Gitea 1693148474 +0800 push diff --git a/routers/private/tests/repos/repo1_hook_verification/logs/refs/heads/main b/routers/private/tests/repos/repo1_hook_verification/logs/refs/heads/main new file mode 100644 index 0000000000000..5c549b9b4ea66 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 d766f2917716d45be24bfa968b8409544941be32 Gitea 1693148474 +0800 push diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c b/routers/private/tests/repos/repo1_hook_verification/objects/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c new file mode 100644 index 0000000000000..d55278f9d45b3 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/0b/5987362fe3fabdd4406babdc819642ee2f5a2a b/routers/private/tests/repos/repo1_hook_verification/objects/0b/5987362fe3fabdd4406babdc819642ee2f5a2a new file mode 100644 index 0000000000000..d8b6020bc0205 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/0b/5987362fe3fabdd4406babdc819642ee2f5a2a differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/13/b0f23f673b161f4b5cb66f051cb93c99729e1e b/routers/private/tests/repos/repo1_hook_verification/objects/13/b0f23f673b161f4b5cb66f051cb93c99729e1e new file mode 100644 index 0000000000000..77936d82415e3 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/13/b0f23f673b161f4b5cb66f051cb93c99729e1e differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/23/33a51fdb238b7023a62ae3dcc58994061a7c86 b/routers/private/tests/repos/repo1_hook_verification/objects/23/33a51fdb238b7023a62ae3dcc58994061a7c86 new file mode 100644 index 0000000000000..5ec09ac7bd220 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/23/33a51fdb238b7023a62ae3dcc58994061a7c86 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/2b/df04adb23d2b40b6085efb230856e5e2a775b7 b/routers/private/tests/repos/repo1_hook_verification/objects/2b/df04adb23d2b40b6085efb230856e5e2a775b7 new file mode 100644 index 0000000000000..355b88e95e80e Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/2b/df04adb23d2b40b6085efb230856e5e2a775b7 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7 b/routers/private/tests/repos/repo1_hook_verification/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7 new file mode 100644 index 0000000000000..ba1f06fc0e570 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/72/920278f2f999e3005801e5d5b8ab8139d3641c b/routers/private/tests/repos/repo1_hook_verification/objects/72/920278f2f999e3005801e5d5b8ab8139d3641c new file mode 100644 index 0000000000000..4705fbf6b198e --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/72/920278f2f999e3005801e5d5b8ab8139d3641c @@ -0,0 +1,2 @@ +xK +1] AS$"32 ooW{!`JC%. $r]sѱe$mM)(O`btlE[:;4H1_rayl~EL@cXvM":MۃG_}? \ No newline at end of file diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/8b/903ede7c494725624bf842ec890f6342dababd b/routers/private/tests/repos/repo1_hook_verification/objects/8b/903ede7c494725624bf842ec890f6342dababd new file mode 100644 index 0000000000000..fd3c3a488b22a Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/8b/903ede7c494725624bf842ec890f6342dababd differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/93/eac826f6188f34646cea81bf426aa5ba7d3bfe b/routers/private/tests/repos/repo1_hook_verification/objects/93/eac826f6188f34646cea81bf426aa5ba7d3bfe new file mode 100644 index 0000000000000..80abd3ade146e Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/93/eac826f6188f34646cea81bf426aa5ba7d3bfe differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/97/79d17a04f1e2640583d35703c62460b2d86e0a b/routers/private/tests/repos/repo1_hook_verification/objects/97/79d17a04f1e2640583d35703c62460b2d86e0a new file mode 100644 index 0000000000000..7f3293a8bc2e3 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/97/79d17a04f1e2640583d35703c62460b2d86e0a @@ -0,0 +1,2 @@ +x1 +!ES{AwGGa 9EQg W#AZ/p((Bhۼ&:pLY`U-z\ZM:xJ/G}:3 \ No newline at end of file diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/9c/e3f779ae33f31fce17fac3c512047b75d7498b b/routers/private/tests/repos/repo1_hook_verification/objects/9c/e3f779ae33f31fce17fac3c512047b75d7498b new file mode 100644 index 0000000000000..61a9ee8391cac Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/9c/e3f779ae33f31fce17fac3c512047b75d7498b differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/a9/f76e70a663e40091749a97eeac5f57a6fec141 b/routers/private/tests/repos/repo1_hook_verification/objects/a9/f76e70a663e40091749a97eeac5f57a6fec141 new file mode 100644 index 0000000000000..fb79dc96b9586 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/a9/f76e70a663e40091749a97eeac5f57a6fec141 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/ba/0caedd359ebe310ef431335576e20f2b84e9b9 b/routers/private/tests/repos/repo1_hook_verification/objects/ba/0caedd359ebe310ef431335576e20f2b84e9b9 new file mode 100644 index 0000000000000..1801a7f127748 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/ba/0caedd359ebe310ef431335576e20f2b84e9b9 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/bb/87653e0819460e79b5f075f2563f583cbbf18c b/routers/private/tests/repos/repo1_hook_verification/objects/bb/87653e0819460e79b5f075f2563f583cbbf18c new file mode 100644 index 0000000000000..a765d667581bf Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/bb/87653e0819460e79b5f075f2563f583cbbf18c differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa b/routers/private/tests/repos/repo1_hook_verification/objects/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa new file mode 100644 index 0000000000000..c7de09f9ac11c --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa @@ -0,0 +1,3 @@ +xA +0E]$L xL2] + \}e[:{MZ5b8$v fR37];ˆbt 3$,tXG>m p1w͗-7pĄpZsDZL̾Le@ \ No newline at end of file diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/d7/66f2917716d45be24bfa968b8409544941be32 b/routers/private/tests/repos/repo1_hook_verification/objects/d7/66f2917716d45be24bfa968b8409544941be32 new file mode 100644 index 0000000000000..154458468c8e0 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/d7/66f2917716d45be24bfa968b8409544941be32 @@ -0,0 +1,3 @@ +xˮFE3+zn%44!%QxۀsA` 8{2IMjdf2"$e +-( !J"a@BaHo3V<$/)$JJDBH{ # RROnfFO +q[2̇~zjjL}prmFqh `@ث՘f?3[7) ^uֿ,l7zr|&Ou49:Qj1x6Q%tsV| (V,aL,G~r@`$[! Xˊep[8 o(kZγyeйYkd63;3 Ri ދdYDk91V]/C#&poFb}uW&]+m xaqdIX3 3KI#i_rgĩ7=`@[&A̤Lo3~M8MGt>xvQ(aWo"srzeŭ}QD֨fK)mr>>̚$F8x ^J k{mczI*^Mb m6M~hp {0 ]€?nUwgɠJ б<72 \ No newline at end of file diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/e3/7e5d19823e42fad252f6341b1f77a7bc6ee451 b/routers/private/tests/repos/repo1_hook_verification/objects/e3/7e5d19823e42fad252f6341b1f77a7bc6ee451 new file mode 100644 index 0000000000000..b3f925e8178ae Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/e3/7e5d19823e42fad252f6341b1f77a7bc6ee451 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/routers/private/tests/repos/repo1_hook_verification/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 new file mode 100644 index 0000000000000..711223894375f Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/e8/4e452c3a20c02dee17ec2f63c0cb9ef6c759eb b/routers/private/tests/repos/repo1_hook_verification/objects/e8/4e452c3a20c02dee17ec2f63c0cb9ef6c759eb new file mode 100644 index 0000000000000..24580f88e3d35 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/e8/4e452c3a20c02dee17ec2f63c0cb9ef6c759eb differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/info/packs b/routers/private/tests/repos/repo1_hook_verification/objects/info/packs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/info/packs @@ -0,0 +1 @@ + diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c new file mode 100644 index 0000000000000..d55278f9d45b3 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/08/cbc8f0e903b0916025ae7577564b7ed39ecb2c differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/0b/5987362fe3fabdd4406babdc819642ee2f5a2a b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/0b/5987362fe3fabdd4406babdc819642ee2f5a2a new file mode 100644 index 0000000000000..d8b6020bc0205 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/0b/5987362fe3fabdd4406babdc819642ee2f5a2a differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/13/b0f23f673b161f4b5cb66f051cb93c99729e1e b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/13/b0f23f673b161f4b5cb66f051cb93c99729e1e new file mode 100644 index 0000000000000..77936d82415e3 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/13/b0f23f673b161f4b5cb66f051cb93c99729e1e differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/23/33a51fdb238b7023a62ae3dcc58994061a7c86 b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/23/33a51fdb238b7023a62ae3dcc58994061a7c86 new file mode 100644 index 0000000000000..5ec09ac7bd220 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/23/33a51fdb238b7023a62ae3dcc58994061a7c86 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/8b/903ede7c494725624bf842ec890f6342dababd b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/8b/903ede7c494725624bf842ec890f6342dababd new file mode 100644 index 0000000000000..fd3c3a488b22a Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/8b/903ede7c494725624bf842ec890f6342dababd differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/93/eac826f6188f34646cea81bf426aa5ba7d3bfe b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/93/eac826f6188f34646cea81bf426aa5ba7d3bfe new file mode 100644 index 0000000000000..80abd3ade146e Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/93/eac826f6188f34646cea81bf426aa5ba7d3bfe differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/9c/e3f779ae33f31fce17fac3c512047b75d7498b b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/9c/e3f779ae33f31fce17fac3c512047b75d7498b new file mode 100644 index 0000000000000..61a9ee8391cac Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/9c/e3f779ae33f31fce17fac3c512047b75d7498b differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/a9/f76e70a663e40091749a97eeac5f57a6fec141 b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/a9/f76e70a663e40091749a97eeac5f57a6fec141 new file mode 100644 index 0000000000000..fb79dc96b9586 Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/a9/f76e70a663e40091749a97eeac5f57a6fec141 differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/bb/87653e0819460e79b5f075f2563f583cbbf18c b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/bb/87653e0819460e79b5f075f2563f583cbbf18c new file mode 100644 index 0000000000000..a765d667581bf Binary files /dev/null and b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/bb/87653e0819460e79b5f075f2563f583cbbf18c differ diff --git a/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa new file mode 100644 index 0000000000000..c7de09f9ac11c --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/objects/tmp_objdir-incoming-a21648/cb/a4c30c196a0e03e7bdf6eeb8393d14b9d073aa @@ -0,0 +1,3 @@ +xA +0E]$L xL2] + \}e[:{MZ5b8$v fR37];ˆbt 3$,tXG>m p1w͗-7pĄpZsDZL̾Le@ \ No newline at end of file diff --git a/routers/private/tests/repos/repo1_hook_verification/refs/heads/main b/routers/private/tests/repos/repo1_hook_verification/refs/heads/main new file mode 100644 index 0000000000000..2186e820a7990 --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification/refs/heads/main @@ -0,0 +1 @@ +d766f2917716d45be24bfa968b8409544941be32 diff --git a/routers/private/tests/repos/repo1_hook_verification_dummy_gpg_key.txt b/routers/private/tests/repos/repo1_hook_verification_dummy_gpg_key.txt new file mode 100644 index 0000000000000..3061c75dcbeeb --- /dev/null +++ b/routers/private/tests/repos/repo1_hook_verification_dummy_gpg_key.txt @@ -0,0 +1,127 @@ +# GPG key for abcde@gitea.com + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +4akc +=OYIo +-----END PGP PUBLIC KEY BLOCK----- + +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +ZZtqph2TItCeV04HoaKHHc254akc +=PPG4 +-----END PGP PRIVATE KEY BLOCK----- diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 4ceb52d03994a..aee34956124c1 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -460,7 +460,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { rootRepo.ID != ci.HeadRepo.ID && rootRepo.ID != baseRepo.ID { canRead := access_model.CheckRepoUnitUser(ctx, rootRepo, ctx.Doer, unit.TypeCode) - if canRead && rootRepo.AllowsPulls() { + if canRead { ctx.Data["RootRepo"] = rootRepo if !fileOnly { branches, tags, err := getBranchesAndTagsForRepo(ctx, rootRepo) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index d1a4877e6d4b6..a7f6a52f1b110 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -157,7 +157,7 @@ func Milestones(ctx *context.Context) { } repoOpts := repo_model.SearchRepoOptions{ - Actor: ctxUser, + Actor: ctx.Doer, OwnerID: ctxUser.ID, Private: true, AllPublic: false, // Include also all public repositories of users and public organisations @@ -449,7 +449,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // - Team has read permission to repository. repoOpts := &repo_model.SearchRepoOptions{ Actor: ctx.Doer, - OwnerID: ctx.Doer.ID, + OwnerID: ctxUser.ID, Private: true, AllPublic: false, AllLimited: false, @@ -567,12 +567,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Remove repositories that should not be shown, // which are repositories that have no issues and are not selected by the user. - selectedReposMap := make(map[int64]struct{}, len(selectedRepoIDs)) - for _, repoID := range selectedRepoIDs { - selectedReposMap[repoID] = struct{}{} - } + selectedRepos := container.SetOf(selectedRepoIDs...) for k, v := range issueCountByRepo { - if _, ok := selectedReposMap[k]; !ok && v == 0 { + if v == 0 && !selectedRepos.Contains(k) { delete(issueCountByRepo, k) } } diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index 43ee32c84bdc8..df5eb60393866 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" auth_module "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" source_service "code.gitea.io/gitea/services/auth/source" @@ -41,7 +42,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { usernameUsers := make(map[string]*user_model.User, len(users)) mailUsers := make(map[string]*user_model.User, len(users)) - keepActiveUsers := make(map[int64]struct{}) + keepActiveUsers := make(container.Set[int64]) for _, u := range users { usernameUsers[u.LowerName] = u @@ -97,7 +98,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { } if usr != nil { - keepActiveUsers[usr.ID] = struct{}{} + keepActiveUsers.Add(usr.ID) } else if len(su.Username) == 0 { // we cannot create the user if su.Username is empty continue @@ -208,7 +209,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { // Deactivate users not present in LDAP if updateExisting { for _, usr := range users { - if _, ok := keepActiveUsers[usr.ID]; ok { + if keepActiveUsers.Contains(usr.ID) { continue } diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 76180a5159a2b..f626036254e9f 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/structs" @@ -673,16 +674,15 @@ func (g *GitlabDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Revie func (g *GitlabDownloader) awardsToReactions(awards []*gitlab.AwardEmoji) []*base.Reaction { result := make([]*base.Reaction, 0, len(awards)) - uniqCheck := make(map[string]struct{}) + uniqCheck := make(container.Set[string]) for _, award := range awards { uid := fmt.Sprintf("%s%d", award.Name, award.User.ID) - if _, ok := uniqCheck[uid]; !ok { + if uniqCheck.Add(uid) { result = append(result, &base.Reaction{ UserID: int64(award.User.ID), UserName: award.User.Username, Content: award.Name, }) - uniqCheck[uid] = struct{}{} } } return result diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index a086d15a4f99e..7f6b8137ae195 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -114,12 +114,12 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro return nil, err } - filelist := make([]string, len(filenames)) + fileList := make([]string, 0, len(filenames)) for _, line := range bytes.Split(stdOut.Bytes(), []byte{'\000'}) { - filelist = append(filelist, string(line)) + fileList = append(fileList, string(line)) } - return filelist, nil + return fileList, nil } // RemoveFilesFromIndex removes the given files from the index diff --git a/templates/devtest/flex-list.tmpl b/templates/devtest/flex-list.tmpl index f9087a5714446..cbc2632139372 100644 --- a/templates/devtest/flex-list.tmpl +++ b/templates/devtest/flex-list.tmpl @@ -1,8 +1,8 @@ {{template "base/head" .}} -
-
-

Flex List

+
+
+

Flex List (standalone)

@@ -84,6 +84,23 @@
+ +
+ +

Flex List (with "ui segment")

+
+
+
item 1
+
item 2
+
+
+
+

Flex List (with "ui segment")

+
+
item 1
+
item 2
+
+
{{template "base/footer" .}} diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index a011111d5b7cb..79eff1c53a900 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -30,6 +30,7 @@ 'textCreateBranchFrom': {{.root.locale.Tr "repo.branch.create_from"}}, 'textBranches': {{.root.locale.Tr "repo.branches"}}, 'textTags': {{.root.locale.Tr "repo.tags"}}, + 'textDefaultBranchLabel': {{.root.locale.Tr "repo.default_branch_label"}}, 'mode': '{{if or .root.IsViewTag .isTag}}tags{{else}}branches{{end}}', 'showBranchesInDropdown': {{$showBranchesInDropdown}}, diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl index 3bb7c2e81f89f..e4ae7d4dc8e76 100644 --- a/templates/repo/diff/compare.tmpl +++ b/templates/repo/diff/compare.tmpl @@ -77,7 +77,7 @@
{{$OwnForkCompareName}}:{{.}}
{{end}} {{end}} - {{if .RootRepo}} + {{if and .RootRepo .RootRepo.AllowsPulls}} {{range .RootRepoBranches}}
{{$RootRepoCompareName}}:{{.}}
{{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index d37f4463f55ca..78491de2e1028 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3230,6 +3230,65 @@ } } }, + "/repos/{owner}/{repo}/actions/secrets/{secretname}": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Create or Update a secret value in a repository", + "operationId": "updateRepoSecret", + "parameters": [ + { + "type": "string", + "description": "owner of the repository", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateOrUpdateSecretOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a secret" + }, + "204": { + "description": "response when updating a secret" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/repos/{owner}/{repo}/activities/feeds": { "get": { "produces": [ diff --git a/web_src/css/base.css b/web_src/css/base.css index 1a88823cb10cd..c0176cc437f13 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -18,7 +18,7 @@ /* non-color variables */ --border-radius: 4px; --border-radius-medium: 6px; - --border-radius-circle: 100%; + --border-radius-circle: 50%; --opacity-disabled: 0.55; --height-loading: 16rem; --tab-size: 4; diff --git a/web_src/css/modules/navbar.css b/web_src/css/modules/navbar.css index 15114f90b2b55..de25ea6811581 100644 --- a/web_src/css/modules/navbar.css +++ b/web_src/css/modules/navbar.css @@ -133,8 +133,8 @@ left: 6px; top: -9px; min-width: 17px; - min-height: 17px; - border-radius: var(--border-radius-circle); + height: 17px; + border-radius: 11px; /* (height + 2 * borderThickness) / 2 */ display: flex; align-items: center; justify-content: center; diff --git a/web_src/css/shared/flex-list.css b/web_src/css/shared/flex-list.css index c73f78ebfe035..1489983cfdcbf 100644 --- a/web_src/css/shared/flex-list.css +++ b/web_src/css/shared/flex-list.css @@ -6,10 +6,7 @@ display: flex; gap: 8px; align-items: flex-start; -} - -.flex-item:not(:last-child) { - padding-bottom: 8px; + padding: 1em 0; } .flex-item-baseline { @@ -92,5 +89,13 @@ .flex-list > .flex-item + .flex-item { border-top: 1px solid var(--color-secondary); - padding-top: 8px; +} + +/* Fomantic UI segment has default "padding: 1em", so here it removes the padding-top and padding-bottom accordingly */ +.ui.segment > .flex-list:first-child > .flex-item:first-child { + padding-top: 0; +} + +.ui.segment > .flex-list:last-child > .flex-item:last-child { + padding-bottom: 0; } diff --git a/web_src/fomantic/build/semantic.css b/web_src/fomantic/build/semantic.css index c2003ab2de904..cddc3f5ee90b8 100644 --- a/web_src/fomantic/build/semantic.css +++ b/web_src/fomantic/build/semantic.css @@ -10928,531 +10928,6 @@ a.ui.black.header:hover { /******************************* Site Overrides *******************************/ -/*! - * # Fomantic-UI - Item - * http://github.com/fomantic/Fomantic-UI/ - * - * - * Released under the MIT license - * http://opensource.org/licenses/MIT - * - */ - -/******************************* - Standard -*******************************/ - -/*-------------- - Item ----------------*/ - -.ui.items > .item { - display: flex; - margin: 1em 0; - width: 100%; - min-height: 0; - background: transparent; - padding: 0; - border: none; - border-radius: 0; - box-shadow: none; - transition: box-shadow 0.1s ease; - z-index: ''; -} - -.ui.items > .item a { - cursor: pointer; -} - -/*-------------- - Items ----------------*/ - -.ui.items { - margin: 1.5em 0; -} - -.ui.items:first-child { - margin-top: 0 !important; -} - -.ui.items:last-child { - margin-bottom: 0 !important; -} - -/*-------------- - Item ----------------*/ - -.ui.items > .item:after { - display: block; - content: ' '; - height: 0; - clear: both; - overflow: hidden; - visibility: hidden; -} - -.ui.items > .item:first-child { - margin-top: 0; -} - -.ui.items > .item:last-child { - margin-bottom: 0; -} - -/*-------------- - Images ----------------*/ - -.ui.items > .item > .image { - position: relative; - flex: 0 0 auto; - display: block; - float: none; - margin: 0; - padding: 0; - max-height: ''; - align-self: start; -} - -.ui.items > .item > .image > img { - display: block; - width: 100%; - height: auto; - border-radius: 0.125rem; - border: none; -} - -.ui.items > .item > .image:only-child > img { - border-radius: 0; -} - -/*-------------- - Content ----------------*/ - -.ui.items > .item > .content { - display: block; - flex: 1 1 auto; - background: none; - color: rgba(0, 0, 0, 0.87); - margin: 0; - padding: 0; - box-shadow: none; - font-size: 1em; - border: none; - border-radius: 0; -} - -.ui.items > .item > .content:after { - display: block; - content: ' '; - height: 0; - clear: both; - overflow: hidden; - visibility: hidden; -} - -.ui.items > .item > .image + .content { - min-width: 0; - width: auto; - display: block; - margin-left: 0; - align-self: start; - padding-left: 1.5em; -} - -.ui.items > .item > .content > .header { - display: inline-block; - margin: -0.21425em 0 0; - font-family: var(--fonts-regular); - font-weight: 500; - color: rgba(0, 0, 0, 0.85); -} - -/* Default Header Size */ - -.ui.items > .item > .content > .header:not(.ui) { - font-size: 1.28571429em; -} - -/*-------------- - Floated ----------------*/ - -.ui.items > .item [class*="left floated"] { - float: left; -} - -.ui.items > .item [class*="right floated"] { - float: right; -} - -/*-------------- - Content Image ----------------*/ - -.ui.items > .item .content img { - align-self: center; - width: ''; -} - -.ui.items > .item img.avatar, -.ui.items > .item .avatar img { - width: ''; - height: ''; - border-radius: 500rem; -} - -/*-------------- - Description ----------------*/ - -.ui.items > .item > .content > .description { - margin-top: 0.6em; - max-width: auto; - font-size: 1em; - line-height: 1.4285em; - color: rgba(0, 0, 0, 0.87); -} - -/*-------------- - Paragraph ----------------*/ - -.ui.items > .item > .content p { - margin: 0 0 0.5em; -} - -.ui.items > .item > .content p:last-child { - margin-bottom: 0; -} - -/*-------------- - Meta ----------------*/ - -.ui.items > .item .meta { - margin: 0.5em 0 0.5em; - font-size: 1em; - line-height: 1em; - color: rgba(0, 0, 0, 0.6); -} - -.ui.items > .item .meta * { - margin-right: 0.3em; -} - -.ui.items > .item .meta :last-child { - margin-right: 0; -} - -.ui.items > .item .meta [class*="right floated"] { - margin-right: 0; - margin-left: 0.3em; -} - -/*-------------- - Links ----------------*/ - -/* Generic */ - -.ui.items > .item > .content a:not(.ui) { - color: ''; - transition: color 0.1s ease; -} - -.ui.items > .item > .content a:not(.ui):hover { - color: ''; -} - -/* Header */ - -.ui.items > .item > .content > a.header { - color: rgba(0, 0, 0, 0.85); -} - -.ui.items > .item > .content > a.header:hover { - color: #1e70bf; -} - -/* Meta */ - -.ui.items > .item .meta > a:not(.ui) { - color: rgba(0, 0, 0, 0.4); -} - -.ui.items > .item .meta > a:not(.ui):hover { - color: rgba(0, 0, 0, 0.87); -} - -/*-------------- - Labels ----------------*/ - -/*-----Star----- */ - -/* Icon */ - -.ui.items > .item > .content .favorite.icon { - cursor: pointer; - opacity: 0.75; - transition: color 0.1s ease; -} - -.ui.items > .item > .content .favorite.icon:hover { - opacity: 1; - color: #FFB70A; -} - -.ui.items > .item > .content .active.favorite.icon { - color: #FFE623; -} - -/*-----Like----- */ - -/* Icon */ - -.ui.items > .item > .content .like.icon { - cursor: pointer; - opacity: 0.75; - transition: color 0.1s ease; -} - -.ui.items > .item > .content .like.icon:hover { - opacity: 1; - color: #FF2733; -} - -.ui.items > .item > .content .active.like.icon { - color: #FF2733; -} - -/*---------------- - Extra Content ------------------*/ - -.ui.items > .item .extra { - display: block; - position: relative; - background: none; - margin: 0.5rem 0 0; - width: 100%; - padding: 0 0 0; - top: 0; - left: 0; - color: rgba(0, 0, 0, 0.4); - box-shadow: none; - transition: color 0.1s ease; - border-top: none; -} - -.ui.items > .item .extra > * { - margin: 0.25rem 0.5rem 0.25rem 0; -} - -.ui.items > .item .extra > [class*="right floated"] { - margin: 0.25rem 0 0.25rem 0.5rem; -} - -.ui.items > .item .extra:after { - display: block; - content: ' '; - height: 0; - clear: both; - overflow: hidden; - visibility: hidden; -} - -/******************************* - Responsive -*******************************/ - -/* Default Image Width */ - -.ui.items > .item > .image:not(.ui) { - width: 175px; -} - -/* Tablet Only */ - -@media only screen and (min-width: 768px) and (max-width: 991.98px) { - .ui.items > .item { - margin: 1em 0; - } - - .ui.items > .item > .image:not(.ui) { - width: 150px; - } - - .ui.items > .item > .image + .content { - display: block; - padding: 0 0 0 1em; - } -} - -/* Mobile Only */ - -@media only screen and (max-width: 767.98px) { - .ui.items:not(.unstackable) > .item { - flex-direction: column; - margin: 2em 0; - } - - .ui.items:not(.unstackable) > .item > .image { - display: block; - margin-left: auto; - margin-right: auto; - } - - .ui.items:not(.unstackable) > .item > .image, - .ui.items:not(.unstackable) > .item > .image > img { - max-width: 100% !important; - width: auto !important; - max-height: 250px !important; - } - - .ui.items:not(.unstackable) > .item > .image + .content { - display: block; - padding: 1.5em 0 0; - } -} - -/******************************* - Variations -*******************************/ - -/*------------------- - Aligned - --------------------*/ - -.ui.items > .item > .image + [class*="top aligned"].content { - align-self: flex-start; -} - -.ui.items > .item > .image + [class*="middle aligned"].content { - align-self: center; -} - -.ui.items > .item > .image + [class*="bottom aligned"].content { - align-self: flex-end; -} - -/*-------------- - Relaxed - ---------------*/ - -.ui.relaxed.items > .item { - margin: 1.5em 0; -} - -.ui[class*="very relaxed"].items > .item { - margin: 2em 0; -} - -/*------------------- - Divided - --------------------*/ - -.ui.divided.items > .item { - border-top: 1px solid rgba(34, 36, 38, 0.15); - margin: 0; - padding: 1em 0; -} - -.ui.divided.items > .item:first-child { - border-top: none; - margin-top: 0 !important; - padding-top: 0 !important; -} - -.ui.divided.items > .item:last-child { - margin-bottom: 0 !important; - padding-bottom: 0 !important; -} - -/* Relaxed Divided */ - -.ui.relaxed.divided.items > .item { - margin: 0; - padding: 1.5em 0; -} - -.ui[class*="very relaxed"].divided.items > .item { - margin: 0; - padding: 2em 0; -} - -/*------------------- - Link - --------------------*/ - -.ui.items a.item:hover, -.ui.link.items > .item:hover { - cursor: pointer; -} - -.ui.items a.item:hover .content .header, -.ui.link.items > .item:hover .content .header { - color: #1e70bf; -} - -/*-------------- - Size ----------------*/ - -.ui.items > .item { - font-size: 1em; -} - -.ui.mini.items > .item { - font-size: 0.78571429em; -} - -.ui.tiny.items > .item { - font-size: 0.85714286em; -} - -.ui.small.items > .item { - font-size: 0.92857143em; -} - -.ui.large.items > .item { - font-size: 1.14285714em; -} - -.ui.big.items > .item { - font-size: 1.28571429em; -} - -.ui.huge.items > .item { - font-size: 1.42857143em; -} - -.ui.massive.items > .item { - font-size: 1.71428571em; -} - -/*--------------- - Unstackable - ----------------*/ - -@media only screen and (max-width: 767.98px) { - .ui.unstackable.items > .item > .image, - .ui.unstackable.items > .item > .image > img { - width: 125px !important; - } -} - -/******************************* - Theme Overrides -*******************************/ - -/******************************* - User Variable Overrides -*******************************/ /*! * # Fomantic-UI - Label * http://github.com/fomantic/Fomantic-UI/ diff --git a/web_src/fomantic/semantic.json b/web_src/fomantic/semantic.json index 79aec9493f8ef..eeb67f6097976 100644 --- a/web_src/fomantic/semantic.json +++ b/web_src/fomantic/semantic.json @@ -31,7 +31,6 @@ "grid", "header", "input", - "item", "label", "list", "menu", diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index 07fbd634fd54c..1889bfb2221eb 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -30,6 +30,9 @@
{{ item.name }} +
+ {{ textDefaultBranchLabel }} +
diff --git a/web_src/js/utils.test.js b/web_src/js/utils.test.js index 812ef3bedfdc0..6648b669c7cc1 100644 --- a/web_src/js/utils.test.js +++ b/web_src/js/utils.test.js @@ -133,17 +133,22 @@ test('toAbsoluteUrl', () => { expect(() => toAbsoluteUrl('path')).toThrowError('unsupported'); }); -const uint8array = (s) => new TextEncoder().encode(s); test('encodeURLEncodedBase64, decodeURLEncodedBase64', () => { + // TextEncoder is Node.js API while Uint8Array is jsdom API and their outputs are not + // structurally comparable, so we convert to array to compare. The conversion can be + // removed once https://github.com/jsdom/jsdom/issues/2524 is resolved. + const encoder = new TextEncoder(); + const uint8array = encoder.encode.bind(encoder); + expect(encodeURLEncodedBase64(uint8array('AA?'))).toEqual('QUE_'); // standard base64: "QUE/" expect(encodeURLEncodedBase64(uint8array('AA~'))).toEqual('QUF-'); // standard base64: "QUF+" - expect(decodeURLEncodedBase64('QUE/')).toEqual(uint8array('AA?')); - expect(decodeURLEncodedBase64('QUF+')).toEqual(uint8array('AA~')); - expect(decodeURLEncodedBase64('QUE_')).toEqual(uint8array('AA?')); - expect(decodeURLEncodedBase64('QUF-')).toEqual(uint8array('AA~')); + expect(Array.from(decodeURLEncodedBase64('QUE/'))).toEqual(Array.from(uint8array('AA?'))); + expect(Array.from(decodeURLEncodedBase64('QUF+'))).toEqual(Array.from(uint8array('AA~'))); + expect(Array.from(decodeURLEncodedBase64('QUE_'))).toEqual(Array.from(uint8array('AA?'))); + expect(Array.from(decodeURLEncodedBase64('QUF-'))).toEqual(Array.from(uint8array('AA~'))); expect(encodeURLEncodedBase64(uint8array('a'))).toEqual('YQ'); // standard base64: "YQ==" - expect(decodeURLEncodedBase64('YQ')).toEqual(uint8array('a')); - expect(decodeURLEncodedBase64('YQ==')).toEqual(uint8array('a')); + expect(Array.from(decodeURLEncodedBase64('YQ'))).toEqual(Array.from(uint8array('a'))); + expect(Array.from(decodeURLEncodedBase64('YQ=='))).toEqual(Array.from(uint8array('a'))); });