Compare commits

...

55 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
76f3497e3b Fix embedded Postgres configuration and initialization order
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
2026-02-06 01:48:00 +00:00
copilot-swe-agent[bot]
74d4d9a262 Fix trailing whitespace in code review feedback
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
2026-02-06 01:32:05 +00:00
deepsource-autofix[bot]
f5daceef55 style: format code with Go fmt and Gofumpt
This commit fixes the style issues introduced in 4616bd6 according to the output
from Go fmt and Gofumpt.

Details: https://github.com/gogs/gogs/pull/8150
2026-02-06 01:29:34 +00:00
copilot-swe-agent[bot]
4616bd64dd Add embedded PostgreSQL support via --embedded-postgres flag
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
2026-02-06 01:29:19 +00:00
copilot-swe-agent[bot]
39b27c3503 Initial plan 2026-02-06 01:18:32 +00:00
Joe Chen
ed5d02e036 chore: free up "docs/" subdir for Mintlify
[skip ci]
2026-02-01 23:15:47 -05:00
dependabot[bot]
5874791a57 mod: bump golang.org/x/crypto from 0.45.0 to 0.47.0 (#8141)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-01 09:20:24 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
17ad3d3425 pkgr: fix up install main package path (#8146) 2026-02-01 09:12:12 -05:00
dependabot[bot]
9b2a967e45 mod: bump github.com/editorconfig/editorconfig-core-go/v2 from 2.6.3 to 2.6.4 (#8143)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-01 09:01:09 -05:00
dependabot[bot]
e80635a449 mod: bump github.com/go-ldap/ldap/v3 from 3.4.11 to 3.4.12 (#8144)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-01 09:00:50 -05:00
Joe Chen
47bccf292d pkgr: fix up install path
[skip ci]
2026-02-01 08:53:52 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
38def73489 Update security policy for version support and advisories
[skip ci]
2026-02-01 08:16:22 -05:00
Copilot
6cf6422b88 Remove codecov config and upload in CI (#8145)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
2026-02-01 08:10:55 -05:00
dependabot[bot]
8d8d66ec1d mod: bump github.com/olekukonko/tablewriter from 1.1.0 to 1.1.3 (#8140)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-01 07:45:08 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
7ea2c4093f refactor: move main package from root to cmd/gogs (#8139)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:28:48 -05:00
dependabot[bot]
7ebfb202e4 mod: bump github.com/olekukonko/tablewriter from 0.0.5 to 1.1.0 (#8039)
Co-authored-by: Joe Chen <jc@unknwon.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:11:08 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
7b8c560f15 ci(go): use tparse for test output in non-Windows jobs (#8138)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:58:41 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
a636dcf678 fix(release): remove "v" prefix from archive names (#8137)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:42:45 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
3dcb74be39 release: cut CHANGELOG entries for 0.14.1
[skip ci]
2026-01-31 22:23:09 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
7ad425025e fix(ssh): git clone via built-in SSH server hangs (#8135)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:20:43 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
85abee4b9b chore: update release templates (#8134)
[skip ci]
2026-01-31 20:08:38 -05:00
Joe Chen
997c3c5eab chore: take care of legacy code 2026-01-31 20:07:49 -05:00
Joe Chen
a5ddb2665e chore: bump dev version to 0.15
[skip ci]
2026-01-31 20:04:55 -05:00
Joe Chen
b68e6886c6 release: cut CHANGELOG entries for 0.14.0
[skip ci]
2026-01-31 16:29:15 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
ac7ba9c8a7 locale: sync from Crowdin (#8131) 2026-01-31 16:07:47 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
dd862ee058 ci(docker): auto-tag minor version for stable releases (#8129)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 15:50:42 -05:00
Joe Chen
f94042ce6f chore: update release templates
[skip ci]
2026-01-31 15:17:59 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
628216d588 security: require authentication for attachment uploads (#8128)
https://github.com/gogs/gogs/security/advisories/GHSA-fc3h-92p8-h36f

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:40:39 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
7306b955a9 ci: use external unknwon/send-email-on-failure action (#8127) 2026-01-31 13:29:30 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
fc6d1e2055 ci(release): add email notification on failure for main branch (#8126)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:13:51 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
3b01892d85 fix(docker): correct binary path in Dockerfiles(#8125)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:02:25 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
7b7e38c880 security: prevent deletion of protected and default branches via web UI (#8124)
https://github.com/gogs/gogs/security/advisories/GHSA-2c6v-8r3v-gh6p

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 12:51:07 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
bb68c0a042 security: fix cross-repository label modification vulnerability (#8123)
https://github.com/gogs/gogs/security/advisories/GHSA-cv22-72px-f4gh

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 12:28:30 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
68271e6af0 chore: update vulnerability reporting guidelines
[skip ci]
2026-01-31 12:01:23 -05:00
Copilot
4f5b00f8c4 Build artifacts for every commit on main (#8122)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Joe Chen <jc@unknwon.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:58:45 -05:00
Joe Chen
5d3ffd132b chore: bunch of minor tidy-ups
[skip ci]
2026-01-31 09:59:32 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
ee65aa89ca ci: add cross-compilation workflow for releases (#8121)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:40:32 -05:00
dependabot[bot]
a1a97de76f mod: bump modernc.org/sqlite from 1.38.2 to 1.39.0 (#8038)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-30 23:19:19 -05:00
Matthias Jobst
9963268267 docker: ignore proxy for healthcheck command (#7532)
Co-authored-by: Joe Chen <jc@unknwon.io>
2026-01-30 23:12:49 -05:00
dependabot[bot]
49a45290ae mod: bump gopkg.in/macaron.v1 from 1.5.0 to 1.5.1 (#8035)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ᴊᴏᴇ ᴄʜᴇɴ <jc@unknwon.io>
2026-01-30 23:10:14 -05:00
Yaroslav Halchenko
3cc8e7aa6d Fix typos throughout the codebase (#7514) 2026-01-30 23:03:05 -05:00
Rajat Jain
9f1499f3ab Support comparing tags in addition to branches (#6493)
Co-authored-by: Joe Chen <jc@unknwon.io>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-30 22:45:03 -05:00
Jeff Li
77dba1b5ea repo: fix 500 error on watchers and stargazers pages using MSSQL (#6386)
Co-authored-by: Joe Chen <jc@unknwon.io>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-30 22:24:43 -05:00
Georg Wicke-Arndt
f70f29fdb0 Show file name in browser tab title when viewing files (#5896) 2026-01-30 22:11:10 -05:00
Joe Chen
ed6109d35d chore: update AGENTS.md
[skip ci]
2026-01-30 22:01:02 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
54e08ba678 docker: add image versions instructions
[skip ci]
2026-01-30 21:52:31 -05:00
Sino
87c8faaf08 Standardize HTTP status codes (#7851)
Co-authored-by: Joe Chen <jc@unknwon.io>
2026-01-30 09:27:59 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
1b226ca48d repo: improve authz for resources (#8119)
https://github.com/gogs/gogs/security/advisories/GHSA-jj5m-h57j-5gv7
2026-01-29 20:56:09 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
e3bb4165dc database: impersonate pure-Go SQLite driver as the old "sqlite3" (#8118) 2026-01-29 14:49:36 -05:00
pikomonde
df3d945a2c config: validate and print warnings for invalid options (#7705)
Co-authored-by: Joe Chen <jc@unknwon.io>
2026-01-28 11:36:03 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
ae41bab5f2 repo: always list tree entries with verbatim (#8116)
Co-authored-by: Ali <alicse3@gmail.com>
2026-01-28 10:11:30 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
2316b09eaf database: fully switch over to pure-Go SQLite driver (#8115) 2026-01-27 22:45:50 -05:00
Copilot
3477bbac0e Add ED25519 test coverage and refactor SSH key parsing tests (#8107)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:04:12 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
bb3cab921b chore: update release template (#8110)
[skip ci]
2026-01-24 23:07:27 -05:00
Copilot
1cdeef2ce8 Replace tool.IsMaliciousPath with pathutil.Clean and move IsSameSite to urlutil (#8106) 2026-01-23 21:13:27 -05:00
122 changed files with 1461 additions and 924 deletions

View File

@@ -1,6 +1,7 @@
--- ---
name: "Dev: Release a minor version" name: "Dev: Release a minor version"
about: ONLY USED BY MAINTAINERS. about: ONLY USED BY MAINTAINERS.
assignees: "unknwon"
title: "Release [VERSION]" title: "Release [VERSION]"
labels: 📸 release labels: 📸 release
--- ---
@@ -13,40 +14,33 @@ On the `main` branch:
- [ ] Close stale issues with the label [status: needs feedback](https://github.com/gogs/gogs/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+needs+feedback%22). - [ ] Close stale issues with the label [status: needs feedback](https://github.com/gogs/gogs/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+needs+feedback%22).
- [ ] [Sync locales from Crowdin](https://github.com/gogs/gogs/blob/main/docs/dev/import_locale.md). - [ ] [Sync locales from Crowdin](https://github.com/gogs/gogs/blob/main/docs/dev/import_locale.md).
- [ ] [Update CHANGELOG](https://github.com/gogs/gogs/commit/540134d4436d8da82247dd2cabe9312ca2f5b1f1) to include entries for the current minor release. - [ ] [Update CHANGELOG](https://github.com/gogs/gogs/commit/f1102a7a7c545ec221d2906f02fa19170d96f96d) to include entries for the current minor release.
- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.12`. - Do not forget adding entries for GHSA patches.
- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.14`.
## During release ## During release
On the release branch: On the release branch:
- [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f17e7d5a2c36c52a1121d2315f3d75dcd8053b89) to the current release, e.g. `0.12.0+dev` -> `0.12.0`. - [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f0e3cd90f8d7695960eeef2e4e54b2e717302f6c) to the current release, e.g. `0.14.0+dev` -> `0.14.0`.
- [ ] Wait for GitHub Actions to complete and no failed jobs. - [ ] Wait for GitHub Actions to complete and no failed jobs.
- [ ] Publish new RC releases (e.g. `v0.12.0-rc.1`, `v0.12.0-rc.2`) to ensure Docker workflow succeeds. **Make sure the tag is created on the release branch**. - [ ] Publish new RC releases (e.g. `v0.14.0-rc.1`, `v0.14.0-rc.2`) ⚠️ **on the release branch** ⚠️ and ensure Docker and release workflows both succeed.
- [ ] Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
- [ ] Download one of the release archives and run through application setup to make sure nothing blows up.
- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) ⚠️ **on the release branch** ⚠️ with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current minor release.
- [ ] [Wait for new image tags for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs).
- Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up. - Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current minor release. **Make sure the tag is created on the release branch**. - [ ] Download all release archives and [generate SHA256 checksum](https://github.com/gogs/gogs/blob/main/docs/dev/release/sha256.sh) for all binaries to the file `checksum_sha256.txt`.
- [ ] [Wait for a new image tag for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs). - [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
- [ ] [Push a new Docker image tag](https://github.com/gogs/gogs/blob/main/docs/dev/release/release_new_version.md#update-docker-image-tag) as `<MAJOR>.<MINOR>` to both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs), e.g.:
- [ ] [Compile and pack binaries](https://github.com/gogs/gogs/blob/main/docs/dev/release/release_new_version.md#compile-and-pack-binaries) (all prefixed with `gogs_<MAJOR>.<MINOR>.<PATCH>_`, e.g. `gogs_0.12.0_`):
- [ ] macOS: `darwin_amd64.zip`, `darwin_arm64.zip`
- [ ] Linux: `linux_386.tar.gz`, `linux_386.zip`, `linux_amd64.tar.gz`, `linux_amd64.zip`
- [ ] ARM: `linux_armv7.tar.gz`, `linux_armv7.zip`, `linux_armv8.tar.gz`, `linux_armv8.zip`
- [ ] Windows: `windows_amd64.zip`, `windows_amd64_mws.zip`
- [ ] [Generate SHA256 checksum](https://github.com/gogs/gogs/blob/main/docs/dev/release/sha256.sh) for all binaries to the file `checksum_sha256.txt`.
- [ ] Upload all binaries and `checksum_sha256.txt` to:
- [ ] GitHub release
- [ ] https://dl.gogs.io
- [ ] Update content of [Install from binary](https://gogs.io/docs/installation/install_from_binary).
## After release ## After release
On the `main` branch: On the `main` branch:
- [ ] Publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release.
- [ ] Update the repository mirror on [Gitee](https://gitee.com/unknwon/gogs). - [ ] Update the repository mirror on [Gitee](https://gitee.com/unknwon/gogs).
- [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements). - [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements).
- [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the minor release. - [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the minor release.
- [ ] Publish a new release article on [OSChina](http://my.oschina.net/Obahua/admin/releases). - [ ] Close the milestone for the minor release.
- [ ] Close the minor milestone. - [ ] [Bump the hard-coded version](https://github.com/gogs/gogs/commit/a98968436cd5841cf691bb0b80c54c81470d1676) to the new develop version, e.g. `0.14.0+dev` -> `0.15.0+dev`.
- [ ] [Bump the hard-coded version](https://github.com/gogs/gogs/commit/a98968436cd5841cf691bb0b80c54c81470d1676) to the new develop version, e.g. `0.12.0+dev` -> `0.13.0+dev`.
- [ ] Run `task legacy` to identify deprecated code that is aimed to be removed in current develop version. - [ ] Run `task legacy` to identify deprecated code that is aimed to be removed in current develop version.
- [ ] **After 14 days**, publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release.

View File

@@ -1,6 +1,7 @@
--- ---
name: "Dev: Release a patch version" name: "Dev: Release a patch version"
about: ONLY USED BY MAINTAINERS. about: ONLY USED BY MAINTAINERS.
assignees: "unknwon"
title: "Release [VERSION]" title: "Release [VERSION]"
labels: 📸 release labels: 📸 release
--- ---
@@ -13,7 +14,7 @@ On the release branch:
- [ ] Make sure all commits are cherry-picked from the `main` branch by checking the patch milestone. - [ ] Make sure all commits are cherry-picked from the `main` branch by checking the patch milestone.
- Run `task build` for every cherry-picked commit to make sure there is no compilation error. - Run `task build` for every cherry-picked commit to make sure there is no compilation error.
- [ ] [Update CHANGELOG on the `main` branch](https://github.com/gogs/gogs/commit/e6c5633f580399c8f4dfc07166a63a01c6c70346) to include entries for the current patch release. - [ ] [Update CHANGELOG on the `main` branch](https://github.com/gogs/gogs/commit/f1102a7a7c545ec221d2906f02fa19170d96f96d) to include entries for the current patch release.
## During release ## During release
@@ -21,28 +22,18 @@ On the release branch:
- [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f0e3cd90f8d7695960eeef2e4e54b2e717302f6c) to the current release, e.g. `0.12.0` -> `0.12.1`. - [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f0e3cd90f8d7695960eeef2e4e54b2e717302f6c) to the current release, e.g. `0.12.0` -> `0.12.1`.
- [ ] Wait for GitHub Actions to complete and no failed jobs. - [ ] Wait for GitHub Actions to complete and no failed jobs.
- [ ] Publish new RC releases in [GitHub release](https://github.com/gogs/gogs/releases) (e.g. `v0.12.0-rc.1`, `v0.12.0-rc.2`) to ensure Docker workflow succeeds. - [ ] Publish new RC releases in [GitHub release](https://github.com/gogs/gogs/releases) (e.g. `v0.12.0-rc.1`, `v0.12.0-rc.2`) ⚠️ **on the release branch** ⚠️ and ensure Docker workflow succeeds.
- ⚠️ **Make sure the tag is created on the release branch**. - [ ] Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
- Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up. - [ ] Download one of the release archives and run through application setup to make sure nothing blows up.
- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current patch release and all previous releases with same minor version. - [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) ⚠️ **on the release branch** ⚠️ with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current patch release and all previous releases with same minor version.
- ⚠️ **Make sure the tag is created on the release branch**.
- [ ] Update all previous GitHub releases with same minor version with the warning: - [ ] Update all previous GitHub releases with same minor version with the warning:
``` ```
** Heads up! There is a new patch release [0.12.1](https://github.com/gogs/gogs/releases/tag/v0.12.1) available, we recommend directly installing or upgrading to that version.** ** Heads up! There is a new patch release [0.12.1](https://github.com/gogs/gogs/releases/tag/v0.12.1) available, we recommend directly installing or upgrading to that version.**
``` ```
- [ ] [Wait for a new image tag for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs). - [ ] [Wait for new image tags for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs).
- Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up. - Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
- [ ] [Update Docker image tag](https://www.notion.so/jcunknwon/Cheatsheet-and-playbooks-c3b053da42114411bd27285cd065b2a6?source=copy_link#1654f105c63f80958d96cd72e2f5df69) for the minor release `<MAJOR>.<MINOR>` on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs). - [ ] Download all release archives and [generate SHA256 checksum](https://github.com/gogs/gogs/blob/main/docs/dev/release/sha256.sh) for all binaries to the file `checksum_sha256.txt`.
- [ ] [Compile and pack binaries](https://www.notion.so/jcunknwon/Cheatsheet-and-playbooks-c3b053da42114411bd27285cd065b2a6?source=copy_link#1654f105c63f803f8bfcc117395d9747) (all prefixed with `gogs_<MAJOR>.<MINOR>.<PATCH>_`, e.g. `gogs_0.12.0_`): - [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
- [ ] macOS: `darwin_arm64.zip`, `darwin_amd64.zip`
- [ ] Linux: `linux_amd64.tar.gz`, `linux_amd64.zip`
- [ ] ARM: `linux_armv8.tar.gz`, `linux_armv8.zip`
- [ ] Windows: `windows_amd64.zip`, `windows_amd64_mws.zip`
- [ ] [Generate SHA256 checksum](https://www.notion.so/jcunknwon/Cheatsheet-and-playbooks-c3b053da42114411bd27285cd065b2a6?source=copy_link#1654f105c63f80d4a74ad8821a403f52) for all binaries to the file `checksum_sha256.txt`.
- [ ] Upload all binaries and `checksum_sha256.txt` to:
- [ ] GitHub release
- [ ] https://dl.gogs.io
- [ ] Update content of [Install from binary](https://gogs.io/docs/installation/install_from_binary).
## After release ## After release
@@ -54,5 +45,5 @@ On the `main` branch:
``` ```
- [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements). - [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements).
- [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the patch release. - [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the patch release.
- [ ] Close the patch milestone. - [ ] Close the milestone for the patch release.
- [ ] **After 14 days**, publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release. - [ ] **After 14 days**, publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release.

View File

@@ -19,18 +19,8 @@ jobs:
# --include-untagged-manifests: Deletes unreferenced manifests to maximize space # --include-untagged-manifests: Deletes unreferenced manifests to maximize space
doctl registry garbage-collection start --force --include-untagged-manifests doctl registry garbage-collection start --force --include-untagged-manifests
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -68,21 +68,11 @@ jobs:
image-ref: gogs/gogs:latest image-ref: gogs/gogs:latest
exit-code: '1' exit-code: '1'
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
buildx-next: buildx-next:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }} if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
@@ -145,21 +135,11 @@ jobs:
image-ref: gogs/gogs:next-latest image-ref: gogs/gogs:next-latest
exit-code: '1' exit-code: '1'
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
deploy-demo: deploy-demo:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }} if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
@@ -181,21 +161,11 @@ jobs:
kubectl rollout restart deployment gogs-demo -n gogs kubectl rollout restart deployment gogs-demo -n gogs
kubectl rollout status deployment gogs-demo -n gogs kubectl rollout status deployment gogs-demo -n gogs
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
buildx-pull-request: buildx-pull-request:
if: ${{ github.event_name == 'pull_request'}} if: ${{ github.event_name == 'pull_request'}}
@@ -285,8 +255,25 @@ jobs:
contents: read contents: read
packages: write packages: write
steps: steps:
- name: Compute image tag name - name: Compute image tags
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV run: |
IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
TAGS="gogs/gogs:$IMAGE_TAG
ghcr.io/gogs/gogs:$IMAGE_TAG"
# Add minor version tag for stable releases (no prerelease suffix per semver).
if [[ ! "$IMAGE_TAG" =~ - ]]; then
MINOR_TAG=$(echo "$IMAGE_TAG" | cut -d. -f1,2)
TAGS="$TAGS
gogs/gogs:$MINOR_TAG
ghcr.io/gogs/gogs:$MINOR_TAG"
fi
echo "TAGS<<EOF" >> $GITHUB_ENV
echo "$TAGS" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Checkout code - name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up QEMU - name: Set up QEMU
@@ -320,25 +307,13 @@ jobs:
context: . context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7 platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true push: true
tags: | tags: ${{ env.TAGS }}
gogs/gogs:${{ env.IMAGE_TAG }}
ghcr.io/gogs/gogs:${{ env.IMAGE_TAG }}
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
# Updates to the following section needs to be synced to all release branches within their lifecycles. # Updates to the following section needs to be synced to all release branches within their lifecycles.
buildx-next-release: buildx-next-release:
@@ -349,8 +324,25 @@ jobs:
contents: read contents: read
packages: write packages: write
steps: steps:
- name: Compute image tag name - name: Compute image tags
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV run: |
IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
TAGS="gogs/gogs:next-$IMAGE_TAG
ghcr.io/gogs/gogs:next-$IMAGE_TAG"
# Add minor version tag for stable releases (no prerelease suffix per semver).
if [[ ! "$IMAGE_TAG" =~ - ]]; then
MINOR_TAG=$(echo "$IMAGE_TAG" | cut -d. -f1,2)
TAGS="$TAGS
gogs/gogs:next-$MINOR_TAG
ghcr.io/gogs/gogs:next-$MINOR_TAG"
fi
echo "TAGS<<EOF" >> $GITHUB_ENV
echo "$TAGS" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Checkout code - name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up QEMU - name: Set up QEMU
@@ -385,25 +377,13 @@ jobs:
file: Dockerfile.next file: Dockerfile.next
platforms: linux/amd64,linux/arm64,linux/arm/v7 platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true push: true
tags: | tags: ${{ env.TAGS }}
gogs/gogs:next-${{ env.IMAGE_TAG }}
ghcr.io/gogs/gogs:next-${{ env.IMAGE_TAG }}
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }} if: ${{ failure() }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
digitalocean-gc: digitalocean-gc:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }} if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}

View File

@@ -72,28 +72,16 @@ jobs:
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Run tests with coverage - name: Run tests with coverage
run: go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic ./... run: |
- name: Upload coverage report to Codecov go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./... > test-report.json
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 go install github.com/mfridman/tparse@latest
with: tparse -all -file=test-report.json
file: ./coverage
flags: unittests
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }} if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
# Running tests with race detection consumes too much memory on Windows, # Running tests with race detection consumes too much memory on Windows,
# see https://github.com/golang/go/issues/46099 for details. # see https://github.com/golang/go/issues/46099 for details.
@@ -113,27 +101,12 @@ jobs:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Run tests with coverage - name: Run tests with coverage
run: go test -shuffle=on -v -coverprofile=coverage -covermode=atomic ./... run: go test -shuffle=on -v -coverprofile=coverage -covermode=atomic ./...
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
file: ./coverage
flags: unittests
- name: Send email on failure - name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }} if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
with: with:
server_address: smtp.mailgun.org smtp_username: ${{ secrets.SMTP_USERNAME }}
server_port: 465 smtp_password: ${{ secrets.SMTP_PASSWORD }}
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: GitHub Actions (${{ github.repository }}) job result
to: github-actions-8ce6454@unknwon.io
from: GitHub Actions (${{ github.repository }})
reply_to: noreply@unknwon.io
body: |
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
postgres: postgres:
name: Postgres name: Postgres
@@ -162,7 +135,10 @@ jobs:
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Run tests with coverage - name: Run tests with coverage
run: go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic ./internal/database/... run: |
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./internal/database/... > test-report.json
go install github.com/mfridman/tparse@latest
tparse -all -file=test-report.json
env: env:
GOGS_DATABASE_TYPE: postgres GOGS_DATABASE_TYPE: postgres
PGPORT: 5432 PGPORT: 5432
@@ -188,29 +164,13 @@ jobs:
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Run tests with coverage - name: Run tests with coverage
run: go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic ./internal/database/... run: |
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./internal/database/... > test-report.json
go install github.com/mfridman/tparse@latest
tparse -all -file=test-report.json
env: env:
GOGS_DATABASE_TYPE: mysql GOGS_DATABASE_TYPE: mysql
MYSQL_USER: root MYSQL_USER: root
MYSQL_PASSWORD: root MYSQL_PASSWORD: root
MYSQL_HOST: localhost MYSQL_HOST: localhost
MYSQL_PORT: 3306 MYSQL_PORT: 3306
sqlite-go:
name: SQLite - Go
strategy:
matrix:
go-version: [ 1.25.x ]
platform: [ ubuntu-latest ]
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Install Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ matrix.go-version }}
- name: Run tests with coverage
run: go test -shuffle=on -v -race -parallel=1 -coverprofile=coverage -covermode=atomic ./internal/database/...
env:
GOGS_DATABASE_TYPE: sqlite

146
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,146 @@
name: Release
on:
release:
types: [published]
push:
branches:
- main
pull_request:
paths:
- '.github/workflows/release.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
GOPROXY: "https://proxy.golang.org"
permissions:
contents: write
jobs:
build:
name: Build ${{ matrix.goos }}/${{ matrix.goarch }}${{ matrix.suffix }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- {goos: linux, goarch: amd64}
- {goos: linux, goarch: arm64}
- {goos: linux, goarch: "386"}
- {goos: darwin, goarch: amd64}
- {goos: darwin, goarch: arm64}
- {goos: windows, goarch: amd64}
- {goos: windows, goarch: arm64}
- {goos: windows, goarch: "386"}
- {goos: windows, goarch: amd64, suffix: "_mws", tags: minwinsvc}
- {goos: windows, goarch: arm64, suffix: "_mws", tags: minwinsvc}
- {goos: windows, goarch: "386", suffix: "_mws", tags: minwinsvc}
steps:
- name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.25.x
- name: Determine version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "version=${{ github.event.release.tag_name }}" | sed 's/version=v/version=/' >> "$GITHUB_OUTPUT"
echo "release_tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
elif [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "version=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
echo "release_tag=latest-commit-build" >> "$GITHUB_OUTPUT"
else
echo "version=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
echo "release_tag=release-archive-testing" >> "$GITHUB_OUTPUT"
fi
- name: Build binary
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
run: |
BINARY_NAME="gogs"
if [ "${{ matrix.goos }}" = "windows" ]; then
BINARY_NAME="gogs.exe"
fi
TAGS_FLAG=""
if [ -n "${{ matrix.tags }}" ]; then
TAGS_FLAG="-tags ${{ matrix.tags }}"
fi
go build -v \
-ldflags "
-X \"gogs.io/gogs/internal/conf.BuildTime=$(date -u '+%Y-%m-%d %I:%M:%S %Z')\"
-X \"gogs.io/gogs/internal/conf.BuildCommit=$(git rev-parse HEAD)\"
" \
$TAGS_FLAG \
-trimpath -o "$BINARY_NAME" ./cmd/gogs
- name: Prepare archive contents
run: |
mkdir -p dist/gogs
BINARY_NAME="gogs"
if [ "${{ matrix.goos }}" = "windows" ]; then
BINARY_NAME="gogs.exe"
fi
cp "$BINARY_NAME" dist/gogs/
cp LICENSE README.md README_ZH.md dist/gogs/
cp -r scripts dist/gogs/
- name: Create archives
working-directory: dist
run: |
VERSION="${{ steps.version.outputs.version }}"
ARCHIVE_BASE="gogs_${VERSION}_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.suffix }}"
zip -r "${ARCHIVE_BASE}.zip" gogs
if [ "${{ matrix.goos }}" = "linux" ]; then
tar -czvf "${ARCHIVE_BASE}.tar.gz" gogs
fi
- name: Upload to release
env:
GH_TOKEN: ${{ github.token }}
run: |
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
if [ "${{ github.event_name }}" != "release" ]; then
git tag -f "$RELEASE_TAG"
git push origin "$RELEASE_TAG" --force || true
RELEASE_TITLE="Release Archive Testing"
RELEASE_NOTES="Automated testing release for workflow development."
if [ "$RELEASE_TAG" = "latest-commit-build" ]; then
RELEASE_TITLE="Latest Commit Build"
RELEASE_NOTES="Automated build from the latest commit on main branch. This release is updated automatically with every push to main."
fi
gh release view "$RELEASE_TAG" || gh release create "$RELEASE_TAG" --title "$RELEASE_TITLE" --notes "$RELEASE_NOTES" --prerelease
fi
PATTERN="_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.suffix }}\."
gh release view "$RELEASE_TAG" --json assets --jq ".assets[].name" | grep "$PATTERN" | while read -r asset; do
gh release delete-asset "$RELEASE_TAG" "$asset" --yes || true
done
gh release upload "$RELEASE_TAG" dist/gogs_*.zip --clobber
if [ "${{ matrix.goos }}" = "linux" ]; then
gh release upload "$RELEASE_TAG" dist/gogs_*.tar.gz --clobber
fi
notify-failure:
name: Notify on failure
runs-on: ubuntu-latest
needs: [build]
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- name: Send email on failure
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
with:
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}

24
.gitignore vendored
View File

@@ -1,18 +1,16 @@
.DS_Store # Build artifacts
*.db .bin/
*.log dist/
# Runtime data
log/ log/
custom/ custom/
data/ data/
# Configuration and application files
.idea/ .idea/
*.iml .task/
public/img/avatar/
*.exe
*.exe~
/gogs
profile/
*.pem
output*
/release
.task
.envrc .envrc
# System junk
.DS_Store

View File

@@ -1,6 +1,7 @@
## Core principles ## Core principles
- When you see changes made outside your knowledge, use the current version as your new starting point. Do not blindly overwrite those changes or you suck. Even if you have to update the code, always respect the god damn pattern in the surrounding context! - Stop telling me "You're right", it just shows how incompetent you are. Do it right on your first try, fact-check and review after changes. If you are not sure, ask for help.
- When you see changes made outside your knowledge, use the current version as your new starting point. Do not blindly overwrite those changes or you suck. Even if you have to update the code, always respect the pattern in the surrounding context!
## Style and mechanics ## Style and mechanics
@@ -15,6 +16,17 @@ This applies to all texts, including but not limited to UI, documentation, code
- Use `github.com/cockroachdb/errors` for error handling. - Use `github.com/cockroachdb/errors` for error handling.
- Use `github.com/stretchr/testify` for assertions in tests. Be mindful about the choice of `require` and `assert`, the former should be used when the test cannot proceed meaningfully after a failed assertion. - Use `github.com/stretchr/testify` for assertions in tests. Be mindful about the choice of `require` and `assert`, the former should be used when the test cannot proceed meaningfully after a failed assertion.
## Build instructions
- Prefer `task` command over vanilla `go` command when available. Use `--force` flag when necessary.
- Run `task lint` after every time you finish changing code, and fix all linter errors.
## Tool-use guidance ## Tool-use guidance
- Use `gh` CLI to access information on github.com that is not publicly available. - Use `gh` CLI to access information on github.com that is not publicly available.
## Source code control
- When pushing changes to a pull request from a fork, use SSH address and do not add remote.
- Never automatically executes commands that touches Git history even if the session does not require approvals, including but not limited to `rebase`, `commit`, `push`, `pull`, `reset`, `amend`. Exceptions are only allowed case-by-case.
- Do not amend commits unless being explicitly asked to do so.

View File

@@ -2,26 +2,38 @@
All notable changes to Gogs are documented in this file. All notable changes to Gogs are documented in this file.
## 0.14.0+dev (`main`) ## 0.15.0+dev (`main`)
## 0.14.1
### Added ### Added
- Support comparing tags in addition to branches. [#6141](https://github.com/gogs/gogs/issues/6141)
- Show file name in browser tab title when viewing files. [#5896](https://github.com/gogs/gogs/pull/5896)
- Support using TLS for Redis session provider using `[session] PROVIDER_CONFIG = ...,tls=true`. [#7860](https://github.com/gogs/gogs/pull/7860) - Support using TLS for Redis session provider using `[session] PROVIDER_CONFIG = ...,tls=true`. [#7860](https://github.com/gogs/gogs/pull/7860)
- Support expanading values in `app.ini` from environment variables, e.g. `[database] PASSWORD = ${DATABASE_PASSWORD}`. [#8057](https://github.com/gogs/gogs/pull/8057) - Support expanading values in `app.ini` from environment variables, e.g. `[database] PASSWORD = ${DATABASE_PASSWORD}`. [#8057](https://github.com/gogs/gogs/pull/8057)
- Support custom logout URL that users get redirected to after sign out using `[auth] CUSTOM_LOGOUT_URL`. [#8089](https://github.com/gogs/gogs/pull/8089) - Support custom logout URL that users get redirected to after sign out using `[auth] CUSTOM_LOGOUT_URL`. [#8089](https://github.com/gogs/gogs/pull/8089)
- Start publishing next-generation, security-focused Docker image via `gogs/gogs:next-latest`, which will become the default image distribution (`gogs/gogs:latest`) starting 0.15.0. While not all container options support have been added in the next-generation image, the use of current legacy Docker image is deprecated, it will be published as `gogs/gogs:legacy-latest` starting 0.15.0, and be completely removed starting 0.16.0. [#8061](https://github.com/gogs/gogs/pull/8061) - Start publishing next-generation, security-focused Docker image via `gogs/gogs:next-latest`, which will become the default image distribution (`gogs/gogs:latest`) starting 0.16.0. While not all container options support have been added in the next-generation image, the use of current legacy Docker image is deprecated, it will be published as `gogs/gogs:legacy-latest` starting 0.16.0, and be completely removed no earlier than 0.17.0. [#8061](https://github.com/gogs/gogs/pull/8061)
### Changed ### Changed
- The required Go version to compile source code changed to 1.25. - The required Go version to compile source code changed to 1.25.
- The build tag `cert` has been removed, and the `gogs cert` subcommand is now always available. [#7883](https://github.com/gogs/gogs/pull/7883) - The build tag `cert` has been removed, and the `gogs cert` subcommand is now always available. [#7883](https://github.com/gogs/gogs/pull/7883)
- Switched to pure-Go SQLite driver, CGO is no longer required to compile Gogs. [#7882](https://github.com/gogs/gogs/issues/7882)
- Updated Mermaid JS to 11.9.0. [#8009](https://github.com/gogs/gogs/pull/8009) - Updated Mermaid JS to 11.9.0. [#8009](https://github.com/gogs/gogs/pull/8009)
- Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091) - Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091)
### Fixed ### Fixed
- _Security:_ Unauthenticated file upload. [#8128](https://github.com/gogs/gogs/pull/8128) - [GHSA-fc3h-92p8-h36f](https://github.com/gogs/gogs/security/advisories/GHSA-fc3h-92p8-h36f)
- _Security:_ Protected branch bypass in web UI. [#8124](https://github.com/gogs/gogs/pull/8124) - [GHSA-2c6v-8r3v-gh6p](https://github.com/gogs/gogs/security/advisories/GHSA-2c6v-8r3v-gh6p)
- _Security:_ Authorization bypass allows cross-repository label modification. [#8123](https://github.com/gogs/gogs/pull/8123) - [GHSA-cv22-72px-f4gh](https://github.com/gogs/gogs/security/advisories/GHSA-cv22-72px-f4gh)
- _Security:_ Cross-repository comment deletion. [#8119](https://github.com/gogs/gogs/pull/8119) - [GHSA-jj5m-h57j-5gv7](https://github.com/gogs/gogs/security/advisories/GHSA-jj5m-h57j-5gv7)
- 500 error on repository watchers and stargazers pages when using MSSQL. [#5482](https://github.com/gogs/gogs/issues/5482)
- Submodules using `ssh://` protocol and a port number are not rendered correctly. [#4941](https://github.com/gogs/gogs/issues/4941) - Submodules using `ssh://` protocol and a port number are not rendered correctly. [#4941](https://github.com/gogs/gogs/issues/4941)
- Missing link to user profile on the first commit in commits history page. [#7404](https://github.com/gogs/gogs/issues/7404) - Missing link to user profile on the first commit in commits history page. [#7404](https://github.com/gogs/gogs/issues/7404)
- Unable to delete or display files with special characters in their names. [#7596](https://github.com/gogs/gogs/issues/7596)
- Docker healthcheck fails when `HTTP_PROXY` or `HTTPS_PROXY` environment variables are set. [#7529](https://github.com/gogs/gogs/issues/7529)
## 0.13.4 ## 0.13.4

1
CLAUDE.md Symbolic link
View File

@@ -0,0 +1 @@
AGENTS.md

View File

@@ -25,20 +25,20 @@ RUN apk --no-cache --no-progress add \
tzdata \ tzdata \
rsync rsync
ENV GOGS_CUSTOM /data/gogs ENV GOGS_CUSTOM=/data/gogs
# Configure LibC Name Service # Configure LibC Name Service
COPY docker/nsswitch.conf /etc/nsswitch.conf COPY docker/nsswitch.conf /etc/nsswitch.conf
WORKDIR /app/gogs WORKDIR /app/gogs
COPY docker ./docker COPY docker ./docker
COPY --from=binarybuilder /gogs.io/gogs/gogs . COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
RUN ./docker/build/finalize.sh RUN ./docker/build/finalize.sh
# Configure Docker Container # Configure Docker Container
VOLUME ["/data", "/backup"] VOLUME ["/data", "/backup"]
EXPOSE 22 3000 EXPOSE 22 3000
HEALTHCHECK CMD (curl -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1 HEALTHCHECK CMD (curl --noproxy localhost -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1
ENTRYPOINT ["/app/gogs/docker/start.sh"] ENTRYPOINT ["/app/gogs/docker/start.sh"]
CMD ["/usr/bin/s6-svscan", "/app/gogs/docker/s6/"] CMD ["/usr/bin/s6-svscan", "/app/gogs/docker/s6/"]

View File

@@ -31,7 +31,7 @@ RUN apk --no-cache --no-progress add \
ENV GOGS_CUSTOM=/data/gogs ENV GOGS_CUSTOM=/data/gogs
WORKDIR /app/gogs WORKDIR /app/gogs
COPY --from=binarybuilder /gogs.io/gogs/gogs . COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
COPY docker-next/start.sh . COPY docker-next/start.sh .
RUN chmod +x start.sh && \ RUN chmod +x start.sh && \
mkdir -p /data && \ mkdir -p /data && \
@@ -41,7 +41,7 @@ RUN chmod +x start.sh && \
# Configure Docker Container # Configure Docker Container
VOLUME ["/data", "/backup"] VOLUME ["/data", "/backup"]
EXPOSE 22 3000 EXPOSE 22 3000
HEALTHCHECK CMD (curl -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1 HEALTHCHECK CMD (curl --noproxy localhost -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1
# Run as non-root user by default for better K8s security context support. # Run as non-root user by default for better K8s security context support.
USER git:git USER git:git

View File

@@ -2,9 +2,9 @@
## Supported versions ## Supported versions
Only the latest minor version releases are supported (>= 0.13) for accepting vulnerability reports and patching fixes. Only the latest minor version releases are supported (e.g., 0.14) for patching vulnerabilities. You can find the latest minor version in the [GitHub releases](https://github.com/gogs/gogs/releases) page.
Existing vulnerability reports are being tracked in [GitHub Security Advisories](https://github.com/gogs/gogs/security/advisories). Existing vulnerability reports are being tracked in [GitHub Security Advisories](https://github.com/gogs/gogs/security/advisories). Not all accepted GHSA are published.
## Vulnerability lifecycle ## Vulnerability lifecycle
@@ -14,6 +14,7 @@ Existing vulnerability reports are being tracked in [GitHub Security Advisories]
1. Report an advisory for the vulnerability. 1. Report an advisory for the vulnerability.
- Please be aware that **only advisories reported in plain English** will be reviewed. - Please be aware that **only advisories reported in plain English** will be reviewed.
- We DO NOT accept vulnerabilities cannot be reproduced on the latest `main` commit.
1. Project maintainers review the advisory: 1. Project maintainers review the advisory:
- Ask clarifying questions - Ask clarifying questions
- Make sure there was no prior advisory exists for the same vulnerability - Make sure there was no prior advisory exists for the same vulnerability

View File

@@ -10,8 +10,10 @@ tasks:
web: web:
desc: Build the binary and start the web server desc: Build the binary and start the web server
deps: [build] deps: [build]
env:
GOGS_WORK_DIR: '{{.ROOT_DIR}}'
cmds: cmds:
- ./gogs web - .bin/gogs web
build: build:
desc: Build the binary desc: Build the binary
@@ -22,7 +24,7 @@ tasks:
-X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}" -X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
' '
-tags '{{.TAGS}}' -tags '{{.TAGS}}'
-trimpath -o gogs{{.BINARY_EXT}} -trimpath -o .bin/gogs{{.BINARY_EXT}} ./cmd/gogs
vars: vars:
PKG_PATH: gogs.io/gogs/internal/conf PKG_PATH: gogs.io/gogs/internal/conf
BUILD_TIME: BUILD_TIME:
@@ -31,7 +33,7 @@ tasks:
sh: git rev-parse HEAD sh: git rev-parse HEAD
sources: sources:
- go.mod - go.mod
- gogs.go - cmd/gogs/*.go
- internal/**/*.go - internal/**/*.go
- conf/**/* - conf/**/*
- public/**/* - public/**/*
@@ -59,18 +61,6 @@ tasks:
cmds: cmds:
- find . -name "*.DS_Store" -type f -delete - find . -name "*.DS_Store" -type f -delete
release:
desc: Build the binary and pack resources to a ZIP file
deps: [build]
cmds:
- rm -rf {{.RELEASE_GOGS}}
- mkdir -p {{.RELEASE_GOGS}}
- cp -r gogs{{.BINARY_EXT}} LICENSE README.md README_ZH.md scripts {{.RELEASE_GOGS}}
- cd {{.RELEASE_ROOT}} && zip -r gogs.zip "gogs"
vars:
RELEASE_ROOT: release
RELEASE_GOGS: release/gogs
less: less:
desc: Generate CSS from LESS files desc: Generate CSS from LESS files
cmds: cmds:
@@ -99,3 +89,8 @@ tasks:
dropdb "$dbname" dropdb "$dbname"
echo "dropped $dbname" echo "dropped $dbname"
done done
lint:
desc: Run all linters
cmds:
- golangci-lint run

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"context" "context"
@@ -14,7 +14,7 @@ import (
) )
var ( var (
Admin = cli.Command{ adminCommand = cli.Command{
Name: "admin", Name: "admin",
Usage: "Perform admin operations on command line", Usage: "Perform admin operations on command line",
Description: `Allow using internal logic of Gogs without hacking into the source code Description: `Allow using internal logic of Gogs without hacking into the source code

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"context" "context"
@@ -20,7 +20,7 @@ import (
"gogs.io/gogs/internal/osutil" "gogs.io/gogs/internal/osutil"
) )
var Backup = cli.Command{ var backupCommand = cli.Command{
Name: "backup", Name: "backup",
Usage: "Backup files and database", Usage: "Backup files and database",
Description: `Backup dumps and compresses all related files and database into zip file, Description: `Backup dumps and compresses all related files and database into zip file,

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package cmd package main
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
@@ -22,7 +22,7 @@ import (
"github.com/urfave/cli" "github.com/urfave/cli"
) )
var Cert = cli.Command{ var certCommand = cli.Command{
Name: "cert", Name: "cert",
Usage: "Generate self-signed certificate", Usage: "Generate self-signed certificate",
Description: `Generate a self-signed X.509 certificate for a TLS server. Description: `Generate a self-signed X.509 certificate for a TLS server.

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"time" "time"
@@ -21,7 +21,6 @@ func boolFlag(name, usage string) cli.BoolFlag {
} }
} }
//nolint:deadcode,unused
func intFlag(name string, value int, usage string) cli.IntFlag { func intFlag(name string, value int, usage string) cli.IntFlag {
return cli.IntFlag{ return cli.IntFlag{
Name: name, Name: name,
@@ -30,7 +29,6 @@ func intFlag(name string, value int, usage string) cli.IntFlag {
} }
} }
//nolint:deadcode,unused
func durationFlag(name string, value time.Duration, usage string) cli.DurationFlag { func durationFlag(name string, value time.Duration, usage string) cli.DurationFlag {
return cli.DurationFlag{ return cli.DurationFlag{
Name: name, Name: name,

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"bufio" "bufio"
@@ -24,7 +24,7 @@ import (
) )
var ( var (
Hook = cli.Command{ hookCommand = cli.Command{
Name: "hook", Name: "hook",
Usage: "Delegate commands to corresponding Git hooks", Usage: "Delegate commands to corresponding Git hooks",
Description: "All sub-commands should only be called by Git", Description: "All sub-commands should only be called by Git",

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"bufio" "bufio"
@@ -16,7 +16,7 @@ import (
) )
var ( var (
Import = cli.Command{ importCommand = cli.Command{
Name: "import", Name: "import",
Usage: "Import portable data as local Gogs data", Usage: "Import portable data as local Gogs data",
Description: `Allow user import data from other Gogs installations to local instance Description: `Allow user import data from other Gogs installations to local instance

View File

@@ -1,5 +1,3 @@
//go:build go1.18
// Gogs is a painless self-hosted Git Service. // Gogs is a painless self-hosted Git Service.
package main package main
@@ -9,12 +7,11 @@ import (
"github.com/urfave/cli" "github.com/urfave/cli"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/cmd"
"gogs.io/gogs/internal/conf" "gogs.io/gogs/internal/conf"
) )
func init() { func init() {
conf.App.Version = "0.14.0+dev" conf.App.Version = "0.15.0+dev"
} }
func main() { func main() {
@@ -23,14 +20,14 @@ func main() {
app.Usage = "A painless self-hosted Git service" app.Usage = "A painless self-hosted Git service"
app.Version = conf.App.Version app.Version = conf.App.Version
app.Commands = []cli.Command{ app.Commands = []cli.Command{
cmd.Web, webCommand,
cmd.Serv, servCommand,
cmd.Hook, hookCommand,
cmd.Cert, certCommand,
cmd.Admin, adminCommand,
cmd.Import, importCommand,
cmd.Backup, backupCommand,
cmd.Restore, restoreCommand,
} }
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Fatal("Failed to start application: %v", err) log.Fatal("Failed to start application: %v", err)

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"context" "context"
@@ -18,7 +18,7 @@ import (
"gogs.io/gogs/internal/semverutil" "gogs.io/gogs/internal/semverutil"
) )
var Restore = cli.Command{ var restoreCommand = cli.Command{
Name: "restore", Name: "restore",
Usage: "Restore files and database from backup", Usage: "Restore files and database from backup",
Description: `Restore imports all related files and database from a backup archive. Description: `Restore imports all related files and database from a backup archive.

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"context" "context"
@@ -21,7 +21,7 @@ const (
accessDeniedMessage = "Repository does not exist or you do not have access" accessDeniedMessage = "Repository does not exist or you do not have access"
) )
var Serv = cli.Command{ var servCommand = cli.Command{
Name: "serv", Name: "serv",
Usage: "This command should only be called by SSH shell", Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`, Description: `Serv provide access auth for repositories`,

View File

@@ -1,4 +1,4 @@
package cmd package main
import ( import (
"crypto/tls" "crypto/tls"
@@ -30,6 +30,7 @@ import (
"gogs.io/gogs/internal/conf" "gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context" "gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database" "gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/embeddedpg"
"gogs.io/gogs/internal/form" "gogs.io/gogs/internal/form"
"gogs.io/gogs/internal/osutil" "gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/route" "gogs.io/gogs/internal/route"
@@ -45,7 +46,7 @@ import (
"gogs.io/gogs/templates" "gogs.io/gogs/templates"
) )
var Web = cli.Command{ var webCommand = cli.Command{
Name: "web", Name: "web",
Usage: "Start web server", Usage: "Start web server",
Description: `Gogs web server is the only thing you need to run, Description: `Gogs web server is the only thing you need to run,
@@ -54,6 +55,7 @@ and it takes care of all the other things for you`,
Flags: []cli.Flag{ Flags: []cli.Flag{
stringFlag("port, p", "3000", "Temporary port number to prevent conflict"), stringFlag("port, p", "3000", "Temporary port number to prevent conflict"),
stringFlag("config, c", "", "Custom configuration file path"), stringFlag("config, c", "", "Custom configuration file path"),
boolFlag("embedded-postgres", "Use embedded PostgreSQL database"),
}, },
} }
@@ -160,7 +162,29 @@ func newMacaron() *macaron.Macaron {
} }
func runWeb(c *cli.Context) error { func runWeb(c *cli.Context) error {
err := route.GlobalInit(c.String("config")) // Initialize configuration first to get WorkDir
err := conf.Init(c.String("config"))
if err != nil {
log.Fatal("Failed to initialize configuration: %v", err)
}
conf.InitLogging(false)
var localPg *embeddedpg.LocalPostgres
if c.Bool("embedded-postgres") {
localPg = embeddedpg.Initialize(conf.WorkDir())
if err := localPg.Launch(); err != nil {
log.Fatal("Failed to launch embedded postgres: %v", err)
}
defer func() {
if err := localPg.Shutdown(); err != nil {
log.Error("Failed to shutdown embedded postgres: %v", err)
}
}()
localPg.ConfigureGlobalDatabase()
}
err = route.GlobalInit(c.String("config"))
if err != nil { if err != nil {
log.Fatal("Failed to initialize application: %v", err) log.Fatal("Failed to initialize application: %v", err)
} }
@@ -329,9 +353,12 @@ func runWeb(c *cli.Context) error {
return return
} }
}) })
}, ignSignIn)
m.Group("", func() {
m.Post("/issues/attachments", repo.UploadIssueAttachment) m.Post("/issues/attachments", repo.UploadIssueAttachment)
m.Post("/releases/attachments", repo.UploadReleaseAttachment) m.Post("/releases/attachments", repo.UploadReleaseAttachment)
}, ignSignIn) }, reqSignIn)
m.Group("/:username", func() { m.Group("/:username", func() {
m.Post("/action/:action", user.Action) m.Post("/action/:action", user.Action)
@@ -476,7 +503,7 @@ func runWeb(c *cli.Context) error {
m.Get("/milestones", repo.Milestones) m.Get("/milestones", repo.Milestones)
}, ignSignIn, context.RepoAssignment(true)) }, ignSignIn, context.RepoAssignment(true))
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest. // FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
// So they can apply their own enable/disable logic on routers. // So they can apply their own enable/disable logic on routers.
m.Group("/issues", func() { m.Group("/issues", func() {
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue). m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
@@ -501,7 +528,7 @@ func runWeb(c *cli.Context) error {
}, ignSignIn, context.RepoAssignment(false, true)) }, ignSignIn, context.RepoAssignment(false, true))
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest. // FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
// So they can apply their own enable/disable logic on routers. // So they can apply their own enable/disable logic on routers.
m.Group("/issues", func() { m.Group("/issues", func() {
m.Group("/:index", func() { m.Group("/:index", func() {

View File

@@ -1,16 +0,0 @@
coverage:
range: "60...95"
status:
project:
default:
threshold: 1%
informational: true
patch:
default:
only_pulls: true
informational: true
comment:
layout: 'diff'
github_checks: false

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Застинали клонове
branches.all=Всички клонове branches.all=Всички клонове
branches.updated_by=Актуализирани %[1]s от %[2]s branches.updated_by=Актуализирани %[1]s от %[2]s
branches.change_default_branch=Промяна на клон по подразбиране branches.change_default_branch=Промяна на клон по подразбиране
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Нов файл editor.new_file=Нов файл
editor.upload_file=Качи файл editor.upload_file=Качи файл
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Zastaralé větve
branches.all=Všechny větve branches.all=Všechny větve
branches.updated_by=%[2]s změnil %[1]s branches.updated_by=%[2]s změnil %[1]s
branches.change_default_branch=Změnit výchozí větev branches.change_default_branch=Změnit výchozí větev
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nový soubor editor.new_file=Nový soubor
editor.upload_file=Nahrát soubor editor.upload_file=Nahrát soubor
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Alte Branches
branches.all=Alle Branches branches.all=Alle Branches
branches.updated_by=Aktualisiert %[1]s von %[2]s branches.updated_by=Aktualisiert %[1]s von %[2]s
branches.change_default_branch=Ändere Standard-Branch branches.change_default_branch=Ändere Standard-Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Neue Datei editor.new_file=Neue Datei
editor.upload_file=Datei hochladen editor.upload_file=Datei hochladen
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Fehler beim Senden der Test-E-Mail an '%s': %v
config.email.test_mail_sent=Test-E-Mail wurde an '%s ' gesendet. config.email.test_mail_sent=Test-E-Mail wurde an '%s ' gesendet.
config.auth_config=Authentifizierungskonfiguration config.auth_config=Authentifizierungskonfiguration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Aktivierungscode Lebensdauer config.auth.activate_code_lives=Aktivierungscode Lebensdauer
config.auth.reset_password_code_lives=Gültigkeitsdauer Zurücksetzungs-Code config.auth.reset_password_code_lives=Gültigkeitsdauer Zurücksetzungs-Code
config.auth.require_email_confirm=E-Mail-Bestätigung erforderlich config.auth.require_email_confirm=E-Mail-Bestätigung erforderlich

View File

@@ -501,6 +501,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Change Default Branch branches.change_default_branch=Change Default Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=New file editor.new_file=New file
editor.upload_file=Upload file editor.upload_file=Upload file
@@ -1346,6 +1348,7 @@ config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives

View File

@@ -494,6 +494,8 @@ branches.stale_branches = Stale Branches
branches.all = All Branches branches.all = All Branches
branches.updated_by = Updated %[1]s by %[2]s branches.updated_by = Updated %[1]s by %[2]s
branches.change_default_branch = Change Default Branch branches.change_default_branch = Change Default Branch
branches.default_deletion_not_allowed = Cannot delete the default branch.
branches.protected_deletion_not_allowed = Cannot delete a protected branch.
editor.new_file = New file editor.new_file = New file
editor.upload_file = Upload file editor.upload_file = Upload file

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Ramas Viejas
branches.all=Todas las Ramas branches.all=Todas las Ramas
branches.updated_by=%[1]s actualizado por %[2]s branches.updated_by=%[1]s actualizado por %[2]s
branches.change_default_branch=Cambiar la Rama por Defecto branches.change_default_branch=Cambiar la Rama por Defecto
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nuevo archivo editor.new_file=Nuevo archivo
editor.upload_file=Subir archivo editor.upload_file=Subir archivo
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Error al enviar correo electrónico de prueba a '%
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -496,6 +496,8 @@ branches.stale_branches=شاخه های قدیمی
branches.all=همه شاخه branches.all=همه شاخه
branches.updated_by=%[1]s به روزشده توسط %[2]s branches.updated_by=%[1]s به روزشده توسط %[2]s
branches.change_default_branch=تغییر شاخه ی پیش فرض branches.change_default_branch=تغییر شاخه ی پیش فرض
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=پرونده جدید editor.new_file=پرونده جدید
editor.upload_file=بارگذاری پرونده editor.upload_file=بارگذاری پرونده
@@ -1276,6 +1278,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Passivoituneet haarat
branches.all=Kaikki haarat branches.all=Kaikki haarat
branches.updated_by=Päivitetty %[1]s %[2]s branches.updated_by=Päivitetty %[1]s %[2]s
branches.change_default_branch=Muuta oletushaaraa branches.change_default_branch=Muuta oletushaaraa
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Uusi tiedosto editor.new_file=Uusi tiedosto
editor.upload_file=Liitä tiedosto editor.upload_file=Liitä tiedosto
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Testisähköpostin lähettäminen vastaanottajalle
config.email.test_mail_sent=Testi sähköposti on lähetetty vastaanottajalle '%s'. config.email.test_mail_sent=Testi sähköposti on lähetetty vastaanottajalle '%s'.
config.auth_config=Todennuksen asetukset config.auth_config=Todennuksen asetukset
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Aktiivinen koodi elämät ennen vanhenemista config.auth.activate_code_lives=Aktiivinen koodi elämät ennen vanhenemista
config.auth.reset_password_code_lives=Nollaa salasana koodi elämät config.auth.reset_password_code_lives=Nollaa salasana koodi elämät
config.auth.require_email_confirm=Vaadi sähköpostivahvistus config.auth.require_email_confirm=Vaadi sähköpostivahvistus

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Branches stagnantes
branches.all=Toutes les Branches branches.all=Toutes les Branches
branches.updated_by=Mise à jour %[1]s par %[2]s branches.updated_by=Mise à jour %[1]s par %[2]s
branches.change_default_branch=Changer la Branche par Défaut branches.change_default_branch=Changer la Branche par Défaut
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nouveau fichier editor.new_file=Nouveau fichier
editor.upload_file=Téléverser un fichier editor.upload_file=Téléverser un fichier
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Impossible d'envoyer un e-mail de test à '%s' :
config.email.test_mail_sent=Un e-mail de test à été envoyé à '%s'. config.email.test_mail_sent=Un e-mail de test à été envoyé à '%s'.
config.auth_config=Configuration de l'authentification config.auth_config=Configuration de l'authentification
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activer les vies sur les codes config.auth.activate_code_lives=Activer les vies sur les codes
config.auth.reset_password_code_lives=Vies sur les codes de réinitialisation des mots de passes config.auth.reset_password_code_lives=Vies sur les codes de réinitialisation des mots de passes
config.auth.require_email_confirm=Nécessite une confirmation par e-mail config.auth.require_email_confirm=Nécessite une confirmation par e-mail

View File

@@ -495,6 +495,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Change Default Branch branches.change_default_branch=Change Default Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Novo arquivo editor.new_file=Novo arquivo
editor.upload_file=Subir arquivo editor.upload_file=Subir arquivo
@@ -1275,6 +1277,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Elavult ágak
branches.all=Minden ág branches.all=Minden ág
branches.updated_by=Frissítve ekkor: %[1]s %[2]s által branches.updated_by=Frissítve ekkor: %[1]s %[2]s által
branches.change_default_branch=Alapértelmezett ág megváltoztatása branches.change_default_branch=Alapértelmezett ág megváltoztatása
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Új fájl editor.new_file=Új fájl
editor.upload_file=Fájl feltöltése editor.upload_file=Fájl feltöltése
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Nem sikerült kiküldeni a teszt e-mailt '%s'-nek:
config.email.test_mail_sent=Teszt e-mail kiküldve '%s'-nek. config.email.test_mail_sent=Teszt e-mail kiküldve '%s'-nek.
config.auth_config=Hitelesítési beállítások config.auth_config=Hitelesítési beállítások
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Jelszó visszaállítási kód élettartama config.auth.reset_password_code_lives=Jelszó visszaállítási kód élettartama
config.auth.require_email_confirm=E-mail megerősítés szükségessé tétele config.auth.require_email_confirm=E-mail megerősítés szükségessé tétele

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Cabang Basi
branches.all=Semua Cabang branches.all=Semua Cabang
branches.updated_by=Diperbarui %[1]s oleh %[2]s branches.updated_by=Diperbarui %[1]s oleh %[2]s
branches.change_default_branch=Ubah Cabang Default branches.change_default_branch=Ubah Cabang Default
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Berkas baru editor.new_file=Berkas baru
editor.upload_file=Unggah Berkas editor.upload_file=Unggah Berkas
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Gagal mengirim surel uji ke '%s': %v
config.email.test_mail_sent=Surel uji telah dikirim ke '%s'. config.email.test_mail_sent=Surel uji telah dikirim ke '%s'.
config.auth_config=Konfigurasi otentikasi config.auth_config=Konfigurasi otentikasi
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Perlu konfirmasi surel config.auth.require_email_confirm=Perlu konfirmasi surel

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stale Branches
branches.all=Tutti i rami (branch) branches.all=Tutti i rami (branch)
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Cambia branch di default branches.change_default_branch=Cambia branch di default
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nuovo file editor.new_file=Nuovo file
editor.upload_file=Carica File editor.upload_file=Carica File
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=古いブランチ
branches.all=すべてのブランチ branches.all=すべてのブランチ
branches.updated_by=%[1]s が %[2]s によって更新されました branches.updated_by=%[1]s が %[2]s によって更新されました
branches.change_default_branch=デフォルトブランチの変更 branches.change_default_branch=デフォルトブランチの変更
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=新規ファイル editor.new_file=新規ファイル
editor.upload_file=ファイルをアップロード editor.upload_file=ファイルをアップロード
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -495,6 +495,8 @@ branches.stale_branches=오래된 브랜치
branches.all=모든 브랜치 branches.all=모든 브랜치
branches.updated_by=%[2]s이 %[1]s를 업데이트 branches.updated_by=%[2]s이 %[1]s를 업데이트
branches.change_default_branch=기본 브랜치 변경 branches.change_default_branch=기본 브랜치 변경
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=파일 생성 editor.new_file=파일 생성
editor.upload_file=파일 업로드 editor.upload_file=파일 업로드
@@ -1276,6 +1278,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent='%s'로 테스트 이메일을 보냈습니다. config.email.test_mail_sent='%s'로 테스트 이메일을 보냈습니다.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=이메일 인증 필요 config.auth.require_email_confirm=이메일 인증 필요

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Pamests atzars
branches.all=Visi atzari branches.all=Visi atzari
branches.updated_by=%[2]s atjaunoja %[1]s branches.updated_by=%[2]s atjaunoja %[1]s
branches.change_default_branch=Mainīt noklusēto atzaru branches.change_default_branch=Mainīt noklusēto atzaru
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Jauns fails editor.new_file=Jauns fails
editor.upload_file=Augšupielādēt failu editor.upload_file=Augšupielādēt failu
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Хуучирсан салаанууд
branches.all=Бүх салаанууд branches.all=Бүх салаанууд
branches.updated_by=Шинэчлэгдсэн %[1]s by %[2]s branches.updated_by=Шинэчлэгдсэн %[1]s by %[2]s
branches.change_default_branch=Анхны салаа өөрчлөх branches.change_default_branch=Анхны салаа өөрчлөх
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Шинэ файл editor.new_file=Шинэ файл
editor.upload_file=Файл хуулах editor.upload_file=Файл хуулах
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Туршилтын имэйлийг '%s': %v рү
config.email.test_mail_sent=Туршилтын имэйл '%s' рүү илгээгдлээ. config.email.test_mail_sent=Туршилтын имэйл '%s' рүү илгээгдлээ.
config.auth_config=Authentication тохиргоо config.auth_config=Authentication тохиргоо
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Кодын ашиглалтыг идэвхжүүлэх config.auth.activate_code_lives=Кодын ашиглалтыг идэвхжүүлэх
config.auth.reset_password_code_lives=Нууц үгийн кодыг шинэчлэх config.auth.reset_password_code_lives=Нууц үгийн кодыг шинэчлэх
config.auth.require_email_confirm=Имэйлээр баталгаажуулахыг шаардана config.auth.require_email_confirm=Имэйлээр баталгаажуулахыг шаардана

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Change Default Branch branches.change_default_branch=Change Default Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nieuw bestand editor.new_file=Nieuw bestand
editor.upload_file=Bestand uploaden editor.upload_file=Bestand uploaden
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stare gałęzie
branches.all=Wszystkie gałęzie branches.all=Wszystkie gałęzie
branches.updated_by=Zaktualizowano %[1]s przez %[2]s branches.updated_by=Zaktualizowano %[1]s przez %[2]s
branches.change_default_branch=Zmiana domyślnej gałęzi branches.change_default_branch=Zmiana domyślnej gałęzi
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nowy plik editor.new_file=Nowy plik
editor.upload_file=Załaduj plik editor.upload_file=Załaduj plik
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Nie udało się wysłać wiadomości testowej do '
config.email.test_mail_sent=Wiadomość testowa została wysłana do '%s'. config.email.test_mail_sent=Wiadomość testowa została wysłana do '%s'.
config.auth_config=Konfiguracja uwierzytelniania config.auth_config=Konfiguracja uwierzytelniania
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Wymagaj potwierdzenia adresu e-mail config.auth.require_email_confirm=Wymagaj potwierdzenia adresu e-mail

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Branches obsoletos
branches.all=Todos os branches branches.all=Todos os branches
branches.updated_by=Atualizado %[1]s por %[2]s branches.updated_by=Atualizado %[1]s por %[2]s
branches.change_default_branch=Modificar branch padrão branches.change_default_branch=Modificar branch padrão
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Novo arquivo editor.new_file=Novo arquivo
editor.upload_file=Enviar arquivo editor.upload_file=Enviar arquivo
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -446,7 +446,7 @@ migrate.clone_address_desc=Isto pode ser um URL de HTTP/HTTPS/GIT.
migrate.clone_address_desc_import_local=Você também pode migrar um repositório pelo caminho do servidor local. migrate.clone_address_desc_import_local=Você também pode migrar um repositório pelo caminho do servidor local.
migrate.permission_denied=Não está autorizado a importar repositórios locais. migrate.permission_denied=Não está autorizado a importar repositórios locais.
migrate.invalid_local_path=Caminho local inválido, o caminho não existe ou não é um directório. migrate.invalid_local_path=Caminho local inválido, o caminho não existe ou não é um directório.
migrate.clone_address_resolved_to_blocked_local_address=Clone address resolved to a local network address that is implicitly blocked. migrate.clone_address_resolved_to_blocked_local_address=Clonar endereço resolvido para um endereço de rede local implicitamente bloqueado.
migrate.failed=Migração falhada: %v migrate.failed=Migração falhada: %v
mirror_from=mirror de mirror_from=mirror de
@@ -494,6 +494,8 @@ branches.stale_branches=Ramificações Obsoletas
branches.all=Todas as Ramificações branches.all=Todas as Ramificações
branches.updated_by=Atualizado %[1]s por %[2]s branches.updated_by=Atualizado %[1]s por %[2]s
branches.change_default_branch=Mudar Ramificação Predefinida branches.change_default_branch=Mudar Ramificação Predefinida
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Novo Ficheiro editor.new_file=Novo Ficheiro
editor.upload_file=Enviar ficheiro editor.upload_file=Enviar ficheiro
@@ -1202,119 +1204,120 @@ config.ssh.port=Porta exposta
config.ssh.root_path=Caminho para a raíz config.ssh.root_path=Caminho para a raíz
config.ssh.keygen_path=Localização do gerador de chaves criptográficas config.ssh.keygen_path=Localização do gerador de chaves criptográficas
config.ssh.key_test_path=Localização do teste das chaves criptográficas config.ssh.key_test_path=Localização do teste das chaves criptográficas
config.ssh.minimum_key_size_check=Minimum key size check config.ssh.minimum_key_size_check=Verificação de tamanho mínimo da chave
config.ssh.minimum_key_sizes=Minimum key sizes config.ssh.minimum_key_sizes=Tamanhos mínimos de chaves
config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
config.ssh.start_builtin_server=Start builtin server config.ssh.start_builtin_server=Iniciar servidor embutido
config.ssh.listen_host=Servidor config.ssh.listen_host=Servidor
config.ssh.listen_port=Porta do servidor config.ssh.listen_port=Porta do servidor
config.ssh.server_ciphers=Cifras do servidor config.ssh.server_ciphers=Cifras do servidor
config.ssh.server_macs=Server MACs config.ssh.server_macs=MACs do servidor
config.ssh.server_algorithms=Server algorithms config.ssh.server_algorithms=Algoritmos do servidor
config.repo_config=Configuração de repositório config.repo_config=Configuração de repositório
config.repo.root_path=Localização base config.repo.root_path=Localização base
config.repo.script_type=Tipo de script config.repo.script_type=Tipo de script
config.repo.ansi_chatset=ANSI charset config.repo.ansi_chatset=ANSI charset
config.repo.force_private=Force private config.repo.force_private=Forçar privado
config.repo.max_creation_limit=Max creation limit config.repo.max_creation_limit=Limite máximo de criação
config.repo.preferred_licenses=Preferred licenses config.repo.preferred_licenses=Licenças preferidas
config.repo.disable_http_git=Disable HTTP Git config.repo.disable_http_git=Desativar Git HTTP
config.repo.enable_local_path_migration=Enable local path migration config.repo.enable_local_path_migration=Ativar a migração de caminho local
config.repo.enable_raw_file_render_mode=Enable raw file render mode config.repo.enable_raw_file_render_mode=Ativar o modo de renderização do ficheiro bruto
config.repo.commits_fetch_concurrency=Commits fetch concurrency config.repo.commits_fetch_concurrency=Commits fetch concurrency
config.repo.editor.line_wrap_extensions=Editor line wrap extensions config.repo.editor.line_wrap_extensions=Extensões de quebra automática de linha do editor
config.repo.editor.previewable_file_modes=Editor previewable file modes config.repo.editor.previewable_file_modes=Editor previewable file modes
config.repo.upload.enabled=Upload enabled config.repo.upload.enabled=Envio ativado
config.repo.upload.temp_path=Upload temporary path config.repo.upload.temp_path=Caminho temporário para envios
config.repo.upload.allowed_types=Upload allowed types config.repo.upload.allowed_types=Tipos de envios permitidos
config.repo.upload.file_max_size=Upload file size limit config.repo.upload.file_max_size=Tamanho limite de ficheiros enviados
config.repo.upload.max_files=Upload files limit config.repo.upload.max_files=Quantidade limite de ficheiros enviados
config.db_config=Configuração da base de dados config.db_config=Configuração da base de dados
config.db.type=Type config.db.type=Tipo
config.db.host=Host config.db.host=Anfitrião
config.db.name=Name config.db.name=Nome
config.db.schema=Schema config.db.schema=Esquema
config.db.schema_helper=(for "postgres" only) config.db.schema_helper=(apenas para "postgres")
config.db.user=User config.db.user=Utilizador
config.db.ssl_mode=SSL mode config.db.ssl_mode=Modo SSL
config.db.ssl_mode_helper=(for "postgres" only) config.db.ssl_mode_helper=(apenas para "postgres")
config.db.path=Path config.db.path=Caminho
config.db.path_helper=(for "sqlite3"only) config.db.path_helper=(apenas para "sqlite3")
config.db.max_open_conns=Maximum open connections config.db.max_open_conns=Máximo de conexões abertas
config.db.max_idle_conns=Maximum idle connections config.db.max_idle_conns=Máximo de conexões ociosas
config.security_config=Security configuration config.security_config=Configuração da segurança
config.security.login_remember_days=Login remember days config.security.login_remember_days=Dias lembrados de login
config.security.cookie_remember_name=Remember cookie config.security.cookie_remember_name=Lembrar do cookie
config.security.cookie_username=Username cookie config.security.cookie_username=Cookie do nome do utilizador
config.security.cookie_secure=Enable secure cookie config.security.cookie_secure=Ativar cookie seguro
config.security.reverse_proxy_auth_user=Reverse proxy authentication header config.security.reverse_proxy_auth_user=Cabeçalho de autenticação de proxy reverso
config.security.enable_login_status_cookie=Enable login status cookie config.security.enable_login_status_cookie=Enable login status cookie
config.security.login_status_cookie_name=Login status cookie config.security.login_status_cookie_name=Login status cookie
config.security.local_network_allowlist=Local network allowlist config.security.local_network_allowlist=Local network allowlist
config.email_config=Email configuration config.email_config=Configuração de E-mail
config.email.enabled=Enabled config.email.enabled=Ativado
config.email.subject_prefix=Subject prefix config.email.subject_prefix=Prefixo do assunto
config.email.host=Host config.email.host=Anfitrião
config.email.from=From config.email.from=De
config.email.user=User config.email.user=Utilizador
config.email.disable_helo=Disable HELO config.email.disable_helo=Desativar HELO
config.email.helo_hostname=HELO hostname config.email.helo_hostname=Nome de anfitrião HELO
config.email.skip_verify=Skip certificate verify config.email.skip_verify=Skip certificate verify
config.email.use_certificate=Use custom certificate config.email.use_certificate=Usar certificado personalizado
config.email.cert_file=Certificate file config.email.cert_file=Ficheiro de certificado criptográfico
config.email.key_file=Key file config.email.key_file=Ficheiro da chave criptográfica
config.email.use_plain_text=Use plain text config.email.use_plain_text=Usar texto simples
config.email.add_plain_text_alt=Add plain text alternative config.email.add_plain_text_alt=Adicionar alternativa de texto simples
config.email.send_test_mail=Send test email config.email.send_test_mail=Enviar e-mail de teste
config.email.test_mail_failed=Failed to send test email to '%s': %v config.email.test_mail_failed=Falhou o envio do e-mail de teste para '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=O e-mail de teste foi enviado para '%s'.
config.auth_config=Authentication configuration config.auth_config=Configuração da autenticação
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Exigir confirmação por e-mail
config.auth.require_sign_in_view=Require sign in view config.auth.require_sign_in_view=Exigir login para ver
config.auth.disable_registration=Disable registration config.auth.disable_registration=Desativar registo
config.auth.enable_registration_captcha=Enable registration captcha config.auth.enable_registration_captcha=Ativar captcha para registar
config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication config.auth.enable_reverse_proxy_authentication=Ativar autenticação do proxy reverso
config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration config.auth.enable_reverse_proxy_auto_registration=Ativar o registo automático do proxy reverso
config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header config.auth.reverse_proxy_authentication_header=Cabeçalho de autenticação de proxy reverso
config.user_config=User configuration config.user_config=Configuração do utilizador
config.user.enable_email_notify=Enable email notification config.user.enable_email_notify=Ativar a notificação por e-mail
config.session_config=Configuração de sessão config.session_config=Configuração de sessão
config.session.provider=Provider config.session.provider=Provedor
config.session.provider_config=Provider config config.session.provider_config=Configuração do provedor
config.session.cookie_name=Cookie config.session.cookie_name=Cookie
config.session.https_only=HTTPS only config.session.https_only=Somente HTTPS
config.session.gc_interval=GC interval config.session.gc_interval=GC interval
config.session.max_life_time=Max life time config.session.max_life_time=Max life time
config.session.csrf_cookie_name=CSRF cookie config.session.csrf_cookie_name=CSRF cookie
config.cache_config=Configuração de cache config.cache_config=Configuração de cache
config.cache.adapter=Adapter config.cache.adapter=Adaptador
config.cache.interval=GC interval config.cache.interval=Intervalo de GC
config.cache.host=Host config.cache.host=Anfitrião
config.http_config=Configuração HTTP config.http_config=Configuração HTTP
config.http.access_control_allow_origin=Access control allow origin config.http.access_control_allow_origin=Access control allow origin
config.attachment_config=Attachment configuration config.attachment_config=Configuração de anexos
config.attachment.enabled=Enabled config.attachment.enabled=Ativado
config.attachment.path=Path config.attachment.path=Caminho
config.attachment.allowed_types=Allowed types config.attachment.allowed_types=Tipos permitidos
config.attachment.max_size=Size limit config.attachment.max_size=Limite de tamanho
config.attachment.max_files=Files limit config.attachment.max_files=Limite de ficheiros
config.release_config=Release configuration config.release_config=Release configuration
config.release.attachment.enabled=Attachment enabled config.release.attachment.enabled=Attachment enabled
config.release.attachment.allowed_types=Attachment allowed types config.release.attachment.allowed_types=Attachment allowed types
config.release.attachment.max_size=Attachment size limit config.release.attachment.max_size=Tamanho máximo dos anexos
config.release.attachment.max_files=Attachment files limit config.release.attachment.max_files=Attachment files limit
config.picture_config=Configuração de imagem config.picture_config=Configuração de imagem
@@ -1325,10 +1328,10 @@ config.picture.disable_gravatar=Disable Gravatar
config.picture.enable_federated_avatar=Enable federated avatars config.picture.enable_federated_avatar=Enable federated avatars
config.mirror_config=Mirror configuration config.mirror_config=Mirror configuration
config.mirror.default_interval=Default interval config.mirror.default_interval=Intervalo predefinido
config.webhook_config=Configuração de WebHook config.webhook_config=Configuração de WebHook
config.webhook.types=Types config.webhook.types=Tipos
config.webhook.deliver_timeout=Deliver timeout config.webhook.deliver_timeout=Deliver timeout
config.webhook.skip_tls_verify=Skip TLS verify config.webhook.skip_tls_verify=Skip TLS verify

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Ramuri vechi
branches.all=Toate ramurile branches.all=Toate ramurile
branches.updated_by=Actualizat %[1]s prin %[2]s branches.updated_by=Actualizat %[1]s prin %[2]s
branches.change_default_branch=Schimbarea ramurii implicite branches.change_default_branch=Schimbarea ramurii implicite
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Fișier nou editor.new_file=Fișier nou
editor.upload_file=Încărcați fișier editor.upload_file=Încărcați fișier
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Nu a reușit să trimită un e-mail de test către
config.email.test_mail_sent=E-mailul de test a fost trimis la '%s'. config.email.test_mail_sent=E-mailul de test a fost trimis la '%s'.
config.auth_config=Configurația de autentificare config.auth_config=Configurația de autentificare
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activați viețile de cod config.auth.activate_code_lives=Activați viețile de cod
config.auth.reset_password_code_lives=Resetează viețile codului parolei config.auth.reset_password_code_lives=Resetează viețile codului parolei
config.auth.require_email_confirm=Solicită confirmarea prin e-mail config.auth.require_email_confirm=Solicită confirmarea prin e-mail

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Устаревшие ветки
branches.all=Все ветки branches.all=Все ветки
branches.updated_by=Обновлено %[1]s пользователем %[2]s branches.updated_by=Обновлено %[1]s пользователем %[2]s
branches.change_default_branch=Change Default Branch branches.change_default_branch=Change Default Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Новый файл editor.new_file=Новый файл
editor.upload_file=Загрузить файл editor.upload_file=Загрузить файл
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Не удалось отправить тесто
config.email.test_mail_sent=Тестовое письмо было отправлено на %s config.email.test_mail_sent=Тестовое письмо было отправлено на %s
config.auth_config=Конфигурация аутентификации config.auth_config=Конфигурация аутентификации
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Срок действия кода сброса пароля config.auth.reset_password_code_lives=Срок действия кода сброса пароля
config.auth.require_email_confirm=Требовать подтверждение по электронной почте config.auth.require_email_confirm=Требовать подтверждение по электронной почте

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Zastaralé vetvy
branches.all=Všetky vetvy branches.all=Všetky vetvy
branches.updated_by=%[2]s zmenil %[1]s branches.updated_by=%[2]s zmenil %[1]s
branches.change_default_branch=Zmeniť základnú vetvu branches.change_default_branch=Zmeniť základnú vetvu
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Nový súbor editor.new_file=Nový súbor
editor.upload_file=Nahrať súbor editor.upload_file=Nahrať súbor
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Застареле гране
branches.all=Све гране branches.all=Све гране
branches.updated_by=Ажуриран %[1]s од %[2]s branches.updated_by=Ажуриран %[1]s од %[2]s
branches.change_default_branch=Промените подразумевану грану branches.change_default_branch=Промените подразумевану грану
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Нова датотека editor.new_file=Нова датотека
editor.upload_file=Отпреми датотеку editor.upload_file=Отпреми датотеку
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Djärva brancher
branches.all=Alla brancher branches.all=Alla brancher
branches.updated_by=Uppdaterade %[1]s med %[2]s branches.updated_by=Uppdaterade %[1]s med %[2]s
branches.change_default_branch=Ändra standard branch branches.change_default_branch=Ändra standard branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Ny fil editor.new_file=Ny fil
editor.upload_file=Ladda upp fil editor.upload_file=Ladda upp fil
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Eskimiş Bölümler
branches.all=Bütün Bölümler branches.all=Bütün Bölümler
branches.updated_by=%[2]s tarafından %[1]s güncellendi branches.updated_by=%[2]s tarafından %[1]s güncellendi
branches.change_default_branch=Varsayılan Bölümü Değiştir branches.change_default_branch=Varsayılan Bölümü Değiştir
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Yeni dosya editor.new_file=Yeni dosya
editor.upload_file=Dosyayı yükle editor.upload_file=Dosyayı yükle
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Застарілі гілки
branches.all=Усі гілки branches.all=Усі гілки
branches.updated_by=Оновлено %[1]s з %[2]s branches.updated_by=Оновлено %[1]s з %[2]s
branches.change_default_branch=Гілку за замовчуванням змінено branches.change_default_branch=Гілку за замовчуванням змінено
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Новий файл editor.new_file=Новий файл
editor.upload_file=Завантажити файл editor.upload_file=Завантажити файл
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Помилка відправлення пробн
config.email.test_mail_sent=Пробного листа було відправлено до '%s'. config.email.test_mail_sent=Пробного листа було відправлено до '%s'.
config.auth_config=Налаштування аутентифікації config.auth_config=Налаштування аутентифікації
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Активувати код підтвердження config.auth.activate_code_lives=Активувати код підтвердження
config.auth.reset_password_code_lives=Термін придатності кода при скиданні пароля config.auth.reset_password_code_lives=Термін придатності кода при скиданні пароля
config.auth.require_email_confirm=Вимагає підтвердження електронною поштою config.auth.require_email_confirm=Вимагає підтвердження електронною поштою

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Các nhánh cũ
branches.all=Tất cả các nhánh branches.all=Tất cả các nhánh
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Thay đổi nhánh mặc định branches.change_default_branch=Thay đổi nhánh mặc định
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=Tập tin mới editor.new_file=Tập tin mới
editor.upload_file=Tải tập tin lên editor.upload_file=Tải tập tin lên
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Gửi email kiểm tra đến '%s':%v thất bại
config.email.test_mail_sent=Email kiểm tra đã được gửi đến '%s'. config.email.test_mail_sent=Email kiểm tra đã được gửi đến '%s'.
config.auth_config=Cấu hình xác thực config.auth_config=Cấu hình xác thực
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Yêu cầu xác nhận email config.auth.require_email_confirm=Yêu cầu xác nhận email

View File

@@ -494,6 +494,8 @@ branches.stale_branches=陈旧分支
branches.all=所有分支 branches.all=所有分支
branches.updated_by=由 %[2]s 更新于 %[1]s branches.updated_by=由 %[2]s 更新于 %[1]s
branches.change_default_branch=更改默认分支 branches.change_default_branch=更改默认分支
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=新的文件 editor.new_file=新的文件
editor.upload_file=上传文件 editor.upload_file=上传文件
@@ -1275,6 +1277,7 @@ config.email.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
config.email.test_mail_sent=测试邮件已经发送至 '%s'。 config.email.test_mail_sent=测试邮件已经发送至 '%s'。
config.auth_config=认证配置 config.auth_config=认证配置
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=激活用户链接有效期 config.auth.activate_code_lives=激活用户链接有效期
config.auth.reset_password_code_lives=重置密码链接有效期 config.auth.reset_password_code_lives=重置密码链接有效期
config.auth.require_email_confirm=注册邮件确认 config.auth.require_email_confirm=注册邮件确认

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Change Default Branch branches.change_default_branch=Change Default Branch
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=New file editor.new_file=New file
editor.upload_file=Upload file editor.upload_file=Upload file
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Failed to send test email to '%s': %v
config.email.test_mail_sent=Test email has been sent to '%s'. config.email.test_mail_sent=Test email has been sent to '%s'.
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=陳舊分支
branches.all=所有分支 branches.all=所有分支
branches.updated_by=%[2]s 更新了 %[1]s branches.updated_by=%[2]s 更新了 %[1]s
branches.change_default_branch=變更預設分支 branches.change_default_branch=變更預設分支
branches.default_deletion_not_allowed=Cannot delete the default branch.
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
editor.new_file=開新檔案 editor.new_file=開新檔案
editor.upload_file=上傳檔案 editor.upload_file=上傳檔案
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=發送測試郵件至 '%s' 時失敗:%v
config.email.test_mail_sent=測試電子郵件已發送到 '%s'。 config.email.test_mail_sent=測試電子郵件已發送到 '%s'。
config.auth_config=Authentication configuration config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation config.auth.require_email_confirm=Require email confirmation

View File

@@ -1,7 +1,7 @@
# Docker for Gogs (Next Generation) # Docker for Gogs (Next Generation)
> [!NOTE] > [!NOTE]
> This is the next-generation, security-focused Docker image. This will become the default image distribution (`gogs/gogs:latest`) starting 0.15.0. > This is the next-generation, security-focused Docker image. This will become the default image distribution (`gogs/gogs:latest`) starting 0.16.0.
![Docker pulls](https://img.shields.io/docker/pulls/gogs/gogs?logo=docker&style=for-the-badge) ![Docker pulls](https://img.shields.io/docker/pulls/gogs/gogs?logo=docker&style=for-the-badge)

View File

@@ -1,10 +1,15 @@
# Docker for Gogs # Docker for Gogs
> [!WARNING] > [!WARNING]
> This is now the legacy Docker image that lacks modern security best practices. It will be published as `gogs/gogs:legacy-latest` starting 0.15.0, and be completely removed starting 0.16.0. > This is now the legacy Docker image that lacks modern security best practices. It will be published as `gogs/gogs:legacy-latest` starting 0.16.0, and be completely removed no earlier than 0.17.0.
> >
> To use the next-generation, security-focused Docker image, see [docker-next/README.md](../docker-next/README.md). > To use the next-generation, security-focused Docker image, see [docker-next/README.md](../docker-next/README.md).
> [!IMPORTANT]
> Image versions:
> - Every released version has its own tag , e.g., `gogs/gogs:0.13.4`, and a tag points to the latest patch of the minor version, e.g., `gogs/gogs:0.13`.
> - The `latest` tag is the image version built from the latest `main` branch.
![Docker pulls](https://img.shields.io/docker/pulls/gogs/gogs?logo=docker&style=for-the-badge) ![Docker pulls](https://img.shields.io/docker/pulls/gogs/gogs?logo=docker&style=for-the-badge)
Visit [Docker Hub](https://hub.docker.com/u/gogs) or [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs) to see all available images and tags. Visit [Docker Hub](https://hub.docker.com/u/gogs) or [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs) to see all available images and tags.

View File

@@ -0,0 +1,131 @@
# Table "access"
```
Field | Column | PostgreSQL | MySQL | SQLite3
--------+---------+-----------------+-----------------------+-----------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
RepoID | repo_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Mode | mode | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Primary keys: id
Indexes:
"access_user_repo_unique" UNIQUE (user_id, repo_id)
```
# Table "access_token"
```
Field | Column | PostgreSQL | MySQL | SQLite3
-------------+--------------+-----------------------------+-----------------------------+-----------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
UserID | uid | BIGINT | BIGINT | INTEGER
Name | name | TEXT | LONGTEXT | TEXT
Sha1 | sha1 | VARCHAR(40) UNIQUE | VARCHAR(40) UNIQUE | VARCHAR(40) UNIQUE
SHA256 | sha256 | VARCHAR(64) NOT NULL UNIQUE | VARCHAR(64) NOT NULL UNIQUE | VARCHAR(64) NOT NULL UNIQUE
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
UpdatedUnix | updated_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
Indexes:
"idx_access_token_user_id" (uid)
```
# Table "action"
```
Field | Column | PostgreSQL | MySQL | SQLite3
--------------+----------------+--------------------------------+--------------------------------+--------------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
UserID | user_id | BIGINT | BIGINT | INTEGER
OpType | op_type | BIGINT | BIGINT | INTEGER
ActUserID | act_user_id | BIGINT | BIGINT | INTEGER
ActUserName | act_user_name | TEXT | LONGTEXT | TEXT
RepoID | repo_id | BIGINT | BIGINT | INTEGER
RepoUserName | repo_user_name | TEXT | LONGTEXT | TEXT
RepoName | repo_name | TEXT | LONGTEXT | TEXT
RefName | ref_name | TEXT | LONGTEXT | TEXT
IsPrivate | is_private | BOOLEAN NOT NULL DEFAULT FALSE | BOOLEAN NOT NULL DEFAULT FALSE | NUMERIC NOT NULL DEFAULT FALSE
Content | content | TEXT | LONGTEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
Indexes:
"idx_action_repo_id" (repo_id)
"idx_action_user_id" (user_id)
```
# Table "email_address"
```
Field | Column | PostgreSQL | MySQL | SQLite3
-------------+--------------+--------------------------------+--------------------------------+--------------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
UserID | uid | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Email | email | VARCHAR(254) NOT NULL | VARCHAR(254) NOT NULL | TEXT NOT NULL
IsActivated | is_activated | BOOLEAN NOT NULL DEFAULT FALSE | BOOLEAN NOT NULL DEFAULT FALSE | NUMERIC NOT NULL DEFAULT FALSE
Primary keys: id
Indexes:
"email_address_user_email_unique" UNIQUE (uid, email)
"idx_email_address_user_id" (uid)
```
# Table "follow"
```
Field | Column | PostgreSQL | MySQL | SQLite3
----------+-----------+-----------------+-----------------------+-----------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
FollowID | follow_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Primary keys: id
Indexes:
"follow_user_follow_unique" UNIQUE (user_id, follow_id)
```
# Table "lfs_object"
```
Field | Column | PostgreSQL | MySQL | SQLite3
-----------+------------+----------------------+----------------------+-------------------
RepoID | repo_id | BIGINT | BIGINT | INTEGER
OID | oid | TEXT | VARCHAR(191) | TEXT
Size | size | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Storage | storage | TEXT NOT NULL | LONGTEXT NOT NULL | TEXT NOT NULL
CreatedAt | created_at | TIMESTAMPTZ NOT NULL | DATETIME(3) NOT NULL | DATETIME NOT NULL
Primary keys: repo_id, oid
```
# Table "login_source"
```
Field | Column | PostgreSQL | MySQL | SQLite3
-------------+--------------+------------------+-----------------------+-----------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
Type | type | BIGINT | BIGINT | INTEGER
Name | name | TEXT UNIQUE | VARCHAR(191) UNIQUE | TEXT UNIQUE
IsActived | is_actived | BOOLEAN NOT NULL | BOOLEAN NOT NULL | NUMERIC NOT NULL
IsDefault | is_default | BOOLEAN | BOOLEAN | NUMERIC
Config | cfg | TEXT | TEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
UpdatedUnix | updated_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
```
# Table "notice"
```
Field | Column | PostgreSQL | MySQL | SQLite3
-------------+--------------+------------+-----------------------+-----------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER AUTOINCREMENT
Type | type | BIGINT | BIGINT | INTEGER
Description | description | TEXT | TEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
```

View File

@@ -6,7 +6,7 @@
1. Run the `import` subcommand: 1. Run the `import` subcommand:
``` ```
$ ./gogs import locale --source <path to the unzipped directory> --target ./conf/locale $ ./.bin/gogs import locale --source <path to the unzipped directory> --target ./conf/locale
Locale files has been successfully imported! Locale files has been successfully imported!
``` ```

View File

@@ -1,131 +0,0 @@
# Table "access"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
---------+---------+-----------------+-----------------------+-------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
RepoID | repo_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Mode | mode | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Primary keys: id
Indexes:
"access_user_repo_unique" UNIQUE (user_id, repo_id)
```
# Table "access_token"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
--------------+--------------+-----------------------------+-----------------------------+------------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
UserID | uid | BIGINT | BIGINT | INTEGER
Name | name | TEXT | LONGTEXT | TEXT
Sha1 | sha1 | VARCHAR(40) UNIQUE | VARCHAR(40) UNIQUE | VARCHAR(40) UNIQUE
SHA256 | sha256 | VARCHAR(64) NOT NULL UNIQUE | VARCHAR(64) NOT NULL UNIQUE | VARCHAR(64) NOT NULL UNIQUE
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
UpdatedUnix | updated_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
Indexes:
"idx_access_token_user_id" (uid)
```
# Table "action"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
---------------+----------------+--------------------------------+--------------------------------+---------------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
UserID | user_id | BIGINT | BIGINT | INTEGER
OpType | op_type | BIGINT | BIGINT | INTEGER
ActUserID | act_user_id | BIGINT | BIGINT | INTEGER
ActUserName | act_user_name | TEXT | LONGTEXT | TEXT
RepoID | repo_id | BIGINT | BIGINT | INTEGER
RepoUserName | repo_user_name | TEXT | LONGTEXT | TEXT
RepoName | repo_name | TEXT | LONGTEXT | TEXT
RefName | ref_name | TEXT | LONGTEXT | TEXT
IsPrivate | is_private | BOOLEAN NOT NULL DEFAULT FALSE | BOOLEAN NOT NULL DEFAULT FALSE | NUMERIC NOT NULL DEFAULT FALSE
Content | content | TEXT | LONGTEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
Indexes:
"idx_action_repo_id" (repo_id)
"idx_action_user_id" (user_id)
```
# Table "email_address"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
--------------+--------------+--------------------------------+--------------------------------+---------------------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
UserID | uid | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Email | email | VARCHAR(254) NOT NULL | VARCHAR(254) NOT NULL | TEXT NOT NULL
IsActivated | is_activated | BOOLEAN NOT NULL DEFAULT FALSE | BOOLEAN NOT NULL DEFAULT FALSE | NUMERIC NOT NULL DEFAULT FALSE
Primary keys: id
Indexes:
"email_address_user_email_unique" UNIQUE (uid, email)
"idx_email_address_user_id" (uid)
```
# Table "follow"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
-----------+-----------+-----------------+-----------------------+-------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
FollowID | follow_id | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Primary keys: id
Indexes:
"follow_user_follow_unique" UNIQUE (user_id, follow_id)
```
# Table "lfs_object"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
------------+------------+----------------------+----------------------+--------------------
RepoID | repo_id | BIGINT | BIGINT | INTEGER
OID | oid | TEXT | VARCHAR(191) | TEXT
Size | size | BIGINT NOT NULL | BIGINT NOT NULL | INTEGER NOT NULL
Storage | storage | TEXT NOT NULL | LONGTEXT NOT NULL | TEXT NOT NULL
CreatedAt | created_at | TIMESTAMPTZ NOT NULL | DATETIME(3) NOT NULL | DATETIME NOT NULL
Primary keys: repo_id, oid
```
# Table "login_source"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
--------------+--------------+------------------+-----------------------+-------------------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
Type | type | BIGINT | BIGINT | INTEGER
Name | name | TEXT UNIQUE | VARCHAR(191) UNIQUE | TEXT UNIQUE
IsActived | is_actived | BOOLEAN NOT NULL | BOOLEAN NOT NULL | NUMERIC NOT NULL
IsDefault | is_default | BOOLEAN | BOOLEAN | NUMERIC
Config | cfg | TEXT | TEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
UpdatedUnix | updated_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
```
# Table "notice"
```
FIELD | COLUMN | POSTGRESQL | MYSQL | SQLITE3
--------------+--------------+------------+-----------------------+----------
ID | id | BIGSERIAL | BIGINT AUTO_INCREMENT | INTEGER
Type | type | BIGINT | BIGINT | INTEGER
Description | description | TEXT | TEXT | TEXT
CreatedUnix | created_unix | BIGINT | BIGINT | INTEGER
Primary keys: id
```

48
go.mod
View File

@@ -6,8 +6,11 @@ require (
github.com/Masterminds/semver/v3 v3.4.0 github.com/Masterminds/semver/v3 v3.4.0
github.com/cockroachdb/errors v1.12.0 github.com/cockroachdb/errors v1.12.0
github.com/derision-test/go-mockgen/v2 v2.1.1 github.com/derision-test/go-mockgen/v2 v2.1.1
github.com/editorconfig/editorconfig-core-go/v2 v2.6.3 github.com/editorconfig/editorconfig-core-go/v2 v2.6.4
github.com/go-ldap/ldap/v3 v3.4.11 github.com/fergusstrange/embedded-postgres v1.33.0
github.com/glebarez/go-sqlite v1.21.2
github.com/glebarez/sqlite v1.11.0
github.com/go-ldap/ldap/v3 v3.4.12
github.com/go-macaron/binding v1.2.0 github.com/go-macaron/binding v1.2.0
github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196 github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196
github.com/go-macaron/captcha v0.2.0 github.com/go-macaron/captcha v0.2.0
@@ -18,19 +21,19 @@ require (
github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6 github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6
github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/gogs/git-module v1.8.4 github.com/gogs/git-module v1.8.6
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0
github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a
github.com/google/go-github v17.0.0+incompatible github.com/google/go-github v17.0.0+incompatible
github.com/inbucket/html2text v1.0.0
github.com/issue9/identicon v1.2.1 github.com/issue9/identicon v1.2.1
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/microcosm-cc/bluemonday v1.0.27 github.com/microcosm-cc/bluemonday v1.0.27
github.com/msteinert/pam v1.2.0 github.com/msteinert/pam v1.2.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/niklasfasching/go-org v1.9.1 github.com/niklasfasching/go-org v1.9.1
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v1.1.3
github.com/pquerna/otp v1.5.0 github.com/pquerna/otp v1.5.0
github.com/prometheus/client_golang v1.23.0 github.com/prometheus/client_golang v1.23.0
github.com/russross/blackfriday v1.6.0 github.com/russross/blackfriday v1.6.0
@@ -43,19 +46,17 @@ require (
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e
github.com/urfave/cli v1.22.17 github.com/urfave/cli v1.22.17
golang.org/x/crypto v0.45.0 golang.org/x/crypto v0.47.0
golang.org/x/net v0.47.0 golang.org/x/net v0.48.0
golang.org/x/text v0.31.0 golang.org/x/text v0.33.0
gopkg.in/DATA-DOG/go-sqlmock.v2 v2.0.0-20180914054222-c19298f520d0 gopkg.in/DATA-DOG/go-sqlmock.v2 v2.0.0-20180914054222-c19298f520d0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0 gopkg.in/ini.v1 v1.67.0
gopkg.in/macaron.v1 v1.5.0 gopkg.in/macaron.v1 v1.5.1
gorm.io/driver/mysql v1.5.2 gorm.io/driver/mysql v1.5.2
gorm.io/driver/postgres v1.6.0 gorm.io/driver/postgres v1.6.0
gorm.io/driver/sqlite v1.4.2
gorm.io/driver/sqlserver v1.4.1 gorm.io/driver/sqlserver v1.4.1
gorm.io/gorm v1.25.12 gorm.io/gorm v1.25.12
modernc.org/sqlite v1.38.2
unknwon.dev/clog/v2 v2.2.0 unknwon.dev/clog/v2 v2.2.0
xorm.io/builder v0.3.6 xorm.io/builder v0.3.6
xorm.io/core v0.7.2 xorm.io/core v0.7.2
@@ -70,6 +71,9 @@ require (
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 // indirect github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/displaywidth v0.6.2 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
@@ -79,7 +83,7 @@ require (
github.com/djherbis/buffer v1.2.0 // indirect github.com/djherbis/buffer v1.2.0 // indirect
github.com/djherbis/nio/v3 v3.0.1 // indirect github.com/djherbis/nio/v3 v3.0.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.13.0 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
@@ -104,10 +108,10 @@ require (
github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/compress v1.18.0 // indirect
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.2 // indirect github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.24 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 // indirect github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 // indirect
github.com/microsoft/go-mssqldb v0.17.0 // indirect github.com/microsoft/go-mssqldb v0.17.0 // indirect
@@ -115,24 +119,27 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect github.com/prometheus/procfs v0.16.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
go.bobheadxi.dev/streamline v1.2.1 // indirect go.bobheadxi.dev/streamline v1.2.1 // indirect
go.opentelemetry.io/otel v1.11.0 // indirect go.opentelemetry.io/otel v1.11.0 // indirect
go.opentelemetry.io/otel/trace v1.11.0 // indirect go.opentelemetry.io/otel/trace v1.11.0 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/mod v0.29.0 // indirect golang.org/x/mod v0.31.0 // indirect
golang.org/x/sync v0.18.0 // indirect golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.38.0 // indirect golang.org/x/sys v0.40.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e // indirect gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e // indirect
@@ -141,7 +148,8 @@ require (
modernc.org/libc v1.66.3 // indirect modernc.org/libc v1.66.3 // indirect
modernc.org/mathutil v1.7.1 // indirect modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.39.0 // indirect
) )
// +heroku goVersion go1.25 // +heroku goVersion go1.25
// +heroku install ./ // +heroku install ./cmd/gogs

125
go.sum
View File

@@ -22,8 +22,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
@@ -41,6 +41,12 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo= github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g= github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
@@ -79,12 +85,14 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/editorconfig/editorconfig-core-go/v2 v2.6.3 h1:XVUp6qW3BIkmM3/1EkrHpa6bL56APOynfXcZEmIgOhs= github.com/editorconfig/editorconfig-core-go/v2 v2.6.4 h1:CHwUbBVVyKWRX9kt5A/OtwhYUJB32DrFp9xzmjR6cac=
github.com/editorconfig/editorconfig-core-go/v2 v2.6.3/go.mod h1:ThHVc+hqbUsmE1wmK/MASpQEhCleWu1JDJDNhUOMy0c= github.com/editorconfig/editorconfig-core-go/v2 v2.6.4/go.mod h1:JWRVKHdVW+dkv6F8p+xGCa6a+TyMrqsFbFkSs/aQkrQ=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fergusstrange/embedded-postgres v1.33.0 h1:ka8vmRpm4IDsES7NPXQ/NThAp1fc/f+crcXYjCW7wK0=
github.com/fergusstrange/embedded-postgres v1.33.0/go.mod h1:w0YvnCgf19o6tskInrOOACtnqfVlOvluz3hlNLY7tRk=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -92,13 +100,17 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU= github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=
github.com/go-ldap/ldap/v3 v3.4.11/go.mod h1:bY7t0FLK8OAVpp/vV6sSlpz3EQDGcQwc8pF0ujLgKvM= github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
@@ -142,8 +154,8 @@ github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 h1:aBzukfDxQlCTVS0NBU
github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8= github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk= github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
github.com/gogs/git-module v1.8.4 h1:oSt8sOL4NWOGrSo/CwbS+C4YXtk76QvxyPofem/ViTU= github.com/gogs/git-module v1.8.6 h1:4Io9vWZYQyIjdIPxfKgeYZXnDKNgydc6OZTxII5xCH4=
github.com/gogs/git-module v1.8.4/go.mod h1:bQY0aoMK5Q5+NKgy4jXe3K1GFW+GnsSk0SJK0jh6yD0= github.com/gogs/git-module v1.8.6/go.mod h1:IiMSJqi8XH62Kjqjt5Rw8IawSo+DHfM2dDjkSzWLjhs=
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic= github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic=
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU= github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4= github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4=
@@ -201,8 +213,9 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
@@ -218,6 +231,8 @@ github.com/hexops/valast v1.4.3 h1:oBoGERMJh6UZdRc6cduE1CTPK+VAdXA59Y1HFgu3sm0=
github.com/hexops/valast v1.4.3/go.mod h1:Iqx2kLj3Jn47wuXpj3wX40xn6F93QNFBHuiKBerkTGA= github.com/hexops/valast v1.4.3/go.mod h1:Iqx2kLj3Jn47wuXpj3wX40xn6F93QNFBHuiKBerkTGA=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inbucket/html2text v1.0.0 h1:N5kza++4uBBDJ2Z3KUnTRyPNoBcW+YfOgNiNmNB+sgs=
github.com/inbucket/html2text v1.0.0/go.mod h1:5TrhXQKGU+LXurODaSm55Y9eXoPBRnYiOz4x2XfUoJU=
github.com/issue9/assert/v2 v2.0.0 h1:vN7fr70g5ND6zM39tPZk/E4WCyjGMqApmFbujSTmEo0= github.com/issue9/assert/v2 v2.0.0 h1:vN7fr70g5ND6zM39tPZk/E4WCyjGMqApmFbujSTmEo0=
github.com/issue9/assert/v2 v2.0.0/go.mod h1:rKr1eVGzXUhAo2af1thiKAhIA8uiSK9Wyn7mcZ4BzAg= github.com/issue9/assert/v2 v2.0.0/go.mod h1:rKr1eVGzXUhAo2af1thiKAhIA8uiSK9Wyn7mcZ4BzAg=
github.com/issue9/identicon v1.2.1 h1:9RUq3DcmDJvfXAYZWJDaq/Bi45oS/Fr79W0CazbXNaY= github.com/issue9/identicon v1.2.1 h1:9RUq3DcmDJvfXAYZWJDaq/Bi45oS/Fr79W0CazbXNaY=
@@ -234,8 +249,6 @@ github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 h1:jTkyeF7NZ5oIr0ESmcrpiDgAfoidCBF4F5kJhjtaRwE=
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
@@ -277,31 +290,24 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ= github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0= github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg= github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
@@ -331,8 +337,14 @@ github.com/niklasfasching/go-org v1.9.1/go.mod h1:ZAGFFkWvUQcpazmi/8nHqwvARpr1xp
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM=
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA=
github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -385,8 +397,6 @@ github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlT
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
@@ -405,14 +415,16 @@ github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0
github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/sourcegraph/run v0.12.0 h1:3A8w5e8HIYPfafHekvmdmmh42RHKGVhmiTZAPJclg7I= github.com/sourcegraph/run v0.12.0 h1:3A8w5e8HIYPfafHekvmdmmh42RHKGVhmiTZAPJclg7I=
github.com/sourcegraph/run v0.12.0/go.mod h1:PwaP936BTnAJC1cqR5rSbG5kOs/EWStTK3lqvMX5GUA= github.com/sourcegraph/run v0.12.0/go.mod h1:PwaP936BTnAJC1cqR5rSbG5kOs/EWStTK3lqvMX5GUA=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
@@ -446,6 +458,8 @@ github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e h1:Qf3QQl/zmEbWD
github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0= github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ= github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ=
github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo= github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
@@ -472,8 +486,8 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
@@ -482,8 +496,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -504,8 +518,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -515,9 +529,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -534,8 +547,6 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -544,26 +555,24 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -577,8 +586,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -626,8 +635,8 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI= gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI=
gopkg.in/macaron.v1 v1.3.5/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4= gopkg.in/macaron.v1 v1.3.5/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
gopkg.in/macaron.v1 v1.4.0/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4= gopkg.in/macaron.v1 v1.4.0/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
gopkg.in/macaron.v1 v1.5.0 h1:/dXJaeQagWLjVjCrKH8dgSSU7yG4qTv6rBKpqhYaCyc= gopkg.in/macaron.v1 v1.5.1 h1:0ytdXYcf6//a8bzedl1fVXzPeIXblEqoNPntWAo9YLU=
gopkg.in/macaron.v1 v1.5.0/go.mod h1:sAYUd2r8Q+jLnCN4/ZmdAYHzQn67agV5sAqKFQgrRrw= gopkg.in/macaron.v1 v1.5.1/go.mod h1:AiquOw8YeZJC8sUe11vIO6NeA1/TKSlzQXuJ7Tc4cCQ=
gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs= gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=
gopkg.in/redis.v2 v2.3.2/go.mod h1:4wl9PJ/CqzeHk3LVq1hNLHH8krm3+AXEgut4jVc++LU= gopkg.in/redis.v2 v2.3.2/go.mod h1:4wl9PJ/CqzeHk3LVq1hNLHH8krm3+AXEgut4jVc++LU=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -648,8 +657,6 @@ gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
gorm.io/driver/sqlite v1.4.2 h1:F6vYJcmR4Cnh0ErLyoY8JSfabBGyR0epIGuhgHJuNws=
gorm.io/driver/sqlite v1.4.2/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig= gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
@@ -679,8 +686,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.38.2 h1:Aclu7+tgjgcQVShZqim41Bbw9Cho0y/7WzYptXqkEek= modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY=
modernc.org/sqlite v1.38.2/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= modernc.org/sqlite v1.39.0/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

View File

@@ -70,7 +70,7 @@ func Init(customConf string) error {
if err = File.Append(customConf); err != nil { if err = File.Append(customConf); err != nil {
return errors.Wrapf(err, "append %q", customConf) return errors.Wrapf(err, "append %q", customConf)
} }
} else { } else if !HookMode {
log.Warn("Custom config %q not found. Ignore this warning if you're running for the first time", customConf) log.Warn("Custom config %q not found. Ignore this warning if you're running for the first time", customConf)
} }
@@ -142,9 +142,11 @@ func Init(customConf string) error {
} }
if IsWindowsRuntime() || semverutil.Compare(sshVersion, "<", "5.1") { if IsWindowsRuntime() || semverutil.Compare(sshVersion, "<", "5.1") {
log.Warn(`SSH minimum key size check is forced to be disabled because server is not eligible: if !HookMode {
log.Warn(`SSH minimum key size check is forced to be disabled because server is not eligible:
1. Windows server 1. Windows server
2. OpenSSH version is lower than 5.1`) 2. OpenSSH version is lower than 5.1`)
}
} else { } else {
SSH.MinimumKeySizes = map[string]int{} SSH.MinimumKeySizes = map[string]int{}
for _, key := range File.Section("ssh.minimum_key_sizes").Keys() { for _, key := range File.Section("ssh.minimum_key_sizes").Keys() {
@@ -346,6 +348,11 @@ func Init(customConf string) error {
LFS.ObjectsPath = ensureAbs(LFS.ObjectsPath) LFS.ObjectsPath = ensureAbs(LFS.ObjectsPath)
handleDeprecated() handleDeprecated()
if !HookMode {
for _, warning := range checkInvalidOptions(File) {
log.Warn("%s", warning)
}
}
if err = File.Section("cache").MapTo(&Cache); err != nil { if err = File.Section("cache").MapTo(&Cache); err != nil {
return errors.Wrap(err, "mapping [cache] section") return errors.Wrap(err, "mapping [cache] section")

View File

@@ -1,11 +1,15 @@
package conf package conf
import ( import (
"fmt"
"net/url" "net/url"
"os" "os"
"time" "time"
"github.com/gogs/go-libravatar" "github.com/gogs/go-libravatar"
"gopkg.in/ini.v1"
"gogs.io/gogs/conf"
) )
// README: This file contains static values that should only be set at initialization time. // README: This file contains static values that should only be set at initialization time.
@@ -227,7 +231,7 @@ var (
) )
type AppOpts struct { type AppOpts struct {
// ⚠️ WARNING: Should only be set by the main package (i.e. "gogs.go"). // ⚠️ WARNING: Should only be set by the main package (i.e. "cmd/gogs/main.go").
Version string `ini:"-"` Version string `ini:"-"`
BrandName string BrandName string
@@ -430,10 +434,75 @@ func handleDeprecated() {
// } // }
} }
// checkInvalidOptions checks invalid (renamed/deleted) configuration sections
// and options and returns a list of warnings.
func checkInvalidOptions(config *ini.File) (warnings []string) {
renamedSections := map[string]string{
"mailer": "email",
"service": "auth",
}
for oldSection, newSection := range renamedSections {
if len(config.Section(oldSection).KeyStrings()) > 0 {
warnings = append(warnings, fmt.Sprintf("section [%s] is invalid, use [%s] instead", oldSection, newSection))
}
}
type optionPath struct {
section string
option string
}
renamedOptionPaths := map[optionPath]optionPath{
// Example:
// {"security", "REVERSE_PROXY_AUTHENTICATION_USER"}: {"auth", "REVERSE_PROXY_AUTHENTICATION_HEADER"},
}
for oldPath, newPath := range renamedOptionPaths {
if config.Section(oldPath.section).HasKey(oldPath.option) {
warnings = append(
warnings,
fmt.Sprintf("option [%s] %s is invalid, use [%s] %s instead",
oldPath.section, oldPath.option,
newPath.section, newPath.option,
),
)
}
}
// Check options that don't exist anymore.
defaultConfigData, err := conf.Files.ReadFile("app.ini")
if err != nil {
// Warning is best-effort, OK to skip on error.
return warnings
}
defaultConfig, err := ini.LoadSources(
ini.LoadOptions{IgnoreInlineComment: true},
defaultConfigData,
)
if err != nil {
// Warning is best-effort, OK to skip on error.
return warnings
}
for _, section := range config.Sections() {
// Skip sections already warned about.
if _, ok := renamedSections[section.Name()]; ok {
continue
}
for _, option := range section.Keys() {
if _, ok := renamedOptionPaths[optionPath{section.Name(), option.Name()}]; ok {
continue
}
if !defaultConfig.Section(section.Name()).HasKey(option.Name()) {
warnings = append(warnings, fmt.Sprintf("option [%s] %s is invalid", section.Name(), option.Name()))
}
}
}
return warnings
}
// HookMode indicates whether program starts as Git server-side hook callback. // HookMode indicates whether program starts as Git server-side hook callback.
// All operations should be done synchronously to prevent program exits before finishing. // All operations should be done synchronously to prevent program exits before finishing.
// //
// ⚠️ WARNING: Should only be set by "internal/cmd/serv.go". // ⚠️ WARNING: Should only be set by "cmd/gogs/serv.go".
var HookMode bool var HookMode bool
// Indicates which database backend is currently being used. // Indicates which database backend is currently being used.

View File

@@ -1,9 +1,11 @@
package conf package conf
import ( import (
"sort"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/ini.v1"
) )
func Test_i18n_DateLang(t *testing.T) { func Test_i18n_DateLang(t *testing.T) {
@@ -29,3 +31,48 @@ func Test_i18n_DateLang(t *testing.T) {
}) })
} }
} }
func TestCheckInvalidOptions(t *testing.T) {
cfg := ini.Empty()
_, _ = cfg.Section("mailer").NewKey("ENABLED", "true")
_, _ = cfg.Section("service").NewKey("START_TYPE", "true")
_, _ = cfg.Section("security").NewKey("REVERSE_PROXY_AUTHENTICATION_USER", "true")
_, _ = cfg.Section("auth").NewKey("ACTIVE_CODE_LIVE_MINUTES", "10")
_, _ = cfg.Section("auth").NewKey("RESET_PASSWD_CODE_LIVE_MINUTES", "10")
_, _ = cfg.Section("auth").NewKey("ENABLE_CAPTCHA", "true")
_, _ = cfg.Section("auth").NewKey("ENABLE_NOTIFY_MAIL", "true")
_, _ = cfg.Section("auth").NewKey("REGISTER_EMAIL_CONFIRM", "true")
_, _ = cfg.Section("session").NewKey("GC_INTERVAL_TIME", "10")
_, _ = cfg.Section("session").NewKey("SESSION_LIFE_TIME", "10")
_, _ = cfg.Section("server").NewKey("ROOT_URL", "true")
_, _ = cfg.Section("server").NewKey("LANDING_PAGE", "true")
_, _ = cfg.Section("database").NewKey("DB_TYPE", "true")
_, _ = cfg.Section("database").NewKey("PASSWD", "true")
_, _ = cfg.Section("other").NewKey("SHOW_FOOTER_BRANDING", "true")
_, _ = cfg.Section("other").NewKey("SHOW_FOOTER_TEMPLATE_LOAD_TIME", "true")
_, _ = cfg.Section("email").NewKey("ENABLED", "true")
_, _ = cfg.Section("server").NewKey("NONEXISTENT_OPTION", "true")
wantWarnings := []string{
"option [auth] ACTIVE_CODE_LIVE_MINUTES is invalid",
"option [auth] ENABLE_CAPTCHA is invalid",
"option [auth] ENABLE_NOTIFY_MAIL is invalid",
"option [auth] REGISTER_EMAIL_CONFIRM is invalid",
"option [auth] RESET_PASSWD_CODE_LIVE_MINUTES is invalid",
"option [database] DB_TYPE is invalid",
"option [database] PASSWD is invalid",
"option [security] REVERSE_PROXY_AUTHENTICATION_USER is invalid",
"option [session] GC_INTERVAL_TIME is invalid",
"option [session] SESSION_LIFE_TIME is invalid",
"section [mailer] is invalid, use [email] instead",
"section [service] is invalid, use [auth] instead",
"option [server] ROOT_URL is invalid",
"option [server] LANDING_PAGE is invalid",
"option [server] NONEXISTENT_OPTION is invalid",
}
gotWarnings := checkInvalidOptions(cfg)
sort.Strings(wantWarnings)
sort.Strings(gotWarnings)
assert.Equal(t, wantWarnings, gotWarnings)
}

View File

@@ -28,9 +28,8 @@ PASSWORD = 87654321
ACTIVATE_CODE_LIVES = 10 ACTIVATE_CODE_LIVES = 10
RESET_PASSWORD_CODE_LIVES = 10 RESET_PASSWORD_CODE_LIVES = 10
REQUIRE_EMAIL_CONFIRMATION = true REQUIRE_EMAIL_CONFIRMATION = true
ENABLE_CAPTCHA = true ENABLE_REGISTRATION_CAPTCHA = true
ENABLE_NOTIFY_MAIL = true REVERSE_PROXY_AUTHENTICATION_HEADER = X-FORWARDED-FOR
REVERSE_PROXY_AUTHENTICATION_HEADER=X-FORWARDED-FOR
[user] [user]
ENABLE_EMAIL_NOTIFICATION = true ENABLE_EMAIL_NOTIFICATION = true

View File

@@ -147,13 +147,13 @@ func (c *Context) RedirectSubpath(location string, status ...int) {
} }
// RenderWithErr used for page has form validation but need to prompt error to users. // RenderWithErr used for page has form validation but need to prompt error to users.
func (c *Context) RenderWithErr(msg, tpl string, f any) { func (c *Context) RenderWithErr(msg string, status int, tpl string, f any) {
if f != nil { if f != nil {
form.Assign(f, c.Data) form.Assign(f, c.Data)
} }
c.Flash.ErrorMsg = msg c.Flash.ErrorMsg = msg
c.Data["Flash"] = c.Flash c.Data["Flash"] = c.Flash
c.HTML(http.StatusOK, tpl) c.HTML(status, tpl)
} }
// NotFound renders the 404 page. // NotFound renders the 404 page.

View File

@@ -142,6 +142,11 @@ func actionsCommitRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
now := time.Unix(1588568886, 0).UTC() now := time.Unix(1588568886, 0).UTC()
conf.SetMockSSH(t, conf.SSHOpts{}) conf.SetMockSSH(t, conf.SSHOpts{})
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
t.Run("new commit", func(t *testing.T) { t.Run("new commit", func(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
@@ -432,6 +437,12 @@ func actionsListByUser(t *testing.T, ctx context.Context, s *ActionsStore) {
} }
func actionsMergePullRequest(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsMergePullRequest(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -477,6 +488,12 @@ func actionsMergePullRequest(t *testing.T, ctx context.Context, s *ActionsStore)
} }
func actionsMirrorSyncCreate(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsMirrorSyncCreate(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -518,6 +535,12 @@ func actionsMirrorSyncCreate(t *testing.T, ctx context.Context, s *ActionsStore)
} }
func actionsMirrorSyncDelete(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsMirrorSyncDelete(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -559,6 +582,12 @@ func actionsMirrorSyncDelete(t *testing.T, ctx context.Context, s *ActionsStore)
} }
func actionsMirrorSyncPush(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsMirrorSyncPush(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -624,6 +653,12 @@ func actionsMirrorSyncPush(t *testing.T, ctx context.Context, s *ActionsStore) {
} }
func actionsNewRepo(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsNewRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -703,6 +738,11 @@ func actionsPushTag(t *testing.T, ctx context.Context, s *ActionsStore) {
// to the mock server because this function holds a lock. // to the mock server because this function holds a lock.
conf.SetMockServer(t, conf.ServerOpts{}) conf.SetMockServer(t, conf.ServerOpts{})
conf.SetMockSSH(t, conf.SSHOpts{}) conf.SetMockSSH(t, conf.SSHOpts{})
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
@@ -796,6 +836,12 @@ func actionsPushTag(t *testing.T, ctx context.Context, s *ActionsStore) {
} }
func actionsRenameRepo(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsRenameRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx, repo, err := newReposStore(s.db).Create(ctx,
@@ -833,6 +879,12 @@ func actionsRenameRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
} }
func actionsTransferRepo(t *testing.T, ctx context.Context, s *ActionsStore) { func actionsTransferRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
conf.SetMockUI(t, conf.UIOpts{
User: conf.UIUserOpts{
NewsFeedPagingNum: 20,
},
})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{}) alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
bob, err := newUsersStore(s.db).Create(ctx, "bob", "bob@example.com", CreateUserOptions{}) bob, err := newUsersStore(s.db).Create(ctx, "bob", "bob@example.com", CreateUserOptions{})

View File

@@ -8,7 +8,6 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
_ "modernc.org/sqlite"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf" "gogs.io/gogs/internal/conf"

View File

@@ -7,7 +7,6 @@ import (
"testing" "testing"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
_ "modernc.org/sqlite"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/testutil" "gogs.io/gogs/internal/testutil"

View File

@@ -11,6 +11,7 @@ import (
"time" "time"
"github.com/cockroachdb/errors" "github.com/cockroachdb/errors"
"github.com/glebarez/go-sqlite"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
@@ -45,6 +46,9 @@ var (
) )
func init() { func init() {
// Register the pure-Go SQLite driver as "sqlite3" for XORM compatibility.
sql.Register("sqlite3", &sqlite.Driver{})
legacyTables = append(legacyTables, legacyTables = append(legacyTables,
new(User), new(PublicKey), new(TwoFactor), new(TwoFactorRecoveryCode), new(User), new(PublicKey), new(TwoFactor), new(TwoFactorRecoveryCode),
new(Repository), new(DeployKey), new(Collaboration), new(Upload), new(Repository), new(DeployKey), new(Collaboration), new(Upload),

View File

@@ -2408,7 +2408,7 @@ func GetWatchers(repoID int64) ([]*Watch, error) {
func (r *Repository) GetWatchers(page int) ([]*User, error) { func (r *Repository) GetWatchers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("watch.repo_id=?", r.ID) sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("watch.repo_id=?", r.ID)
if conf.UsePostgreSQL { if conf.UsePostgreSQL || conf.UseMSSQL {
sess = sess.Join("LEFT", "watch", `"user".id=watch.user_id`) sess = sess.Join("LEFT", "watch", `"user".id=watch.user_id`)
} else { } else {
sess = sess.Join("LEFT", "watch", "user.id=watch.user_id") sess = sess.Join("LEFT", "watch", "user.id=watch.user_id")
@@ -2508,7 +2508,7 @@ func IsStaring(userID, repoID int64) bool {
func (r *Repository) GetStargazers(page int) ([]*User, error) { func (r *Repository) GetStargazers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("star.repo_id=?", r.ID) sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("star.repo_id=?", r.ID)
if conf.UsePostgreSQL { if conf.UsePostgreSQL || conf.UseMSSQL {
sess = sess.Join("LEFT", "star", `"user".id=star.uid`) sess = sess.Join("LEFT", "star", `"user".id=star.uid`)
} else { } else {
sess = sess.Join("LEFT", "star", "user.id=star.uid") sess = sess.Join("LEFT", "star", "user.id=star.uid")

View File

@@ -23,7 +23,6 @@ import (
"gogs.io/gogs/internal/osutil" "gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/pathutil" "gogs.io/gogs/internal/pathutil"
"gogs.io/gogs/internal/process" "gogs.io/gogs/internal/process"
"gogs.io/gogs/internal/tool"
) )
// BranchAlreadyExists represents an error when branch already exists. // BranchAlreadyExists represents an error when branch already exists.
@@ -415,8 +414,10 @@ func (upload *Upload) LocalPath() string {
// NewUpload creates a new upload object. // NewUpload creates a new upload object.
func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) { func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) {
if tool.IsMaliciousPath(name) { // 🚨 SECURITY: Prevent path traversal.
return nil, errors.Newf("malicious path detected: %s", name) name = pathutil.Clean(name)
if name == "" {
return nil, errors.New("empty file name")
} }
upload := &Upload{ upload := &Upload{

View File

@@ -8,11 +8,13 @@ import (
"strings" "strings"
"github.com/cockroachdb/errors" "github.com/cockroachdb/errors"
"github.com/glebarez/sqlite"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/renderer"
"github.com/olekukonko/tablewriter/tw"
"gopkg.in/DATA-DOG/go-sqlmock.v2" "gopkg.in/DATA-DOG/go-sqlmock.v2"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
@@ -61,18 +63,25 @@ func main() {
_, _ = w.WriteString("```\n") _, _ = w.WriteString("```\n")
table := tablewriter.NewWriter(w) table := tablewriter.NewTable(w,
table.SetHeader([]string{"Field", "Column", "PostgreSQL", "MySQL", "SQLite3"}) tablewriter.WithRenderer(renderer.NewBlueprint(tw.Rendition{
table.SetBorder(false) Borders: tw.BorderNone,
Symbols: tw.NewSymbols(tw.StyleASCII),
})),
tablewriter.WithHeaderAutoFormat(tw.Off),
)
table.Header("Field", "Column", "PostgreSQL", "MySQL", "SQLite3")
for j, f := range ti.Fields { for j, f := range ti.Fields {
table.Append([]string{ sqlite3Type := strings.ToUpper(collected[2][i].Fields[j].Type)
sqlite3Type = strings.ReplaceAll(sqlite3Type, "PRIMARY KEY ", "")
_ = table.Append([]string{
f.Name, f.Column, f.Name, f.Column,
strings.ToUpper(f.Type), // PostgreSQL strings.ToUpper(f.Type), // PostgreSQL
strings.ToUpper(collected[1][i].Fields[j].Type), // MySQL strings.ToUpper(collected[1][i].Fields[j].Type), // MySQL
strings.ToUpper(collected[2][i].Fields[j].Type), // SQLite3 sqlite3Type,
}) })
} }
table.Render() _ = table.Render()
_, _ = w.WriteString("\n") _, _ = w.WriteString("\n")
_, _ = w.WriteString("Primary keys: ") _, _ = w.WriteString("Primary keys: ")

View File

@@ -175,8 +175,8 @@ func parseKeyString(content string) (string, error) {
// writeTmpKeyFile writes key content to a temporary file // writeTmpKeyFile writes key content to a temporary file
// and returns the name of that file, along with any possible errors. // and returns the name of that file, along with any possible errors.
func writeTmpKeyFile(content string) (string, error) { func writeTmpKeyFile(content, keyTestPath string) (string, error) {
tmpFile, err := os.CreateTemp(conf.SSH.KeyTestPath, "gogs_keytest") tmpFile, err := os.CreateTemp(keyTestPath, "gogs_keytest")
if err != nil { if err != nil {
return "", errors.Newf("TempFile: %v", err) return "", errors.Newf("TempFile: %v", err)
} }
@@ -188,15 +188,15 @@ func writeTmpKeyFile(content string) (string, error) {
return tmpFile.Name(), nil return tmpFile.Name(), nil
} }
// SSHKeyGenParsePublicKey extracts key type and length using ssh-keygen. // SSHKeygenParsePublicKey extracts key type and length using ssh-keygen.
func SSHKeyGenParsePublicKey(key string) (string, int, error) { func SSHKeygenParsePublicKey(key, keyTestPath, keygenPath string) (string, int, error) {
tmpName, err := writeTmpKeyFile(key) tmpName, err := writeTmpKeyFile(key, keyTestPath)
if err != nil { if err != nil {
return "", 0, errors.Newf("writeTmpKeyFile: %v", err) return "", 0, errors.Newf("writeTmpKeyFile: %v", err)
} }
defer os.Remove(tmpName) defer os.Remove(tmpName)
stdout, stderr, err := process.Exec("SSHKeyGenParsePublicKey", conf.SSH.KeygenPath, "-lf", tmpName) stdout, stderr, err := process.Exec("SSHKeygenParsePublicKey", keygenPath, "-lf", tmpName)
if err != nil { if err != nil {
return "", 0, errors.Newf("fail to parse public key: %s - %s", err, stderr) return "", 0, errors.Newf("fail to parse public key: %s - %s", err, stderr)
} }
@@ -301,8 +301,8 @@ func CheckPublicKeyString(content string) (_ string, err error) {
fnName = "SSHNativeParsePublicKey" fnName = "SSHNativeParsePublicKey"
keyType, length, err = SSHNativeParsePublicKey(content) keyType, length, err = SSHNativeParsePublicKey(content)
} else { } else {
fnName = "SSHKeyGenParsePublicKey" fnName = "SSHKeygenParsePublicKey"
keyType, length, err = SSHKeyGenParsePublicKey(content) keyType, length, err = SSHKeygenParsePublicKey(content, conf.SSH.KeyTestPath, conf.SSH.KeygenPath)
} }
if err != nil { if err != nil {
return "", errors.Newf("%s: %v", fnName, err) return "", errors.Newf("%s: %v", fnName, err)

View File

@@ -4,13 +4,11 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gogs.io/gogs/internal/conf"
) )
func Test_SSHParsePublicKey(t *testing.T) { func TestSSHParsePublicKey(t *testing.T) {
// TODO: Refactor SSHKeyGenParsePublicKey to accept a tempPath and remove this init. tempPath := t.TempDir()
conf.MustInit("")
tests := []struct { tests := []struct {
name string name string
content string content string
@@ -53,20 +51,22 @@ func Test_SSHParsePublicKey(t *testing.T) {
expType: "ecdsa", expType: "ecdsa",
expLength: 521, expLength: 521,
}, },
{
name: "ed25519-256",
content: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGYutovQfTewtcodVN1E1UUzMk4GQfiRI5ZoP/kTlDb nocomment",
expType: "ed25519",
expLength: 256,
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
typ, length, err := SSHNativeParsePublicKey(test.content) typ, length, err := SSHNativeParsePublicKey(test.content)
if err != nil { require.NoError(t, err)
t.Fatal(err)
}
assert.Equal(t, test.expType, typ) assert.Equal(t, test.expType, typ)
assert.Equal(t, test.expLength, length) assert.Equal(t, test.expLength, length)
typ, length, err = SSHKeyGenParsePublicKey(test.content) typ, length, err = SSHKeygenParsePublicKey(test.content, tempPath, "ssh-keygen")
if err != nil { require.NoError(t, err)
t.Fatal(err)
}
assert.Equal(t, test.expType, typ) assert.Equal(t, test.expType, typ)
assert.Equal(t, test.expLength, length) assert.Equal(t, test.expLength, length)
}) })

View File

@@ -465,7 +465,7 @@ func usersDeleteByID(t *testing.T, ctx context.Context, s *UsersStore) {
reposStore := newReposStore(s.db) reposStore := newReposStore(s.db)
t.Run("user still has repository ownership", func(t *testing.T) { t.Run("user still has repository ownership", func(t *testing.T) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
_, err = reposStore.Create(ctx, alice.ID, CreateRepoOptions{Name: "repo1"}) _, err = reposStore.Create(ctx, alice.ID, CreateRepoOptions{Name: "repo1"})
@@ -477,7 +477,7 @@ func usersDeleteByID(t *testing.T, ctx context.Context, s *UsersStore) {
}) })
t.Run("user still has organization membership", func(t *testing.T) { t.Run("user still has organization membership", func(t *testing.T) {
bob, err := s.Create(ctx, "bob", "bob@exmaple.com", CreateUserOptions{}) bob, err := s.Create(ctx, "bob", "bob@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
// TODO: Use Orgs.Create to replace SQL hack when the method is available. // TODO: Use Orgs.Create to replace SQL hack when the method is available.
@@ -498,14 +498,14 @@ func usersDeleteByID(t *testing.T, ctx context.Context, s *UsersStore) {
assert.Equal(t, wantErr, err) assert.Equal(t, wantErr, err)
}) })
cindy, err := s.Create(ctx, "cindy", "cindy@exmaple.com", CreateUserOptions{}) cindy, err := s.Create(ctx, "cindy", "cindy@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
frank, err := s.Create(ctx, "frank", "frank@exmaple.com", CreateUserOptions{}) frank, err := s.Create(ctx, "frank", "frank@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
repo2, err := reposStore.Create(ctx, cindy.ID, CreateRepoOptions{Name: "repo2"}) repo2, err := reposStore.Create(ctx, cindy.ID, CreateRepoOptions{Name: "repo2"})
require.NoError(t, err) require.NoError(t, err)
testUser, err := s.Create(ctx, "testUser", "testUser@exmaple.com", CreateUserOptions{}) testUser, err := s.Create(ctx, "testUser", "testUser@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
// Mock watches, stars and follows // Mock watches, stars and follows
@@ -673,14 +673,14 @@ func usersDeleteByID(t *testing.T, ctx context.Context, s *UsersStore) {
func usersDeleteInactivated(t *testing.T, ctx context.Context, s *UsersStore) { func usersDeleteInactivated(t *testing.T, ctx context.Context, s *UsersStore) {
// User with repository ownership should be skipped // User with repository ownership should be skipped
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
reposStore := newReposStore(s.db) reposStore := newReposStore(s.db)
_, err = reposStore.Create(ctx, alice.ID, CreateRepoOptions{Name: "repo1"}) _, err = reposStore.Create(ctx, alice.ID, CreateRepoOptions{Name: "repo1"})
require.NoError(t, err) require.NoError(t, err)
// User with organization membership should be skipped // User with organization membership should be skipped
bob, err := s.Create(ctx, "bob", "bob@exmaple.com", CreateUserOptions{}) bob, err := s.Create(ctx, "bob", "bob@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
// TODO: Use Orgs.Create to replace SQL hack when the method is available. // TODO: Use Orgs.Create to replace SQL hack when the method is available.
org1, err := s.Create(ctx, "org1", "org1@example.com", CreateUserOptions{}) org1, err := s.Create(ctx, "org1", "org1@example.com", CreateUserOptions{})
@@ -695,11 +695,11 @@ func usersDeleteInactivated(t *testing.T, ctx context.Context, s *UsersStore) {
require.NoError(t, err) require.NoError(t, err)
// User activated state should be skipped // User activated state should be skipped
_, err = s.Create(ctx, "cindy", "cindy@exmaple.com", CreateUserOptions{Activated: true}) _, err = s.Create(ctx, "cindy", "cindy@example.com", CreateUserOptions{Activated: true})
require.NoError(t, err) require.NoError(t, err)
// User meant to be deleted // User meant to be deleted
david, err := s.Create(ctx, "david", "david@exmaple.com", CreateUserOptions{}) david, err := s.Create(ctx, "david", "david@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
tempSSHRootPath := filepath.Join(os.TempDir(), "usersDeleteInactivated-tempSSHRootPath") tempSSHRootPath := filepath.Join(os.TempDir(), "usersDeleteInactivated-tempSSHRootPath")
@@ -726,7 +726,7 @@ func usersGetByEmail(t *testing.T, ctx context.Context, s *UsersStore) {
t.Run("ignore organization", func(t *testing.T) { t.Run("ignore organization", func(t *testing.T) {
// TODO: Use Orgs.Create to replace SQL hack when the method is available. // TODO: Use Orgs.Create to replace SQL hack when the method is available.
org, err := s.Create(ctx, "gogs", "gogs@exmaple.com", CreateUserOptions{}) org, err := s.Create(ctx, "gogs", "gogs@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
err = s.db.Model(&User{}).Where("id", org.ID).UpdateColumn("type", UserTypeOrganization).Error err = s.db.Model(&User{}).Where("id", org.ID).UpdateColumn("type", UserTypeOrganization).Error
@@ -738,7 +738,7 @@ func usersGetByEmail(t *testing.T, ctx context.Context, s *UsersStore) {
}) })
t.Run("by primary email", func(t *testing.T) { t.Run("by primary email", func(t *testing.T) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
_, err = s.GetByEmail(ctx, alice.Email) _, err = s.GetByEmail(ctx, alice.Email)
@@ -760,7 +760,7 @@ func usersGetByEmail(t *testing.T, ctx context.Context, s *UsersStore) {
require.NoError(t, err) require.NoError(t, err)
// TODO: Use UserEmails.Create to replace SQL hack when the method is available. // TODO: Use UserEmails.Create to replace SQL hack when the method is available.
email2 := "bob2@exmaple.com" email2 := "bob2@example.com"
err = s.db.Exec(`INSERT INTO email_address (uid, email) VALUES (?, ?)`, bob.ID, email2).Error err = s.db.Exec(`INSERT INTO email_address (uid, email) VALUES (?, ?)`, bob.ID, email2).Error
require.NoError(t, err) require.NoError(t, err)
@@ -779,7 +779,7 @@ func usersGetByEmail(t *testing.T, ctx context.Context, s *UsersStore) {
} }
func usersGetByID(t *testing.T, ctx context.Context, s *UsersStore) { func usersGetByID(t *testing.T, ctx context.Context, s *UsersStore) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
user, err := s.GetByID(ctx, alice.ID) user, err := s.GetByID(ctx, alice.ID)
@@ -792,7 +792,7 @@ func usersGetByID(t *testing.T, ctx context.Context, s *UsersStore) {
} }
func usersGetByUsername(t *testing.T, ctx context.Context, s *UsersStore) { func usersGetByUsername(t *testing.T, ctx context.Context, s *UsersStore) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
user, err := s.GetByUsername(ctx, alice.Name) user, err := s.GetByUsername(ctx, alice.Name)
@@ -805,7 +805,7 @@ func usersGetByUsername(t *testing.T, ctx context.Context, s *UsersStore) {
} }
func usersGetByKeyID(t *testing.T, ctx context.Context, s *UsersStore) { func usersGetByKeyID(t *testing.T, ctx context.Context, s *UsersStore) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
// TODO: Use PublicKeys.Create to replace SQL hack when the method is available. // TODO: Use PublicKeys.Create to replace SQL hack when the method is available.
@@ -830,11 +830,11 @@ func usersGetByKeyID(t *testing.T, ctx context.Context, s *UsersStore) {
} }
func usersGetMailableEmailsByUsernames(t *testing.T, ctx context.Context, s *UsersStore) { func usersGetMailableEmailsByUsernames(t *testing.T, ctx context.Context, s *UsersStore) {
alice, err := s.Create(ctx, "alice", "alice@exmaple.com", CreateUserOptions{}) alice, err := s.Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err) require.NoError(t, err)
bob, err := s.Create(ctx, "bob", "bob@exmaple.com", CreateUserOptions{Activated: true}) bob, err := s.Create(ctx, "bob", "bob@example.com", CreateUserOptions{Activated: true})
require.NoError(t, err) require.NoError(t, err)
_, err = s.Create(ctx, "cindy", "cindy@exmaple.com", CreateUserOptions{Activated: true}) _, err = s.Create(ctx, "cindy", "cindy@example.com", CreateUserOptions{Activated: true})
require.NoError(t, err) require.NoError(t, err)
got, err := s.GetMailableEmailsByUsernames(ctx, []string{alice.Name, bob.Name, "ignore-non-exist"}) got, err := s.GetMailableEmailsByUsernames(ctx, []string{alice.Name, bob.Name, "ignore-non-exist"})

View File

@@ -96,19 +96,6 @@ func NewDB(t *testing.T, suite string, tables ...any) *gorm.DB {
_, _ = sqlDB.Exec(fmt.Sprintf(`DROP DATABASE %q`, dbName)) _, _ = sqlDB.Exec(fmt.Sprintf(`DROP DATABASE %q`, dbName))
_ = sqlDB.Close() _ = sqlDB.Close()
} }
case "sqlite":
dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
dbOpts = conf.DatabaseOpts{
Type: "sqlite",
Path: dbName,
}
cleanup = func(db *gorm.DB) {
sqlDB, err := db.DB()
if err == nil {
_ = sqlDB.Close()
}
_ = os.Remove(dbName)
}
default: default:
dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix())) dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
dbOpts = conf.DatabaseOpts{ dbOpts = conf.DatabaseOpts{

View File

@@ -5,9 +5,9 @@ import (
"strings" "strings"
"github.com/cockroachdb/errors" "github.com/cockroachdb/errors"
"github.com/glebarez/sqlite"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/driver/sqlserver" "gorm.io/driver/sqlserver"
"gorm.io/gorm" "gorm.io/gorm"
@@ -73,7 +73,7 @@ func NewDSN(opts conf.DatabaseOpts) (dsn string, err error) {
dsn = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", dsn = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
host, port, opts.Name, opts.User, opts.Password) host, port, opts.Name, opts.User, opts.Password)
case "sqlite3", "sqlite": case "sqlite3":
dsn = "file:" + opts.Path + "?cache=shared&mode=rwc" dsn = "file:" + opts.Path + "?cache=shared&mode=rwc"
default: default:
@@ -101,9 +101,6 @@ func OpenDB(opts conf.DatabaseOpts, cfg *gorm.Config) (*gorm.DB, error) {
dialector = sqlserver.Open(dsn) dialector = sqlserver.Open(dsn)
case "sqlite3": case "sqlite3":
dialector = sqlite.Open(dsn) dialector = sqlite.Open(dsn)
case "sqlite":
dialector = sqlite.Open(dsn)
dialector.(*sqlite.Dialector).DriverName = "sqlite"
default: default:
panic("unreachable") panic("unreachable")
} }

View File

@@ -10,7 +10,7 @@ import (
"time" "time"
"github.com/cockroachdb/errors" "github.com/cockroachdb/errors"
"github.com/jaytaylor/html2text" "github.com/inbucket/html2text"
"gopkg.in/gomail.v2" "gopkg.in/gomail.v2"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"

View File

@@ -0,0 +1,92 @@
package embeddedpg
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/cockroachdb/errors"
embpg "github.com/fergusstrange/embedded-postgres"
log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf"
)
// LocalPostgres wraps embedded PostgreSQL server functionality.
type LocalPostgres struct {
srv *embpg.EmbeddedPostgres
baseDir string
tcpPort uint32
database string
user string
pass string
}
// Initialize creates a LocalPostgres with default settings based on workDir.
func Initialize(workDir string) *LocalPostgres {
storageBase := filepath.Join(workDir, "data", "local-postgres")
return &LocalPostgres{
baseDir: storageBase,
tcpPort: 15432,
database: "gogs",
user: "gogs",
pass: "gogs",
}
}
// Launch starts the embedded PostgreSQL server and blocks until ready.
func (pg *LocalPostgres) Launch() error {
log.Info("Launching local PostgreSQL server...")
log.Trace("Base directory: %s", pg.baseDir)
// Create base directory
if err := os.MkdirAll(pg.baseDir, 0o700); err != nil {
return errors.Wrap(err, "mkdir local postgres base")
}
opts := embpg.DefaultConfig().
Username(pg.user).
Password(pg.pass).
Database(pg.database).
Port(pg.tcpPort).
DataPath(pg.baseDir).
StartTimeout(45 * time.Second).
Logger(os.Stderr)
pg.srv = embpg.NewDatabase(opts)
if err := pg.srv.Start(); err != nil {
return errors.Wrap(err, "launch embedded pg")
}
log.Info("Local PostgreSQL ready on port %d", pg.tcpPort)
return nil
}
// Shutdown stops the embedded PostgreSQL server gracefully.
func (pg *LocalPostgres) Shutdown() error {
if pg.srv == nil {
return nil
}
log.Info("Shutting down local PostgreSQL...")
if err := pg.srv.Stop(); err != nil {
return errors.Wrap(err, "shutdown embedded pg")
}
log.Info("Local PostgreSQL shutdown complete")
return nil
}
// ConfigureGlobalDatabase modifies global conf.Database to point to this instance.
func (pg *LocalPostgres) ConfigureGlobalDatabase() {
conf.Database.Type = "postgres"
conf.Database.Host = fmt.Sprintf("localhost:%d", pg.tcpPort)
conf.Database.Name = pg.database
conf.Database.User = pg.user
conf.Database.Password = pg.pass
conf.Database.SSLMode = "disable"
log.Trace("Global database configured for local PostgreSQL")
}

View File

@@ -0,0 +1,28 @@
package embeddedpg
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestInitialize(t *testing.T) {
workDir := "/tmp/gogs-test"
pg := Initialize(workDir)
assert.NotNil(t, pg)
assert.Equal(t, filepath.Join(workDir, "data", "local-postgres"), pg.baseDir)
assert.Equal(t, uint32(15432), pg.tcpPort)
assert.Equal(t, "gogs", pg.database)
assert.Equal(t, "gogs", pg.user)
assert.Equal(t, "gogs", pg.pass)
}
func TestShutdownWithoutStart(t *testing.T) {
pg := Initialize("/tmp/gogs-test")
// Should not error when stopping a non-started instance
err := pg.Shutdown()
assert.NoError(t, err)
}

View File

@@ -73,7 +73,7 @@ func (s *DiffSection) ComputedInlineDiffFor(line *git.DiffLine) template.HTML {
func diffsToHTML(diffs []diffmatchpatch.Diff, lineType git.DiffLineType) template.HTML { func diffsToHTML(diffs []diffmatchpatch.Diff, lineType git.DiffLineType) template.HTML {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
// Reproduce signs which are cutted for inline diff before. // Reproduce signs which are cut for inline diff before.
switch lineType { switch lineType {
case git.DiffLineAdd: case git.DiffLineAdd:
buf.WriteByte('+') buf.WriteByte('+')

View File

@@ -151,7 +151,7 @@ func NewAuthSourcePost(c *context.Context, f form.Authentication) {
c.Data["HasTLS"] = hasTLS c.Data["HasTLS"] = hasTLS
if c.HasError() { if c.HasError() {
c.Success(tmplAdminAuthNew) c.HTML(http.StatusBadRequest, tmplAdminAuthNew)
return return
} }
@@ -167,7 +167,7 @@ func NewAuthSourcePost(c *context.Context, f form.Authentication) {
if err != nil { if err != nil {
if database.IsErrLoginSourceAlreadyExist(err) { if database.IsErrLoginSourceAlreadyExist(err) {
c.FormErr("Name") c.FormErr("Name")
c.RenderWithErr(c.Tr("admin.auths.login_source_exist", f.Name), tmplAdminAuthNew, f) c.RenderWithErr(c.Tr("admin.auths.login_source_exist", f.Name), http.StatusUnprocessableEntity, tmplAdminAuthNew, f)
} else { } else {
c.Error(err, "create login source") c.Error(err, "create login source")
} }
@@ -223,7 +223,7 @@ func EditAuthSourcePost(c *context.Context, f form.Authentication) {
c.Data["HasTLS"] = source.Provider.HasTLS() c.Data["HasTLS"] = source.Provider.HasTLS()
if c.HasError() { if c.HasError() {
c.Success(tmplAdminAuthEdit) c.HTML(http.StatusBadRequest, tmplAdminAuthEdit)
return return
} }

View File

@@ -1,6 +1,7 @@
package admin package admin
import ( import (
"net/http"
"strconv" "strconv"
"strings" "strings"
@@ -68,7 +69,7 @@ func NewUserPost(c *context.Context, f form.AdminCrateUser) {
c.Data["CanSendEmail"] = conf.Email.Enabled c.Data["CanSendEmail"] = conf.Email.Enabled
if c.HasError() { if c.HasError() {
c.Success(tmplAdminUserNew) c.HTML(http.StatusBadRequest, tmplAdminUserNew)
return return
} }
@@ -89,13 +90,13 @@ func NewUserPost(c *context.Context, f form.AdminCrateUser) {
switch { switch {
case database.IsErrUserAlreadyExist(err): case database.IsErrUserAlreadyExist(err):
c.Data["Err_UserName"] = true c.Data["Err_UserName"] = true
c.RenderWithErr(c.Tr("form.username_been_taken"), tmplAdminUserNew, &f) c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplAdminUserNew, &f)
case database.IsErrEmailAlreadyUsed(err): case database.IsErrEmailAlreadyUsed(err):
c.Data["Err_Email"] = true c.Data["Err_Email"] = true
c.RenderWithErr(c.Tr("form.email_been_used"), tmplAdminUserNew, &f) c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplAdminUserNew, &f)
case database.IsErrNameNotAllowed(err): case database.IsErrNameNotAllowed(err):
c.Data["Err_UserName"] = true c.Data["Err_UserName"] = true
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplAdminUserNew, &f) c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplAdminUserNew, &f)
default: default:
c.Error(err, "create user") c.Error(err, "create user")
} }
@@ -166,7 +167,7 @@ func EditUserPost(c *context.Context, f form.AdminEditUser) {
} }
if c.HasError() { if c.HasError() {
c.Success(tmplAdminUserEdit) c.HTML(http.StatusBadRequest, tmplAdminUserEdit)
return return
} }
@@ -203,7 +204,7 @@ func EditUserPost(c *context.Context, f form.AdminEditUser) {
if err != nil { if err != nil {
if database.IsErrEmailAlreadyUsed(err) { if database.IsErrEmailAlreadyUsed(err) {
c.Data["Err_Email"] = true c.Data["Err_Email"] = true
c.RenderWithErr(c.Tr("form.email_been_used"), tmplAdminUserEdit, &f) c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplAdminUserEdit, &f)
} else { } else {
c.Error(err, "update user") c.Error(err, "update user")
} }

View File

@@ -137,13 +137,13 @@ func GetContents(c *context.APIContext) {
} }
// The entry is a directory // The entry is a directory
dir, err := gitRepo.LsTree(entry.ID().String()) dir, err := gitRepo.LsTree(entry.ID().String(), git.LsTreeOptions{Verbatim: true})
if err != nil { if err != nil {
c.NotFoundOrError(gitutil.NewError(err), "get tree") c.NotFoundOrError(gitutil.NewError(err), "get tree")
return return
} }
entries, err := dir.Entries() entries, err := dir.Entries(git.LsTreeOptions{Verbatim: true})
if err != nil { if err != nil {
c.NotFoundOrError(gitutil.NewError(err), "list entries") c.NotFoundOrError(gitutil.NewError(err), "list entries")
return return

View File

@@ -88,6 +88,17 @@ func EditIssueComment(c *context.APIContext, form api.EditIssueCommentOption) {
return return
} }
issue, err := database.GetIssueByID(comment.IssueID)
if err != nil {
c.NotFoundOrError(err, "get issue by ID")
return
}
if issue.RepoID != c.Repo.Repository.ID {
c.NotFound()
return
}
if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() { if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
c.Status(http.StatusForbidden) c.Status(http.StatusForbidden)
return return
@@ -112,6 +123,17 @@ func DeleteIssueComment(c *context.APIContext) {
return return
} }
issue, err := database.GetIssueByID(comment.IssueID)
if err != nil {
c.NotFoundOrError(err, "get issue by ID")
return
}
if issue.RepoID != c.Repo.Repository.ID {
c.NotFound()
return
}
if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() { if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
c.Status(http.StatusForbidden) c.Status(http.StatusForbidden)
return return

View File

@@ -45,6 +45,11 @@ func GetDeployKey(c *context.APIContext) {
return return
} }
if key.RepoID != c.Repo.Repository.ID {
c.NotFound()
return
}
if err = key.GetContent(); err != nil { if err = key.GetContent(); err != nil {
c.Error(err, "get content") c.Error(err, "get content")
return return
@@ -94,7 +99,18 @@ func CreateDeployKey(c *context.APIContext, form api.CreateKeyOption) {
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#remove-a-deploy-key // https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#remove-a-deploy-key
func DeleteDeploykey(c *context.APIContext) { func DeleteDeploykey(c *context.APIContext) {
if err := database.DeleteDeployKey(c.User, c.ParamsInt64(":id")); err != nil { key, err := database.GetDeployKeyByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get deploy key by ID")
return
}
if key.RepoID != c.Repo.Repository.ID {
c.NotFound()
return
}
if err := database.DeleteDeployKey(c.User, key.ID); err != nil {
if database.IsErrKeyAccessDenied(err) { if database.IsErrKeyAccessDenied(err) {
c.ErrorStatus(http.StatusForbidden, errors.New("You do not have access to this key")) c.ErrorStatus(http.StatusForbidden, errors.New("You do not have access to this key"))
} else { } else {

View File

@@ -17,13 +17,13 @@ func GetRepoGitTree(c *context.APIContext) {
} }
sha := c.Params(":sha") sha := c.Params(":sha")
tree, err := gitRepo.LsTree(sha) tree, err := gitRepo.LsTree(sha, git.LsTreeOptions{Verbatim: true})
if err != nil { if err != nil {
c.NotFoundOrError(gitutil.NewError(err), "get tree") c.NotFoundOrError(gitutil.NewError(err), "get tree")
return return
} }
entries, err := tree.Entries() entries, err := tree.Entries(git.LsTreeOptions{Verbatim: true})
if err != nil { if err != nil {
c.Error(err, "list entries") c.Error(err, "list entries")
return return

View File

@@ -1,6 +1,7 @@
package route package route
import ( import (
"net/http"
"net/mail" "net/mail"
"os" "os"
"os/exec" "os/exec"
@@ -194,13 +195,12 @@ func InstallPost(c *context.Context, f form.Install) {
c.HasValue("Err_AdminEmail") { c.HasValue("Err_AdminEmail") {
c.FormErr("Admin") c.FormErr("Admin")
} }
c.HTML(http.StatusBadRequest, INSTALL)
c.Success(INSTALL)
return return
} }
if _, err := exec.LookPath("git"); err != nil { if _, err := exec.LookPath("git"); err != nil {
c.RenderWithErr(c.Tr("install.test_git_failed", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.test_git_failed", err), http.StatusInternalServerError, INSTALL, &f)
return return
} }
@@ -222,7 +222,7 @@ func InstallPost(c *context.Context, f form.Install) {
if conf.Database.Type == "sqlite3" && conf.Database.Path == "" { if conf.Database.Type == "sqlite3" && conf.Database.Path == "" {
c.FormErr("DbPath") c.FormErr("DbPath")
c.RenderWithErr(c.Tr("install.err_empty_db_path"), INSTALL, &f) c.RenderWithErr(c.Tr("install.err_empty_db_path"), http.StatusBadRequest, INSTALL, &f)
return return
} }
@@ -230,10 +230,10 @@ func InstallPost(c *context.Context, f form.Install) {
if err := database.NewTestEngine(); err != nil { if err := database.NewTestEngine(); err != nil {
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
c.FormErr("DbType") c.FormErr("DbType")
c.RenderWithErr(c.Tr("install.sqlite3_not_available", "https://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &f) c.RenderWithErr(c.Tr("install.sqlite3_not_available", "https://gogs.io/docs/installation/install_from_binary.html"), http.StatusInternalServerError, INSTALL, &f)
} else { } else {
c.FormErr("DbSetting") c.FormErr("DbSetting")
c.RenderWithErr(c.Tr("install.invalid_db_setting", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.invalid_db_setting", err), http.StatusBadRequest, INSTALL, &f)
} }
return return
} }
@@ -242,7 +242,7 @@ func InstallPost(c *context.Context, f form.Install) {
f.RepoRootPath = strings.ReplaceAll(f.RepoRootPath, "\\", "/") f.RepoRootPath = strings.ReplaceAll(f.RepoRootPath, "\\", "/")
if err := os.MkdirAll(f.RepoRootPath, os.ModePerm); err != nil { if err := os.MkdirAll(f.RepoRootPath, os.ModePerm); err != nil {
c.FormErr("RepoRootPath") c.FormErr("RepoRootPath")
c.RenderWithErr(c.Tr("install.invalid_repo_path", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.invalid_repo_path", err), http.StatusBadRequest, INSTALL, &f)
return return
} }
@@ -250,21 +250,21 @@ func InstallPost(c *context.Context, f form.Install) {
f.LogRootPath = strings.ReplaceAll(f.LogRootPath, "\\", "/") f.LogRootPath = strings.ReplaceAll(f.LogRootPath, "\\", "/")
if err := os.MkdirAll(f.LogRootPath, os.ModePerm); err != nil { if err := os.MkdirAll(f.LogRootPath, os.ModePerm); err != nil {
c.FormErr("LogRootPath") c.FormErr("LogRootPath")
c.RenderWithErr(c.Tr("install.invalid_log_root_path", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.invalid_log_root_path", err), http.StatusBadRequest, INSTALL, &f)
return return
} }
currentUser, match := conf.CheckRunUser(f.RunUser) currentUser, match := conf.CheckRunUser(f.RunUser)
if !match { if !match {
c.FormErr("RunUser") c.FormErr("RunUser")
c.RenderWithErr(c.Tr("install.run_user_not_match", f.RunUser, currentUser), INSTALL, &f) c.RenderWithErr(c.Tr("install.run_user_not_match", f.RunUser, currentUser), http.StatusForbidden, INSTALL, &f)
return return
} }
// Check host address and port // Check host address and port
if len(f.SMTPHost) > 0 && !strings.Contains(f.SMTPHost, ":") { if len(f.SMTPHost) > 0 && !strings.Contains(f.SMTPHost, ":") {
c.FormErr("SMTP", "SMTPHost") c.FormErr("SMTP", "SMTPHost")
c.RenderWithErr(c.Tr("install.smtp_host_missing_port"), INSTALL, &f) c.RenderWithErr(c.Tr("install.smtp_host_missing_port"), http.StatusBadRequest, INSTALL, &f)
return return
} }
@@ -273,7 +273,7 @@ func InstallPost(c *context.Context, f form.Install) {
_, err := mail.ParseAddress(f.SMTPFrom) _, err := mail.ParseAddress(f.SMTPFrom)
if err != nil { if err != nil {
c.FormErr("SMTP", "SMTPFrom") c.FormErr("SMTP", "SMTPFrom")
c.RenderWithErr(c.Tr("install.invalid_smtp_from", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.invalid_smtp_from", err), http.StatusBadRequest, INSTALL, &f)
return return
} }
} }
@@ -281,19 +281,19 @@ func InstallPost(c *context.Context, f form.Install) {
// Check logic loophole between disable self-registration and no admin account. // Check logic loophole between disable self-registration and no admin account.
if f.DisableRegistration && f.AdminName == "" { if f.DisableRegistration && f.AdminName == "" {
c.FormErr("Services", "Admin") c.FormErr("Services", "Admin")
c.RenderWithErr(c.Tr("install.no_admin_and_disable_registration"), INSTALL, f) c.RenderWithErr(c.Tr("install.no_admin_and_disable_registration"), http.StatusUnprocessableEntity, INSTALL, f)
return return
} }
// Check admin password. // Check admin password.
if len(f.AdminName) > 0 && f.AdminPasswd == "" { if len(f.AdminName) > 0 && f.AdminPasswd == "" {
c.FormErr("Admin", "AdminPasswd") c.FormErr("Admin", "AdminPasswd")
c.RenderWithErr(c.Tr("install.err_empty_admin_password"), INSTALL, f) c.RenderWithErr(c.Tr("install.err_empty_admin_password"), http.StatusBadRequest, INSTALL, f)
return return
} }
if f.AdminPasswd != f.AdminConfirmPasswd { if f.AdminPasswd != f.AdminConfirmPasswd {
c.FormErr("Admin", "AdminPasswd") c.FormErr("Admin", "AdminPasswd")
c.RenderWithErr(c.Tr("form.password_not_match"), INSTALL, f) c.RenderWithErr(c.Tr("form.password_not_match"), http.StatusBadRequest, INSTALL, f)
return return
} }
@@ -367,21 +367,21 @@ func InstallPost(c *context.Context, f form.Install) {
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
secretKey, err := strutil.RandomChars(15) secretKey, err := strutil.RandomChars(15)
if err != nil { if err != nil {
c.RenderWithErr(c.Tr("install.secret_key_failed", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.secret_key_failed", err), http.StatusInternalServerError, INSTALL, &f)
return return
} }
cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey) cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
_ = os.MkdirAll(filepath.Dir(conf.CustomConf), os.ModePerm) _ = os.MkdirAll(filepath.Dir(conf.CustomConf), os.ModePerm)
if err := cfg.SaveTo(conf.CustomConf); err != nil { if err := cfg.SaveTo(conf.CustomConf); err != nil {
c.RenderWithErr(c.Tr("install.save_config_failed", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.save_config_failed", err), http.StatusInternalServerError, INSTALL, &f)
return return
} }
// NOTE: We reuse the current value because this handler does not have access to CLI flags. // NOTE: We reuse the current value because this handler does not have access to CLI flags.
err = GlobalInit(conf.CustomConf) err = GlobalInit(conf.CustomConf)
if err != nil { if err != nil {
c.RenderWithErr(c.Tr("install.init_failed", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.init_failed", err), http.StatusInternalServerError, INSTALL, &f)
return return
} }
@@ -401,7 +401,7 @@ func InstallPost(c *context.Context, f form.Install) {
if !database.IsErrUserAlreadyExist(err) { if !database.IsErrUserAlreadyExist(err) {
conf.Security.InstallLock = false conf.Security.InstallLock = false
c.FormErr("AdminName", "AdminEmail") c.FormErr("AdminName", "AdminEmail")
c.RenderWithErr(c.Tr("install.invalid_admin_setting", err), INSTALL, &f) c.RenderWithErr(c.Tr("install.invalid_admin_setting", err), http.StatusBadRequest, INSTALL, &f)
return return
} }

View File

@@ -1,6 +1,8 @@
package org package org
import ( import (
"net/http"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/context" "gogs.io/gogs/internal/context"
@@ -21,7 +23,7 @@ func CreatePost(c *context.Context, f form.CreateOrg) {
c.Title("new_org") c.Title("new_org")
if c.HasError() { if c.HasError() {
c.Success(CREATE) c.HTML(http.StatusBadRequest, CREATE)
return return
} }
@@ -35,9 +37,9 @@ func CreatePost(c *context.Context, f form.CreateOrg) {
c.Data["Err_OrgName"] = true c.Data["Err_OrgName"] = true
switch { switch {
case database.IsErrUserAlreadyExist(err): case database.IsErrUserAlreadyExist(err):
c.RenderWithErr(c.Tr("form.org_name_been_taken"), CREATE, &f) c.RenderWithErr(c.Tr("form.org_name_been_taken"), http.StatusUnprocessableEntity, CREATE, &f)
case database.IsErrNameNotAllowed(err): case database.IsErrNameNotAllowed(err):
c.RenderWithErr(c.Tr("org.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), CREATE, &f) c.RenderWithErr(c.Tr("org.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, CREATE, &f)
default: default:
c.Error(err, "create organization") c.Error(err, "create organization")
} }

View File

@@ -1,6 +1,8 @@
package org package org
import ( import (
"net/http"
log "unknwon.dev/clog/v2" log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/auth" "gogs.io/gogs/internal/auth"
@@ -27,7 +29,7 @@ func SettingsPost(c *context.Context, f form.UpdateOrgSetting) {
c.Data["PageIsSettingsOptions"] = true c.Data["PageIsSettingsOptions"] = true
if c.HasError() { if c.HasError() {
c.Success(tmplOrgSettingsOptions) c.HTML(http.StatusBadRequest, tmplOrgSettingsOptions)
return return
} }
@@ -38,18 +40,14 @@ func SettingsPost(c *context.Context, f form.UpdateOrgSetting) {
err := database.Handle.Users().ChangeUsername(c.Req.Context(), c.Org.Organization.ID, f.Name) err := database.Handle.Users().ChangeUsername(c.Req.Context(), c.Org.Organization.ID, f.Name)
if err != nil { if err != nil {
c.Data["OrgName"] = true c.Data["OrgName"] = true
var msg string
switch { switch {
case database.IsErrUserAlreadyExist(err): case database.IsErrUserAlreadyExist(err):
msg = c.Tr("form.username_been_taken") c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplOrgSettingsOptions, &f)
case database.IsErrNameNotAllowed(err): case database.IsErrNameNotAllowed(err):
msg = c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()) c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplOrgSettingsOptions, &f)
default: default:
c.Error(err, "change organization name") c.Error(err, "change organization name")
return
} }
c.RenderWithErr(msg, tmplOrgSettingsOptions, &f)
return return
} }
@@ -104,7 +102,7 @@ func SettingsDelete(c *context.Context) {
if c.Req.Method == "POST" { if c.Req.Method == "POST" {
if _, err := database.Handle.Users().Authenticate(c.Req.Context(), c.User.Name, c.Query("password"), c.User.LoginSource); err != nil { if _, err := database.Handle.Users().Authenticate(c.Req.Context(), c.User.Name, c.Query("password"), c.User.LoginSource); err != nil {
if auth.IsErrBadCredentials(err) { if auth.IsErrBadCredentials(err) {
c.RenderWithErr(c.Tr("form.enterred_invalid_password"), tmplOrgSettingsDelete, nil) c.RenderWithErr(c.Tr("form.enterred_invalid_password"), http.StatusUnauthorized, tmplOrgSettingsDelete, nil)
} else { } else {
c.Error(err, "authenticate user") c.Error(err, "authenticate user")
} }

View File

@@ -159,7 +159,7 @@ func NewTeamPost(c *context.Context, f form.CreateTeam) {
c.Data["Team"] = t c.Data["Team"] = t
if c.HasError() { if c.HasError() {
c.Success(tmplOrgTeamNew) c.HTML(http.StatusBadRequest, tmplOrgTeamNew)
return return
} }
@@ -167,9 +167,9 @@ func NewTeamPost(c *context.Context, f form.CreateTeam) {
c.Data["Err_TeamName"] = true c.Data["Err_TeamName"] = true
switch { switch {
case database.IsErrTeamAlreadyExist(err): case database.IsErrTeamAlreadyExist(err):
c.RenderWithErr(c.Tr("form.team_name_been_taken"), tmplOrgTeamNew, &f) c.RenderWithErr(c.Tr("form.team_name_been_taken"), http.StatusUnprocessableEntity, tmplOrgTeamNew, &f)
case database.IsErrNameNotAllowed(err): case database.IsErrNameNotAllowed(err):
c.RenderWithErr(c.Tr("org.form.team_name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplOrgTeamNew, &f) c.RenderWithErr(c.Tr("org.form.team_name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplOrgTeamNew, &f)
default: default:
c.Error(err, "new team") c.Error(err, "new team")
} }
@@ -214,7 +214,7 @@ func EditTeamPost(c *context.Context, f form.CreateTeam) {
c.Data["Team"] = t c.Data["Team"] = t
if c.HasError() { if c.HasError() {
c.Success(tmplOrgTeamNew) c.HTML(http.StatusBadRequest, tmplOrgTeamNew)
return return
} }
@@ -245,7 +245,7 @@ func EditTeamPost(c *context.Context, f form.CreateTeam) {
c.Data["Err_TeamName"] = true c.Data["Err_TeamName"] = true
switch { switch {
case database.IsErrTeamAlreadyExist(err): case database.IsErrTeamAlreadyExist(err):
c.RenderWithErr(c.Tr("form.team_name_been_taken"), tmplOrgTeamNew, &f) c.RenderWithErr(c.Tr("form.team_name_been_taken"), http.StatusUnprocessableEntity, tmplOrgTeamNew, &f)
default: default:
c.Error(err, "update team") c.Error(err, "update team")
} }

View File

@@ -10,7 +10,7 @@ import (
"gogs.io/gogs/internal/context" "gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database" "gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/tool" "gogs.io/gogs/internal/urlutil"
) )
const ( const (
@@ -109,7 +109,7 @@ func DeleteBranchPost(c *context.Context) {
defer func() { defer func() {
redirectTo := c.Query("redirect_to") redirectTo := c.Query("redirect_to")
if !tool.IsSameSiteURLPath(redirectTo) { if !urlutil.IsSameSite(redirectTo) {
redirectTo = c.Repo.RepoLink redirectTo = c.Repo.RepoLink
} }
c.Redirect(redirectTo) c.Redirect(redirectTo)
@@ -118,6 +118,21 @@ func DeleteBranchPost(c *context.Context) {
if !c.Repo.GitRepo.HasBranch(branchName) { if !c.Repo.GitRepo.HasBranch(branchName) {
return return
} }
if branchName == c.Repo.Repository.DefaultBranch {
c.Flash.Error(c.Tr("repo.branches.default_deletion_not_allowed"))
return
}
protectBranch, err := database.GetProtectBranchOfRepoByName(c.Repo.Repository.ID, branchName)
if err != nil && !database.IsErrBranchNotExist(err) {
log.Error("Failed to get protected branch %q: %v", branchName, err)
return
}
if protectBranch != nil && protectBranch.Protected {
c.Flash.Error(c.Tr("repo.branches.protected_deletion_not_allowed"))
return
}
if len(commitID) > 0 { if len(commitID) > 0 {
branchCommitID, err := c.Repo.GitRepo.BranchCommitID(branchName) branchCommitID, err := c.Repo.GitRepo.BranchCommitID(branchName)
if err != nil { if err != nil {

Some files were not shown because too many files have changed in this diff Show More