Compare commits
49 commits
97e1853b63
...
71bd71e45d
Author | SHA1 | Date | |
---|---|---|---|
71bd71e45d | |||
26341a7fac | |||
|
89014eb4fe | ||
|
95a18f778a | ||
|
31c4a80979 | ||
|
91e49c45ec | ||
|
1ce155c5a6 | ||
|
52f8fde69f | ||
|
f484ad6a29 | ||
|
3a788340f0 | ||
|
6812c5d634 | ||
|
346635605d | ||
|
693c2b4f15 | ||
|
ce3a24ef5f | ||
|
171b6a294f | ||
|
b1b0d9a3fe | ||
|
8c3e66d604 | ||
|
599211efe4 | ||
|
69bb6c6d71 | ||
|
b69ad623c2 | ||
|
6cc02cdfd4 | ||
|
8aee1ae8e9 | ||
|
13c0df40de | ||
|
694f748f38 | ||
|
93c3924a56 | ||
|
6ffcb5f5a5 | ||
|
b63749b94c | ||
|
ce5260565c | ||
|
897f20d3ed | ||
|
b17113bb06 | ||
|
72bbb30f9d | ||
|
bc0078a50a | ||
|
a923dad82d | ||
|
61fc5c514a | ||
|
69221d84cf | ||
|
114f18f105 | ||
|
1263d0d416 | ||
|
958a20865b | ||
|
4de2148ae4 | ||
|
2552bb7b6e | ||
|
272d0a4c20 | ||
|
55b9aed470 | ||
|
0afc181d20 | ||
|
1fea3ce659 | ||
|
4d54a2b497 | ||
|
e6fb2107f2 | ||
|
1327ca7178 | ||
|
b65e44e464 | ||
|
bc59be2fea |
98 changed files with 1690 additions and 301 deletions
5
.github/workflows/release-tag-rc.yml
vendored
5
.github/workflows/release-tag-rc.yml
vendored
|
@ -44,7 +44,7 @@ jobs:
|
||||||
- name: Get cleaned branch name
|
- name: Get cleaned branch name
|
||||||
id: clean_name
|
id: clean_name
|
||||||
run: |
|
run: |
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
||||||
echo "Cleaned name is ${REF_NAME}"
|
echo "Cleaned name is ${REF_NAME}"
|
||||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
- name: configure aws
|
- name: configure aws
|
||||||
|
@ -78,6 +78,8 @@ jobs:
|
||||||
id: meta
|
id: meta
|
||||||
with:
|
with:
|
||||||
images: gitea/gitea
|
images: gitea/gitea
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
# 1.2.3-rc0
|
# 1.2.3-rc0
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
|
@ -109,6 +111,7 @@ jobs:
|
||||||
images: gitea/gitea
|
images: gitea/gitea
|
||||||
# each tag below will have the suffix of -rootless
|
# each tag below will have the suffix of -rootless
|
||||||
flavor: |
|
flavor: |
|
||||||
|
latest=false
|
||||||
suffix=-rootless
|
suffix=-rootless
|
||||||
# 1.2.3-rc0
|
# 1.2.3-rc0
|
||||||
tags: |
|
tags: |
|
||||||
|
|
6
.github/workflows/release-tag-version.yml
vendored
6
.github/workflows/release-tag-version.yml
vendored
|
@ -46,7 +46,7 @@ jobs:
|
||||||
- name: Get cleaned branch name
|
- name: Get cleaned branch name
|
||||||
id: clean_name
|
id: clean_name
|
||||||
run: |
|
run: |
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
||||||
echo "Cleaned name is ${REF_NAME}"
|
echo "Cleaned name is ${REF_NAME}"
|
||||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
- name: configure aws
|
- name: configure aws
|
||||||
|
@ -86,7 +86,6 @@ jobs:
|
||||||
# 1.2
|
# 1.2
|
||||||
# 1.2.3
|
# 1.2.3
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
|
@ -118,14 +117,13 @@ jobs:
|
||||||
images: gitea/gitea
|
images: gitea/gitea
|
||||||
# each tag below will have the suffix of -rootless
|
# each tag below will have the suffix of -rootless
|
||||||
flavor: |
|
flavor: |
|
||||||
suffix=-rootless
|
suffix=-rootless,onlatest=true
|
||||||
# this will generate tags in the following format (with -rootless suffix added):
|
# this will generate tags in the following format (with -rootless suffix added):
|
||||||
# latest
|
# latest
|
||||||
# 1
|
# 1
|
||||||
# 1.2
|
# 1.2
|
||||||
# 1.2.3
|
# 1.2.3
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
|
|
|
@ -3,7 +3,7 @@ pipeline:
|
||||||
image: docker.io/woodpeckerci/plugin-docker-buildx
|
image: docker.io/woodpeckerci/plugin-docker-buildx
|
||||||
settings:
|
settings:
|
||||||
repo: gitea.nulo.in/nulo/forgejo
|
repo: gitea.nulo.in/nulo/forgejo
|
||||||
tag: v1.21.1-0
|
tag: v1.21.2-0
|
||||||
registry: https://gitea.nulo.in
|
registry: https://gitea.nulo.in
|
||||||
username: Nulo
|
username: Nulo
|
||||||
password:
|
password:
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -89,7 +89,7 @@ endif
|
||||||
VERSION = ${GITEA_VERSION}
|
VERSION = ${GITEA_VERSION}
|
||||||
|
|
||||||
# SemVer
|
# SemVer
|
||||||
FORGEJO_VERSION := 6.0.0+0-gitea-1.21.0
|
FORGEJO_VERSION := 6.0.1+0-gitea-1.21.2
|
||||||
|
|
||||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)" -X "main.ForgejoVersion=$(FORGEJO_VERSION)"
|
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)" -X "main.ForgejoVersion=$(FORGEJO_VERSION)"
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -39,19 +40,28 @@ func renameGiteaForgejo(filename string) []byte {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
replacer := strings.NewReplacer(
|
replacements := []string{
|
||||||
"Gitea", "Forgejo",
|
"Gitea", "Forgejo",
|
||||||
"https://docs.gitea.io/en-us/install-from-binary/", "https://forgejo.org/download/#installation-from-binary",
|
"https://docs.gitea.com/installation/install-from-binary", "https://forgejo.org/download/#installation-from-binary",
|
||||||
"https://github.com/go-gitea/gitea/tree/master/docker", "https://forgejo.org/download/#container-image",
|
"https://github.com/go-gitea/gitea/tree/master/docker", "https://forgejo.org/download/#container-image",
|
||||||
"https://docs.gitea.io/en-us/install-from-package/", "https://forgejo.org/download",
|
"https://docs.gitea.com/installation/install-from-package", "https://forgejo.org/download",
|
||||||
"https://code.gitea.io/gitea", "https://forgejo.org/download",
|
"https://code.gitea.io/gitea", "https://forgejo.org/download",
|
||||||
"code.gitea.io/gitea", "Forgejo",
|
"code.gitea.io/gitea", "Forgejo",
|
||||||
`<a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a>`, `<a href="https://codeberg.org/forgejo/forgejo/issues" target="_blank">Codeberg</a>`,
|
`<a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a>`, `<a href="https://codeberg.org/forgejo/forgejo/issues" target="_blank">Codeberg</a>`,
|
||||||
"https://github.com/go-gitea/gitea", "https://codeberg.org/forgejo/forgejo",
|
"https://github.com/go-gitea/gitea", "https://codeberg.org/forgejo/forgejo",
|
||||||
"https://blog.gitea.io", "https://forgejo.org/news",
|
"https://blog.gitea.io", "https://forgejo.org/news",
|
||||||
"https://docs.gitea.io/en-us/protected-tags/", "https://forgejo.org/docs/latest/user/protection/#protected-tags",
|
"https://docs.gitea.com/usage/protected-tags", "https://forgejo.org/docs/latest/user/protection/#protected-tags",
|
||||||
"https://docs.gitea.io/en-us/webhooks/", "https://forgejo.org/docs/latest/user/webhooks/",
|
"https://docs.gitea.com/usage/webhooks", "https://forgejo.org/docs/latest/user/webhooks/",
|
||||||
)
|
}
|
||||||
|
replacer := strings.NewReplacer(replacements...)
|
||||||
|
replaced := make(map[string]bool, len(replacements)/2)
|
||||||
|
count_replaced := func(original string) {
|
||||||
|
for i := 0; i < len(replacements); i += 2 {
|
||||||
|
if strings.Contains(original, replacements[i]) {
|
||||||
|
replaced[replacements[i]] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out := make([]byte, 0, 1024)
|
out := make([]byte, 0, 1024)
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
|
@ -72,10 +82,18 @@ func renameGiteaForgejo(filename string) []byte {
|
||||||
re := regexp.MustCompile(`(.*Gitea)`)
|
re := regexp.MustCompile(`(.*Gitea)`)
|
||||||
out = append(out, []byte(re.ReplaceAllString(line, "${1}/Forgejo")+"\n")...)
|
out = append(out, []byte(re.ReplaceAllString(line, "${1}/Forgejo")+"\n")...)
|
||||||
} else {
|
} else {
|
||||||
|
count_replaced(line)
|
||||||
out = append(out, []byte(replacer.Replace(line)+"\n")...)
|
out = append(out, []byte(replacer.Replace(line)+"\n")...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.Close()
|
file.Close()
|
||||||
|
if strings.HasSuffix(filename, "gitea_en-US.ini") {
|
||||||
|
for i := 0; i < len(replacements); i += 2 {
|
||||||
|
if replaced[replacements[i]] == false {
|
||||||
|
log.Fatalf("%s was never used to replace something in %s, it is obsolete and must be updated", replacements[i], filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ PASSWD = `password`
|
||||||
|
|
||||||
要发送测试邮件以验证设置,请转到 Gitea > 站点管理 > 配置 > SMTP 邮件配置。
|
要发送测试邮件以验证设置,请转到 Gitea > 站点管理 > 配置 > SMTP 邮件配置。
|
||||||
|
|
||||||
有关所有选项的完整列表,请查看[配置速查表](doc/administration/config-cheat-sheet.md)。
|
有关所有选项的完整列表,请查看[配置速查表](administration/config-cheat-sheet.md)。
|
||||||
|
|
||||||
请注意:只有在使用 TLS 或 `HOST=localhost` 加密 SMTP 服务器通信时才支持身份验证。TLS 加密可以通过以下方式进行:
|
请注意:只有在使用 TLS 或 `HOST=localhost` 加密 SMTP 服务器通信时才支持身份验证。TLS 加密可以通过以下方式进行:
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ If a bug fix is targeted on 1.20.1 but 1.20.1 is not released yet, you can get t
|
||||||
|
|
||||||
To migrate from Gogs to Gitea:
|
To migrate from Gogs to Gitea:
|
||||||
|
|
||||||
|
- [Gogs version 0.9.146 or less](installation/upgrade-from-gogs.md)
|
||||||
- [Gogs version 0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286)
|
- [Gogs version 0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286)
|
||||||
|
|
||||||
To migrate from GitHub to Gitea, you can use Gitea's built-in migration form.
|
To migrate from GitHub to Gitea, you can use Gitea's built-in migration form.
|
||||||
|
|
|
@ -41,6 +41,7 @@ menu:
|
||||||
|
|
||||||
要从Gogs迁移到Gitea:
|
要从Gogs迁移到Gitea:
|
||||||
|
|
||||||
|
- [Gogs版本0.9.146或更低](installation/upgrade-from-gogs.md)
|
||||||
- [Gogs版本0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286)
|
- [Gogs版本0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286)
|
||||||
|
|
||||||
要从GitHub迁移到Gitea,您可以使用Gitea内置的迁移表单。
|
要从GitHub迁移到Gitea,您可以使用Gitea内置的迁移表单。
|
||||||
|
|
|
@ -114,7 +114,7 @@ If you cannot see the settings page, please make sure that you have the right pe
|
||||||
|
|
||||||
The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`.
|
The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`.
|
||||||
|
|
||||||
A registration token can also be obtained from the gitea [command-line interface](../../administration/command-line.md#actions-generate-runner-token):
|
A registration token can also be obtained from the gitea [command-line interface](administration/command-line.md#actions-generate-runner-token):
|
||||||
|
|
||||||
```
|
```
|
||||||
gitea --config /etc/gitea/app.ini actions generate-runner-token
|
gitea --config /etc/gitea/app.ini actions generate-runner-token
|
||||||
|
|
|
@ -113,7 +113,7 @@ Runner级别决定了从哪里获取注册令牌。
|
||||||
|
|
||||||
注册令牌的格式是一个随机字符串 `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`。
|
注册令牌的格式是一个随机字符串 `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`。
|
||||||
|
|
||||||
注册令牌也可以通过 Gitea 的 [命令行](../../administration/command-line.md#actions-generate-runner-token) 获得:
|
注册令牌也可以通过 Gitea 的 [命令行](administration/command-line.md#actions-generate-runner-token) 获得:
|
||||||
|
|
||||||
### 注册Runner
|
### 注册Runner
|
||||||
|
|
||||||
|
|
|
@ -587,7 +587,7 @@ func EnsureUpToDate(x *xorm.Engine) error {
|
||||||
return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
|
return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return forgejo_migrations.EnsureUpToDate(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// Migrate database to current version
|
||||||
|
|
|
@ -32,7 +32,12 @@ func AddGitSizeAndLFSSizeToRepositoryTable(x *xorm.Engine) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = sess.Exec(`UPDATE repository SET git_size = size - lfs_size`)
|
_, err = sess.Exec(`UPDATE repository SET size = 0 WHERE size IS NULL`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sess.Exec(`UPDATE repository SET git_size = size - lfs_size WHERE size > lfs_size`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,7 @@
|
||||||
package v1_21 //nolint
|
package v1_21 //nolint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
giturl "code.gitea.io/gitea/modules/git/url"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
@ -73,7 +67,7 @@ func migratePullMirrors(x *xorm.Engine) error {
|
||||||
start += len(mirrors)
|
start += len(mirrors)
|
||||||
|
|
||||||
for _, m := range mirrors {
|
for _, m := range mirrors {
|
||||||
remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, "origin")
|
remoteAddress, err := repo_model.GetPushMirrorRemoteAddress(m.RepoOwner, m.RepoName, "origin")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -136,7 +130,7 @@ func migratePushMirrors(x *xorm.Engine) error {
|
||||||
start += len(mirrors)
|
start += len(mirrors)
|
||||||
|
|
||||||
for _, m := range mirrors {
|
for _, m := range mirrors {
|
||||||
remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, m.RemoteName)
|
remoteAddress, err := repo_model.GetPushMirrorRemoteAddress(m.RepoOwner, m.RepoName, m.RemoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -160,20 +154,3 @@ func migratePushMirrors(x *xorm.Engine) error {
|
||||||
|
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRemoteAddress(ownerName, repoName, remoteName string) (string, error) {
|
|
||||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(ownerName), strings.ToLower(repoName)+".git")
|
|
||||||
|
|
||||||
remoteURL, err := git.GetRemoteAddress(context.Background(), repoPath, remoteName)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("get remote %s's address of %s/%s failed: %v", remoteName, ownerName, repoName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
u, err := giturl.Parse(remoteURL)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
u.User = nil
|
|
||||||
|
|
||||||
return u.String(), nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,10 +5,16 @@ package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
giturl "code.gitea.io/gitea/modules/git/url"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
|
@ -145,3 +151,21 @@ func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any
|
||||||
}
|
}
|
||||||
return sess.Iterate(new(PushMirror), f)
|
return sess.Iterate(new(PushMirror), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPushMirrorRemoteAddress returns the address of associated with a repository's given remote.
|
||||||
|
func GetPushMirrorRemoteAddress(ownerName, repoName, remoteName string) (string, error) {
|
||||||
|
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(ownerName), strings.ToLower(repoName)+".git")
|
||||||
|
|
||||||
|
remoteURL, err := git.GetRemoteAddress(context.Background(), repoPath, remoteName)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("get remote %s's address of %s/%s failed: %v", remoteName, ownerName, repoName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := giturl.Parse(remoteURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
u.User = nil
|
||||||
|
|
||||||
|
return u.String(), nil
|
||||||
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func SetSettings(ctx context.Context, settings map[string]string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for k, v := range settings {
|
for k, v := range settings {
|
||||||
res, err := e.Exec("UPDATE system_setting SET setting_value=? WHERE setting_key=?", v, k)
|
res, err := e.Exec("UPDATE system_setting SET version=version+1, setting_value=? WHERE setting_key=?", v, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,4 +39,16 @@ func TestSettings(t *testing.T) {
|
||||||
assert.EqualValues(t, 3, rev)
|
assert.EqualValues(t, 3, rev)
|
||||||
assert.Len(t, settings, 2)
|
assert.Len(t, settings, 2)
|
||||||
assert.EqualValues(t, "false", settings[keyName])
|
assert.EqualValues(t, "false", settings[keyName])
|
||||||
|
|
||||||
|
// setting the same value should not trigger DuplicateKey error, and the "version" should be increased
|
||||||
|
setting := &system.Setting{SettingKey: keyName}
|
||||||
|
_, err = db.GetByBean(db.DefaultContext, setting)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 2, setting.Version)
|
||||||
|
err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
setting = &system.Setting{SettingKey: keyName}
|
||||||
|
_, err = db.GetByBean(db.DefaultContext, setting)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 3, setting.Version)
|
||||||
}
|
}
|
||||||
|
|
131
models/unittest/mock_http.go
Normal file
131
models/unittest/mock_http.go
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
// Copyright 2017 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package unittest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mocks HTTP responses of a third-party service (such as GitHub, GitLab…)
|
||||||
|
// This has two modes:
|
||||||
|
// - live mode: the requests made to the mock HTTP server are transmitted to the live
|
||||||
|
// service, and responses are saved as test data files
|
||||||
|
// - test mode: the responses to requests to the mock HTTP server are read from the
|
||||||
|
// test data files
|
||||||
|
func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveMode bool) *httptest.Server {
|
||||||
|
mockServerBaseURL := ""
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
path := NormalizedFullPath(r.URL)
|
||||||
|
log.Info("Mock HTTP Server: got request for path %s", r.URL.Path)
|
||||||
|
// TODO check request method (support POST?)
|
||||||
|
fixturePath := fmt.Sprintf("%s/%s", testDataDir, strings.ReplaceAll(path, "/", "_"))
|
||||||
|
if liveMode {
|
||||||
|
liveURL := fmt.Sprintf("%s%s", liveServerBaseURL, path)
|
||||||
|
|
||||||
|
request, err := http.NewRequest(r.Method, liveURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, "constructing an HTTP request to %s failed", liveURL, err)
|
||||||
|
}
|
||||||
|
for headerName, headerValues := range r.Header {
|
||||||
|
// do not pass on the encoding: let the Transport of the HTTP client handle that for us
|
||||||
|
if strings.ToLower(headerName) != "accept-encoding" {
|
||||||
|
for _, headerValue := range headerValues {
|
||||||
|
request.Header.Add(headerName, headerValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := http.DefaultClient.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, "HTTP request to %s failed: %s", liveURL, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fixture, err := os.Create(fixturePath)
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, fmt.Sprintf("failed to open the fixture file %s for writing", fixturePath), err)
|
||||||
|
}
|
||||||
|
defer fixture.Close()
|
||||||
|
fixtureWriter := bufio.NewWriter(fixture)
|
||||||
|
|
||||||
|
for headerName, headerValues := range response.Header {
|
||||||
|
for _, headerValue := range headerValues {
|
||||||
|
if strings.ToLower(headerName) != "host" {
|
||||||
|
_, err := fixtureWriter.WriteString(fmt.Sprintf("%s: %s\n", headerName, headerValue))
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, "writing the header of the HTTP response to the fixture file failed", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := fixtureWriter.WriteString("\n"); err != nil {
|
||||||
|
assert.Fail(t, "writing the header of the HTTP response to the fixture file failed")
|
||||||
|
}
|
||||||
|
fixtureWriter.Flush()
|
||||||
|
|
||||||
|
reader := response.Body
|
||||||
|
content, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, "reading the response of the HTTP request to %s failed: %s", liveURL, err)
|
||||||
|
}
|
||||||
|
log.Info("Mock HTTP Server: writing response to %s", fixturePath)
|
||||||
|
if _, err := fixture.Write(content); err != nil {
|
||||||
|
assert.Fail(t, "writing the body of the HTTP response to the fixture file failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := fixture.Sync(); err != nil {
|
||||||
|
assert.Fail(t, "writing the body of the HTTP response to the fixture file failed", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fixture, err := os.ReadFile(fixturePath)
|
||||||
|
if err != nil {
|
||||||
|
assert.Fail(t, "missing mock HTTP response: "+fixturePath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
// parse back the fixture file into a series of HTTP headers followed by response body
|
||||||
|
lines := strings.Split(string(fixture), "\n")
|
||||||
|
for idx, line := range lines {
|
||||||
|
colonIndex := strings.Index(line, ": ")
|
||||||
|
if colonIndex != -1 {
|
||||||
|
w.Header().Set(line[0:colonIndex], line[colonIndex+2:])
|
||||||
|
} else {
|
||||||
|
// we reached the end of the headers (empty line), so what follows is the body
|
||||||
|
responseBody := strings.Join(lines[idx+1:], "\n")
|
||||||
|
// replace any mention of the live HTTP service by the mocked host
|
||||||
|
responseBody = strings.ReplaceAll(responseBody, liveServerBaseURL, mockServerBaseURL)
|
||||||
|
if _, err := w.Write([]byte(responseBody)); err != nil {
|
||||||
|
assert.Fail(t, "writing the body of the HTTP response failed", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
mockServerBaseURL = server.URL
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func NormalizedFullPath(url *url.URL) string {
|
||||||
|
// TODO normalize path (remove trailing slash?)
|
||||||
|
// TODO normalize RawQuery (order query parameters?)
|
||||||
|
if len(url.Query()) == 0 {
|
||||||
|
return url.EscapedPath()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s?%s", url.EscapedPath(), url.RawQuery)
|
||||||
|
}
|
91
modules/doctor/push_mirror_consistency.go
Normal file
91
modules/doctor/push_mirror_consistency.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright 2023 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package doctor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FixPushMirrorsWithoutGitRemote(ctx context.Context, logger log.Logger, autofix bool) error {
|
||||||
|
var missingMirrors []*repo_model.PushMirror
|
||||||
|
|
||||||
|
err := db.Iterate(ctx, builder.Gt{"id": 0}, func(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
|
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(pushMirrors); i++ {
|
||||||
|
_, err = repo_model.GetPushMirrorRemoteAddress(repo.OwnerName, repo.Name, pushMirrors[i].RemoteName)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "No such remote") {
|
||||||
|
missingMirrors = append(missingMirrors, pushMirrors[i])
|
||||||
|
} else if logger != nil {
|
||||||
|
logger.Warn("Unable to retrieve the remote address of a mirror: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if logger != nil {
|
||||||
|
logger.Critical("Unable to iterate across repounits to fix push mirrors without a git remote: Error %v", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
count := len(missingMirrors)
|
||||||
|
if !autofix {
|
||||||
|
if logger != nil {
|
||||||
|
if count == 0 {
|
||||||
|
logger.Info("Found no push mirrors with missing git remotes")
|
||||||
|
} else {
|
||||||
|
logger.Warn("Found %d push mirrors with missing git remotes", count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(missingMirrors); i++ {
|
||||||
|
if logger != nil {
|
||||||
|
logger.Info("Removing push mirror #%d (remote: %s), for repo: %s/%s",
|
||||||
|
missingMirrors[i].ID,
|
||||||
|
missingMirrors[i].RemoteName,
|
||||||
|
missingMirrors[i].GetRepository().OwnerName,
|
||||||
|
missingMirrors[i].GetRepository().Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{
|
||||||
|
ID: missingMirrors[i].ID,
|
||||||
|
RepoID: missingMirrors[i].RepoID,
|
||||||
|
RemoteName: missingMirrors[i].RemoteName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if logger != nil {
|
||||||
|
logger.Critical("Error removing a push mirror (repo_id: %d, push_mirror: %d): %s", missingMirrors[i].Repo.ID, missingMirrors[i].ID, err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(&Check{
|
||||||
|
Title: "Check for push mirrors without a git remote configured",
|
||||||
|
Name: "fix-push-mirrors-without-git-remote",
|
||||||
|
IsDefault: false,
|
||||||
|
Run: FixPushMirrorsWithoutGitRemote,
|
||||||
|
Priority: 7,
|
||||||
|
})
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
@ -18,8 +19,10 @@ import (
|
||||||
|
|
||||||
// BlamePart represents block of blame - continuous lines with one sha
|
// BlamePart represents block of blame - continuous lines with one sha
|
||||||
type BlamePart struct {
|
type BlamePart struct {
|
||||||
Sha string
|
Sha string
|
||||||
Lines []string
|
Lines []string
|
||||||
|
PreviousSha string
|
||||||
|
PreviousPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlameReader returns part of file blame one by one
|
// BlameReader returns part of file blame one by one
|
||||||
|
@ -43,30 +46,38 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
|
||||||
var blamePart *BlamePart
|
var blamePart *BlamePart
|
||||||
|
|
||||||
if r.lastSha != nil {
|
if r.lastSha != nil {
|
||||||
blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
|
blamePart = &BlamePart{
|
||||||
|
Sha: *r.lastSha,
|
||||||
|
Lines: make([]string, 0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var line []byte
|
var lineBytes []byte
|
||||||
var isPrefix bool
|
var isPrefix bool
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
for err != io.EOF {
|
for err != io.EOF {
|
||||||
line, isPrefix, err = r.bufferedReader.ReadLine()
|
lineBytes, isPrefix, err = r.bufferedReader.ReadLine()
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return blamePart, err
|
return blamePart, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(line) == 0 {
|
if len(lineBytes) == 0 {
|
||||||
// isPrefix will be false
|
// isPrefix will be false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := shaLineRegex.FindSubmatch(line)
|
line := string(lineBytes)
|
||||||
|
|
||||||
|
lines := shaLineRegex.FindStringSubmatch(line)
|
||||||
if lines != nil {
|
if lines != nil {
|
||||||
sha1 := string(lines[1])
|
sha1 := lines[1]
|
||||||
|
|
||||||
if blamePart == nil {
|
if blamePart == nil {
|
||||||
blamePart = &BlamePart{sha1, make([]string, 0)}
|
blamePart = &BlamePart{
|
||||||
|
Sha: sha1,
|
||||||
|
Lines: make([]string, 0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if blamePart.Sha != sha1 {
|
if blamePart.Sha != sha1 {
|
||||||
|
@ -81,9 +92,11 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
|
||||||
return blamePart, nil
|
return blamePart, nil
|
||||||
}
|
}
|
||||||
} else if line[0] == '\t' {
|
} else if line[0] == '\t' {
|
||||||
code := line[1:]
|
blamePart.Lines = append(blamePart.Lines, line[1:])
|
||||||
|
} else if strings.HasPrefix(line, "previous ") {
|
||||||
blamePart.Lines = append(blamePart.Lines, string(code))
|
parts := strings.SplitN(line[len("previous "):], " ", 2)
|
||||||
|
blamePart.PreviousSha = parts[0]
|
||||||
|
blamePart.PreviousPath = parts[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to munch to end of line...
|
// need to munch to end of line...
|
||||||
|
|
|
@ -24,15 +24,17 @@ func TestReadingBlameOutput(t *testing.T) {
|
||||||
|
|
||||||
parts := []*BlamePart{
|
parts := []*BlamePart{
|
||||||
{
|
{
|
||||||
"72866af952e98d02a73003501836074b286a78f6",
|
Sha: "72866af952e98d02a73003501836074b286a78f6",
|
||||||
[]string{
|
Lines: []string{
|
||||||
"# test_repo",
|
"# test_repo",
|
||||||
"Test repository for testing migration from github to gitea",
|
"Test repository for testing migration from github to gitea",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"f32b0a9dfd09a60f616f29158f772cedd89942d2",
|
Sha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
|
||||||
[]string{"", "Do not make any changes to this repo it is used for unit testing"},
|
Lines: []string{"", "Do not make any changes to this repo it is used for unit testing"},
|
||||||
|
PreviousSha: "72866af952e98d02a73003501836074b286a78f6",
|
||||||
|
PreviousPath: "README.md",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,16 +66,18 @@ func TestReadingBlameOutput(t *testing.T) {
|
||||||
|
|
||||||
full := []*BlamePart{
|
full := []*BlamePart{
|
||||||
{
|
{
|
||||||
"af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
Sha: "af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
||||||
[]string{"line", "line"},
|
Lines: []string{"line", "line"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"45fb6cbc12f970b04eacd5cd4165edd11c8d7376",
|
Sha: "45fb6cbc12f970b04eacd5cd4165edd11c8d7376",
|
||||||
[]string{"changed line"},
|
Lines: []string{"changed line"},
|
||||||
|
PreviousSha: "af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
||||||
|
PreviousPath: "blame.txt",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
Sha: "af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
||||||
[]string{"line", "line", ""},
|
Lines: []string{"line", "line", ""},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +93,8 @@ func TestReadingBlameOutput(t *testing.T) {
|
||||||
Bypass: false,
|
Bypass: false,
|
||||||
Parts: []*BlamePart{
|
Parts: []*BlamePart{
|
||||||
{
|
{
|
||||||
"af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
Sha: "af7486bd54cfc39eea97207ca666aa69c9d6df93",
|
||||||
[]string{"line", "line", "changed line", "line", "line", ""},
|
Lines: []string{"line", "line", "changed line", "line", "line", ""},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,8 +43,9 @@ func (c *Commit) Message() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary returns first line of commit message.
|
// Summary returns first line of commit message.
|
||||||
|
// The string is forced to be valid UTF8
|
||||||
func (c *Commit) Summary() string {
|
func (c *Commit) Summary() string {
|
||||||
return strings.Split(strings.TrimSpace(c.CommitMessage), "\n")[0]
|
return strings.ToValidUTF8(strings.Split(strings.TrimSpace(c.CommitMessage), "\n")[0], "?")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParentID returns oid of n-th parent (0-based index).
|
// ParentID returns oid of n-th parent (0-based index).
|
||||||
|
|
|
@ -8,6 +8,7 @@ package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
|
@ -52,32 +53,46 @@ func (repo *Repository) IsBranchExist(name string) bool {
|
||||||
|
|
||||||
// GetBranches returns branches from the repository, skipping "skip" initial branches and
|
// GetBranches returns branches from the repository, skipping "skip" initial branches and
|
||||||
// returning at most "limit" branches, or all branches if "limit" is 0.
|
// returning at most "limit" branches, or all branches if "limit" is 0.
|
||||||
|
// Branches are returned with sort of `-commiterdate` as the nogogit
|
||||||
|
// implementation. This requires full fetch, sort and then the
|
||||||
|
// skip/limit applies later as gogit returns in undefined order.
|
||||||
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
|
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
|
||||||
var branchNames []string
|
type BranchData struct {
|
||||||
|
name string
|
||||||
|
committerDate int64
|
||||||
|
}
|
||||||
|
var branchData []BranchData
|
||||||
|
|
||||||
branches, err := repo.gogitRepo.Branches()
|
branchIter, err := repo.gogitRepo.Branches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
_ = branchIter.ForEach(func(branch *plumbing.Reference) error {
|
||||||
count := 0
|
obj, err := repo.gogitRepo.CommitObject(branch.Hash())
|
||||||
_ = branches.ForEach(func(branch *plumbing.Reference) error {
|
if err != nil {
|
||||||
count++
|
// skip branch if can't find commit
|
||||||
if i < skip {
|
|
||||||
i++
|
|
||||||
return nil
|
|
||||||
} else if limit != 0 && count > skip+limit {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
branchNames = append(branchNames, strings.TrimPrefix(branch.Name().String(), BranchPrefix))
|
branchData = append(branchData, BranchData{strings.TrimPrefix(branch.Name().String(), BranchPrefix), obj.Committer.When.Unix()})
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Sort?
|
sort.Slice(branchData, func(i, j int) bool {
|
||||||
|
return !(branchData[i].committerDate < branchData[j].committerDate)
|
||||||
|
})
|
||||||
|
|
||||||
return branchNames, count, nil
|
var branchNames []string
|
||||||
|
maxPos := len(branchData)
|
||||||
|
if limit > 0 {
|
||||||
|
maxPos = min(skip+limit, maxPos)
|
||||||
|
}
|
||||||
|
for i := skip; i < maxPos; i++ {
|
||||||
|
branchNames = append(branchNames, branchData[i].name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return branchNames, len(branchData), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WalkReferences walks all the references from the repository
|
// WalkReferences walks all the references from the repository
|
||||||
|
|
|
@ -211,10 +211,11 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
|
||||||
skip, limit := indexer_internal.ParsePaginator(options.Paginator, maxTotalHits)
|
skip, limit := indexer_internal.ParsePaginator(options.Paginator, maxTotalHits)
|
||||||
|
|
||||||
searchRes, err := b.inner.Client.Index(b.inner.VersionedIndexName()).Search(options.Keyword, &meilisearch.SearchRequest{
|
searchRes, err := b.inner.Client.Index(b.inner.VersionedIndexName()).Search(options.Keyword, &meilisearch.SearchRequest{
|
||||||
Filter: query.Statement(),
|
Filter: query.Statement(),
|
||||||
Limit: int64(limit),
|
Limit: int64(limit),
|
||||||
Offset: int64(skip),
|
Offset: int64(skip),
|
||||||
Sort: sortBy,
|
Sort: sortBy,
|
||||||
|
MatchingStrategy: "all",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -160,28 +160,25 @@ const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | o
|
||||||
// getDirectorySize returns the disk consumption for a given path
|
// getDirectorySize returns the disk consumption for a given path
|
||||||
func getDirectorySize(path string) (int64, error) {
|
func getDirectorySize(path string) (int64, error) {
|
||||||
var size int64
|
var size int64
|
||||||
err := filepath.WalkDir(path, func(_ string, info os.DirEntry, err error) error {
|
err := filepath.WalkDir(path, func(_ string, entry os.DirEntry, err error) error {
|
||||||
if err != nil {
|
if os.IsNotExist(err) { // ignore the error because some files (like temp/lock file) may be deleted during traversing.
|
||||||
if os.IsNotExist(err) { // ignore the error because the file maybe deleted during traversing.
|
return nil
|
||||||
return nil
|
} else if err != nil {
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if entry.IsDir() {
|
||||||
fileName := info.Name()
|
|
||||||
// Ignore temporary Git files as they will like be missing once info.Info is
|
|
||||||
// called and cause a disrupt to the whole operation.
|
|
||||||
if info.IsDir() || strings.HasSuffix(fileName, ".lock") || strings.HasPrefix(filepath.Base(fileName), "tmp_graph") {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
f, err := info.Info()
|
info, err := entry.Info()
|
||||||
if err != nil {
|
if os.IsNotExist(err) { // ignore the error as above
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if (f.Mode() & notRegularFileMode) == 0 {
|
if (info.Mode() & notRegularFileMode) == 0 {
|
||||||
size += f.Size()
|
size += info.Size()
|
||||||
}
|
}
|
||||||
return err
|
return nil
|
||||||
})
|
})
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func loadAttachmentFrom(rootCfg ConfigProvider) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip")
|
Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip")
|
||||||
Attachment.MaxSize = sec.Key("MAX_SIZE").MustInt64(4)
|
Attachment.MaxSize = sec.Key("MAX_SIZE").MustInt64(2048)
|
||||||
Attachment.MaxFiles = sec.Key("MAX_FILES").MustInt(5)
|
Attachment.MaxFiles = sec.Key("MAX_FILES").MustInt(5)
|
||||||
Attachment.Enabled = sec.Key("ENABLED").MustBool(true)
|
Attachment.Enabled = sec.Key("ENABLED").MustBool(true)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -119,7 +118,7 @@ func DBConnStr() (string, error) {
|
||||||
if !EnableSQLite3 {
|
if !EnableSQLite3 {
|
||||||
return "", errors.New("this Gitea binary was not built with SQLite3 support")
|
return "", errors.New("this Gitea binary was not built with SQLite3 support")
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(path.Dir(Database.Path), os.ModePerm); err != nil {
|
if err := os.MkdirAll(filepath.Dir(Database.Path), os.ModePerm); err != nil {
|
||||||
return "", fmt.Errorf("Failed to create directories: %w", err)
|
return "", fmt.Errorf("Failed to create directories: %w", err)
|
||||||
}
|
}
|
||||||
journalMode := ""
|
journalMode := ""
|
||||||
|
|
|
@ -2333,7 +2333,7 @@ settings.dismiss_stale_approvals_desc = When new commits that change the content
|
||||||
settings.require_signed_commits = Require Signed Commits
|
settings.require_signed_commits = Require Signed Commits
|
||||||
settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable.
|
settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable.
|
||||||
settings.protect_branch_name_pattern = Protected Branch Name Pattern
|
settings.protect_branch_name_pattern = Protected Branch Name Pattern
|
||||||
settings.protect_branch_name_pattern_desc = "Protected branch name patterns. See <a href="github.com/gobwas/glob">the documentation</a> for pattern syntax. Examples: main, release/**"
|
settings.protect_branch_name_pattern_desc = "Protected branch name patterns. See <a href="https://github.com/gobwas/glob">the documentation</a> for pattern syntax. Examples: main, release/**"
|
||||||
settings.protect_patterns = Patterns
|
settings.protect_patterns = Patterns
|
||||||
settings.protect_protected_file_patterns = "Protected file patterns (separated using semicolon ';'):"
|
settings.protect_protected_file_patterns = "Protected file patterns (separated using semicolon ';'):"
|
||||||
settings.protect_protected_file_patterns_desc = "Protected files are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon (';'). See <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>."
|
settings.protect_protected_file_patterns_desc = "Protected files are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon (';'). See <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>."
|
||||||
|
|
|
@ -520,7 +520,10 @@ func CommonRoutes() *web.Route {
|
||||||
r.Get("", rpm.DownloadPackageFile)
|
r.Get("", rpm.DownloadPackageFile)
|
||||||
r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
||||||
})
|
})
|
||||||
r.Get("/repodata/{filename}", rpm.GetRepositoryFile)
|
r.Group("/repodata/{filename}", func() {
|
||||||
|
r.Head("", rpm.CheckRepositoryFileExistence)
|
||||||
|
r.Get("", rpm.GetRepositoryFile)
|
||||||
|
})
|
||||||
}, reqPackageAccess(perm.AccessModeRead))
|
}, reqPackageAccess(perm.AccessModeRead))
|
||||||
r.Group("/rubygems", func() {
|
r.Group("/rubygems", func() {
|
||||||
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
|
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
|
||||||
|
|
|
@ -57,6 +57,30 @@ func GetRepositoryKey(ctx *context.Context) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckRepositoryFileExistence(ctx *context.Context) {
|
||||||
|
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
|
||||||
|
if err != nil {
|
||||||
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, util.ErrNotExist) {
|
||||||
|
ctx.Status(http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.SetServeHeaders(&context.ServeHeaderOptions{
|
||||||
|
Filename: pf.Name,
|
||||||
|
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||||
|
})
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
// Gets a pre-generated repository metadata file
|
// Gets a pre-generated repository metadata file
|
||||||
func GetRepositoryFile(ctx *context.Context) {
|
func GetRepositoryFile(ctx *context.Context) {
|
||||||
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
|
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
|
||||||
|
|
|
@ -951,10 +951,16 @@ func SignInOAuthCallback(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
} else if !setting.Service.AllowOnlyInternalRegistration && setting.OAuth2Client.EnableAutoRegistration {
|
} else if !setting.Service.AllowOnlyInternalRegistration && setting.OAuth2Client.EnableAutoRegistration {
|
||||||
// create new user with details from oauth2 provider
|
// create new user with details from oauth2 provider
|
||||||
var missingFields []string
|
|
||||||
if gothUser.UserID == "" {
|
if gothUser.UserID == "" {
|
||||||
missingFields = append(missingFields, "sub")
|
log.Error("OAuth2 Provider %s returned empty or missing field: UserID", authSource.Name)
|
||||||
|
if authSource.IsOAuth2() && authSource.Cfg.(*oauth2.Source).Provider == "openidConnect" {
|
||||||
|
log.Error("You may need to change the 'OPENID_CONNECT_SCOPES' setting to request all required fields")
|
||||||
|
}
|
||||||
|
err = fmt.Errorf("OAuth2 Provider %s returned empty or missing field: UserID", authSource.Name)
|
||||||
|
ctx.ServerError("CreateUser", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
var missingFields []string
|
||||||
if gothUser.Email == "" {
|
if gothUser.Email == "" {
|
||||||
missingFields = append(missingFields, "email")
|
missingFields = append(missingFields, "email")
|
||||||
}
|
}
|
||||||
|
@ -962,12 +968,10 @@ func SignInOAuthCallback(ctx *context.Context) {
|
||||||
missingFields = append(missingFields, "nickname")
|
missingFields = append(missingFields, "nickname")
|
||||||
}
|
}
|
||||||
if len(missingFields) > 0 {
|
if len(missingFields) > 0 {
|
||||||
log.Error("OAuth2 Provider %s returned empty or missing fields: %s", authSource.Name, missingFields)
|
// we don't have enough information to create an account automatically,
|
||||||
if authSource.IsOAuth2() && authSource.Cfg.(*oauth2.Source).Provider == "openidConnect" {
|
// so we prompt the user for the remaining bits
|
||||||
log.Error("You may need to change the 'OPENID_CONNECT_SCOPES' setting to request all required fields")
|
log.Trace("OAuth2 Provider %s returned empty or missing fields: %s, prompting the user for them", authSource.Name, missingFields)
|
||||||
}
|
showLinkingLogin(ctx, gothUser)
|
||||||
err = fmt.Errorf("OAuth2 Provider %s returned empty or missing fields: %s", authSource.Name, missingFields)
|
|
||||||
ctx.ServerError("CreateUser", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u = &user_model.User{
|
u = &user_model.User{
|
||||||
|
|
|
@ -201,6 +201,7 @@ func List(ctx *context.Context) {
|
||||||
pager.AddParamString("actor", fmt.Sprint(actorID))
|
pager.AddParamString("actor", fmt.Sprint(actorID))
|
||||||
pager.AddParamString("status", fmt.Sprint(status))
|
pager.AddParamString("status", fmt.Sprint(status))
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
|
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplListActions)
|
ctx.HTML(http.StatusOK, tplListActions)
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,12 +114,12 @@ func RefBlame(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commitNames, previousCommits := processBlameParts(ctx, result.Parts)
|
commitNames := processBlameParts(ctx, result.Parts)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBlame(ctx, result.Parts, commitNames, previousCommits)
|
renderBlame(ctx, result.Parts, commitNames)
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplRepoHome)
|
ctx.HTML(http.StatusOK, tplRepoHome)
|
||||||
}
|
}
|
||||||
|
@ -185,12 +185,9 @@ func fillBlameResult(br *git.BlameReader, r *blameResult) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) (map[string]*user_model.UserCommit, map[string]string) {
|
func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) map[string]*user_model.UserCommit {
|
||||||
// store commit data by SHA to look up avatar info etc
|
// store commit data by SHA to look up avatar info etc
|
||||||
commitNames := make(map[string]*user_model.UserCommit)
|
commitNames := make(map[string]*user_model.UserCommit)
|
||||||
// previousCommits contains links from SHA to parent SHA,
|
|
||||||
// if parent also contains the current TreePath.
|
|
||||||
previousCommits := make(map[string]string)
|
|
||||||
// and as blameParts can reference the same commits multiple
|
// and as blameParts can reference the same commits multiple
|
||||||
// times, we cache the lookup work locally
|
// times, we cache the lookup work locally
|
||||||
commits := make([]*git.Commit, 0, len(blameParts))
|
commits := make([]*git.Commit, 0, len(blameParts))
|
||||||
|
@ -214,29 +211,11 @@ func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) (map[st
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("Repo.GitRepo.GetCommit", err)
|
ctx.ServerError("Repo.GitRepo.GetCommit", err)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
commitCache[sha] = commit
|
commitCache[sha] = commit
|
||||||
}
|
}
|
||||||
|
|
||||||
// find parent commit
|
|
||||||
if commit.ParentCount() > 0 {
|
|
||||||
psha := commit.Parents[0]
|
|
||||||
previousCommit, ok := commitCache[psha.String()]
|
|
||||||
if !ok {
|
|
||||||
previousCommit, _ = commit.Parent(0)
|
|
||||||
if previousCommit != nil {
|
|
||||||
commitCache[psha.String()] = previousCommit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// only store parent commit ONCE, if it has the file
|
|
||||||
if previousCommit != nil {
|
|
||||||
if haz1, _ := previousCommit.HasFile(ctx.Repo.TreePath); haz1 {
|
|
||||||
previousCommits[commit.ID.String()] = previousCommit.ID.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
commits = append(commits, commit)
|
commits = append(commits, commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +224,10 @@ func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) (map[st
|
||||||
commitNames[c.ID.String()] = c
|
commitNames[c.ID.String()] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
return commitNames, previousCommits
|
return commitNames
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames map[string]*user_model.UserCommit, previousCommits map[string]string) {
|
func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames map[string]*user_model.UserCommit) {
|
||||||
repoLink := ctx.Repo.RepoLink
|
repoLink := ctx.Repo.RepoLink
|
||||||
|
|
||||||
language := ""
|
language := ""
|
||||||
|
@ -295,7 +274,6 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
|
||||||
}
|
}
|
||||||
|
|
||||||
commit := commitNames[part.Sha]
|
commit := commitNames[part.Sha]
|
||||||
previousSha := previousCommits[part.Sha]
|
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
// Count commit number
|
// Count commit number
|
||||||
commitCnt++
|
commitCnt++
|
||||||
|
@ -313,8 +291,8 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
|
||||||
br.Avatar = gotemplate.HTML(avatar)
|
br.Avatar = gotemplate.HTML(avatar)
|
||||||
br.RepoLink = repoLink
|
br.RepoLink = repoLink
|
||||||
br.PartSha = part.Sha
|
br.PartSha = part.Sha
|
||||||
br.PreviousSha = previousSha
|
br.PreviousSha = part.PreviousSha
|
||||||
br.PreviousShaURL = fmt.Sprintf("%s/blame/commit/%s/%s", repoLink, url.PathEscape(previousSha), util.PathEscapeSegments(ctx.Repo.TreePath))
|
br.PreviousShaURL = fmt.Sprintf("%s/blame/commit/%s/%s", repoLink, url.PathEscape(part.PreviousSha), util.PathEscapeSegments(part.PreviousPath))
|
||||||
br.CommitURL = fmt.Sprintf("%s/commit/%s", repoLink, url.PathEscape(part.Sha))
|
br.CommitURL = fmt.Sprintf("%s/commit/%s", repoLink, url.PathEscape(part.Sha))
|
||||||
br.CommitMessage = commit.CommitMessage
|
br.CommitMessage = commit.CommitMessage
|
||||||
br.CommitSince = commitSince
|
br.CommitSince = commitSince
|
||||||
|
|
|
@ -1309,7 +1309,7 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use
|
||||||
return roleDescriptor, err
|
return roleDescriptor, err
|
||||||
} else if hasMergedPR {
|
} else if hasMergedPR {
|
||||||
roleDescriptor.RoleInRepo = issues_model.RoleRepoContributor
|
roleDescriptor.RoleInRepo = issues_model.RoleRepoContributor
|
||||||
} else {
|
} else if issue.IsPull {
|
||||||
// only display first time contributor in the first opening pull request
|
// only display first time contributor in the first opening pull request
|
||||||
roleDescriptor.RoleInRepo = issues_model.RoleRepoFirstTimeContributor
|
roleDescriptor.RoleInRepo = issues_model.RoleRepoFirstTimeContributor
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,21 +702,14 @@ func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) {
|
||||||
}
|
}
|
||||||
for _, entry := range allEntries {
|
for _, entry := range allEntries {
|
||||||
if entry.Name() == "CITATION.cff" || entry.Name() == "CITATION.bib" {
|
if entry.Name() == "CITATION.cff" || entry.Name() == "CITATION.bib" {
|
||||||
ctx.Data["CitiationExist"] = true
|
|
||||||
// Read Citation file contents
|
// Read Citation file contents
|
||||||
blob := entry.Blob()
|
if content, err := entry.Blob().GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
|
||||||
dataRc, err := blob.DataAsync()
|
log.Error("checkCitationFile: GetBlobContent: %v", err)
|
||||||
if err != nil {
|
} else {
|
||||||
ctx.ServerError("DataAsync", err)
|
ctx.Data["CitiationExist"] = true
|
||||||
return
|
ctx.PageData["citationFileContent"] = content
|
||||||
|
break
|
||||||
}
|
}
|
||||||
defer dataRc.Close()
|
|
||||||
ctx.PageData["citationFileContent"], err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetBlobContent", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,6 +295,10 @@ func Milestones(ctx *context.Context) {
|
||||||
return !showRepoIds.Contains(v)
|
return !showRepoIds.Contains(v)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// This is to ensure that testing the expected pagination link is stable.
|
||||||
|
// As there's no guarantee of order.
|
||||||
|
slices.Sort(repoIDs)
|
||||||
|
|
||||||
var pagerCount int
|
var pagerCount int
|
||||||
if isShowClosed {
|
if isShowClosed {
|
||||||
ctx.Data["State"] = "closed"
|
ctx.Data["State"] = "closed"
|
||||||
|
@ -315,9 +319,18 @@ func Milestones(ctx *context.Context) {
|
||||||
ctx.Data["RepoIDs"] = repoIDs
|
ctx.Data["RepoIDs"] = repoIDs
|
||||||
ctx.Data["IsShowClosed"] = isShowClosed
|
ctx.Data["IsShowClosed"] = isShowClosed
|
||||||
|
|
||||||
|
// Convert []int64 to string
|
||||||
|
reposParam, err := json.Marshal(repoIDs)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("json.Marshal", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Data["ReposParam"] = string(reposParam)
|
||||||
|
|
||||||
pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5)
|
pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5)
|
||||||
pager.AddParam(ctx, "q", "Keyword")
|
pager.AddParam(ctx, "q", "Keyword")
|
||||||
pager.AddParam(ctx, "repos", "RepoIDs")
|
pager.AddParam(ctx, "repos", "ReposParam")
|
||||||
pager.AddParam(ctx, "sort", "SortType")
|
pager.AddParam(ctx, "sort", "SortType")
|
||||||
pager.AddParam(ctx, "state", "State")
|
pager.AddParam(ctx, "state", "State")
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
|
@ -690,7 +703,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert []int64 to string
|
// Convert []int64 to string
|
||||||
reposParam, _ := json.Marshal(opts.RepoIDs)
|
reposParam, err := json.Marshal(selectedRepoIDs)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("json.Marshal", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["ReposParam"] = string(reposParam)
|
ctx.Data["ReposParam"] = string(reposParam)
|
||||||
|
|
||||||
|
|
|
@ -130,3 +130,25 @@ func (r *indexerNotifier) IssueChangeTitle(ctx context.Context, doer *user_model
|
||||||
func (r *indexerNotifier) IssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) {
|
func (r *indexerNotifier) IssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) {
|
||||||
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *indexerNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
|
||||||
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *indexerNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
|
||||||
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *indexerNotifier) IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
|
||||||
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *indexerNotifier) IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
|
||||||
|
addedLabels, removedLabels []*issues_model.Label,
|
||||||
|
) {
|
||||||
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *indexerNotifier) IssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
|
||||||
|
issue_indexer.UpdateIssueIndexer(ctx, issue.ID)
|
||||||
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ func mailNewUser(ctx context.Context, u *user_model.User, lang string, tos []str
|
||||||
"Subject": subject,
|
"Subject": subject,
|
||||||
"Body": body,
|
"Body": body,
|
||||||
"Language": locale.Language(),
|
"Language": locale.Language(),
|
||||||
"locale": locale,
|
"Locale": locale,
|
||||||
"Str2html": templates.Str2html,
|
"Str2html": templates.Str2html,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,22 +6,25 @@ package mailer
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/translation"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getTestUsers() []*user_model.User {
|
func getTestUsers(t *testing.T) []*user_model.User {
|
||||||
|
t.Helper()
|
||||||
admin := new(user_model.User)
|
admin := new(user_model.User)
|
||||||
admin.Name = "admin"
|
admin.Name = "testadmin"
|
||||||
admin.IsAdmin = true
|
admin.IsAdmin = true
|
||||||
admin.Language = "en_US"
|
admin.Language = "en_US"
|
||||||
admin.Email = "admin@example.com"
|
admin.Email = "admin@example.com"
|
||||||
|
require.NoError(t, user_model.CreateUser(db.DefaultContext, admin))
|
||||||
|
|
||||||
newUser := new(user_model.User)
|
newUser := new(user_model.User)
|
||||||
newUser.Name = "new_user"
|
newUser.Name = "new_user"
|
||||||
|
@ -30,15 +33,9 @@ func getTestUsers() []*user_model.User {
|
||||||
newUser.Email = "new_user@example.com"
|
newUser.Email = "new_user@example.com"
|
||||||
newUser.LastLoginUnix = 1693648327
|
newUser.LastLoginUnix = 1693648327
|
||||||
newUser.CreatedUnix = 1693648027
|
newUser.CreatedUnix = 1693648027
|
||||||
|
require.NoError(t, user_model.CreateUser(db.DefaultContext, newUser))
|
||||||
|
|
||||||
user_model.CreateUser(db.DefaultContext, admin)
|
return []*user_model.User{admin, newUser}
|
||||||
user_model.CreateUser(db.DefaultContext, newUser)
|
|
||||||
|
|
||||||
users := make([]*user_model.User, 0)
|
|
||||||
users = append(users, admin)
|
|
||||||
users = append(users, newUser)
|
|
||||||
|
|
||||||
return users
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanUpUsers(ctx context.Context, users []*user_model.User) {
|
func cleanUpUsers(ctx context.Context, users []*user_model.User) {
|
||||||
|
@ -48,6 +45,12 @@ func cleanUpUsers(ctx context.Context, users []*user_model.User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdminNotificationMail_test(t *testing.T) {
|
func TestAdminNotificationMail_test(t *testing.T) {
|
||||||
|
translation.InitLocales(context.Background())
|
||||||
|
locale := translation.NewLocale("")
|
||||||
|
key := "mail.admin.new_user.user_info"
|
||||||
|
translatedKey := locale.Tr(key)
|
||||||
|
require.NotEqualValues(t, key, translatedKey)
|
||||||
|
|
||||||
mailService := setting.Mailer{
|
mailService := setting.Mailer{
|
||||||
From: "test@example.com",
|
From: "test@example.com",
|
||||||
Protocol: "dummy",
|
Protocol: "dummy",
|
||||||
|
@ -63,20 +66,28 @@ func TestAdminNotificationMail_test(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
NewContext(ctx)
|
NewContext(ctx)
|
||||||
|
|
||||||
users := getTestUsers()
|
users := getTestUsers(t)
|
||||||
oldSendAsync := sa
|
oldSendAsync := sa
|
||||||
defer func() {
|
defer func() {
|
||||||
sa = oldSendAsync
|
sa = oldSendAsync
|
||||||
cleanUpUsers(ctx, users)
|
cleanUpUsers(ctx, users)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
called := false
|
||||||
sa = func(msgs ...*Message) {
|
sa = func(msgs ...*Message) {
|
||||||
assert.Equal(t, len(msgs), 1, "Test provides only one admin user, so only one email must be sent")
|
assert.Equal(t, len(msgs), 1, "Test provides only one admin user, so only one email must be sent")
|
||||||
assert.Equal(t, msgs[0].To, users[0].Email, "checks if the recipient is the admin of the instance")
|
assert.Equal(t, msgs[0].To, users[0].Email, "checks if the recipient is the admin of the instance")
|
||||||
manageUserURL := "/admin/users/" + strconv.FormatInt(users[1].ID, 10)
|
manageUserURL := "/admin/users/" + strconv.FormatInt(users[1].ID, 10)
|
||||||
assert.True(t, strings.ContainsAny(msgs[0].Body, manageUserURL), "checks if the message contains the link to manage the newly created user from the admin panel")
|
assert.Contains(t, msgs[0].Body, manageUserURL)
|
||||||
|
assert.Contains(t, msgs[0].Body, translatedKey, "the .Locale translates to nothing")
|
||||||
|
assert.Contains(t, msgs[0].Body, users[1].Name, "user name of the newly created user")
|
||||||
|
for _, untranslated := range []string{"mail.admin", "admin.users"} {
|
||||||
|
assert.NotContains(t, msgs[0].Body, untranslated, "this is an untranslated placeholder prefix")
|
||||||
|
}
|
||||||
|
called = true
|
||||||
}
|
}
|
||||||
MailNewUser(ctx, users[1])
|
MailNewUser(ctx, users[1])
|
||||||
|
assert.True(t, called)
|
||||||
|
|
||||||
// test with SEND_NOTIFICATION_EMAIL_ON_NEW_USER disabled; emails shouldn't be sent
|
// test with SEND_NOTIFICATION_EMAIL_ON_NEW_USER disabled; emails shouldn't be sent
|
||||||
setting.Admin.SendNotificationEmailOnNewUser = false
|
setting.Admin.SendNotificationEmailOnNewUser = false
|
||||||
|
|
20
services/migrations/forgejo_downloader.go
Normal file
20
services/migrations/forgejo_downloader.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2023 The Forgejo Authors
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterDownloaderFactory(&ForgejoDownloaderFactory{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForgejoDownloaderFactory struct {
|
||||||
|
GiteaDownloaderFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ForgejoDownloaderFactory) GitServiceType() structs.GitServiceType {
|
||||||
|
return structs.ForgejoService
|
||||||
|
}
|
|
@ -867,7 +867,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
|
||||||
line := comment.Line
|
line := comment.Line
|
||||||
if line != 0 {
|
if line != 0 {
|
||||||
comment.Position = 1
|
comment.Position = 1
|
||||||
} else {
|
} else if comment.DiffHunk != "" {
|
||||||
_, _, line, _ = git.ParseDiffHunkString(comment.DiffHunk)
|
_, _, line, _ = git.ParseDiffHunkString(comment.DiffHunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,17 +57,18 @@ func (f *GitlabDownloaderFactory) GitServiceType() structs.GitServiceType {
|
||||||
|
|
||||||
// GitlabDownloader implements a Downloader interface to get repository information
|
// GitlabDownloader implements a Downloader interface to get repository information
|
||||||
// from gitlab via go-gitlab
|
// from gitlab via go-gitlab
|
||||||
// - issueCount is incremented in GetIssues() to ensure PR and Issue numbers do not overlap,
|
// - maxIssueNumber is the maximum issue number seen, updated in GetIssues() to ensure PR and Issue numbers do not overlap,
|
||||||
// because Gitlab has individual Issue and Pull Request numbers.
|
// because Gitlab has individual Issue and Pull Request numbers.
|
||||||
|
// Note that because some issue numbers may be skipped, this number may be greater than the total number of issues
|
||||||
type GitlabDownloader struct {
|
type GitlabDownloader struct {
|
||||||
base.NullDownloader
|
base.NullDownloader
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
client *gitlab.Client
|
client *gitlab.Client
|
||||||
baseURL string
|
baseURL string
|
||||||
repoID int
|
repoID int
|
||||||
repoName string
|
repoName string
|
||||||
issueCount int64
|
maxIssueNumber int64
|
||||||
maxPerPage int
|
maxPerPage int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGitlabDownloader creates a gitlab Downloader via gitlab API
|
// NewGitlabDownloader creates a gitlab Downloader via gitlab API
|
||||||
|
@ -450,8 +451,8 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
|
||||||
Context: gitlabIssueContext{IsMergeRequest: false},
|
Context: gitlabIssueContext{IsMergeRequest: false},
|
||||||
})
|
})
|
||||||
|
|
||||||
// increment issueCount, to be used in GetPullRequests()
|
// update maxIssueNumber, to be used in GetPullRequests()
|
||||||
g.issueCount++
|
g.maxIssueNumber = max(g.maxIssueNumber, int64(issue.IID))
|
||||||
}
|
}
|
||||||
|
|
||||||
return allIssues, len(issues) < perPage, nil
|
return allIssues, len(issues) < perPage, nil
|
||||||
|
@ -595,7 +596,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the PR ID to the Issue Count because PR and Issues share ID space in Gitea
|
// Add the PR ID to the Issue Count because PR and Issues share ID space in Gitea
|
||||||
newPRNumber := g.issueCount + int64(pr.IID)
|
newPRNumber := g.maxIssueNumber + int64(pr.IID)
|
||||||
|
|
||||||
allPRs = append(allPRs, &base.PullRequest{
|
allPRs = append(allPRs, &base.PullRequest{
|
||||||
Title: pr.Title,
|
Title: pr.Title,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/unittest"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
base "code.gitea.io/gitea/modules/migration"
|
base "code.gitea.io/gitea/modules/migration"
|
||||||
|
|
||||||
|
@ -21,18 +22,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGitlabDownloadRepo(t *testing.T) {
|
func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
// Skip tests if Gitlab token is not found
|
// If a GitLab access token is provided, this test will make HTTP requests to the live gitlab.com instance.
|
||||||
|
// When doing so, the responses from gitlab.com will be saved as test data files.
|
||||||
|
// If no access token is available, those cached responses will be used instead.
|
||||||
gitlabPersonalAccessToken := os.Getenv("GITLAB_READ_TOKEN")
|
gitlabPersonalAccessToken := os.Getenv("GITLAB_READ_TOKEN")
|
||||||
if gitlabPersonalAccessToken == "" {
|
fixturePath := "./testdata/gitlab/full_download"
|
||||||
t.Skip("skipped test because GITLAB_READ_TOKEN was not in the environment")
|
server := unittest.NewMockWebServer(t, "https://gitlab.com", fixturePath, gitlabPersonalAccessToken != "")
|
||||||
}
|
defer server.Close()
|
||||||
|
|
||||||
resp, err := http.Get("https://gitlab.com/gitea/test_repo")
|
downloader, err := NewGitlabDownloader(context.Background(), server.URL, "gitea/test_repo", "", "", gitlabPersonalAccessToken)
|
||||||
if err != nil || resp.StatusCode != http.StatusOK {
|
|
||||||
t.Skipf("Can't access test repo, skipping %s", t.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
downloader, err := NewGitlabDownloader(context.Background(), "https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewGitlabDownloader is nil: %v", err)
|
t.Fatalf("NewGitlabDownloader is nil: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -43,8 +41,8 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
Name: "test_repo",
|
Name: "test_repo",
|
||||||
Owner: "",
|
Owner: "",
|
||||||
Description: "Test repository for testing migration from gitlab to gitea",
|
Description: "Test repository for testing migration from gitlab to gitea",
|
||||||
CloneURL: "https://gitlab.com/gitea/test_repo.git",
|
CloneURL: server.URL + "/gitea/test_repo.git",
|
||||||
OriginalURL: "https://gitlab.com/gitea/test_repo",
|
OriginalURL: server.URL + "/gitea/test_repo",
|
||||||
DefaultBranch: "master",
|
DefaultBranch: "master",
|
||||||
}, repo)
|
}, repo)
|
||||||
|
|
||||||
|
@ -281,10 +279,10 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
UserName: "real6543",
|
UserName: "real6543",
|
||||||
Content: "tada",
|
Content: "tada",
|
||||||
}},
|
}},
|
||||||
PatchURL: "https://gitlab.com/gitea/test_repo/-/merge_requests/2.patch",
|
PatchURL: server.URL + "/gitea/test_repo/-/merge_requests/2.patch",
|
||||||
Head: base.PullRequestBranch{
|
Head: base.PullRequestBranch{
|
||||||
Ref: "feat/test",
|
Ref: "feat/test",
|
||||||
CloneURL: "https://gitlab.com/gitea/test_repo/-/merge_requests/2",
|
CloneURL: server.URL + "/gitea/test_repo/-/merge_requests/2",
|
||||||
SHA: "9f733b96b98a4175276edf6a2e1231489c3bdd23",
|
SHA: "9f733b96b98a4175276edf6a2e1231489c3bdd23",
|
||||||
RepoName: "test_repo",
|
RepoName: "test_repo",
|
||||||
OwnerName: "lafriks",
|
OwnerName: "lafriks",
|
||||||
|
@ -309,16 +307,16 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
assertReviewsEqual(t, []*base.Review{
|
assertReviewsEqual(t, []*base.Review{
|
||||||
{
|
{
|
||||||
IssueIndex: 1,
|
IssueIndex: 1,
|
||||||
ReviewerID: 4102996,
|
ReviewerID: 527793,
|
||||||
ReviewerName: "zeripath",
|
ReviewerName: "axifive",
|
||||||
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
CreatedAt: time.Date(2019, 11, 28, 8, 54, 41, 34000000, time.UTC),
|
||||||
State: "APPROVED",
|
State: "APPROVED",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
IssueIndex: 1,
|
IssueIndex: 1,
|
||||||
ReviewerID: 527793,
|
ReviewerID: 4102996,
|
||||||
ReviewerName: "axifive",
|
ReviewerName: "zeripath",
|
||||||
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
CreatedAt: time.Date(2019, 11, 28, 8, 54, 41, 34000000, time.UTC),
|
||||||
State: "APPROVED",
|
State: "APPROVED",
|
||||||
},
|
},
|
||||||
}, rvs)
|
}, rvs)
|
||||||
|
@ -330,12 +328,55 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
IssueIndex: 2,
|
IssueIndex: 2,
|
||||||
ReviewerID: 4575606,
|
ReviewerID: 4575606,
|
||||||
ReviewerName: "real6543",
|
ReviewerName: "real6543",
|
||||||
CreatedAt: time.Date(2020, 4, 19, 19, 24, 21, 108000000, time.UTC),
|
CreatedAt: time.Date(2019, 11, 28, 15, 56, 54, 108000000, time.UTC),
|
||||||
State: "APPROVED",
|
State: "APPROVED",
|
||||||
},
|
},
|
||||||
}, rvs)
|
}, rvs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGitlabSkippedIssueNumber(t *testing.T) {
|
||||||
|
// If a GitLab access token is provided, this test will make HTTP requests to the live gitlab.com instance.
|
||||||
|
// When doing so, the responses from gitlab.com will be saved as test data files.
|
||||||
|
// If no access token is available, those cached responses will be used instead.
|
||||||
|
gitlabPersonalAccessToken := os.Getenv("GITLAB_READ_TOKEN")
|
||||||
|
fixturePath := "./testdata/gitlab/skipped_issue_number"
|
||||||
|
server := unittest.NewMockWebServer(t, "https://gitlab.com", fixturePath, gitlabPersonalAccessToken != "")
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
downloader, err := NewGitlabDownloader(context.Background(), server.URL, "troyengel/archbuild", "", "", gitlabPersonalAccessToken)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewGitlabDownloader is nil: %v", err)
|
||||||
|
}
|
||||||
|
repo, err := downloader.GetRepoInfo()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertRepositoryEqual(t, &base.Repository{
|
||||||
|
Name: "archbuild",
|
||||||
|
Owner: "troyengel",
|
||||||
|
Description: "Arch packaging and build files",
|
||||||
|
CloneURL: server.URL + "/troyengel/archbuild.git",
|
||||||
|
OriginalURL: server.URL + "/troyengel/archbuild",
|
||||||
|
DefaultBranch: "master",
|
||||||
|
}, repo)
|
||||||
|
|
||||||
|
issues, isEnd, err := downloader.GetIssues(1, 10)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, isEnd)
|
||||||
|
|
||||||
|
// the only issue in this repository has number 2
|
||||||
|
assert.EqualValues(t, 1, len(issues))
|
||||||
|
assert.EqualValues(t, 2, issues[0].Number)
|
||||||
|
assert.EqualValues(t, "vpn unlimited errors", issues[0].Title)
|
||||||
|
|
||||||
|
prs, _, err := downloader.GetPullRequests(1, 10)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// the only merge request in this repository has number 1,
|
||||||
|
// but we offset it by the maximum issue number so it becomes
|
||||||
|
// pull request 3 in Forgejo
|
||||||
|
assert.EqualValues(t, 1, len(prs))
|
||||||
|
assert.EqualValues(t, 3, prs[0].Number)
|
||||||
|
assert.EqualValues(t, "Review", prs[0].Title)
|
||||||
|
}
|
||||||
|
|
||||||
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
|
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
|
||||||
// mux is the HTTP request multiplexer used with the test server.
|
// mux is the HTTP request multiplexer used with the test server.
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026
vendored
Normal file
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Gitlab-Lb: haproxy-main-20-lb-gprd
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Server: cloudflare
|
||||||
|
Set-Cookie: _cfuvid=B8MjUX35S.9gzhNVFW.tUMZhMCWSro7kxdL8zYdOSdE-1701175752950-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:12 GMT
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=zfW56h3iMmcrXW4Isy7oE34xI2hcyFtpb6ZRXF8Y576uz3oFoGx89kE%2B%2FKsyRYv31WVcXkrj1njz2sip5F8D4fwbjpFGzijtAlHezacLgnL%2BuhTON0YgFp0iEyZKtxRGM6hOvTYISJM%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Cf-Ray: 82d2bac66b8d36e0-FRA
|
||||||
|
Etag: W/"3cacfe29f44a69e84a577337eac55d89"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"8dcf1672ae472d596d8e52a70e4e92f7","version":"1"}
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
X-Request-Id: 8dcf1672ae472d596d8e52a70e4e92f7
|
||||||
|
X-Runtime: 0.117723
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
{"id":15578026,"description":"Test repository for testing migration from gitlab to gitea","name":"test_repo","name_with_namespace":"gitea / test_repo","path":"test_repo","path_with_namespace":"gitea/test_repo","created_at":"2019-11-28T08:20:33.019Z","default_branch":"master","tag_list":["migration","test"],"topics":["migration","test"],"ssh_url_to_repo":"git@gitlab.com:gitea/test_repo.git","http_url_to_repo":"https://gitlab.com/gitea/test_repo.git","web_url":"https://gitlab.com/gitea/test_repo","readme_url":"https://gitlab.com/gitea/test_repo/-/blob/master/README.md","forks_count":1,"avatar_url":null,"star_count":0,"last_activity_at":"2020-04-19T19:46:04.527Z","namespace":{"id":3181312,"name":"gitea","path":"gitea","kind":"group","full_path":"gitea","parent_id":null,"avatar_url":"/uploads/-/system/group/avatar/3181312/gitea.png","web_url":"https://gitlab.com/groups/gitea"},"container_registry_image_prefix":"registry.gitlab.com/gitea/test_repo","_links":{"self":"https://gitlab.com/api/v4/projects/15578026","issues":"https://gitlab.com/api/v4/projects/15578026/issues","merge_requests":"https://gitlab.com/api/v4/projects/15578026/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/15578026/repository/branches","labels":"https://gitlab.com/api/v4/projects/15578026/labels","events":"https://gitlab.com/api/v4/projects/15578026/events","members":"https://gitlab.com/api/v4/projects/15578026/members","cluster_agents":"https://gitlab.com/api/v4/projects/15578026/cluster_agents"},"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1241334,"import_status":"none","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:58\" dir=\"auto\"\u003eTest repository for testing migration from gitlab to gitea\u003c/p\u003e","updated_at":"2022-08-26T19:41:46.691Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"ff","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
|
|
@ -0,0 +1,30 @@
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues?id=15578026&order_by=created_at&page=1&per_page=2&sort=asc&state=all&with_labels_details=false>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues?id=15578026&order_by=created_at&page=1&per_page=2&sort=asc&state=all&with_labels_details=false>; rel="last"
|
||||||
|
X-Runtime: 0.159122
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Ray: 82d2bad3084536e0-FRA
|
||||||
|
X-Page: 1
|
||||||
|
Server: cloudflare
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:15 GMT
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Next-Page:
|
||||||
|
Etag: W/"4c0531a3595f741f229f5a105e013b95"
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Prev-Page:
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Set-Cookie: _cfuvid=2r5.2KKcEaduxzeG8mTqeefWM9VWUOxTEnR.39DvYRE-1701175755017-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"9f580eca2b094d4791d372c37bf78ddb","version":"1"}
|
||||||
|
X-Per-Page: 2
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Gitlab-Lb: haproxy-main-14-lb-gprd
|
||||||
|
X-Request-Id: 9f580eca2b094d4791d372c37bf78ddb
|
||||||
|
X-Total: 2
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=9E7OZqlUQ62jqWuT3%2B6gdy6JarFz57SLgPf3vVE%2F9kY39EHL700%2FCXWmYicztZ2RKW8FeEfKYiVXLRA4bOd6eSeEfx3h6yDeDffXHOc7otZ5nj7v6tRtGxIeMMpntykH9RwYbNYR0LY%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[{"id":27687675,"iid":1,"project_id":15578026,"title":"Please add an animated gif icon to the merge button","description":"I just want the merge button to hurt my eyes a little. :stuck_out_tongue_closed_eyes:","state":"closed","created_at":"2019-11-28T08:43:35.459Z","updated_at":"2019-11-28T08:46:23.304Z","closed_at":"2019-11-28T08:46:23.275Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["bug","discussion"],"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":0,"merge_requests_count":0,"upvotes":1,"downvotes":0,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/1","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/1","notes":"https://gitlab.com/api/v4/projects/15578026/issues/1/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#1","relative":"#1","full":"gitea/test_repo#1"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null},{"id":27687706,"iid":2,"project_id":15578026,"title":"Test issue","description":"This is test issue 2, do not touch!","state":"closed","created_at":"2019-11-28T08:44:46.277Z","updated_at":"2019-11-28T08:45:44.987Z","closed_at":"2019-11-28T08:45:44.959Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["duplicate"],"milestone":{"id":1082927,"iid":2,"project_id":15578026,"title":"1.1.0","description":"","state":"active","created_at":"2019-11-28T08:42:44.575Z","updated_at":"2019-11-28T08:42:44.575Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/2"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":2,"merge_requests_count":0,"upvotes":1,"downvotes":1,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/2","notes":"https://gitlab.com/api/v4/projects/15578026/issues/2/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#2","relative":"#2","full":"gitea/test_repo#2"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Content-Type: application/json
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji?id=15578026&issue_iid=1&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji?id=15578026&issue_iid=1&page=1&per_page=2>; rel="last"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"e7004439ffc110c87370872a44c60a0c","version":"1"}
|
||||||
|
X-Next-Page:
|
||||||
|
Cf-Ray: 82d2bad50a5036e0-FRA
|
||||||
|
X-Total: 2
|
||||||
|
Gitlab-Lb: haproxy-main-05-lb-gprd
|
||||||
|
Server: cloudflare
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Per-Page: 2
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:15 GMT
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Page: 1
|
||||||
|
X-Runtime: 0.083400
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=FGgIHqeMkQfVcvYR2OvVkGghGfBMCX7OdZP2R9KPX1C1EbqhK5Q91enyHfOB%2FTPE1tavm%2FrQjCVlC1DpczhDkA3dDQ%2FXnEMsgNdKSCPMI6XY9Q5UwNUliA%2FIQmrvb8BLBjFcZQuf0qA%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
X-Request-Id: e7004439ffc110c87370872a44c60a0c
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Set-Cookie: _cfuvid=FTUGd2.HvTbs3C.AqBngn4_DMsUeKKDVU2iUlk9AYC0-1701175755249-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Etag: W/"69c922434ed11248c864d157eb8eabfc"
|
||||||
|
X-Total-Pages: 1
|
||||||
|
X-Prev-Page:
|
||||||
|
|
||||||
|
[{"id":3009580,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:43:40.322Z","updated_at":"2019-11-28T08:43:40.322Z","awardable_id":27687675,"awardable_type":"Issue","url":null},{"id":3009585,"name":"open_mouth","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:01.902Z","updated_at":"2019-11-28T08:44:01.902Z","awardable_id":27687675,"awardable_type":"Issue","url":null}]
|
|
@ -0,0 +1,32 @@
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji?id=15578026&issue_iid=1&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji?id=15578026&issue_iid=1&page=1&per_page=2>; rel="last"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"f20460891555dcf146d340bc54a11b6d","version":"1"}
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Server: cloudflare
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:15 GMT
|
||||||
|
X-Page: 2
|
||||||
|
X-Per-Page: 2
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Content-Length: 2
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=Bkk22CNDQrv7p4D3Bv61f2WkW%2BWU1E3RioJZfjI%2BPxqDwi5NRfqpkRR795HhnUvCND5Sbk9cWJnET5ewf7YSCIpRBjsuxeG8sb2iRg4lkEOYTxiJphQ7EEbqaZh8Bxj3U3pcUezUjgk%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Set-Cookie: _cfuvid=x26H_NQHx0V8bDfYro78pCd.h0i8fyYb8Vlqpq324ZM-1701175755696-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Next-Page:
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Cf-Ray: 82d2bad66c0336e0-FRA
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Prev-Page:
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
X-Request-Id: f20460891555dcf146d340bc54a11b6d
|
||||||
|
X-Runtime: 0.289453
|
||||||
|
X-Total: 2
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Lb: haproxy-main-11-lb-gprd
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=2&per_page=2>; rel="next", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=3&per_page=2>; rel="last"
|
||||||
|
X-Page: 1
|
||||||
|
X-Runtime: 0.115916
|
||||||
|
X-Total: 6
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=ADEmtI0JuDZjWVSHJOsQaMLciy9VlKx99GnnvJCu3dhruUwvZtlaumIg66Rp11DfZ%2FVwF4ccEdcWkFGB1WRhHZ6l2l4QHSd7XynqUquDn0NIlCPRAMKdUcu5IVoxQ4I0eLLlnC6YjRM%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Server: cloudflare
|
||||||
|
Cf-Ray: 82d2bad93ec736e0-FRA
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"4e94ae6766e981799b1cb058e123531d","version":"1"}
|
||||||
|
X-Per-Page: 2
|
||||||
|
X-Request-Id: 4e94ae6766e981799b1cb058e123531d
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Set-Cookie: _cfuvid=dSnltVw8Zz3q9EeG6JoHz.E2rKQJrf8TJpuY.TK4R3M-1701175755959-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Gitlab-Lb: haproxy-main-35-lb-gprd
|
||||||
|
Content-Type: application/json
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:15 GMT
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Prev-Page:
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"5fdbcbf64f34ba0e74ce9dd8d6e0efe3"
|
||||||
|
X-Next-Page: 2
|
||||||
|
X-Total-Pages: 3
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[{"id":3009627,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:42.657Z","updated_at":"2019-11-28T08:46:42.657Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009628,"name":"thumbsdown","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:43.471Z","updated_at":"2019-11-28T08:46:43.471Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
X-Page: 2
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:16 GMT
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Server: cloudflare
|
||||||
|
Cf-Ray: 82d2badaf87c36e0-FRA
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Prev-Page: 1
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Set-Cookie: _cfuvid=oMXmuUzJyrMWnL7AZ6Rv_LEdPzTtTDXYj5QeS2aWgMk-1701175756551-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"c870b177189ee30c89f8a2a9b4e73dd1","version":"1"}
|
||||||
|
X-Request-Id: c870b177189ee30c89f8a2a9b4e73dd1
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=1&per_page=2>; rel="prev", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=3&per_page=2>; rel="next", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=3&per_page=2>; rel="last"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Per-Page: 2
|
||||||
|
X-Runtime: 0.127639
|
||||||
|
X-Total: 6
|
||||||
|
Etag: W/"d16c513b32212d9286fce6f53340c1cf"
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
X-Next-Page: 3
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Lb: haproxy-main-36-lb-gprd
|
||||||
|
Gitlab-Sv: api-gke-us-east1-b
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=%2FI0CdRwNeg7W0N4yZ3QhDC3KMI8IjKMzE6bBxxqRFc6PHF2Ch%2BTeGF2V6is9KAA5oiX4gUEk%2BYmceKQAWx2LoTkixvqjkFN7ygCEAfh44HwZ%2FM7pxUGD7uUUAycRKNhFNhfMQCyikpM%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Total-Pages: 3
|
||||||
|
|
||||||
|
[{"id":3009632,"name":"laughing","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:14.381Z","updated_at":"2019-11-28T08:47:14.381Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009634,"name":"tada","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:18.254Z","updated_at":"2019-11-28T08:47:18.254Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Per-Page: 2
|
||||||
|
X-Runtime: 0.064908
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Set-Cookie: _cfuvid=ZjDbW2vPFo78ylQFSBUBFxG52YQDettE8ToOtGdjcuA-1701175757074-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Page: 3
|
||||||
|
X-Prev-Page: 2
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"165d37bf09a54bb31f4619cca8722cb4"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=O88Hv3gnBHSRVnjU6A0vZz9VFYLkUI2aW%2FZiC26Tgu35WHtO9UsoGZNnTsQZ6jmsJvi8UX2jNHScalDn4%2FcjYk32GTcBYx6sHTz4tFS2YO4udL%2F1BjJBDG1F%2Br59XlTCgC2RZKSBYGg%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
X-Total-Pages: 3
|
||||||
|
Cf-Ray: 82d2badeac3536e0-FRA
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:17 GMT
|
||||||
|
Gitlab-Lb: haproxy-main-23-lb-gprd
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Request-Id: 23c23dd0a05c4fc887a2090ed880e0cf
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Server: cloudflare
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"23c23dd0a05c4fc887a2090ed880e0cf","version":"1"}
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=2&per_page=2>; rel="prev", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=3&per_page=2>; rel="last"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Next-Page:
|
||||||
|
X-Total: 6
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
|
||||||
|
[{"id":3009636,"name":"confused","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:27.248Z","updated_at":"2019-11-28T08:47:27.248Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009640,"name":"hearts","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:33.059Z","updated_at":"2019-11-28T08:47:33.059Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
|
|
@ -0,0 +1,32 @@
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Sv: api-gke-us-east1-b
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Total: 6
|
||||||
|
X-Total-Pages: 3
|
||||||
|
Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
X-Next-Page:
|
||||||
|
X-Page: 4
|
||||||
|
X-Runtime: 0.084379
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Request-Id: 3236d6ec6845224f284a741528203ece
|
||||||
|
Cf-Ray: 82d2bae1df9036e0-FRA
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"3236d6ec6845224f284a741528203ece","version":"1"}
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=KylRcRbE8E7pfR1zdRiqiCe5Tq%2FCqFKgyO01E7o9yLEtU1tW7Xi2PGPau9SZasTalmgkxUeyKWymp%2BE2ClVxldnQom%2BpoAMgccEtFGhHWOTsNyfiI%2B0NbOpytx%2Bf1%2BZLyf0vV84%2FuSQ%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=1&per_page=2>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji?id=15578026&issue_iid=2&page=3&per_page=2>; rel="last"
|
||||||
|
X-Per-Page: 2
|
||||||
|
X-Prev-Page:
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Gitlab-Lb: haproxy-main-33-lb-gprd
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:17 GMT
|
||||||
|
Content-Length: 2
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Set-Cookie: _cfuvid=aeqVJxNjrsFvkPxbn5RmHE1mf1qsFlHnDXahuXTl4FU-1701175757309-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Server: cloudflare
|
||||||
|
|
||||||
|
[]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Next-Page:
|
||||||
|
X-Page: 1
|
||||||
|
X-Request-Id: b9e599712b5bf48889f4823ed0fa7a48
|
||||||
|
X-Runtime: 0.206772
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Etag: W/"bcc91e8a7b2eac98b4d96ae791e0649d"
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/issues/2/discussions?id=15578026¬eable_id=2&page=1&per_page=100>; rel="first", <https://gitlab.com/api/v4/projects/15578026/issues/2/discussions?id=15578026¬eable_id=2&page=1&per_page=100>; rel="last"
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"b9e599712b5bf48889f4823ed0fa7a48","version":"1"}
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Server: cloudflare
|
||||||
|
Set-Cookie: _cfuvid=D83dc_PGYBYEnaF84X545Fe9FtHn5aPGRxVc5ZgBzQI-1701175757669-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Per-Page: 100
|
||||||
|
X-Total: 4
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=eUe2Fe%2BfauPaulXPbv0BrsPVKsTex9VG99r8umtpujViX5FKUHY0TLekejB1ptkQ5b9sVJcbddSZxmdy28fDpAArAuFrUJ2kCq6cT0NguQYEZMUi97Z2VldHTCwONM72HGZ29k5aqv8%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Gitlab-Lb: haproxy-main-19-lb-gprd
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:17 GMT
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Cf-Ray: 82d2bae349d636e0-FRA
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Prev-Page:
|
||||||
|
|
||||||
|
[{"id":"617967369d98d8b73b6105a40318fe839f931a24","individual_note":true,"notes":[{"id":251637434,"type":null,"body":"This is a comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:52.501Z","updated_at":"2019-11-28T08:44:52.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"b92d74daee411a17d844041bcd3c267ade58f680","individual_note":true,"notes":[{"id":251637528,"type":null,"body":"changed milestone to %2","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:02.329Z","updated_at":"2019-11-28T08:45:02.335Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"6010f567d2b58758ef618070372c97891ac75349","individual_note":true,"notes":[{"id":251637892,"type":null,"body":"closed","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:45.007Z","updated_at":"2019-11-28T08:45:45.010Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"632d0cbfd6a1a08f38aaf9ef7715116f4b188ebb","individual_note":true,"notes":[{"id":251637999,"type":null,"body":"A second comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:53.501Z","updated_at":"2019-11-28T08:45:53.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Total: 9
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Runtime: 0.181345
|
||||||
|
Set-Cookie: _cfuvid=tqgklLOiSYdxU.Rdf6ibHODgg3IHELmncXoiqglyFi8-1701175753621-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Server: cloudflare
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"f7dd6b0d5b6d5a817cc078222a55edd3","version":"1"}
|
||||||
|
Gitlab-Lb: haproxy-main-11-lb-gprd
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/labels?id=15578026&include_ancestor_groups=true&page=1&per_page=100&with_counts=false>; rel="first", <https://gitlab.com/api/v4/projects/15578026/labels?id=15578026&include_ancestor_groups=true&page=1&per_page=100&with_counts=false>; rel="last"
|
||||||
|
X-Prev-Page:
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Next-Page:
|
||||||
|
X-Page: 1
|
||||||
|
X-Per-Page: 100
|
||||||
|
X-Request-Id: f7dd6b0d5b6d5a817cc078222a55edd3
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Cf-Ray: 82d2baca3f9336e0-FRA
|
||||||
|
Etag: W/"5a3fb9bc7b1018070943f4aa1353f8b6"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:13 GMT
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=vBPSME6dCCR0uB6BtpQoxmGck36BNkbw%2FrKW1HdGJUMqb%2BUg2SDK2svgh8Ep9oouUPVRiv2wxThIeNRPuypD32GLZR%2BongLpjwLN1LLypMkr5dbRBzcYdBuQ5gKPT9s7dEx1K6fITxE%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[{"id":12959095,"name":"bug","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959097,"name":"confirmed","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959096,"name":"critical","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959100,"name":"discussion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959098,"name":"documentation","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true},{"id":12959554,"name":"duplicate","description":null,"description_html":"","text_color":"#FFFFFF","color":"#7F8C8D","subscribed":false,"priority":null,"is_project_label":true},{"id":12959102,"name":"enhancement","description":null,"description_html":"","text_color":"#FFFFFF","color":"#5cb85c","subscribed":false,"priority":null,"is_project_label":true},{"id":12959101,"name":"suggestion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959099,"name":"support","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true}]
|
|
@ -0,0 +1,35 @@
|
||||||
|
X-Runtime: 0.140709
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Lb: haproxy-main-25-lb-gprd
|
||||||
|
X-Per-Page: 1
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=Yxfg3VXL84aLa%2B7sASJXNs%2Bv1ryYavIp%2FdWwad7uSmIsVGhd4OECab4q%2FzFypHh1Vx7zawm56cfD8wF8NIxR8D8wkN%2Bzmx8utZg28gMngF21Wg8zgZt4293BcGQ%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Date: Thu, 30 Nov 2023 21:39:53 GMT
|
||||||
|
X-Total: 2
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Set-Cookie: _cfuvid=x8eBh.bCoL4rQUlZEETrbE0Y9oYpby0FkuVaEemtRAw-1701380393077-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Next-Page: 2
|
||||||
|
Server: cloudflare
|
||||||
|
Content-Type: application/json
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"ecee0be27d05191e5dbe8659e53f3291","version":"1"}
|
||||||
|
X-Total-Pages: 2
|
||||||
|
Ratelimit-Reset: 1701380453
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 21:40:53 GMT
|
||||||
|
Etag: W/"74b529e4304f473cdaef7761fe9dd9de"
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=2&per_page=1&sort=desc&state=all&with_labels_details=false&with_merge_status_recheck=false>; rel="next", <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=1&per_page=1&sort=desc&state=all&with_labels_details=false&with_merge_status_recheck=false>; rel="first", <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=2&per_page=1&sort=desc&state=all&with_labels_details=false&with_merge_status_recheck=false>; rel="last"
|
||||||
|
X-Page: 1
|
||||||
|
X-Prev-Page:
|
||||||
|
X-Request-Id: ecee0be27d05191e5dbe8659e53f3291
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Ray: 82e63edf0ff22bcd-FRA
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Ratelimit-Observed: 16
|
||||||
|
Ratelimit-Remaining: 1984
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merged_by":null,"merge_user":null,"merged_at":null,"closed_by":null,"closed_at":null,"target_branch":"master","source_branch":"feat/test","user_notes_count":0,"upvotes":1,"downvotes":0,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"assignees":[],"assignee":null,"reviewers":[],"source_project_id":15578026,"target_project_id":15578026,"labels":["bug"],"draft":false,"work_in_progress":false,"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"merge_when_pipeline_succeeds":false,"merge_status":"can_be_merged","detailed_merge_status":"mergeable","sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","merge_commit_sha":null,"squash_commit_sha":null,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":true,"prepared_at":"2019-11-28T15:56:54.104Z","reference":"!2","references":{"short":"!2","relative":"!2","full":"gitea/test_repo!2"},"web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":true,"squash_on_merge":true,"task_completion_status":{"count":0,"completed_count":0},"has_conflicts":false,"blocking_discussions_resolved":true,"approvals_before_merge":null}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
X-Page: 1
|
||||||
|
X-Runtime: 0.080106
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Content-Type: application/json
|
||||||
|
Etag: W/"14f72c1f555b0e6348d338190e9e4839"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=2&per_page=1&sort=desc&state=all&view=simple&with_labels_details=false&with_merge_status_recheck=false>; rel="next", <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=1&per_page=1&sort=desc&state=all&view=simple&with_labels_details=false&with_merge_status_recheck=false>; rel="first", <https://gitlab.com/api/v4/projects/15578026/merge_requests?id=15578026&order_by=created_at&page=2&per_page=1&sort=desc&state=all&view=simple&with_labels_details=false&with_merge_status_recheck=false>; rel="last"
|
||||||
|
X-Per-Page: 1
|
||||||
|
X-Prev-Page:
|
||||||
|
X-Total-Pages: 2
|
||||||
|
Gitlab-Lb: haproxy-main-34-lb-gprd
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
X-Next-Page: 2
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"c2b2e764848cdb6ecf4d8a7d7c922688","version":"1"}
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Server: cloudflare
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Set-Cookie: _cfuvid=M3EZpj9mLuYTgMFWWmkkBGvWpVgZ61toE.mNUK37CMo-1701175757911-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:17 GMT
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Request-Id: c2b2e764848cdb6ecf4d8a7d7c922688
|
||||||
|
X-Total: 2
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=E1Jc0rth%2F2ypS8ir3R%2F4jcUkjOQ42zmaLRUbfdSeHVSKN%2B0F1ilpTeJnxPxgHEtezhKAfhP3unfGLgTyU26LAM45wY3Z%2BYsy9h4zFONERT2DZJ1OnIVBtUytMxGydtA1udhaKGg%2F3GI%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Cf-Ray: 82d2bae59c2b36e0-FRA
|
||||||
|
|
||||||
|
[{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2"}]
|
|
@ -0,0 +1,23 @@
|
||||||
|
X-Request-Id: 39d7aa2a51e4d9f37a03e96b680351e0
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Etag: W/"19aa54b7d4531bd5ab98282e0b772f20"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Set-Cookie: _cfuvid=XhF1L3bWZC2inu9yZkro76aF91u9GJJBnoqyOdufOyI-1701175759569-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"39d7aa2a51e4d9f37a03e96b680351e0","version":"1"}
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Gitlab-Lb: haproxy-main-45-lb-gprd
|
||||||
|
Gitlab-Sv: api-gke-us-east1-b
|
||||||
|
Server: cloudflare
|
||||||
|
Cf-Ray: 82d2baeeed7736e0-FRA
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:19 GMT
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Runtime: 0.255470
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=Gw2KB2oAUyBAoAywnQOt9gnd75FsNNUzAPhzeoPPOYadqEe5fRn1fO8HfI1Arzg%2FFCJlErmAPT1%2Fpru2pqknOR%2BWglTuwSXc4rqB6JMkVKr2clNqtc8bQtQWpYWPSzKk3ah%2BaNm0SeE%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
|
||||||
|
{"id":43486906,"iid":1,"project_id":15578026,"title":"Update README.md","description":"add warning to readme","state":"merged","created_at":"2019-11-28T08:54:41.034Z","updated_at":"2019-11-28T16:02:08.377Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":527793,"username":"axifive","name":"Alexey Terentyev","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/06683cd6b2e2c2ce0ab00fb80cc0729f?s=80\u0026d=identicon","web_url":"https://gitlab.com/axifive"}},{"user":{"id":4102996,"username":"zeripath","name":"zeripath","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/1ae18535c2b1aed798da090448997248?s=80\u0026d=identicon","web_url":"https://gitlab.com/zeripath"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
|
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2
vendored
Normal file
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Request-Id: f0766496f6471b5094feef229598e805
|
||||||
|
Gitlab-Sv: api-gke-us-east1-d
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Runtime: 0.231575
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Set-Cookie: _cfuvid=nPK.Xwtzg2kzeRs.DjmoL3AN1KK0agwAL7PMtFvwWW4-1701175758289-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Server: cloudflare
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Cf-Ray: 82d2bae71d9936e0-FRA
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"f0766496f6471b5094feef229598e805","version":"1"}
|
||||||
|
Gitlab-Lb: haproxy-main-14-lb-gprd
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=YpHQHD49AjdP6A0Ulak9dKotai6JsP7dBztPbxSg1Lf9bA6HmwzSYhC1PU39cGVaAC6B6%2FIJOLNYKBCzWLM%2BSipooPRkP9xvrC5C3rG%2BoMljYnojsOVO%2FRLTavJ%2B0NbBAPsBBMQbWLQ%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:18 GMT
|
||||||
|
Content-Type: application/json
|
||||||
|
Etag: W/"914149155d75f8d8f7ed2e5351f0fadb"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
|
||||||
|
{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merged_by":null,"merge_user":null,"merged_at":null,"closed_by":null,"closed_at":null,"target_branch":"master","source_branch":"feat/test","user_notes_count":0,"upvotes":1,"downvotes":0,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"assignees":[],"assignee":null,"reviewers":[],"source_project_id":15578026,"target_project_id":15578026,"labels":["bug"],"draft":false,"work_in_progress":false,"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"merge_when_pipeline_succeeds":false,"merge_status":"can_be_merged","detailed_merge_status":"mergeable","sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","merge_commit_sha":null,"squash_commit_sha":null,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":true,"prepared_at":"2019-11-28T15:56:54.104Z","reference":"!2","references":{"short":"!2","relative":"!2","full":"gitea/test_repo!2"},"web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":true,"squash_on_merge":true,"task_completion_status":{"count":0,"completed_count":0},"has_conflicts":false,"blocking_discussions_resolved":true,"approvals_before_merge":null,"subscribed":false,"changes_count":"1","latest_build_started_at":null,"latest_build_finished_at":null,"first_deployed_to_production_at":null,"pipeline":null,"head_pipeline":null,"diff_refs":{"base_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83","head_sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","start_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83"},"merge_error":null,"first_contribution":false,"user":{"can_merge":false}}
|
|
@ -0,0 +1,23 @@
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"814f11429b2b91f72eeb08165ab2349c","version":"1"}
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Cf-Ray: 82d2baf16fcb36e0-FRA
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Request-Id: 814f11429b2b91f72eeb08165ab2349c
|
||||||
|
X-Runtime: 0.222724
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Server: cloudflare
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"ce2f774c1b05c5c8a14ec9274444cba3"
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Set-Cookie: _cfuvid=0F0t7Ona1H1_aeSqd5RbpJy.UPCAuw_8RTwbzS5JFDs-1701175759949-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:19 GMT
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Gitlab-Lb: haproxy-main-28-lb-gprd
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=fKmiF%2B4ysmvyUtD1riYc7vhKs%2FhANqYGs7as1gnUhnpj3Av%2BDBMUozQGl8aRk2e5ygs5qR5Fe%2BXaQM%2BhigKFFYKwhxCbFgGGR1ep58ZIq%2FgQjNbq7SG%2Bc0RuIsq1Hj1R1rXLPavhlHw%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[{"group":{"id":3181312,"web_url":"https://gitlab.com/groups/gitea","name":"gitea","path":"gitea","description":"Mirror of Gitea source code repositories","visibility":"public","share_with_group_lock":false,"require_two_factor_authentication":false,"two_factor_grace_period":48,"project_creation_level":"maintainer","auto_devops_enabled":null,"subgroup_creation_level":"owner","emails_disabled":false,"emails_enabled":true,"mentions_disabled":null,"lfs_enabled":true,"default_branch_protection":2,"default_branch_protection_defaults":{"allowed_to_push":[{"access_level":30}],"allow_force_push":true,"allowed_to_merge":[{"access_level":30}]},"avatar_url":"https://gitlab.com/uploads/-/system/group/avatar/3181312/gitea.png","request_access_enabled":true,"full_name":"gitea","full_path":"gitea","created_at":"2018-07-04T16:32:10.176Z","parent_id":null,"shared_runners_setting":"enabled","ldap_cn":null,"ldap_access":null,"wiki_access_level":"enabled"}}],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
|
|
@ -0,0 +1,30 @@
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=2&per_page=1>; rel="next", <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=1&per_page=1>; rel="first", <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=2&per_page=1>; rel="last"
|
||||||
|
X-Total: 2
|
||||||
|
Cf-Ray: 82d2bae97fef36e0-FRA
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"a03d58b947b8fc6eaa1f702a4da99cb8","version":"1"}
|
||||||
|
X-Per-Page: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Server: cloudflare
|
||||||
|
Set-Cookie: _cfuvid=Y1.tZj_8_Ypf7nCIz3MuECuo4mMp2XGQH3QUuYMsf50-1701175758616-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Etag: W/"798718b23a2ec66b16cce20cb7155116"
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Page: 1
|
||||||
|
X-Prev-Page:
|
||||||
|
X-Runtime: 0.147890
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=%2BvzfARP%2F9AEt96t12WX5y2oM%2B%2B7FroI2hLNRG1pNVzCcie35th7z04cfqSJGe4FKKz1BYV5JGqY83AbCnKS%2BHq5IGFKUhI2DQokiIm%2Fi4pRQnXNBOAVgdbuJD5NT%2FuzgLNROkq7inQo%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
X-Next-Page: 2
|
||||||
|
X-Total-Pages: 2
|
||||||
|
Gitlab-Lb: haproxy-main-19-lb-gprd
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:18 GMT
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Request-Id: a03d58b947b8fc6eaa1f702a4da99cb8
|
||||||
|
|
||||||
|
[{"id":5541414,"name":"thumbsup","user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"},"created_at":"2020-09-02T23:42:34.310Z","updated_at":"2020-09-02T23:42:34.310Z","awardable_id":43524600,"awardable_type":"MergeRequest","url":null}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:18 GMT
|
||||||
|
X-Page: 2
|
||||||
|
X-Prev-Page: 1
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=MoRRmJLqv7AdPRfOKxbzB0Mr4KHlwQvL5%2Bn9Kb7SZHKf6sXHkKh7Wiv8pEcbtjzLg64Z7NR%2F1mfJDQ0MOGArqDb3JxzuvTO8T4GqEE36y8ZUalRlJanhHXdDFbr5XBDtj5aP26gnHBc%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Server: cloudflare
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Total-Pages: 2
|
||||||
|
X-Next-Page:
|
||||||
|
X-Request-Id: ad42ea570b4ae89a252ffbc8549e1bb9
|
||||||
|
Cf-Ray: 82d2baeb8a0836e0-FRA
|
||||||
|
Content-Type: application/json
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=1&per_page=1>; rel="prev", <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=1&per_page=1>; rel="first", <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=2&per_page=1>; rel="last"
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"ad42ea570b4ae89a252ffbc8549e1bb9","version":"1"}
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Etag: W/"e6776aaa57e6a81bf8a2d8823272cc70"
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Set-Cookie: _cfuvid=a1ruFsVJA3A69TvmmItKeOsOTtls1DsSwOsZnIz9rD8-1701175758922-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Per-Page: 1
|
||||||
|
X-Total: 2
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Runtime: 0.151691
|
||||||
|
Gitlab-Lb: haproxy-main-07-lb-gprd
|
||||||
|
|
||||||
|
[{"id":5541415,"name":"tada","user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"},"created_at":"2020-09-02T23:42:59.060Z","updated_at":"2020-09-02T23:42:59.060Z","awardable_id":43524600,"awardable_type":"MergeRequest","url":null}]
|
|
@ -0,0 +1,32 @@
|
||||||
|
Set-Cookie: _cfuvid=Kdqgfjzfy0DbIhYqXh_7uBzUHX9Jv0pPisJFLQXIrVg-1701175759167-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"5f864445eae9bc04ffe7ed09402cca0c","version":"1"}
|
||||||
|
X-Per-Page: 1
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=zGsr%2BOFk2NbQGZlTUyA7C9HA8iLUvecAlrACaCR%2BhodJsskFtUYZRGQ6a2u9%2FTm8L0wv4ZhHGaD4jbGIBJTyjEmLpOEwmxY%2Bv9C%2BOR6cehuRfI%2Bbn1lWaBquuotpnRzVPvPRcDAzTnI%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=1&per_page=1>; rel="first", <https://gitlab.com/api/v4/projects/15578026/merge_requests/2/award_emoji?id=15578026&merge_request_iid=2&page=2&per_page=1>; rel="last"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Total-Pages: 2
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:19 GMT
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Content-Length: 2
|
||||||
|
X-Total: 2
|
||||||
|
Server: cloudflare
|
||||||
|
Cf-Ray: 82d2baed6c0236e0-FRA
|
||||||
|
Content-Type: application/json
|
||||||
|
Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
X-Next-Page:
|
||||||
|
Gitlab-Lb: haproxy-main-34-lb-gprd
|
||||||
|
X-Page: 3
|
||||||
|
X-Prev-Page:
|
||||||
|
X-Request-Id: 5f864445eae9bc04ffe7ed09402cca0c
|
||||||
|
X-Runtime: 0.092640
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
|
||||||
|
[]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Cf-Ray: 82d2bac82d2d36e0-FRA
|
||||||
|
X-Request-Id: 06597dd0fd8d77bd6e3876f985a4f847
|
||||||
|
X-Total: 2
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
X-Next-Page:
|
||||||
|
Set-Cookie: _cfuvid=DJncZbrWf4Pj5gJ6t20ry9vG7xD9rEkKh0Xc5MepOic-1701175753285-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Per-Page: 100
|
||||||
|
Gitlab-Sv: api-gke-us-east1-b
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Runtime: 0.175518
|
||||||
|
Server: cloudflare
|
||||||
|
Content-Type: application/json
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/milestones?id=15578026&include_parent_milestones=false&page=1&per_page=100&state=all>; rel="first", <https://gitlab.com/api/v4/projects/15578026/milestones?id=15578026&include_parent_milestones=false&page=1&per_page=100&state=all>; rel="last"
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"06597dd0fd8d77bd6e3876f985a4f847","version":"1"}
|
||||||
|
X-Page: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Lb: haproxy-main-21-lb-gprd
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:13 GMT
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Prev-Page:
|
||||||
|
Etag: W/"c8e2d3a5f05ee29c58b665c86684f9f9"
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=Hcs6%2BZ%2BCvPTYwKVmytWNkDQViuU9NMqNg5p1%2Fu7fAnVHqMcfKleFoBeF0%2B9P0%2Fv%2B7AJYmGBYX133zwHkYq0ZpiffQTHXsN%2F5DwMpcbSZ%2BTUwJtQW6HNDWetWrsid027TzuBpO4XA%2FkM%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
[{"id":1082927,"iid":2,"project_id":15578026,"title":"1.1.0","description":"","state":"active","created_at":"2019-11-28T08:42:44.575Z","updated_at":"2019-11-28T08:42:44.575Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/2"},{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"}]
|
|
@ -0,0 +1,30 @@
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"5440b41f88cf08eff25ed0f01b672b6c"
|
||||||
|
X-Next-Page:
|
||||||
|
X-Total: 1
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/15578026/releases?id=15578026&order_by=released_at&page=1&per_page=100&sort=desc>; rel="first", <https://gitlab.com/api/v4/projects/15578026/releases?id=15578026&order_by=released_at&page=1&per_page=100&sort=desc>; rel="last"
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=btZ1m94fXWqfBgsZQR%2FOZ0DQyIKl3Z%2FsE4BqWylbeVfH90wqFEHh0ppa7qoqWjvrYLU4NXSXIKRzKSqQWwlo%2BsWY8uA%2F50yds8tQKf%2BQZGls66SdyHN6PDz3mpnUvQuqq%2F1Q8xURUEI%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Per-Page: 100
|
||||||
|
X-Request-Id: 7f7348d2dbae86671a1696b37412e15a
|
||||||
|
Set-Cookie: _cfuvid=xIo7QFSlYPXO7zvrYz0Zx_952rFkLYu7YM7OxFu15M0-1701175754703-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Page: 1
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Cf-Ray: 82d2bacc49c036e0-FRA
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Server: cloudflare
|
||||||
|
X-Prev-Page:
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:14 GMT
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"7f7348d2dbae86671a1696b37412e15a","version":"1"}
|
||||||
|
X-Runtime: 0.803723
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Lb: haproxy-main-09-lb-gprd
|
||||||
|
Gitlab-Sv: api-gke-us-east1-b
|
||||||
|
|
||||||
|
[{"name":"First Release","tag_name":"v0.9.99","description":"A test release","created_at":"2019-11-28T09:09:48.840Z","released_at":"2019-11-28T09:09:48.836Z","upcoming_release":false,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"commit":{"id":"0720a3ec57c1f843568298117b874319e7deee75","short_id":"0720a3ec","created_at":"2019-11-28T08:49:16.000+00:00","parent_ids":["93ea21ce45d35690c35e80961d239645139e872c"],"title":"Add new file","message":"Add new file","author_name":"Lauris BH","author_email":"lauris@nix.lv","authored_date":"2019-11-28T08:49:16.000+00:00","committer_name":"Lauris BH","committer_email":"lauris@nix.lv","committed_date":"2019-11-28T08:49:16.000+00:00","trailers":{},"web_url":"https://gitlab.com/gitea/test_repo/-/commit/0720a3ec57c1f843568298117b874319e7deee75"},"commit_path":"/gitea/test_repo/-/commit/0720a3ec57c1f843568298117b874319e7deee75","tag_path":"/gitea/test_repo/-/tags/v0.9.99","assets":{"count":4,"sources":[{"format":"zip","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.zip"},{"format":"tar.gz","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar.gz"},{"format":"tar.bz2","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar.bz2"},{"format":"tar","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar"}],"links":[]},"evidences":[{"sha":"89f1223473ee01f192a83d0cb89f4d1eac1de74f01ad","filepath":"https://gitlab.com/gitea/test_repo/-/releases/v0.9.99/evidences/52147.json","collected_at":"2019-11-28T09:09:48.888Z"}],"_links":{"closed_issues_url":"https://gitlab.com/gitea/test_repo/-/issues?release_tag=v0.9.99\u0026scope=all\u0026state=closed","closed_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=closed","merged_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=merged","opened_issues_url":"https://gitlab.com/gitea/test_repo/-/issues?release_tag=v0.9.99\u0026scope=all\u0026state=opened","opened_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=opened","self":"https://gitlab.com/gitea/test_repo/-/releases/v0.9.99"}}]
|
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_gitea%2Ftest_repo
vendored
Normal file
23
services/migrations/testdata/gitlab/full_download/_api_v4_projects_gitea%2Ftest_repo
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Cf-Ray: 82d2bac30fed36e0-FRA
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:12 GMT
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Runtime: 0.116312
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Request-Id: 5084076bcc10e9b464dc50d43bbed946
|
||||||
|
Etag: W/"3cacfe29f44a69e84a577337eac55d89"
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"5084076bcc10e9b464dc50d43bbed946","version":"1"}
|
||||||
|
Gitlab-Lb: haproxy-main-40-lb-gprd
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=GpgxXRqGFvANSigzGH3DNrmjsm%2FRpte0wJDN%2FXtsuShjd1pPQp21f9s2XcTl9FZvNUTu63HS%2Bgk9U7VOVZA4WXoEY0cojyAmY1p7PVJpjreGruNAWxqjlN7NSGZ7%2FmvcjgsSjwT%2BdGA%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
Set-Cookie: _cfuvid=BJFuMJd_VojO_sw8EOU4omJmLYeYXbDIivrgVhLib0I-1701175752406-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Server: cloudflare
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
|
||||||
|
{"id":15578026,"description":"Test repository for testing migration from gitlab to gitea","name":"test_repo","name_with_namespace":"gitea / test_repo","path":"test_repo","path_with_namespace":"gitea/test_repo","created_at":"2019-11-28T08:20:33.019Z","default_branch":"master","tag_list":["migration","test"],"topics":["migration","test"],"ssh_url_to_repo":"git@gitlab.com:gitea/test_repo.git","http_url_to_repo":"https://gitlab.com/gitea/test_repo.git","web_url":"https://gitlab.com/gitea/test_repo","readme_url":"https://gitlab.com/gitea/test_repo/-/blob/master/README.md","forks_count":1,"avatar_url":null,"star_count":0,"last_activity_at":"2020-04-19T19:46:04.527Z","namespace":{"id":3181312,"name":"gitea","path":"gitea","kind":"group","full_path":"gitea","parent_id":null,"avatar_url":"/uploads/-/system/group/avatar/3181312/gitea.png","web_url":"https://gitlab.com/groups/gitea"},"container_registry_image_prefix":"registry.gitlab.com/gitea/test_repo","_links":{"self":"https://gitlab.com/api/v4/projects/15578026","issues":"https://gitlab.com/api/v4/projects/15578026/issues","merge_requests":"https://gitlab.com/api/v4/projects/15578026/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/15578026/repository/branches","labels":"https://gitlab.com/api/v4/projects/15578026/labels","events":"https://gitlab.com/api/v4/projects/15578026/events","members":"https://gitlab.com/api/v4/projects/15578026/members","cluster_agents":"https://gitlab.com/api/v4/projects/15578026/cluster_agents"},"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1241334,"import_status":"none","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:58\" dir=\"auto\"\u003eTest repository for testing migration from gitlab to gitea\u003c/p\u003e","updated_at":"2022-08-26T19:41:46.691Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"ff","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
|
23
services/migrations/testdata/gitlab/full_download/_api_v4_version
vendored
Normal file
23
services/migrations/testdata/gitlab/full_download/_api_v4_version
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Gitlab-Lb: haproxy-main-31-lb-gprd
|
||||||
|
Set-Cookie: _cfuvid=gGLTCQ.DBiLTAaGLmVcffUW2lZvY.zMxk5xBKUQHLPM-1701175752131-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Server: cloudflare
|
||||||
|
Cf-Ray: 82d2bac1be3636e0-FRA
|
||||||
|
Content-Type: application/json
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Etag: W/"4648d4a6bf714a790516932423329284"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Gitlab-Sv: api-gke-us-east1-c
|
||||||
|
X-Request-Id: 27484ae5219156b31c1cc83893083969
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=kdjyYWvTDoPNQ4iBJJYS%2Fjbs5F20wM3pU2b9NaqMkiYLRy66lnlp00bppZl2fJOmp4xVD7WF0aDBG5UPGTSdRmAs%2BJUfFxgcX9mrehewmVftcwk6iUKdCqZA9xVIMEC5qiGi0f1bAEg%3D"}],"group":"cf-nel","max_age":604800}
|
||||||
|
Date: Tue, 28 Nov 2023 12:49:12 GMT
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"27484ae5219156b31c1cc83893083969","version":"1"}
|
||||||
|
X-Runtime: 0.044589
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
|
||||||
|
|
||||||
|
{"version":"16.7.0-pre","revision":"25ffee8ef90","kas":{"enabled":true,"externalUrl":"wss://kas.gitlab.com","version":"v16.7.0-rc2"},"enterprise":true}
|
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996
vendored
Normal file
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
X-Runtime: 0.088022
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Ratelimit-Observed: 3
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Etag: W/"03ce4f6ce1c1e8c5a31df8a44cf2fbdd"
|
||||||
|
Gitlab-Lb: haproxy-main-11-lb-gprd
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"b57b226f741f9140a1fea54f65cb5cfd","version":"1"}
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Remaining: 1997
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:53 GMT
|
||||||
|
Set-Cookie: _cfuvid=V0ToiOTUW0XbtWq7BirwVNfL1_YP1POMrLBnDSEWS0M-1701332633965-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Content-Type: application/json
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Ratelimit-Reset: 1701332693
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
|
||||||
|
{"id":6590996,"description":"Arch packaging and build files","name":"archbuild","name_with_namespace":"Troy Engel / archbuild","path":"archbuild","path_with_namespace":"troyengel/archbuild","created_at":"2018-06-03T22:53:17.388Z","default_branch":"master","tag_list":[],"topics":[],"ssh_url_to_repo":"git@gitlab.com:troyengel/archbuild.git","http_url_to_repo":"https://gitlab.com/troyengel/archbuild.git","web_url":"https://gitlab.com/troyengel/archbuild","readme_url":"https://gitlab.com/troyengel/archbuild/-/blob/master/README.md","forks_count":0,"avatar_url":null,"star_count":0,"last_activity_at":"2020-12-13T18:09:32.071Z","namespace":{"id":1452515,"name":"Troy Engel","path":"troyengel","kind":"user","full_path":"troyengel","parent_id":null,"avatar_url":"https://secure.gravatar.com/avatar/b226c267929f1bcfcc446e75a025591c?s=80\u0026d=identicon","web_url":"https://gitlab.com/troyengel"},"container_registry_image_prefix":"registry.gitlab.com/troyengel/archbuild","_links":{"self":"https://gitlab.com/api/v4/projects/6590996","issues":"https://gitlab.com/api/v4/projects/6590996/issues","merge_requests":"https://gitlab.com/api/v4/projects/6590996/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/6590996/repository/branches","labels":"https://gitlab.com/api/v4/projects/6590996/labels","events":"https://gitlab.com/api/v4/projects/6590996/events","members":"https://gitlab.com/api/v4/projects/6590996/members","cluster_agents":"https://gitlab.com/api/v4/projects/6590996/cluster_agents"},"packages_enabled":null,"empty_repo":false,"archived":true,"visibility":"public","owner":{"id":1215848,"username":"troyengel","name":"Troy Engel","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/b226c267929f1bcfcc446e75a025591c?s=80\u0026d=identicon","web_url":"https://gitlab.com/troyengel"},"resolve_outdated_diff_discussions":false,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":false,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":false,"creator_id":1215848,"import_status":"finished","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:30\" dir=\"auto\"\u003eArch packaging and build files\u003c/p\u003e","updated_at":"2022-07-13T21:32:12.624Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":null,"printing_merge_request_link_enabled":true,"merge_method":"merge","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
|
|
@ -0,0 +1,29 @@
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/6590996/issues?id=6590996&order_by=created_at&page=1&per_page=10&sort=asc&state=all&with_labels_details=false>; rel="first", <https://gitlab.com/api/v4/projects/6590996/issues?id=6590996&order_by=created_at&page=1&per_page=10&sort=asc&state=all&with_labels_details=false>; rel="last"
|
||||||
|
Ratelimit-Observed: 4
|
||||||
|
Ratelimit-Remaining: 1996
|
||||||
|
Gitlab-Lb: haproxy-main-04-lb-gprd
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Next-Page:
|
||||||
|
Ratelimit-Reset: 1701332694
|
||||||
|
Etag: W/"f50a70d0fc1465a289d231f80806ced7"
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"47afd74254dd7946d2b2bded87448c60","version":"1"}
|
||||||
|
X-Page: 1
|
||||||
|
X-Prev-Page:
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:54 GMT
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Total: 1
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Set-Cookie: _cfuvid=YDWTZ5VoSuLBDZgKsBnXMyYxz.0rHJ9TBYXv5zBj24Q-1701332634294-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Per-Page: 10
|
||||||
|
X-Runtime: 0.179458
|
||||||
|
|
||||||
|
[{"id":11201348,"iid":2,"project_id":6590996,"title":"vpn unlimited errors","description":"updated version to 2.8.0, build and tried running `vpnu-arch`:\n\n```\nvpn-unlimited: /usr/lib/libcurl.so.3: no version information available (required by /usr/lib/libvpnu_rpc.so.1)\nvpn-unlimited: /usr/lib/libssl.so.1.0.0: no version information available (required by /usr/lib/libvpnu_enc.so.1)\nvpn-unlimited: symbol lookup error: /usr/lib/libvpnu_rpc.so.1: undefined symbol: _ZNK4Json5Value8asStringEv\n```\n","state":"closed","created_at":"2016-03-26T16:41:12.000Z","updated_at":"2016-03-27T12:19:27.000Z","closed_at":null,"closed_by":null,"labels":[],"milestone":null,"assignees":[],"author":{"id":10273,"username":"brauliobo","name":"Bráulio Bhavamitra","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/cd3fcb7a417c8acb989fc320b604a2a8?s=80\u0026d=identicon","web_url":"https://gitlab.com/brauliobo"},"type":"ISSUE","assignee":null,"user_notes_count":1,"merge_requests_count":0,"upvotes":0,"downvotes":0,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/troyengel/archbuild/-/issues/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/6590996/issues/2","notes":"https://gitlab.com/api/v4/projects/6590996/issues/2/notes","award_emoji":"https://gitlab.com/api/v4/projects/6590996/issues/2/award_emoji","project":"https://gitlab.com/api/v4/projects/6590996","closed_as_duplicate_of":null},"references":{"short":"#2","relative":"#2","full":"troyengel/archbuild#2"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null}]
|
|
@ -0,0 +1,31 @@
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Gitlab-Lb: haproxy-main-25-lb-gprd
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Observed: 5
|
||||||
|
Ratelimit-Remaining: 1995
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"eeab46d836341bd4cb18e3d2e82abf97","version":"1"}
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Page: 1
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Prev-Page:
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Total: 0
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:54 GMT
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/6590996/issues/2/award_emoji?id=6590996&issue_iid=2&page=1&per_page=10>; rel="first", <https://gitlab.com/api/v4/projects/6590996/issues/2/award_emoji?id=6590996&issue_iid=2&page=1&per_page=10>; rel="last"
|
||||||
|
X-Per-Page: 10
|
||||||
|
Set-Cookie: _cfuvid=c5HuTPxOuSXdHSuVrXQALS.uV7WvAYfc5Mc_143EAB8-1701332634513-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Length: 2
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
X-Runtime: 0.069269
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Ratelimit-Reset: 1701332694
|
||||||
|
X-Next-Page:
|
||||||
|
|
||||||
|
[]
|
|
@ -0,0 +1,29 @@
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Prev-Page:
|
||||||
|
Ratelimit-Reset: 1701332694
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Observed: 6
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:54 GMT
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"1a50811aa3cccb2e6a404a976422a83a"
|
||||||
|
X-Total: 1
|
||||||
|
Ratelimit-Remaining: 1994
|
||||||
|
Set-Cookie: _cfuvid=u.zumTkG1ayCnh_OwrT9Q1Fl3MXV9Gh98W.ma4WN2Xs-1701332634745-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/6590996/merge_requests?id=6590996&order_by=created_at&page=1&per_page=10&sort=desc&state=all&view=simple&with_labels_details=false&with_merge_status_recheck=false>; rel="first", <https://gitlab.com/api/v4/projects/6590996/merge_requests?id=6590996&order_by=created_at&page=1&per_page=10&sort=desc&state=all&view=simple&with_labels_details=false&with_merge_status_recheck=false>; rel="last"
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
X-Page: 1
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Gitlab-Lb: haproxy-main-05-lb-gprd
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"907f9e1f94131ea7a6d1405100a8cc4b","version":"1"}
|
||||||
|
X-Next-Page:
|
||||||
|
X-Per-Page: 10
|
||||||
|
X-Runtime: 0.078413
|
||||||
|
|
||||||
|
[{"id":10518914,"iid":1,"project_id":6590996,"title":"Review","description":"*Created by: cgtx*\n\n### remove patch from makedepends\n- patch is in base-devel\n- The group base-devel is assumed to be already installed when building with makepkg. Members of \"base-devel\" should not be included in makedepends arrays.\n- https://wiki.archlinux.org/index.php/Pkgbuild#makedepends\n### remove python2 from makedepends\n- python2 is a dependency of python2-setuptools. It is redundant to list it again.\n- You do not need to list packages that your software depends on if other packages your software depends on already have those packages listed in their dependency.\n- https://wiki.archlinux.org/index.php/Pkgbuild#depends\n### more simple find/delete command\n- just because\n","state":"merged","created_at":"2014-12-12T15:01:32.000Z","updated_at":"2014-12-12T15:28:38.000Z","author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"web_url":"https://gitlab.com/troyengel/archbuild/-/merge_requests/1"}]
|
|
@ -0,0 +1,22 @@
|
||||||
|
Ratelimit-Observed: 7
|
||||||
|
Set-Cookie: _cfuvid=_b9GQEo3CBPMs9QmGE89dBdOmbSTfnYjZlzValULQPs-1701332635000-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:54 GMT
|
||||||
|
Gitlab-Lb: haproxy-main-50-lb-gprd
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"da44cd0303a4e62cc52ed8de3b2adf14","version":"1"}
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Remaining: 1993
|
||||||
|
Etag: W/"f6299e7e884cb8df8109256c086eb4e7"
|
||||||
|
X-Runtime: 0.107573
|
||||||
|
Content-Type: application/json
|
||||||
|
Ratelimit-Reset: 1701332694
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
|
||||||
|
{"id":10518914,"iid":1,"project_id":6590996,"title":"Review","description":"*Created by: cgtx*\n\n### remove patch from makedepends\n- patch is in base-devel\n- The group base-devel is assumed to be already installed when building with makepkg. Members of \"base-devel\" should not be included in makedepends arrays.\n- https://wiki.archlinux.org/index.php/Pkgbuild#makedepends\n### remove python2 from makedepends\n- python2 is a dependency of python2-setuptools. It is redundant to list it again.\n- You do not need to list packages that your software depends on if other packages your software depends on already have those packages listed in their dependency.\n- https://wiki.archlinux.org/index.php/Pkgbuild#depends\n### more simple find/delete command\n- just because\n","state":"merged","created_at":"2014-12-12T15:01:32.000Z","updated_at":"2014-12-12T15:28:38.000Z","merged_by":null,"merge_user":null,"merged_at":null,"closed_by":null,"closed_at":null,"target_branch":"master","source_branch":"cgtx:review","user_notes_count":1,"upvotes":0,"downvotes":0,"author":{"id":1215848,"username":"troyengel","name":"Troy Engel","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/b226c267929f1bcfcc446e75a025591c?s=80\u0026d=identicon","web_url":"https://gitlab.com/troyengel"},"assignees":[],"assignee":null,"reviewers":[],"source_project_id":6590996,"target_project_id":6590996,"labels":[],"draft":false,"work_in_progress":false,"milestone":null,"merge_when_pipeline_succeeds":false,"merge_status":"cannot_be_merged","detailed_merge_status":"not_open","sha":"9006fee398299beed8f5d5086f8e6008ffc02280","merge_commit_sha":null,"squash_commit_sha":null,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":null,"prepared_at":"2014-12-12T15:01:32.000Z","reference":"!1","references":{"short":"!1","relative":"!1","full":"troyengel/archbuild!1"},"web_url":"https://gitlab.com/troyengel/archbuild/-/merge_requests/1","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":false,"squash_on_merge":false,"task_completion_status":{"count":0,"completed_count":0},"has_conflicts":true,"blocking_discussions_resolved":true,"approvals_before_merge":null,"subscribed":false,"changes_count":"1","latest_build_started_at":null,"latest_build_finished_at":null,"first_deployed_to_production_at":null,"pipeline":null,"head_pipeline":null,"diff_refs":{"base_sha":"6edcf8fc09f6c44213c892f5108d34a5255a47e1","head_sha":"9006fee398299beed8f5d5086f8e6008ffc02280","start_sha":"6edcf8fc09f6c44213c892f5108d34a5255a47e1"},"merge_error":null,"first_contribution":false,"user":{"can_merge":false}}
|
|
@ -0,0 +1,31 @@
|
||||||
|
Link: <https://gitlab.com/api/v4/projects/6590996/merge_requests/1/award_emoji?id=6590996&merge_request_iid=1&page=1&per_page=10>; rel="first", <https://gitlab.com/api/v4/projects/6590996/merge_requests/1/award_emoji?id=6590996&merge_request_iid=1&page=1&per_page=10>; rel="last"
|
||||||
|
Set-Cookie: _cfuvid=qK29tijoyp0AdVoHf9Lqjc8Y28h4jplJDW9hOFLfq28-1701332635229-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
Ratelimit-Observed: 8
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Content-Length: 2
|
||||||
|
Gitlab-Lb: haproxy-main-16-lb-gprd
|
||||||
|
X-Total: 0
|
||||||
|
Ratelimit-Remaining: 1992
|
||||||
|
Ratelimit-Reset: 1701332695
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
X-Next-Page:
|
||||||
|
X-Page: 1
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
X-Per-Page: 10
|
||||||
|
X-Total-Pages: 1
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:55 GMT
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"eb59d63fed23cdbec69308570cc49c3e","version":"1"}
|
||||||
|
X-Runtime: 0.065972
|
||||||
|
X-Prev-Page:
|
||||||
|
|
||||||
|
[]
|
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_troyengel%2Farchbuild
vendored
Normal file
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_troyengel%2Farchbuild
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:53 GMT
|
||||||
|
Gitlab-Lb: haproxy-main-41-lb-gprd
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Set-Cookie: _cfuvid=r78xThY2IPR6QvHnea1t_L7DbvuQp4.HWOiG1cKTWUg-1701332633720-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"4c3e0f8b5858454b6e138ecae9902a8d","version":"1"}
|
||||||
|
X-Runtime: 0.097047
|
||||||
|
Ratelimit-Observed: 2
|
||||||
|
Ratelimit-Remaining: 1998
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Etag: W/"03ce4f6ce1c1e8c5a31df8a44cf2fbdd"
|
||||||
|
Content-Type: application/json
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Ratelimit-Reset: 1701332693
|
||||||
|
|
||||||
|
{"id":6590996,"description":"Arch packaging and build files","name":"archbuild","name_with_namespace":"Troy Engel / archbuild","path":"archbuild","path_with_namespace":"troyengel/archbuild","created_at":"2018-06-03T22:53:17.388Z","default_branch":"master","tag_list":[],"topics":[],"ssh_url_to_repo":"git@gitlab.com:troyengel/archbuild.git","http_url_to_repo":"https://gitlab.com/troyengel/archbuild.git","web_url":"https://gitlab.com/troyengel/archbuild","readme_url":"https://gitlab.com/troyengel/archbuild/-/blob/master/README.md","forks_count":0,"avatar_url":null,"star_count":0,"last_activity_at":"2020-12-13T18:09:32.071Z","namespace":{"id":1452515,"name":"Troy Engel","path":"troyengel","kind":"user","full_path":"troyengel","parent_id":null,"avatar_url":"https://secure.gravatar.com/avatar/b226c267929f1bcfcc446e75a025591c?s=80\u0026d=identicon","web_url":"https://gitlab.com/troyengel"},"container_registry_image_prefix":"registry.gitlab.com/troyengel/archbuild","_links":{"self":"https://gitlab.com/api/v4/projects/6590996","issues":"https://gitlab.com/api/v4/projects/6590996/issues","merge_requests":"https://gitlab.com/api/v4/projects/6590996/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/6590996/repository/branches","labels":"https://gitlab.com/api/v4/projects/6590996/labels","events":"https://gitlab.com/api/v4/projects/6590996/events","members":"https://gitlab.com/api/v4/projects/6590996/members","cluster_agents":"https://gitlab.com/api/v4/projects/6590996/cluster_agents"},"packages_enabled":null,"empty_repo":false,"archived":true,"visibility":"public","owner":{"id":1215848,"username":"troyengel","name":"Troy Engel","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/b226c267929f1bcfcc446e75a025591c?s=80\u0026d=identicon","web_url":"https://gitlab.com/troyengel"},"resolve_outdated_diff_discussions":false,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":false,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":false,"creator_id":1215848,"import_status":"finished","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:30\" dir=\"auto\"\u003eArch packaging and build files\u003c/p\u003e","updated_at":"2022-07-13T21:32:12.624Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":null,"printing_merge_request_link_enabled":true,"merge_method":"merge","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
|
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_version
vendored
Normal file
22
services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_version
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Ratelimit-Observed: 1
|
||||||
|
X-Gitlab-Meta: {"correlation_id":"aa75720bd9c597c7f2f886a4042d1f80","version":"1"}
|
||||||
|
Etag: W/"4e5c0a031c3aacb6ba0a3c19e67d7592"
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
Ratelimit-Limit: 2000
|
||||||
|
Ratelimit-Resettime: Thu, 30 Nov 2023 08:24:53 GMT
|
||||||
|
X-Runtime: 0.039899
|
||||||
|
Ratelimit-Remaining: 1999
|
||||||
|
Set-Cookie: _cfuvid=7OAEitQ3J0BOxrXk2pMBApFg1KFnz5aBVqOY7mHwLRk-1701332633452-0-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Gitlab-Sv: localhost
|
||||||
|
Cf-Cache-Status: MISS
|
||||||
|
Vary: Origin, Accept-Encoding
|
||||||
|
X-Frame-Options: SAMEORIGIN
|
||||||
|
Cache-Control: max-age=0, private, must-revalidate
|
||||||
|
Strict-Transport-Security: max-age=31536000
|
||||||
|
Referrer-Policy: strict-origin-when-cross-origin
|
||||||
|
Ratelimit-Reset: 1701332693
|
||||||
|
Gitlab-Lb: haproxy-main-39-lb-gprd
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{"version":"16.7.0-pre","revision":"acd848a9228","kas":{"enabled":true,"externalUrl":"wss://kas.gitlab.com","version":"v16.7.0-rc2"},"enterprise":true}
|
|
@ -67,7 +67,7 @@ func GetOrCreateKeyPair(ctx context.Context, ownerID int64) (string, string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateKeypair() (string, string, error) {
|
func generateKeypair() (string, string, error) {
|
||||||
e, err := openpgp.NewEntity(setting.AppName, "Debian Registry", "", nil)
|
e, err := openpgp.NewEntity("", "Debian Registry", "", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
packages_module "code.gitea.io/gitea/modules/packages"
|
packages_module "code.gitea.io/gitea/modules/packages"
|
||||||
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
|
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
packages_service "code.gitea.io/gitea/services/packages"
|
packages_service "code.gitea.io/gitea/services/packages"
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ func GetOrCreateKeyPair(ctx context.Context, ownerID int64) (string, string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateKeypair() (string, string, error) {
|
func generateKeypair() (string, string, error) {
|
||||||
e, err := openpgp.NewEntity(setting.AppName, "RPM Registry", "", nil)
|
e, err := openpgp.NewEntity("", "RPM Registry", "", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
@ -126,7 +125,7 @@ type packageData struct {
|
||||||
|
|
||||||
type packageCache = map[*packages_model.PackageFile]*packageData
|
type packageCache = map[*packages_model.PackageFile]*packageData
|
||||||
|
|
||||||
// BuildSpecificRepositoryFiles builds metadata files for the repository
|
// BuildRepositoryFiles builds metadata files for the repository
|
||||||
func BuildRepositoryFiles(ctx context.Context, ownerID int64) error {
|
func BuildRepositoryFiles(ctx context.Context, ownerID int64) error {
|
||||||
pv, err := GetOrCreateRepositoryVersion(ctx, ownerID)
|
pv, err := GetOrCreateRepositoryVersion(ctx, ownerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -219,7 +219,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle links
|
// Handle links
|
||||||
if entry.IsRegular() || entry.IsLink() {
|
if entry.IsRegular() || entry.IsLink() || entry.IsExecutable() {
|
||||||
downloadURL, err := url.Parse(repo.HTMLURL() + "/raw/" + url.PathEscape(string(refType)) + "/" + util.PathEscapeSegments(ref) + "/" + util.PathEscapeSegments(treePath))
|
downloadURL, err := url.Parse(repo.HTMLURL() + "/raw/" + url.PathEscape(string(refType)) + "/" + util.PathEscapeSegments(ref) + "/" + util.PathEscapeSegments(treePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-item-trailing">
|
<div class="flex-item-trailing">
|
||||||
{{if .PrimaryLanguage}}
|
{{if .PrimaryLanguage}}
|
||||||
<a class="muted" href="{{$.Link}}?q={{$.Keyword}}&sort={{$.SortType}}&language={{.PrimaryLanguage.Language}}">
|
<a class="muted" href="{{$.Link}}?q={{$.Keyword}}&sort={{$.SortType}}&language={{.PrimaryLanguage.Language}}{{if $.TabName}}&tab={{$.TabName}}{{end}}">
|
||||||
<span class="flex-text-inline"><i class="color-icon gt-mr-3" style="background-color: {{.PrimaryLanguage.Color}}"></i>{{.PrimaryLanguage.Language}}</span>
|
<span class="flex-text-inline"><i class="color-icon gt-mr-3" style="background-color: {{.PrimaryLanguage.Color}}"></i>{{.PrimaryLanguage.Language}}</span>
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<ul>
|
<ul>
|
||||||
<h3>{{ctx.Locale.Tr "mail.admin.new_user.user_info"}}</h3>
|
<h3>{{.Locale.Tr "mail.admin.new_user.user_info" | Str2html}}: {{.NewUser.Name}}</h3>
|
||||||
<li>{{ctx.Locale.Tr "admin.users.created"}}: {{DateTime "full" .NewUser.LastLoginUnix}}</li>
|
<li>{{.Locale.Tr "admin.users.created" | Str2html}}: {{DateTime "full" .NewUser.CreatedUnix}}</li>
|
||||||
<li>{{ctx.Locale.Tr "admin.users.last_login"}}: {{DateTime "full" .NewUser.CreatedUnix}}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<p> {{.Body | Str2html}} </p>
|
<p> {{.Body | Str2html}} </p>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
<div role="main" aria-label="{{.Title}}" class="page-content repository projects view-project">
|
<div role="main" aria-label="{{.Title}}" class="page-content repository projects view-project">
|
||||||
{{template "shared/user/org_profile_avatar" .}}
|
{{template "shared/user/org_profile_avatar" .}}
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
{{template "user/overview/header" .}}
|
{{template "user/overview/header" .}}
|
||||||
{{template "projects/view" .}}
|
</div>
|
||||||
|
<div class="ui container fluid padded">
|
||||||
|
{{template "projects/view" .}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
||||||
|
|
|
@ -1,66 +1,68 @@
|
||||||
{{$canWriteProject := and .CanWriteProjects (or (not .Repository) (not .Repository.IsArchived))}}
|
{{$canWriteProject := and .CanWriteProjects (or (not .Repository) (not .Repository.IsArchived))}}
|
||||||
|
|
||||||
<div class="gt-df gt-sb gt-ac gt-mb-4">
|
<div class="ui container">
|
||||||
<h2 class="gt-mb-0">{{.Project.Title}}</h2>
|
<div class="gt-df gt-sb gt-ac gt-mb-4">
|
||||||
{{if $canWriteProject}}
|
<h2 class="gt-mb-0">{{.Project.Title}}</h2>
|
||||||
<div class="ui compact mini menu">
|
{{if $canWriteProject}}
|
||||||
<a class="item" href="{{.Link}}/edit?redirect=project">
|
<div class="ui compact mini menu">
|
||||||
{{svg "octicon-pencil"}}
|
<a class="item" href="{{.Link}}/edit?redirect=project">
|
||||||
{{ctx.Locale.Tr "repo.issues.label_edit"}}
|
{{svg "octicon-pencil"}}
|
||||||
</a>
|
{{ctx.Locale.Tr "repo.issues.label_edit"}}
|
||||||
{{if .Project.IsClosed}}
|
</a>
|
||||||
<button class="item btn link-action" data-url="{{.Link}}/open">
|
{{if .Project.IsClosed}}
|
||||||
{{svg "octicon-check"}}
|
<button class="item btn link-action" data-url="{{.Link}}/open">
|
||||||
{{ctx.Locale.Tr "repo.projects.open"}}
|
{{svg "octicon-check"}}
|
||||||
|
{{ctx.Locale.Tr "repo.projects.open"}}
|
||||||
|
</button>
|
||||||
|
{{else}}
|
||||||
|
<button class="item btn link-action" data-url="{{.Link}}/close">
|
||||||
|
{{svg "octicon-skip"}}
|
||||||
|
{{ctx.Locale.Tr "repo.projects.close"}}
|
||||||
|
</button>
|
||||||
|
{{end}}
|
||||||
|
<button class="item btn delete-button" data-url="{{.Link}}/delete" data-id="{{.Project.ID}}">
|
||||||
|
{{svg "octicon-trash"}}
|
||||||
|
{{ctx.Locale.Tr "repo.issues.label_delete"}}
|
||||||
</button>
|
</button>
|
||||||
{{else}}
|
<button class="item btn show-modal" data-modal="#new-project-column-item">
|
||||||
<button class="item btn link-action" data-url="{{.Link}}/close">
|
{{svg "octicon-plus"}}
|
||||||
{{svg "octicon-skip"}}
|
{{ctx.Locale.Tr "new_project_column"}}
|
||||||
{{ctx.Locale.Tr "repo.projects.close"}}
|
|
||||||
</button>
|
</button>
|
||||||
{{end}}
|
|
||||||
<button class="item btn delete-button" data-url="{{.Link}}/delete" data-id="{{.Project.ID}}">
|
|
||||||
{{svg "octicon-trash"}}
|
|
||||||
{{ctx.Locale.Tr "repo.issues.label_delete"}}
|
|
||||||
</button>
|
|
||||||
<button class="item btn show-modal" data-modal="#new-project-column-item">
|
|
||||||
{{svg "octicon-plus"}}
|
|
||||||
{{ctx.Locale.Tr "new_project_column"}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="ui small modal new-project-column-modal" id="new-project-column-item">
|
|
||||||
<div class="header">
|
|
||||||
{{ctx.Locale.Tr "repo.projects.column.new"}}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="ui small modal new-project-column-modal" id="new-project-column-item">
|
||||||
<form class="ui form">
|
<div class="header">
|
||||||
<div class="required field">
|
{{ctx.Locale.Tr "repo.projects.column.new"}}
|
||||||
<label for="new_project_column">{{ctx.Locale.Tr "repo.projects.column.new_title"}}</label>
|
</div>
|
||||||
<input class="new-project-column" id="new_project_column" name="title" required>
|
<div class="content">
|
||||||
</div>
|
<form class="ui form">
|
||||||
|
<div class="required field">
|
||||||
<div class="field color-field">
|
<label for="new_project_column">{{ctx.Locale.Tr "repo.projects.column.new_title"}}</label>
|
||||||
<label for="new_project_column_color">{{ctx.Locale.Tr "repo.projects.column.color"}}</label>
|
<input class="new-project-column" id="new_project_column" name="title" required>
|
||||||
<div class="color picker column">
|
|
||||||
<input class="color-picker" maxlength="7" placeholder="#c320f6" id="new_project_column_color_picker" name="color">
|
|
||||||
{{template "repo/issue/label_precolors"}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text right actions">
|
<div class="field color-field">
|
||||||
<button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
|
<label for="new_project_column_color">{{ctx.Locale.Tr "repo.projects.column.color"}}</label>
|
||||||
<button data-url="{{$.Link}}" class="ui primary button" id="new_project_column_submit">{{ctx.Locale.Tr "repo.projects.column.new_submit"}}</button>
|
<div class="color picker column">
|
||||||
</div>
|
<input class="color-picker" maxlength="7" placeholder="#c320f6" id="new_project_column_color_picker" name="color">
|
||||||
</form>
|
{{template "repo/issue/label_precolors"}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text right actions">
|
||||||
|
<button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
|
||||||
|
<button data-url="{{$.Link}}" class="ui primary button" id="new_project_column_submit">{{ctx.Locale.Tr "repo.projects.column.new_submit"}}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{end}}
|
||||||
{{end}}
|
</div>
|
||||||
|
|
||||||
|
<div class="content">{{$.Project.RenderedContent|Str2html}}</div>
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">{{$.Project.RenderedContent|Str2html}}</div>
|
|
||||||
|
|
||||||
<div class="divider"></div>
|
|
||||||
|
|
||||||
<div id="project-board">
|
<div id="project-board">
|
||||||
<div class="board {{if .CanWriteProjects}}sortable{{end}}">
|
<div class="board {{if .CanWriteProjects}}sortable{{end}}">
|
||||||
{{range .Columns}}
|
{{range .Columns}}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
{{template "base/alert" .}}
|
{{template "base/alert" .}}
|
||||||
|
|
||||||
{{if .workflows}}
|
{{if .HasWorkflowsOrRuns}}
|
||||||
<div class="ui stackable grid">
|
<div class="ui stackable grid">
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<div class="ui fluid vertical menu">
|
<div class="ui fluid vertical menu">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="flex-list">
|
<div class="flex-list">
|
||||||
{{if eq (len .Runs) 0}}
|
{{if not .Runs}}
|
||||||
<div class="empty-placeholder">
|
<div class="empty-placeholder">
|
||||||
{{svg "octicon-no-entry" 48}}
|
{{svg "octicon-no-entry" 48}}
|
||||||
<h2>{{if $.IsFiltered}}{{ctx.Locale.Tr "actions.runs.no_results"}}{{else}}{{ctx.Locale.Tr "actions.runs.no_runs"}}{{end}}</h2>
|
<h2>{{if $.IsFiltered}}{{ctx.Locale.Tr "actions.runs.no_results"}}{{else}}{{ctx.Locale.Tr "actions.runs.no_runs"}}{{end}}</h2>
|
||||||
|
|
|
@ -201,7 +201,7 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
<span title="{{ctx.Locale.Tr "gpg.default_key"}}">{{svg "gitea-lock-cog" 16 "gt-mr-3"}}</span>
|
<span title="{{ctx.Locale.Tr "gpg.default_key"}}">{{svg "gitea-lock-cog" 16 "gt-mr-3"}}</span>
|
||||||
<span class="ui text gt-mr-3">{{ctx.Locale.Tr "repo.commits.signed_by"}}:</span>
|
<span class="ui text gt-mr-3">{{ctx.Locale.Tr "repo.commits.signed_by"}}:</span>
|
||||||
{{ctx.AvatarUtils.AvatarByEmail .Verification.SigningEmail "" 28}}
|
{{ctx.AvatarUtils.AvatarByEmail .Verification.SigningEmail "" 28 "gt-mr-3"}}
|
||||||
<strong>{{.Verification.SigningUser.GetDisplayName}}</strong>
|
<strong>{{.Verification.SigningUser.GetDisplayName}}</strong>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -108,25 +108,27 @@
|
||||||
</tr>
|
</tr>
|
||||||
{{if and (eq .GetType 3) $hasmatch}}
|
{{if and (eq .GetType 3) $hasmatch}}
|
||||||
{{$match := index $section.Lines $line.Match}}
|
{{$match := index $section.Lines $line.Match}}
|
||||||
{{if or (gt (len $line.Comments) 0) (gt (len $match.Comments) 0)}}
|
{{if or $line.Comments $match.Comments}}
|
||||||
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
||||||
<td class="add-comment-left" colspan="4">
|
<td class="add-comment-left" colspan="4">
|
||||||
{{if gt (len $line.Comments) 0}}
|
{{if $line.Comments}}
|
||||||
{{if eq $line.GetCommentSide "previous"}}
|
{{if eq $line.GetCommentSide "previous"}}
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if gt (len $match.Comments) 0}}
|
{{if $match.Comments}}
|
||||||
{{if eq $match.GetCommentSide "previous"}}
|
{{if eq $match.GetCommentSide "previous"}}
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}}
|
{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td class="add-comment-right" colspan="4">
|
<td class="add-comment-right" colspan="4">
|
||||||
{{if eq $line.GetCommentSide "proposed"}}
|
{{if $line.Comments}}
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
{{if eq $line.GetCommentSide "proposed"}}
|
||||||
|
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if gt (len $match.Comments) 0}}
|
{{if $match.Comments}}
|
||||||
{{if eq $match.GetCommentSide "proposed"}}
|
{{if eq $match.GetCommentSide "proposed"}}
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}}
|
{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -134,13 +136,11 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if gt (len $line.Comments) 0}}
|
{{else if $line.Comments}}
|
||||||
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
||||||
<td class="add-comment-left" colspan="4">
|
<td class="add-comment-left" colspan="4">
|
||||||
{{if gt (len $line.Comments) 0}}
|
{{if eq $line.GetCommentSide "previous"}}
|
||||||
{{if eq $line.GetCommentSide "previous"}}
|
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td class="add-comment-right" colspan="4">
|
<td class="add-comment-right" colspan="4">
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
*/}}</td>
|
*/}}</td>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{if gt (len $line.Comments) 0}}
|
{{if $line.Comments}}
|
||||||
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
|
||||||
<td class="add-comment-left add-comment-right" colspan="5">
|
<td class="add-comment-left add-comment-right" colspan="5">
|
||||||
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
|
||||||
|
|
|
@ -81,12 +81,12 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
|
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||||
<div class="ui labeled button
|
<div class="ui labeled button
|
||||||
{{if or (not $.IsSigned) (and (not $.CanSignedUserFork) (eq (len $.UserAndOrgForks) 0))}}
|
{{if or (not $.IsSigned) (and (not $.CanSignedUserFork) (not $.UserAndOrgForks))}}
|
||||||
disabled
|
disabled
|
||||||
{{end}}"
|
{{end}}"
|
||||||
{{if not $.IsSigned}}
|
{{if not $.IsSigned}}
|
||||||
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_guest_user"}}"
|
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_guest_user"}}"
|
||||||
{{else if and (not $.CanSignedUserFork) (eq (len $.UserAndOrgForks) 0)}}
|
{{else if and (not $.CanSignedUserFork) (not $.UserAndOrgForks)}}
|
||||||
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_from_self"}}"
|
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_from_self"}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
>
|
>
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
href="{{AppSubUrl}}/{{(index $.UserAndOrgForks 0).FullName}}"
|
href="{{AppSubUrl}}/{{(index $.UserAndOrgForks 0).FullName}}"
|
||||||
{{/*else is not required here, because the button shouldn't link to any site if you can't create a fork*/}}
|
{{/*else is not required here, because the button shouldn't link to any site if you can't create a fork*/}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if eq (len $.UserAndOrgForks) 0}}
|
{{else if not $.UserAndOrgForks}}
|
||||||
href="{{AppSubUrl}}/repo/fork/{{.ID}}"
|
href="{{AppSubUrl}}/repo/fork/{{.ID}}"
|
||||||
{{else}}
|
{{else}}
|
||||||
data-modal="#fork-repo-modal"
|
data-modal="#fork-repo-modal"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div id="issue-filters" class="issue-list-toolbar">
|
<div id="issue-filters" class="issue-list-toolbar">
|
||||||
<div class="issue-list-toolbar-left">
|
<div class="issue-list-toolbar-left">
|
||||||
{{if and ($.CanWriteIssuesOrPulls) (gt (len .Issues) 0)}}
|
{{if and $.CanWriteIssuesOrPulls .Issues}}
|
||||||
<input type="checkbox" autocomplete="off" class="issue-checkbox-all gt-mr-4" title="{{ctx.Locale.Tr "repo.issues.action_check_all"}}">
|
<input type="checkbox" autocomplete="off" class="issue-checkbox-all gt-mr-4" title="{{ctx.Locale.Tr "repo.issues.action_check_all"}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "repo/issue/openclose" .}}
|
{{template "repo/issue/openclose" .}}
|
||||||
|
|
|
@ -339,7 +339,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if gt (len .WorkingUsers) 0}}
|
{{if .WorkingUsers}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div class="ui comments">
|
<div class="ui comments">
|
||||||
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Time) | Safe}}</strong></span>
|
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Time) | Safe}}</strong></span>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
{{template "repo/issue/navbar" .}}
|
{{template "repo/issue/navbar" .}}
|
||||||
<a class="ui small primary button" href="{{.RepoLink}}/issues/new/choose?project={{.Project.ID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
|
<a class="ui small primary button" href="{{.RepoLink}}/issues/new/choose?project={{.Project.ID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui container fluid padded">
|
||||||
{{template "projects/view" .}}
|
{{template "projects/view" .}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -140,7 +140,7 @@
|
||||||
{{ctx.Locale.TrN $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n" $waitingOfficial}}
|
{{ctx.Locale.TrN $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n" $waitingOfficial}}
|
||||||
</span>
|
</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
|
{{if and (not .PullRequest.HasMerged) .PullRequest.ConflictedFiles}}
|
||||||
<span class="conflicting flex-text-inline">
|
<span class="conflicting flex-text-inline">
|
||||||
{{svg "octicon-x" 14}}
|
{{svg "octicon-x" 14}}
|
||||||
{{ctx.Locale.TrN (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n" (len .PullRequest.ConflictedFiles)}}
|
{{ctx.Locale.TrN (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n" (len .PullRequest.ConflictedFiles)}}
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
{{else if .GetOpType.InActions "comment_issue" "approve_pull_request" "reject_pull_request" "comment_pull"}}
|
{{else if .GetOpType.InActions "comment_issue" "approve_pull_request" "reject_pull_request" "comment_pull"}}
|
||||||
<a href="{{.GetCommentLink ctx}}" class="text truncate issue title">{{(.GetIssueTitle ctx) | RenderEmoji $.Context | RenderCodeBlock}}</a>
|
<a href="{{.GetCommentLink ctx}}" class="text truncate issue title">{{(.GetIssueTitle ctx) | RenderEmoji $.Context | RenderCodeBlock}}</a>
|
||||||
{{$comment := index .GetIssueInfos 1}}
|
{{$comment := index .GetIssueInfos 1}}
|
||||||
{{if gt (len $comment) 0}}
|
{{if $comment}}
|
||||||
<div class="markup gt-font-14">{{RenderMarkdownToHtml ctx $comment}}</div>
|
<div class="markup gt-font-14">{{RenderMarkdownToHtml ctx $comment}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if .GetOpType.InActions "merge_pull_request"}}
|
{{else if .GetOpType.InActions "merge_pull_request"}}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="gt-p-0">
|
<div class="gt-p-0">
|
||||||
<div id="notification_table">
|
<div id="notification_table">
|
||||||
{{if eq (len .Notifications) 0}}
|
{{if not .Notifications}}
|
||||||
<div class="gt-df gt-ac gt-fc gt-p-4">
|
<div class="gt-df gt-ac gt-fc gt-p-4">
|
||||||
{{svg "octicon-inbox" 56 "gt-mb-4"}}
|
{{svg "octicon-inbox" 56 "gt-mb-4"}}
|
||||||
{{if eq .Status 1}}
|
{{if eq .Status 1}}
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
{{if eq (len .Issues) 0}}
|
{{if not .Issues}}
|
||||||
{{ctx.Locale.Tr "notification.no_subscriptions"}}
|
{{ctx.Locale.Tr "notification.no_subscriptions"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{template "shared/issuelist" dict "." . "listType" "dashboard"}}
|
{{template "shared/issuelist" dict "." . "listType" "dashboard"}}
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
{{if .Verified}}
|
{{if .Verified}}
|
||||||
<span class="flex-text-block" data-tooltip-content="{{ctx.Locale.Tr "settings.gpg_key_verified_long"}}">{{svg "octicon-verified"}} <strong>{{ctx.Locale.Tr "settings.gpg_key_verified"}}</strong></span>
|
<span class="flex-text-block" data-tooltip-content="{{ctx.Locale.Tr "settings.gpg_key_verified_long"}}">{{svg "octicon-verified"}} <strong>{{ctx.Locale.Tr "settings.gpg_key_verified"}}</strong></span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if gt (len .Emails) 0}}
|
{{if .Emails}}
|
||||||
<span class="flex-text-block" data-tooltip-content="{{ctx.Locale.Tr "settings.gpg_key_matched_identities_long"}}">{{svg "octicon-mail"}} {{ctx.Locale.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}<strong>{{.Email}} </strong>{{end}}</span>
|
<span class="flex-text-block" data-tooltip-content="{{ctx.Locale.Tr "settings.gpg_key_matched_identities_long"}}">{{svg "octicon-mail"}} {{ctx.Locale.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}<strong>{{.Email}} </strong>{{end}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="flex-item-body">
|
<div class="flex-item-body">
|
||||||
|
|
|
@ -149,12 +149,18 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN
|
||||||
|
|
||||||
url := rootURL + "/repodata"
|
url := rootURL + "/repodata"
|
||||||
|
|
||||||
req := NewRequest(t, "GET", url+"/dummy.xml")
|
req := NewRequest(t, "HEAD", url+"/dummy.xml")
|
||||||
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", url+"/dummy.xml")
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
t.Run("repomd.xml", func(t *testing.T) {
|
t.Run("repomd.xml", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req = NewRequest(t, "HEAD", url+"/repomd.xml")
|
||||||
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", url+"/repomd.xml")
|
req = NewRequest(t, "GET", url+"/repomd.xml")
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
gitea_context "code.gitea.io/gitea/modules/context"
|
gitea_context "code.gitea.io/gitea/modules/context"
|
||||||
|
doctor "code.gitea.io/gitea/modules/doctor"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/services/migrations"
|
"code.gitea.io/gitea/services/migrations"
|
||||||
|
@ -47,10 +48,11 @@ func testMirrorPush(t *testing.T, u *url.URL) {
|
||||||
ctx := NewAPITestContext(t, user.LowerName, srcRepo.Name)
|
ctx := NewAPITestContext(t, user.LowerName, srcRepo.Name)
|
||||||
|
|
||||||
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t)
|
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t)
|
||||||
|
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape("does-not-matter")), user.LowerName, userPassword)(t)
|
||||||
|
|
||||||
mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, mirrors, 1)
|
assert.Len(t, mirrors, 2)
|
||||||
|
|
||||||
ok := mirror_service.SyncPushMirror(context.Background(), mirrors[0].ID)
|
ok := mirror_service.SyncPushMirror(context.Background(), mirrors[0].ID)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
@ -71,6 +73,30 @@ func testMirrorPush(t *testing.T, u *url.URL) {
|
||||||
|
|
||||||
assert.Equal(t, srcCommit.ID, mirrorCommit.ID)
|
assert.Equal(t, srcCommit.ID, mirrorCommit.ID)
|
||||||
|
|
||||||
|
// Test that we can "repair" push mirrors where the remote doesn't exist in git's state.
|
||||||
|
// To do that, we artificially remove the remote...
|
||||||
|
cmd := git.NewCommand(db.DefaultContext, "remote", "rm").AddDynamicArguments(mirrors[0].RemoteName)
|
||||||
|
_, _, err = cmd.RunStdString(&git.RunOpts{Dir: srcRepo.RepoPath()})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// ...then ensure that trying to get its remote address fails
|
||||||
|
_, err = repo_model.GetPushMirrorRemoteAddress(srcRepo.OwnerName, srcRepo.Name, mirrors[0].RemoteName)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
// ...and that we can fix it.
|
||||||
|
err = doctor.FixPushMirrorsWithoutGitRemote(db.DefaultContext, nil, true)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// ...and after fixing, we only have one remote
|
||||||
|
mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, mirrors, 1)
|
||||||
|
|
||||||
|
// ...one we can get the address of, and it's not the one we removed
|
||||||
|
remoteAddress, err := repo_model.GetPushMirrorRemoteAddress(srcRepo.OwnerName, srcRepo.Name, mirrors[0].RemoteName)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Contains(t, remoteAddress, "does-not-matter")
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t)
|
doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t)
|
||||||
mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
||||||
|
|
|
@ -469,3 +469,30 @@ func TestSignInOAuthCallbackSignIn(t *testing.T) {
|
||||||
userAfterLogin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userGitLab.ID})
|
userAfterLogin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userGitLab.ID})
|
||||||
assert.Greater(t, userAfterLogin.LastLoginUnix, userGitLab.LastLoginUnix)
|
assert.Greater(t, userAfterLogin.LastLoginUnix, userGitLab.LastLoginUnix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSignUpViaOAuthWithMissingFields(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
// enable auto-creation of accounts via OAuth2
|
||||||
|
enableAutoRegistration := setting.OAuth2Client.EnableAutoRegistration
|
||||||
|
setting.OAuth2Client.EnableAutoRegistration = true
|
||||||
|
defer func() {
|
||||||
|
setting.OAuth2Client.EnableAutoRegistration = enableAutoRegistration
|
||||||
|
}()
|
||||||
|
|
||||||
|
// OAuth2 authentication source GitLab
|
||||||
|
gitlabName := "gitlab"
|
||||||
|
addAuthSource(t, authSourcePayloadGitLabCustom(gitlabName))
|
||||||
|
userGitLabUserID := "5678"
|
||||||
|
|
||||||
|
// The Goth User returned by the oauth2 integration is missing
|
||||||
|
// an email address, so we won't be able to automatically create a local account for it.
|
||||||
|
defer mockCompleteUserAuth(func(res http.ResponseWriter, req *http.Request) (goth.User, error) {
|
||||||
|
return goth.User{
|
||||||
|
Provider: gitlabName,
|
||||||
|
UserID: userGitLabUserID,
|
||||||
|
}, nil
|
||||||
|
})()
|
||||||
|
req := NewRequest(t, "GET", fmt.Sprintf("/user/oauth2/%s/callback?code=XYZ&state=XYZ", gitlabName))
|
||||||
|
resp := MakeRequest(t, req, http.StatusSeeOther)
|
||||||
|
assert.Equal(t, test.RedirectURL(resp), "/user/link_account")
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
auth_model "code.gitea.io/gitea/models/auth"
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
|
@ -297,3 +300,82 @@ func TestUserLocationMapLink(t *testing.T) {
|
||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true)
|
htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPagination(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
// Force pagination to almost always happen.
|
||||||
|
defer test.MockVariableValue(&setting.UI.IssuePagingNum, 1)()
|
||||||
|
|
||||||
|
session := loginUser(t, "user2")
|
||||||
|
|
||||||
|
assertHref := func(t *testing.T, resp *httptest.ResponseRecorder, expectedHref string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
href, ok := htmlDoc.Find(".pagination a.item").Not(".active").Not(".navigation").Attr("href")
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.EqualValues(t, expectedHref, href)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pagination links can be seen multiple times, due to 'last' or 'next' having
|
||||||
|
// the same link, so take that into consideration when writing asserts.
|
||||||
|
t.Run("Issues", func(t *testing.T) {
|
||||||
|
t.Run("No selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/issues")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, "/issues?page=2&q=&type=your_repositories&repos=%5B%5D&sort=recentupdate&state=open&labels=")
|
||||||
|
})
|
||||||
|
t.Run("Selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
escapedQuery := url.QueryEscape("[3,5]")
|
||||||
|
req := NewRequest(t, "GET", "/issues?repos="+escapedQuery)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, fmt.Sprintf(`/issues?page=2&q=&type=your_repositories&repos=%s&sort=recentupdate&state=open&labels=`, escapedQuery))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Pulls", func(t *testing.T) {
|
||||||
|
t.Run("No selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/pulls")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, "/pulls?page=2&q=&type=your_repositories&repos=%5B%5D&sort=recentupdate&state=open&labels=")
|
||||||
|
})
|
||||||
|
t.Run("Selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
escapedQuery := url.QueryEscape("[1,3]")
|
||||||
|
req := NewRequest(t, "GET", "/pulls?repos="+escapedQuery)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, fmt.Sprintf("/pulls?page=2&q=&type=your_repositories&repos=%s&sort=recentupdate&state=open&labels=", escapedQuery))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Milestones", func(t *testing.T) {
|
||||||
|
t.Run("No selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/milestones")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, fmt.Sprintf(`/milestones?page=2&q=&repos=%s&sort=&state=open`, url.QueryEscape("[1,42]")))
|
||||||
|
})
|
||||||
|
t.Run("Selected repositories", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
escapedQuery := url.QueryEscape("[1]")
|
||||||
|
req := NewRequest(t, "GET", "/milestones?repos="+escapedQuery)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
assertHref(t, resp, fmt.Sprintf(`/milestones?page=2&q=&repos=%s&sort=&state=open`, escapedQuery))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'jquery';
|
||||||
import {checkAppUrl} from '../common-global.js';
|
import {checkAppUrl} from '../common-global.js';
|
||||||
import {hideElem, showElem, toggleElem} from '../../utils/dom.js';
|
import {hideElem, showElem, toggleElem} from '../../utils/dom.js';
|
||||||
|
|
||||||
const {csrfToken} = window.config;
|
const {csrfToken, appSubUrl} = window.config;
|
||||||
|
|
||||||
export function initAdminCommon() {
|
export function initAdminCommon() {
|
||||||
if ($('.page-content.admin').length === 0) {
|
if ($('.page-content.admin').length === 0) {
|
||||||
|
@ -172,7 +172,8 @@ export function initAdminCommon() {
|
||||||
|
|
||||||
if ($('.admin.authentication').length > 0) {
|
if ($('.admin.authentication').length > 0) {
|
||||||
$('#auth_name').on('input', function () {
|
$('#auth_name').on('input', function () {
|
||||||
$('#oauth2-callback-url').text(`${window.location.origin}/user/oauth2/${encodeURIComponent($(this).val())}/callback`);
|
// appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash.
|
||||||
|
$('#oauth2-callback-url').text(`${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent($(this).val())}/callback`);
|
||||||
}).trigger('input');
|
}).trigger('input');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue