Compare commits

...

65 Commits

Author SHA1 Message Date
JSS
997011bfb2 markup: expand test coverage and sanitize notice banner output
Add previously covered autolink test cases that were dropped during the
goldmark migration (hosts without dots, https variants, single-digit
issues, cross-repo issues). Add new test suites for link rewriting with
both path-only and absolute URL prefixes, and for HTML passthrough
behavior confirming raw HTML is stripped without WithUnsafe.

Sanitize RawMarkdown output in the server notice banner to prevent
potential XSS, since it was the only call site not passing through
SanitizeBytes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:49:17 -05:00
JSS
60f62b6583 markup: address review feedback for goldmark migration
- Use lazyregexp for linkifyURLRegexp to avoid compile-at-init overhead.
- Replace stdlib log with clog/v2 and return HTML-escaped body on
  conversion error instead of nil.
- Handle absolute URL prefixes in linkTransformer using net/url to
  preserve scheme and host.
- Remove goldmarkhtml.WithUnsafe() from RawMarkdown renderer options.
- Use exact assertions in autolink tests instead of Contains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:28:15 -05:00
deepsource-autofix[bot]
3b7e331191 style: format code with Go fmt and Gofumpt
This commit fixes the style issues introduced in f9b4c5a according to the output
from Go fmt and Gofumpt.

Details: https://github.com/gogs/gogs/pull/8163
2026-02-08 05:48:28 +00:00
Joe Chen
f9b4c5a3ff markup: migrate from blackfriday to goldmark
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c3baf-c434-7794-9efd-084363bad1a2
2026-02-08 00:48:11 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
48500aa2b0 all: migrate from satori/go.uuid to google/uuid (#8161) 2026-02-08 00:13:43 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
785157ba1f all: migrate from nfnt/resize to golang.org/x/image/draw (#8158) 2026-02-08 00:08:50 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
1c8016a27b database/schemadoc: migrate to github.com/DATA-DOG/go-sqlmock (#8157) 2026-02-08 00:07:45 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
00c36d8d8a public: update jQuery from 3.6.0 to 3.7.1 (#8156) 2026-02-07 23:48:49 -05:00
Copilot
3747cd9058 Fix broken links in docs/getting-started/introduction.mdx (#8155)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-02-07 18:19:02 -05:00
Joe Chen
08e7cfd76c docs: fix up wwads-cn style in dark mode
[skip ci]
2026-02-07 17:49:58 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
9dd3e58f7b docs: migrate to Mintlify (#8154) 2026-02-07 17:32:52 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
edc1478f6b cmd: remove cert subcommand (#8153)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:23:33 -05:00
ᴊᴏᴇ ᴄʜᴇɴ
bb86d12c36 cmd: show detected config path in web command help (#8152)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:38:53 -05:00
Copilot
bf17cc6c69 Replace github.com/unknwon/com with stdlib and internal helpers (#8148)
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.6 <noreply@anthropic.com>
2026-02-05 22:08:54 -05:00
Copilot
6d56105f8f Run modernize tool across codebase (#8147)
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.6 <noreply@anthropic.com>
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2026-02-05 21:32:09 -05: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
299 changed files with 11410 additions and 1556 deletions

View File

@@ -1,6 +1,7 @@
---
name: "Dev: Release a minor version"
about: ONLY USED BY MAINTAINERS.
assignees: "unknwon"
title: "Release [VERSION]"
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).
- [ ] [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.
- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.12`.
- [ ] [Update CHANGELOG](https://github.com/gogs/gogs/commit/f1102a7a7c545ec221d2906f02fa19170d96f96d) to include entries for the current minor release.
- Do not forget adding entries for GHSA patches.
- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.14`.
## During release
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.
- [ ] 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.
- [ ] 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**.
- [ ] [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).
- [ ] [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).
- [ ] 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`.
- [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
## After release
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).
- [ ] 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.
- [ ] Publish a new release article on [OSChina](http://my.oschina.net/Obahua/admin/releases).
- [ ] Close the minor milestone.
- [ ] [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`.
- [ ] Close the milestone for the minor release.
- [ ] [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`.
- [ ] 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"
about: ONLY USED BY MAINTAINERS.
assignees: "unknwon"
title: "Release [VERSION]"
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.
- 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
@@ -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`.
- [ ] 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.
- ⚠️ **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.
- [ ] 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.
- ⚠️ **Make sure the tag is created on the release branch**.
- [ ] 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.
- [ ] 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 patch release and all previous releases with same minor version.
- [ ] 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.**
```
- [ ] [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.
- [ ] [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).
- [ ] [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_`):
- [ ] 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).
- [ ] 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`.
- [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
## 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).
- [ ] 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.

View File

@@ -19,18 +19,8 @@ jobs:
# --include-untagged-manifests: Deletes unreferenced manifests to maximize space
doctl registry garbage-collection start --force --include-untagged-manifests
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}

View File

@@ -68,21 +68,11 @@ jobs:
image-ref: gogs/gogs:latest
exit-code: '1'
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
buildx-next:
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
exit-code: '1'
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
deploy-demo:
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 status deployment gogs-demo -n gogs
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
buildx-pull-request:
if: ${{ github.event_name == 'pull_request'}}
@@ -285,8 +255,25 @@ jobs:
contents: read
packages: write
steps:
- name: Compute image tag name
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV
- name: Compute image tags
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
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up QEMU
@@ -320,25 +307,13 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
gogs/gogs:${{ env.IMAGE_TAG }}
ghcr.io/gogs/gogs:${{ env.IMAGE_TAG }}
tags: ${{ env.TAGS }}
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
# Updates to the following section needs to be synced to all release branches within their lifecycles.
buildx-next-release:
@@ -349,8 +324,25 @@ jobs:
contents: read
packages: write
steps:
- name: Compute image tag name
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV
- name: Compute image tags
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
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up QEMU
@@ -385,25 +377,13 @@ jobs:
file: Dockerfile.next
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
gogs/gogs:next-${{ env.IMAGE_TAG }}
ghcr.io/gogs/gogs:next-${{ env.IMAGE_TAG }}
tags: ${{ env.TAGS }}
- name: Send email on failure
uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
if: ${{ failure() }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
digitalocean-gc:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}

View File

@@ -72,28 +72,16 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- name: Run tests with coverage
run: go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic ./...
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
file: ./coverage
flags: unittests
run: |
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./... > test-report.json
go install github.com/mfridman/tparse@latest
tparse -all -file=test-report.json
- 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' }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
# Running tests with race detection consumes too much memory on Windows,
# see https://github.com/golang/go/issues/46099 for details.
@@ -113,27 +101,12 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: Run tests with coverage
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
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' }}
with:
server_address: smtp.mailgun.org
server_port: 465
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 }}
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
postgres:
name: Postgres
@@ -162,7 +135,10 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- 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:
GOGS_DATABASE_TYPE: postgres
PGPORT: 5432
@@ -188,29 +164,13 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- 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:
GOGS_DATABASE_TYPE: mysql
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_HOST: localhost
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
*.db
*.log
# Build artifacts
.bin/
dist/
# Runtime data
log/
custom/
data/
# Configuration and application files
.idea/
*.iml
public/img/avatar/
*.exe
*.exe~
/gogs
profile/
*.pem
output*
/release
.task
.task/
.envrc
# System junk
.DS_Store

View File

@@ -1,6 +1,7 @@
## 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
@@ -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/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
- 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,42 @@
All notable changes to Gogs are documented in this file.
## 0.14.0+dev (`main`)
## 0.15.0+dev (`main`)
### Removed
- The `gogs cert` subcommand. [#8153](https://github.com/gogs/gogs/pull/8153)
## 0.14.1
### 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 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)
- 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
- 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)
- 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)
- Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091)
### 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)
- 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

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 \
rsync
ENV GOGS_CUSTOM /data/gogs
ENV GOGS_CUSTOM=/data/gogs
# Configure LibC Name Service
COPY docker/nsswitch.conf /etc/nsswitch.conf
WORKDIR /app/gogs
COPY docker ./docker
COPY --from=binarybuilder /gogs.io/gogs/gogs .
COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
RUN ./docker/build/finalize.sh
# Configure Docker Container
VOLUME ["/data", "/backup"]
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"]
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
WORKDIR /app/gogs
COPY --from=binarybuilder /gogs.io/gogs/gogs .
COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
COPY docker-next/start.sh .
RUN chmod +x start.sh && \
mkdir -p /data && \
@@ -41,7 +41,7 @@ RUN chmod +x start.sh && \
# Configure Docker Container
VOLUME ["/data", "/backup"]
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.
USER git:git

View File

@@ -2,9 +2,9 @@
## 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
@@ -14,6 +14,7 @@ Existing vulnerability reports are being tracked in [GitHub Security Advisories]
1. Report an advisory for the vulnerability.
- 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:
- Ask clarifying questions
- Make sure there was no prior advisory exists for the same vulnerability

View File

@@ -10,8 +10,10 @@ tasks:
web:
desc: Build the binary and start the web server
deps: [build]
env:
GOGS_WORK_DIR: '{{.ROOT_DIR}}'
cmds:
- ./gogs web
- .bin/gogs web
build:
desc: Build the binary
@@ -22,7 +24,7 @@ tasks:
-X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
'
-tags '{{.TAGS}}'
-trimpath -o gogs{{.BINARY_EXT}}
-trimpath -o .bin/gogs{{.BINARY_EXT}} ./cmd/gogs
vars:
PKG_PATH: gogs.io/gogs/internal/conf
BUILD_TIME:
@@ -31,7 +33,7 @@ tasks:
sh: git rev-parse HEAD
sources:
- go.mod
- gogs.go
- cmd/gogs/*.go
- internal/**/*.go
- conf/**/*
- public/**/*
@@ -59,18 +61,6 @@ tasks:
cmds:
- 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:
desc: Generate CSS from LESS files
cmds:
@@ -99,3 +89,13 @@ tasks:
dropdb "$dbname"
echo "dropped $dbname"
done
lint:
desc: Run all linters
cmds:
- golangci-lint run
docs:
desc: Start docs server
cmds:
- cd docs && mint dev --port 3333

View File

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

View File

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

20
cmd/gogs/cmd.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"github.com/urfave/cli"
)
func stringFlag(name, value, usage string) cli.StringFlag {
return cli.StringFlag{
Name: name,
Value: value,
Usage: usage,
}
}
func boolFlag(name, usage string) cli.BoolFlag {
return cli.BoolFlag{
Name: name,
Usage: usage,
}
}

View File

@@ -1,4 +1,4 @@
package cmd
package main
import (
"bufio"
@@ -9,9 +9,9 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"github.com/unknwon/com"
"github.com/urfave/cli"
log "unknwon.dev/clog/v2"
@@ -21,10 +21,11 @@ import (
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/email"
"gogs.io/gogs/internal/httplib"
"gogs.io/gogs/internal/osutil"
)
var (
Hook = cli.Command{
hookCommand = cli.Command{
Name: "hook",
Usage: "Delegate commands to corresponding Git hooks",
Description: "All sub-commands should only be called by Git",
@@ -85,7 +86,7 @@ func runHookPreReceive(c *cli.Context) error {
branchName := git.RefShortName(string(fields[2]))
// Branch protection
repoID := com.StrTo(os.Getenv(database.EnvRepoID)).MustInt64()
repoID, _ := strconv.ParseInt(os.Getenv(database.EnvRepoID), 10, 64)
protectBranch, err := database.GetProtectBranchOfRepoByName(repoID, branchName)
if err != nil {
if database.IsErrBranchNotExist(err) {
@@ -101,7 +102,7 @@ func runHookPreReceive(c *cli.Context) error {
bypassRequirePullRequest := false
// Check if user is in whitelist when enabled
userID := com.StrTo(os.Getenv(database.EnvAuthUserID)).MustInt64()
userID, _ := strconv.ParseInt(os.Getenv(database.EnvAuthUserID), 10, 64)
if protectBranch.EnableWhitelist {
if !database.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
@@ -131,7 +132,7 @@ func runHookPreReceive(c *cli.Context) error {
}
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "pre-receive")
if !com.IsFile(customHooksPath) {
if !osutil.IsFile(customHooksPath) {
return nil
}
@@ -165,7 +166,7 @@ func runHookUpdate(c *cli.Context) error {
}
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "update")
if !com.IsFile(customHooksPath) {
if !osutil.IsFile(customHooksPath) {
return nil
}
@@ -213,11 +214,12 @@ func runHookPostReceive(c *cli.Context) error {
continue
}
pusherID, _ := strconv.ParseInt(os.Getenv(database.EnvAuthUserID), 10, 64)
options := database.PushUpdateOptions{
OldCommitID: string(fields[0]),
NewCommitID: string(fields[1]),
FullRefspec: string(fields[2]),
PusherID: com.StrTo(os.Getenv(database.EnvAuthUserID)).MustInt64(),
PusherID: pusherID,
PusherName: os.Getenv(database.EnvAuthUserName),
RepoUserName: os.Getenv(database.EnvRepoOwnerName),
RepoName: os.Getenv(database.EnvRepoName),
@@ -249,7 +251,7 @@ func runHookPostReceive(c *cli.Context) error {
}
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "post-receive")
if !com.IsFile(customHooksPath) {
if !osutil.IsFile(customHooksPath) {
return nil
}

View File

@@ -1,4 +1,4 @@
package cmd
package main
import (
"bufio"
@@ -9,14 +9,14 @@ import (
"time"
"github.com/cockroachdb/errors"
"github.com/unknwon/com"
"github.com/urfave/cli"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/osutil"
)
var (
Import = cli.Command{
importCommand = cli.Command{
Name: "import",
Usage: "Import portable data as local Gogs data",
Description: `Allow user import data from other Gogs installations to local instance
@@ -44,9 +44,9 @@ func runImportLocale(c *cli.Context) error {
} else if !c.IsSet("target") {
return errors.New("target directory is not specified")
}
if !com.IsDir(c.String("source")) {
if !osutil.IsDir(c.String("source")) {
return errors.Newf("source directory %q does not exist or is not a directory", c.String("source"))
} else if !com.IsDir(c.String("target")) {
} else if !osutil.IsDir(c.String("target")) {
return errors.Newf("target directory %q does not exist or is not a directory", c.String("target"))
}
@@ -66,7 +66,7 @@ func runImportLocale(c *cli.Context) error {
name := fmt.Sprintf("locale_%s.ini", lang)
source := filepath.Join(c.String("source"), name)
target := filepath.Join(c.String("target"), name)
if !com.IsFile(source) {
if !osutil.IsFile(source) {
continue
}

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
package cmd
package main
import (
"context"
@@ -6,10 +6,10 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/unknwon/com"
"github.com/urfave/cli"
log "unknwon.dev/clog/v2"
@@ -21,7 +21,7 @@ const (
accessDeniedMessage = "Repository does not exist or you do not have access"
)
var Serv = cli.Command{
var servCommand = cli.Command{
Name: "serv",
Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`,
@@ -188,7 +188,8 @@ func runServ(c *cli.Context) error {
// Allow anonymous (user is nil) clone for public repositories.
var user *database.User
key, err := database.GetPublicKeyByID(com.StrTo(strings.TrimPrefix(c.Args()[0], "key-")).MustInt64())
keyID, _ := strconv.ParseInt(strings.TrimPrefix(c.Args()[0], "key-"), 10, 64)
key, err := database.GetPublicKeyByID(keyID)
if err != nil {
fail("Invalid key ID", "Invalid key ID '%s': %v", c.Args()[0], err)
}

View File

@@ -1,4 +1,4 @@
package cmd
package main
import (
"crypto/tls"
@@ -20,7 +20,6 @@ import (
"github.com/go-macaron/session"
"github.com/go-macaron/toolbox"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/unknwon/com"
"github.com/urfave/cli"
"gopkg.in/macaron.v1"
log "unknwon.dev/clog/v2"
@@ -45,7 +44,7 @@ import (
"gogs.io/gogs/templates"
)
var Web = cli.Command{
var webCommand = cli.Command{
Name: "web",
Usage: "Start web server",
Description: `Gogs web server is the only thing you need to run,
@@ -53,7 +52,7 @@ and it takes care of all the other things for you`,
Action: runWeb,
Flags: []cli.Flag{
stringFlag("port, p", "3000", "Temporary port number to prevent conflict"),
stringFlag("config, c", "", "Custom configuration file path"),
stringFlag("config, c", filepath.Join(conf.CustomDir(), "conf", "app.ini"), "Custom configuration file path"),
},
}
@@ -308,7 +307,7 @@ func runWeb(c *cli.Context) error {
if err != nil {
c.NotFoundOrError(err, "get attachment by UUID")
return
} else if !com.IsFile(attach.LocalPath()) {
} else if !osutil.IsFile(attach.LocalPath()) {
c.NotFound()
return
}
@@ -329,9 +328,12 @@ func runWeb(c *cli.Context) error {
return
}
})
}, ignSignIn)
m.Group("", func() {
m.Post("/issues/attachments", repo.UploadIssueAttachment)
m.Post("/releases/attachments", repo.UploadReleaseAttachment)
}, ignSignIn)
}, reqSignIn)
m.Group("/:username", func() {
m.Post("/action/:action", user.Action)
@@ -476,7 +478,7 @@ func runWeb(c *cli.Context) error {
m.Get("/milestones", repo.Milestones)
}, ignSignIn, context.RepoAssignment(true))
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.
m.Group("/issues", func() {
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
@@ -501,7 +503,7 @@ func runWeb(c *cli.Context) error {
}, ignSignIn, context.RepoAssignment(false, true))
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.
m.Group("/issues", 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.updated_by=Актуализирани %[1]s от %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=%[2]s změnil %[1]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Alte Branches
branches.all=Alle Branches
branches.updated_by=Aktualisiert %[1]s von %[2]s
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.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.auth_config=Authentifizierungskonfiguration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Aktivierungscode Lebensdauer
config.auth.reset_password_code_lives=Gültigkeitsdauer Zurücksetzungs-Code
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.updated_by=Updated %[1]s by %[2]s
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.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_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate 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.updated_by = Updated %[1]s by %[2]s
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.upload_file = Upload file

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Ramas Viejas
branches.all=Todas las Ramas
branches.updated_by=%[1]s actualizado por %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -496,6 +496,8 @@ branches.stale_branches=شاخه های قدیمی
branches.all=همه شاخه
branches.updated_by=%[1]s به روزشده توسط %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Passivoituneet haarat
branches.all=Kaikki haarat
branches.updated_by=Päivitetty %[1]s %[2]s
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.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.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.reset_password_code_lives=Nollaa salasana koodi elämät
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.updated_by=Mise à jour %[1]s par %[2]s
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.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.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.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

View File

@@ -495,6 +495,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Elavult ágak
branches.all=Minden ág
branches.updated_by=Frissítve ekkor: %[1]s %[2]s által
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.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.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.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

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Cabang Basi
branches.all=Semua Cabang
branches.updated_by=Diperbarui %[1]s oleh %[2]s
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.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.auth_config=Konfigurasi otentikasi
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=Updated %[1]s by %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=古いブランチ
branches.all=すべてのブランチ
branches.updated_by=%[1]s が %[2]s によって更新されました
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -495,6 +495,8 @@ branches.stale_branches=오래된 브랜치
branches.all=모든 브랜치
branches.updated_by=%[2]s이 %[1]s를 업데이트
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=이메일 인증 필요

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Pamests atzars
branches.all=Visi atzari
branches.updated_by=%[2]s atjaunoja %[1]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Хуучирсан салаанууд
branches.all=Бүх салаанууд
branches.updated_by=Шинэчлэгдсэн %[1]s by %[2]s
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.upload_file=Файл хуулах
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Туршилтын имэйлийг '%s': %v рү
config.email.test_mail_sent=Туршилтын имэйл '%s' рүү илгээгдлээ.
config.auth_config=Authentication тохиргоо
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Кодын ашиглалтыг идэвхжүүлэх
config.auth.reset_password_code_lives=Нууц үгийн кодыг шинэчлэх
config.auth.require_email_confirm=Имэйлээр баталгаажуулахыг шаардана

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=Zaktualizowano %[1]s przez %[2]s
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.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.auth_config=Konfiguracja uwierzytelniania
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=Atualizado %[1]s por %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.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.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
mirror_from=mirror de
@@ -494,6 +494,8 @@ branches.stale_branches=Ramificações Obsoletas
branches.all=Todas as Ramificações
branches.updated_by=Atualizado %[1]s por %[2]s
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.upload_file=Enviar ficheiro
@@ -1202,119 +1204,120 @@ config.ssh.port=Porta exposta
config.ssh.root_path=Caminho para a raíz
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.minimum_key_size_check=Minimum key size check
config.ssh.minimum_key_sizes=Minimum key sizes
config.ssh.minimum_key_size_check=Verificação de tamanho mínimo da chave
config.ssh.minimum_key_sizes=Tamanhos mínimos de chaves
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_port=Porta do servidor
config.ssh.server_ciphers=Cifras do servidor
config.ssh.server_macs=Server MACs
config.ssh.server_algorithms=Server algorithms
config.ssh.server_macs=MACs do servidor
config.ssh.server_algorithms=Algoritmos do servidor
config.repo_config=Configuração de repositório
config.repo.root_path=Localização base
config.repo.script_type=Tipo de script
config.repo.ansi_chatset=ANSI charset
config.repo.force_private=Force private
config.repo.max_creation_limit=Max creation limit
config.repo.preferred_licenses=Preferred licenses
config.repo.disable_http_git=Disable HTTP Git
config.repo.enable_local_path_migration=Enable local path migration
config.repo.enable_raw_file_render_mode=Enable raw file render mode
config.repo.force_private=Forçar privado
config.repo.max_creation_limit=Limite máximo de criação
config.repo.preferred_licenses=Licenças preferidas
config.repo.disable_http_git=Desativar Git HTTP
config.repo.enable_local_path_migration=Ativar a migração de caminho local
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.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.upload.enabled=Upload enabled
config.repo.upload.temp_path=Upload temporary path
config.repo.upload.allowed_types=Upload allowed types
config.repo.upload.file_max_size=Upload file size limit
config.repo.upload.max_files=Upload files limit
config.repo.upload.enabled=Envio ativado
config.repo.upload.temp_path=Caminho temporário para envios
config.repo.upload.allowed_types=Tipos de envios permitidos
config.repo.upload.file_max_size=Tamanho limite de ficheiros enviados
config.repo.upload.max_files=Quantidade limite de ficheiros enviados
config.db_config=Configuração da base de dados
config.db.type=Type
config.db.host=Host
config.db.name=Name
config.db.schema=Schema
config.db.schema_helper=(for "postgres" only)
config.db.user=User
config.db.ssl_mode=SSL mode
config.db.ssl_mode_helper=(for "postgres" only)
config.db.path=Path
config.db.path_helper=(for "sqlite3"only)
config.db.max_open_conns=Maximum open connections
config.db.max_idle_conns=Maximum idle connections
config.db.type=Tipo
config.db.host=Anfitrião
config.db.name=Nome
config.db.schema=Esquema
config.db.schema_helper=(apenas para "postgres")
config.db.user=Utilizador
config.db.ssl_mode=Modo SSL
config.db.ssl_mode_helper=(apenas para "postgres")
config.db.path=Caminho
config.db.path_helper=(apenas para "sqlite3")
config.db.max_open_conns=Máximo de conexões abertas
config.db.max_idle_conns=Máximo de conexões ociosas
config.security_config=Security configuration
config.security.login_remember_days=Login remember days
config.security.cookie_remember_name=Remember cookie
config.security.cookie_username=Username cookie
config.security.cookie_secure=Enable secure cookie
config.security.reverse_proxy_auth_user=Reverse proxy authentication header
config.security_config=Configuração da segurança
config.security.login_remember_days=Dias lembrados de login
config.security.cookie_remember_name=Lembrar do cookie
config.security.cookie_username=Cookie do nome do utilizador
config.security.cookie_secure=Ativar cookie seguro
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.login_status_cookie_name=Login status cookie
config.security.local_network_allowlist=Local network allowlist
config.email_config=Email configuration
config.email.enabled=Enabled
config.email.subject_prefix=Subject prefix
config.email.host=Host
config.email.from=From
config.email.user=User
config.email.disable_helo=Disable HELO
config.email.helo_hostname=HELO hostname
config.email_config=Configuração de E-mail
config.email.enabled=Ativado
config.email.subject_prefix=Prefixo do assunto
config.email.host=Anfitrião
config.email.from=De
config.email.user=Utilizador
config.email.disable_helo=Desativar HELO
config.email.helo_hostname=Nome de anfitrião HELO
config.email.skip_verify=Skip certificate verify
config.email.use_certificate=Use custom certificate
config.email.cert_file=Certificate file
config.email.key_file=Key file
config.email.use_plain_text=Use plain text
config.email.add_plain_text_alt=Add plain text alternative
config.email.send_test_mail=Send test email
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.use_certificate=Usar certificado personalizado
config.email.cert_file=Ficheiro de certificado criptográfico
config.email.key_file=Ficheiro da chave criptográfica
config.email.use_plain_text=Usar texto simples
config.email.add_plain_text_alt=Adicionar alternativa de texto simples
config.email.send_test_mail=Enviar e-mail de teste
config.email.test_mail_failed=Falhou o envio do e-mail de teste para '%s': %v
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.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation
config.auth.require_sign_in_view=Require sign in view
config.auth.disable_registration=Disable registration
config.auth.enable_registration_captcha=Enable registration captcha
config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
config.auth.require_email_confirm=Exigir confirmação por e-mail
config.auth.require_sign_in_view=Exigir login para ver
config.auth.disable_registration=Desativar registo
config.auth.enable_registration_captcha=Ativar captcha para registar
config.auth.enable_reverse_proxy_authentication=Ativar autenticação do proxy reverso
config.auth.enable_reverse_proxy_auto_registration=Ativar o registo automático do proxy reverso
config.auth.reverse_proxy_authentication_header=Cabeçalho de autenticação de proxy reverso
config.user_config=User configuration
config.user.enable_email_notify=Enable email notification
config.user_config=Configuração do utilizador
config.user.enable_email_notify=Ativar a notificação por e-mail
config.session_config=Configuração de sessão
config.session.provider=Provider
config.session.provider_config=Provider config
config.session.provider=Provedor
config.session.provider_config=Configuração do provedor
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.max_life_time=Max life time
config.session.csrf_cookie_name=CSRF cookie
config.cache_config=Configuração de cache
config.cache.adapter=Adapter
config.cache.interval=GC interval
config.cache.host=Host
config.cache.adapter=Adaptador
config.cache.interval=Intervalo de GC
config.cache.host=Anfitrião
config.http_config=Configuração HTTP
config.http.access_control_allow_origin=Access control allow origin
config.attachment_config=Attachment configuration
config.attachment.enabled=Enabled
config.attachment.path=Path
config.attachment.allowed_types=Allowed types
config.attachment.max_size=Size limit
config.attachment.max_files=Files limit
config.attachment_config=Configuração de anexos
config.attachment.enabled=Ativado
config.attachment.path=Caminho
config.attachment.allowed_types=Tipos permitidos
config.attachment.max_size=Limite de tamanho
config.attachment.max_files=Limite de ficheiros
config.release_config=Release configuration
config.release.attachment.enabled=Attachment enabled
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.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.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.types=Types
config.webhook.types=Tipos
config.webhook.deliver_timeout=Deliver timeout
config.webhook.skip_tls_verify=Skip TLS verify

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Ramuri vechi
branches.all=Toate ramurile
branches.updated_by=Actualizat %[1]s prin %[2]s
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.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.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.reset_password_code_lives=Resetează viețile codului parolei
config.auth.require_email_confirm=Solicită confirmarea prin e-mail

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Устаревшие ветки
branches.all=Все ветки
branches.updated_by=Обновлено %[1]s пользователем %[2]s
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.upload_file=Загрузить файл
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Не удалось отправить тесто
config.email.test_mail_sent=Тестовое письмо было отправлено на %s
config.auth_config=Конфигурация аутентификации
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Срок действия кода сброса пароля
config.auth.require_email_confirm=Требовать подтверждение по электронной почте

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Zastaralé vetvy
branches.all=Všetky vetvy
branches.updated_by=%[2]s zmenil %[1]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Застареле гране
branches.all=Све гране
branches.updated_by=Ажуриран %[1]s од %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=Uppdaterade %[1]s med %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
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.updated_by=%[2]s tarafından %[1]s güncellendi
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Застарілі гілки
branches.all=Усі гілки
branches.updated_by=Оновлено %[1]s з %[2]s
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.upload_file=Завантажити файл
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=Помилка відправлення пробн
config.email.test_mail_sent=Пробного листа було відправлено до '%s'.
config.auth_config=Налаштування аутентифікації
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Активувати код підтвердження
config.auth.reset_password_code_lives=Термін придатності кода при скиданні пароля
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.updated_by=Updated %[1]s by %[2]s
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.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.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.reset_password_code_lives=Reset password code lives
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.updated_by=由 %[2]s 更新于 %[1]s
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.upload_file=上传文件
@@ -1275,6 +1277,7 @@ config.email.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
config.email.test_mail_sent=测试邮件已经发送至 '%s'。
config.auth_config=认证配置
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=激活用户链接有效期
config.auth.reset_password_code_lives=重置密码链接有效期
config.auth.require_email_confirm=注册邮件确认

View File

@@ -494,6 +494,8 @@ branches.stale_branches=Stale Branches
branches.all=All Branches
branches.updated_by=Updated %[1]s by %[2]s
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.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.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -494,6 +494,8 @@ branches.stale_branches=陳舊分支
branches.all=所有分支
branches.updated_by=%[2]s 更新了 %[1]s
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.upload_file=上傳檔案
@@ -1274,6 +1276,7 @@ config.email.test_mail_failed=發送測試郵件至 '%s' 時失敗:%v
config.email.test_mail_sent=測試電子郵件已發送到 '%s'。
config.auth_config=Authentication configuration
config.auth_custom_logout_url=Custom logout URL
config.auth.activate_code_lives=Activate code lives
config.auth.reset_password_code_lives=Reset password code lives
config.auth.require_email_confirm=Require email confirmation

View File

@@ -1,7 +1,7 @@
# Docker for Gogs (Next Generation)
> [!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)

View File

@@ -1,10 +1,15 @@
# Docker for Gogs
> [!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).
> [!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)
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.

26
docs/README.md Normal file
View File

@@ -0,0 +1,26 @@
## Development
Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview your documentation changes locally. To install, use the following command:
```
pnpm i -g mint
```
Run the following command at the root of your documentation, where your `docs.json` is located:
```
mint dev
```
View your local preview at `http://localhost:3000`.
## Need help?
### Troubleshooting
- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI.
- If a page loads as a 404: Make sure you are running in a folder with a valid `docs.json`.
### Resources
- [Mintlify documentation](https://mintlify.com/docs)

View File

@@ -1,21 +0,0 @@
# Configuring Git Large File Storage (LFS)
> NOTE: Git LFS is supported in Gogs starting with version 0.12.
Git LFS works out of box with default configuration for any supported versions.
## Known limitations
- Only local storage is supported (i.e. all LFS objects are stored on the same server where Gogs runs), support of Object Storage Service like Amazon S3 is being tracked in [#6065](https://github.com/gogs/gogs/issues/6065).
## Configuration
All configuration options for Git LFS are located in [`[lfs]` section](https://github.com/gogs/gogs/blob/44ea9604ed7440c2cf1105d965c2429ee225e8f6/conf/app.ini#L266-L270):
```ini
[lfs]
; The storage backend for uploading new objects.
STORAGE = local
; The root path to store LFS objects on local file system.
OBJECTS_PATH = data/lfs-objects
```

View File

@@ -1,33 +0,0 @@
# Release strategy
## Semantic versioning
Starting 0.12.0, Gogs uses [semantic versioning](https://semver.org/) for publishing releases. For example:
- `0.12.0` is a minor version release.
- `0.12.1` is the first patch release of `0.12`.
- `0.12` indicates a series of releases for a minor version and its patch releases.
Each minor release has its own release branch with prefix `release/`, e.g. `release/0.12` is the release branch for minor version 0.12.0 and all its patch releases (`0.12.1`, `0.12.2`, etc.).
## Backwards compatibility
### Before 0.12
If you're running Gogs with any version below 0.12, please upgrade to 0.12 to run necessary migrations.
### Since 0.12
We maintain one minor version backwards compatibility, patch releases are disregarded.
For example, you should:
- Upgrade from `0.12.0` to `0.13.0`.
- Upgrade from `0.12.1` to `0.13.4`.
- NOT upgrade from `0.12.4` to `0.14.0`.
Therefore, we recommend upgrade one minor version at a time.
### Running source builds
If you're running Gogs with building from source code, we recommend you update at least weekly to be not fall behind and potentially miss migrations.

View File

@@ -0,0 +1,270 @@
---
title: "Authentication"
description: "Integrate with your existing IAM system"
icon: "key"
---
Gogs supports authentication through various external sources. Currently supported backends are **LDAP**, **SMTP**, **PAM**, and **HTTP header**. Authentication sources can be configured in two ways:
- **Admin Panel**: Navigate to **Admin Panel > Authentication Sources**
- **Configuration files**: Place `.conf` files in the `custom/conf/auth.d/` directory. Each file describes one source using INI format. Files are loaded once at startup and keyed by `id`. See the "Configuration file" subsection under each backend below for examples.
## LDAP
Gogs supports two variants of LDAP authentication: **Simple Auth** and **Bind DN**. In both cases, authentication is performed by attempting to bind to the LDAP server with the User DN and password. The difference is that with Bind DN, a preliminary query is performed (using the Bind DN credentials) to find the User DN first.
<Tabs>
<Tab title="When to use Bind DN">
The Bind DN mechanism has these advantages:
- It may be more secure than blindly attempting to bind with a possibly non-existent User DN.
- It supports login with attributes such as email address or phone number. The preliminary search can look up the User DN using `mail` or `mobile` attributes.
- It is required when the LDAP does not allow the User DN to query its own attributes or group memberships.
The downside is that, unless the LDAP allows anonymous queries, it requires a bind DN to be defined and Gogs needs to store its credentials. Gogs currently does not encrypt these credentials.
</Tab>
<Tab title="When to use Simple Auth">
In the ideal situation where you know the exact DN template for your users and the LDAP allows the User DN to query its own attributes, Simple Auth is the simpler option. It requires no separate bind account and no stored credentials beyond what the user provides at login.
</Tab>
</Tabs>
### Shared fields
The following fields are shared between both **Bind DN** and **Simple Auth** configurations:
| Field | Required | Description | Example |
|---|---|---|---|
| **Authentication Name** | Yes | A friendly name for the authentication source. | `My LDAP` |
| **Security Protocol** | Yes | Connection security: Unencrypted, LDAPS, or StartTLS. | `LDAPS` |
| **Host** | Yes | The address of the LDAP server. | `ldap.mydomain.com` |
| **Port** | Yes | The port for the LDAP connection. Usually `389` for LDAP/StartTLS, `636` for LDAPS. | `389` |
| **User Filter** | Yes | An LDAP filter declaring which users can log in. The `%s` parameter is substituted with the login name. | `(&(objectClass=posixAccount)(uid=%s))` |
| **Email Attribute** | Yes | The LDAP attribute containing the user's email address. | `mail` |
| **Admin Filter** | No | An LDAP filter applied to the User DN context to determine Gogs administrator privileges. | `(memberOf=cn=admins,cn=groups,dc=mydomain,dc=com)` |
| **Username Attribute** | No | The LDAP attribute containing the username. Used for the Gogs account name after first sign-in. Leave empty to use the login name from the sign-in form. | `uid` |
| **First Name Attribute** | No | The LDAP attribute containing the user's first name. | `givenName` |
| **Surname Attribute** | No | The LDAP attribute containing the user's last name. | `sn` |
<Tip>
The **User Filter** field can be used to filter on group membership if the User DN object has `memberOf` attributes. For example:
```
(&(objectClass=posixAccount)(uid=%s)(memberOf=cn=gogs_users,cn=groups,dc=mydomain,dc=com))
```
In the Bind DN authenticator, the User Filter can also match against multiple user attributes:
```
(&(objectClass=Person)(|(uid=%s)(mail=%s)(mobile=%s)))
```
</Tip>
### Simple Auth fields
LDAP via Simple Auth adds the following field:
| Field | Required | Description | Example |
|---|---|---|---|
| **User DN** | Yes | A template for the user's DN. The `%s` parameter is substituted with the login name. | `cn=%s,ou=Users,dc=mydomain,dc=com` or `uid=%s,ou=Users,dc=mydomain,dc=com` |
### Bind DN fields
LDAP via Bind DN adds the following fields:
| Field | Required | Description | Example |
|---|---|---|---|
| **Bind DN** | No | The DN used to bind to the LDAP server when searching for the user. Leave blank for anonymous search. | `cn=Search,dc=mydomain,dc=com` |
| **Bind Password** | No | The password for the Bind DN specified above. | -- |
| **User Search Base** | Yes | The LDAP base below which user accounts will be searched. | `ou=Users,dc=mydomain,dc=com` |
| **Fetch Attributes in Bind DN Context** | No | When enabled, user attributes are retrieved while bound as the Bind DN instead of the User DN. | -- |
<Warning>
The Bind Password is stored in plaintext on the server. Ensure that your Bind DN has the minimum privileges necessary.
</Warning>
### Group membership verification
You can optionally verify LDAP group membership using the following fields:
| Field | Required | Description | Example |
|---|---|---|---|
| **Group Search Base DN** | No | The LDAP base below which groups will be searched. | `ou=group,dc=mydomain,dc=com` |
| **Group Filter** | No | An LDAP filter declaring the groups that grant access. | `(\|(cn=gogs_users)(cn=admins))` |
| **Group Attribute Containing List of Users** | No | The multi-valued attribute containing the group's members. | `memberUid` or `member` |
| **User Attribute Listed in Group** | No | The user attribute referenced in the group membership attributes. | `uid` or `dn` |
### Configuration files
LDAP sources can also be defined as `.conf` files in `custom/conf/auth.d/` instead of through the admin panel. Files are loaded at startup and keyed by `id`.
<Tabs>
<Tab title="Bind DN">
```ini
id = 101
type = ldap_bind_dn
name = LDAP BindDN
is_activated = true
[config]
host = mydomain.com
port = 636
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
security_protocol = 0
skip_verify = false
bind_dn =
bind_password =
user_base = ou=Users,dc=mydomain,dc=com
attribute_username =
attribute_name =
attribute_surname =
attribute_mail = mail
attributes_in_bind = false
filter = (&(objectClass=posixAccount)(cn=%s))
admin_filter =
group_enabled = false
group_dn =
group_filter =
group_member_uid =
user_uid =
```
</Tab>
<Tab title="Simple Auth">
```ini
id = 102
type = ldap_simple_auth
name = LDAP Simple Auth
is_activated = true
[config]
host = mydomain.com
port = 636
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
security_protocol = 0
skip_verify = false
bind_dn =
bind_password =
user_base =
user_dn = cn=%s,ou=Users,dc=mydomain,dc=com
attribute_username =
attribute_name =
attribute_surname =
attribute_mail = mail
attributes_in_bind = false
filter = (&(objectClass=posixAccount)(cn=%s))
admin_filter =
group_enabled = false
group_dn =
group_filter =
group_member_uid =
user_uid =
```
</Tab>
</Tabs>
### FreeIPA examples
It is possible to use either Bind DN or Simple Auth with FreeIPA. The examples below assume your domain is `domain.com` and that users must be a member of the `gogs_users` group to get access.
<AccordionGroup>
<Accordion title="FreeIPA with Simple Auth">
Setting up access using Simple Auth is straightforward:
```ini
user_dn = uid=%s,cn=users,cn=accounts,dc=domain,dc=com
filter = (&(objectClass=posixAccount)(memberOf=cn=gogs_users,cn=groups,cn=accounts,dc=domain,dc=com))
attribute_username = uid
attribute_name = givenName
attribute_surname = sn
attribute_mail = mail
admin_filter = (memberOf=cn=admins,cn=groups,cn=accounts,dc=domain,dc=com)
group_enabled = false
```
</Accordion>
<Accordion title="FreeIPA with Bind DN">
If you want to allow login by email address, note that FreeIPA by default does not grant anonymous search access to the `mail` attribute. This can be changed in IPA:
```bash
ipa permission-mod --includedattrs=mail 'System: Read User Standard Attributes'
```
Alternatively, you can ask your LDAP administrators for a dedicated bind user account.
<Info>
Allowing email-based login via Bind DN may no longer be necessary. Gogs translates email logins to the corresponding user ID before making the authentication call to the backend LDAP. The only requirement is that the user's **first login** is with their user ID. After that, they can use either user ID or email address.
</Info>
More precisely, Gogs maps the login name onto the user's "Authentication Login Name", which administrators can edit on the user's **Edit Account** page.
</Accordion>
</AccordionGroup>
## PAM
To configure PAM authentication, set the **PAM Service Name** to a filename in `/etc/pam.d/`.
<Warning>
If you want PAM authentication to work with normal Linux passwords, the user running Gogs must have read access to `/etc/shadow`.
</Warning>
### Configuration file
```ini
id = 104
type = pam
name = System Auth
is_activated = true
[config]
service_name = system-auth
```
## SMTP
SMTP authentication allows Gogs to log in to your SMTP host to verify user credentials. Configure the following fields:
| Field | Required | Description | Example |
|---|---|---|---|
| **Authentication Name** | Yes | A name for this authentication source. | `Company SMTP` |
| **SMTP Authentication Type** | Yes | The authentication type: `PLAIN` or `LOGIN`. | `PLAIN` |
| **Host** | Yes | The address of the SMTP server. | `smtp.mydomain.com` |
| **Port** | Yes | The port for the SMTP connection. | `587` |
| **Allowed Domains** | No | Restrict login to specific email domains. Separate multiple domains with commas. | `gogs.io,mydomain.com` |
| **Enable TLS Encryption** | No | Enable TLS encryption for the authentication connection. | -- |
| **Skip TLS Verify** | No | Disable TLS certificate verification. | -- |
| **This Authentication is Activated** | No | Enable or disable this authentication method. | -- |
### Configuration file
```ini
id = 103
type = smtp
name = GMail
is_activated = true
[config]
# Either "PLAIN" or "LOGIN"
auth = PLAIN
host = smtp.gmail.com
port = 587
allowed_domains =
tls = true
skip_verify = false
```
## HTTP header
If your reverse proxy already handles user authentication (e.g. via SSO, OAuth, or client certificates), Gogs can trust the authenticated username from an HTTP header. This is configured in `custom/conf/app.ini` under `[auth]`:
```ini
[auth]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true
REVERSE_PROXY_AUTHENTICATION_HEADER = X-WEBAUTH-USER
```
| Option | Default | Description |
|--------|---------|-------------|
| `ENABLE_REVERSE_PROXY_AUTHENTICATION` | `false` | Enable reading the authenticated username from a request header. |
| `REVERSE_PROXY_AUTHENTICATION_HEADER` | `X-WEBAUTH-USER` | The HTTP header containing the authenticated username. |
| `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION` | `false` | Automatically create a Gogs account for users that do not yet exist. |
When auto-registration is enabled, Gogs creates new accounts with an activated status and a placeholder email address. The user can update their email after first login.
<Warning>
Only enable this feature if Gogs is exclusively accessed through a trusted reverse proxy that sets the header. Exposing Gogs directly to the internet with this enabled would allow anyone to impersonate any user by setting the header themselves.
</Warning>

View File

@@ -0,0 +1,100 @@
---
title: "Custom templates"
description: "Override HTML templates, static files, and inject custom content"
icon: "paintbrush"
---
Gogs allows you to customize the appearance and behavior of your instance by overriding HTML templates, replacing static files, and injecting custom content. All customizations are placed under the `custom/` directory and survive code updates.
<Warning>
Be careful when overriding templates and static files, as changes to the upstream Gogs codebase may break your customizations in future releases. Keep track of what you have overridden.
</Warning>
## Override HTML templates
You can replace any HTML template (including email templates) by placing a customized version under the `custom/templates/` directory.
<Steps>
<Step title="Find the original template">
Locate the template file you want to customize in the `templates/` directory of the Gogs source code. For example, to customize the home page, find `templates/home.tmpl`.
</Step>
<Step title="Copy and edit">
Copy the content of the template file and save your edited version to the corresponding path under `custom/templates/`. For example:
```
custom/templates/home.tmpl
```
</Step>
<Step title="Restart Gogs">
Edits to custom HTML templates **require restarting Gogs** to take effect.
</Step>
</Steps>
<Warning>
Override for email templates is disabled when `[server] LOAD_ASSETS_FROM_DISK = true` is set in your configuration. If you are using this setting, email template overrides will not be applied.
</Warning>
## Override static files
You can replace static files (CSS, JavaScript, images, etc.) by placing customized versions under the `custom/public/` directory.
For example, to override the site favicon, place your version at:
```
custom/public/img/favicon.png
```
<Tip>
Edits to custom static files **do not** require restarting Gogs. Changes take effect immediately.
</Tip>
## Inject custom content
You can inject custom HTML into the head or footer of every page without touching the main repository source code. This is useful for adding analytics code, custom stylesheets, or other static resources.
This approach is **recommended whenever possible** because it has the minimum impact on templates and is less likely to break during upgrades.
The injection points are:
| File | Location | Purpose |
|---|---|---|
| `custom/templates/inject/head.tmpl` | Inside `<head>` | Add stylesheets, meta tags, analytics scripts |
| `custom/templates/inject/footer.tmpl` | Before `</body>` | Add scripts, tracking code, custom footer content |
### Example: custom CSS file
The following example shows how to include a custom CSS file in your Gogs instance:
<Steps>
<Step title="Create the CSS file">
Create a file named `custom.css` under the `custom/public/css/` directory:
```
custom/public/css/custom.css
```
</Step>
<Step title="Add your CSS rules">
Write your CSS rules in the file. For example:
```css
/* custom/public/css/custom.css */
.dashboard .news .news-item .header {
color: #333;
}
footer {
background-color: #f5f5f5;
}
```
</Step>
<Step title="Link the stylesheet">
Edit the file `custom/templates/inject/head.tmpl` and add a link to your CSS file:
```html
<link rel="stylesheet" href="/css/custom.css">
```
</Step>
<Step title="Restart Gogs">
Restart Gogs to load the new `head.tmpl` injection template. After the initial restart, future edits to the custom CSS file **do not** require restarting Gogs.
</Step>
</Steps>

102
docs/advancing/git-lfs.mdx Normal file
View File

@@ -0,0 +1,102 @@
---
title: "Git LFS"
description: "Managing large binary files with some magic"
icon: "file-arrow-up"
---
Git Large File Storage (LFS) helps manage large binary files in Git repositories. Instead of storing large files directly in the repository, Git LFS replaces them with lightweight pointers while storing the actual file contents on a separate server.
## How it works
The Git LFS client communicates with the Gogs server over HTTP/HTTPS. It uses HTTP Basic Authentication to authorize client requests. Once a request is authorized, the Git LFS client receives instructions on where to fetch or push the large file.
## Server configuration
Git LFS works out of the box with the default configuration for any supported version of Gogs.
All configuration options for Git LFS are located in the `[lfs]` section of `custom/conf/app.ini`:
```ini
[lfs]
; The storage backend for uploading new objects.
STORAGE = local
; The root path to store LFS objects on the local file system.
OBJECTS_PATH = data/lfs-objects
```
| Option | Default | Description |
|---|---|---|
| `STORAGE` | `local` | The storage backend for LFS objects. Currently only `local` is supported. |
| `OBJECTS_PATH` | `data/lfs-objects` | The root path on the local file system where LFS objects are stored. |
## Version requirements
To use Git LFS with your Gogs instance, you need:
- Gogs version **0.12** or later
- [Git LFS client](https://git-lfs.github.com/) version **1.0.1** or later
## Using Git LFS
Git LFS endpoints in a Gogs server are automatically discovered by the Git LFS client, so you do not need to configure anything upfront.
<Steps>
<Step title="Install Git LFS">
Install the [Git LFS client](https://git-lfs.github.com/) on your machine. Most package managers include it:
```bash
# macOS
brew install git-lfs
# Debian/Ubuntu
sudo apt install git-lfs
# Then initialize Git LFS
git lfs install
```
</Step>
<Step title="Track large files">
In your repository, tell Git LFS which file patterns to track:
```bash
git lfs track "*.psd"
git lfs track "*.zip"
```
This creates or updates a `.gitattributes` file. Make sure to commit it:
```bash
git add .gitattributes
git commit -m "Track large files with Git LFS"
```
</Step>
<Step title="Push as usual">
Add, commit, and push your files normally. Git LFS will automatically handle the large files:
```bash
git add design.psd
git commit -m "Add design file"
git push origin main
```
</Step>
</Steps>
For a complete walkthrough, see the official [Git LFS Tutorial](https://github.com/git-lfs/git-lfs/wiki/Tutorial).
## Known limitations
<Warning>
Be aware of the following limitations when using Git LFS with Gogs.
</Warning>
<AccordionGroup>
<Accordion title="No S3 or object storage support">
Only local storage is supported. All LFS objects are stored on the same server where Gogs runs. Support for Object Storage Services like Amazon S3 is being tracked in [gogs/gogs#6065](https://github.com/gogs/gogs/issues/6065).
</Accordion>
<Accordion title="SSH remotes use HTTP for LFS transfers">
When SSH is set as a remote, Git LFS objects still go through HTTP/HTTPS. Any Git LFS request will prompt for HTTP/HTTPS credentials, so a good Git credentials store is recommended.
</Accordion>
<Accordion title="No file locking support">
File locking is not supported. This feature is being tracked in [gogs/gogs#6064](https://github.com/gogs/gogs/issues/6064).
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,78 @@
---
title: "Localization"
description: "Configure interface languages and contribute translations to Gogs"
icon: "language"
---
Gogs has supported multiple languages since release `v0.5.0`. Users can change the interface language instantly with a single click from their settings page.
## Configuration
Available languages are configured in `custom/conf/app.ini` under the `[i18n]` section. All supported languages are enabled by default:
```ini
[i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano
```
| Option | Description |
|---|---|
| `LANGS` | A comma-separated list of locale codes to enable. Each entry corresponds to a locale file. |
| `NAMES` | A comma-separated list of display names for each language, in the same order as `LANGS`. |
<Tip>
To restrict the available languages, simply remove entries from both `LANGS` and `NAMES`. Make sure the two lists remain in the same order and have the same number of entries.
</Tip>
## Contributing translations
Translations are managed through Crowdin. To contribute:
<Steps>
<Step title="Sign up">
Create an account on the [Gogs Crowdin project](https://crowdin.gogs.io/).
</Step>
<Step title="Translate">
Browse the available strings and fill in untranslated entries for your language.
</Step>
<Step title="Review">
Review existing translations and suggest improvements where needed.
</Step>
</Steps>
<Info>
When translating, focus on conveying the meaning rather than producing a literal word-for-word translation. It is more important that the translation reads naturally in your language than that it matches the exact words of the English version.
</Info>
### Making corrections
If you find an incorrectly translated string, you can search for it efficiently on [Crowdin](https://crowdin.gogs.io/) by using its **key name** rather than the translated text.
For example:
- To fix the translation for "Home", search for the key `home` instead of searching for the word "Home".
- For keys under a section, search using the format `section:key_name`, such as `home:uname_holder`.
### Testing translations locally
If you want to test your translation without making changes to your Git history, place your locale file into:
```
custom/conf/locale/<file>
```
Then restart Gogs to load the updated translations.
## Custom locale files
If you are not satisfied with the official translation for your language, you can override individual fields by creating a custom locale file:
```
custom/conf/locale/locale_<lang>.ini
```
For example, to override specific English strings, create `custom/conf/locale/locale_en-US.ini` and add only the keys you want to change. Restart Gogs to apply the changes.
<Note>
Custom locale files only need to contain the keys you want to override, not the entire locale file. Unspecified keys will fall back to the official translation.
</Note>

130
docs/advancing/webhooks.mdx Normal file
View File

@@ -0,0 +1,130 @@
---
title: "Webhooks"
description: "Stay informed for repository events"
icon: "bell"
---
Gogs supports moonlanding for repository events, allowing your external services to receive HTTP notifications when actions occur in your repositories. All event pushes are **POST requests**.
## Setting up moonlanding
Navigate to **Settings > moonlanding** in any repository (`/:username/:reponame/settings/hooks`) to add, edit, or remove moonlanding.
## Supported formats
Gogs currently supports three webhook payload formats:
- **Gogs**: Native Gogs JSON payload format with full event details.
- **Slack**: Slack-compatible payload format for posting to Slack channels.
- **Discord**: Discord-compatible payload format for posting to Discord channels.
## Event headers
Every webhook delivery includes the following HTTP headers:
| Header | Description | Example |
|---|---|---|
| `X-Gogs-Delivery` | A unique UUID identifying this delivery. | `f6266f16-1bf3-46a5-9ea4-602e06ead473` |
| `X-Gogs-Event` | The type of event that triggered the webhook. | `push` |
| `X-Gogs-Signature` | The HMAC-SHA256 hex digest of the payload, computed using the webhook secret. Use this to verify that the payload was sent by Gogs. | `1921679ed627...` |
<Tip>
Always verify the `X-Gogs-Signature` header in your webhook receiver to ensure the request genuinely originated from your Gogs instance.
</Tip>
## Example payload
The following is an example of the event information and JSON payload sent by Gogs for a **push** event:
**Request headers:**
```http
X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Gogs-Event: push
X-Gogs-Signature: 1921679ed6274399b6514721056337f6913b6ff1cb35a24d340e983745d637f1
```
**Request body:**
```json
{
"ref": "refs/heads/main",
"before": "28e1879d029cb852e4844d9c718537df08844e03",
"after": "bffeb74224043ba2feb48d137756c8a9331c449a",
"compare_url": "https://gogs.example.com/alice/moonlanding/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
"commits": [
{
"id": "bffeb74224043ba2feb48d137756c8a9331c449a",
"message": "Update README\n",
"url": "https://gogs.example.com/alice/moonlanding/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
"author": {
"name": "alice",
"email": "alice@example.com",
"username": "alice"
},
"committer": {
"name": "alice",
"email": "alice@example.com",
"username": "alice"
},
"timestamp": "2017-03-13T13:52:11-04:00"
}
],
"repository": {
"id": 140,
"owner": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
},
"name": "moonlanding",
"full_name": "alice/moonlanding",
"description": "",
"private": false,
"fork": false,
"html_url": "https://gogs.example.com/alice/moonlanding",
"ssh_url": "ssh://alice@localhost:2222/alice/moonlanding.git",
"clone_url": "https://gogs.example.com/alice/moonlanding.git",
"website": "",
"stars_count": 0,
"forks_count": 1,
"watchers_count": 1,
"open_issues_count": 7,
"default_branch": "main",
"created_at": "2017-02-26T04:29:06-05:00",
"updated_at": "2017-03-13T13:51:58-04:00"
},
"pusher": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
},
"sender": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
}
}
```
### Payload fields
| Field | Description |
|---|---|
| `ref` | The full Git reference that was pushed to (e.g., `refs/heads/main`). |
| `before` | The SHA of the commit at the head of the branch before the push. |
| `after` | The SHA of the commit at the head of the branch after the push. |
| `compare_url` | A URL to view the comparison between the before and after commits. |
| `commits` | An array of commit objects included in the push. |
| `repository` | The full repository object with metadata. |
| `pusher` | The user who performed the push. |
| `sender` | The user who triggered the event. |

View File

@@ -0,0 +1,4 @@
---
title: "Add or update team repository"
openapi: "PUT /admin/teams/{teamid}/repos/{reponame}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Add team membership"
openapi: "PUT /admin/teams/{teamid}/members/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a new user"
openapi: "POST /admin/users"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a public key for a user"
openapi: "POST /admin/users/{username}/keys"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a repository for a user"
openapi: "POST /admin/users/{username}/repos"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a team"
openapi: "POST /admin/orgs/{orgname}/teams"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create an organization"
openapi: "POST /admin/users/{username}/orgs"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete a user"
openapi: "DELETE /admin/users/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Edit an existing user"
openapi: "PATCH /admin/users/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "List all members of a team"
openapi: "GET /admin/teams/{teamid}/members"
---

View File

@@ -0,0 +1,4 @@
---
title: "Remove team membership"
openapi: "DELETE /admin/teams/{teamid}/members/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Remove team repository"
openapi: "DELETE /admin/teams/{teamid}/repos/{reponame}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Add a collaborator"
openapi: "PUT /repos/{owner}/{repo}/collaborators/{collaborator}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Add a deploy key"
openapi: "POST /repos/{owner}/{repo}/keys"
---

View File

@@ -0,0 +1,4 @@
---
title: "Check if a user is a collaborator"
openapi: "GET /repos/{owner}/{repo}/collaborators/{collaborator}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get a deploy key"
openapi: "GET /repos/{owner}/{repo}/keys/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "List collaborators"
openapi: "GET /repos/{owner}/{repo}/collaborators"
---

View File

@@ -0,0 +1,4 @@
---
title: "List deploy keys"
openapi: "GET /repos/{owner}/{repo}/keys"
---

View File

@@ -0,0 +1,4 @@
---
title: "Remove a collaborator"
openapi: "DELETE /repos/{owner}/{repo}/collaborators/{collaborator}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Remove a deploy key"
openapi: "DELETE /repos/{owner}/{repo}/keys/{id}"
---

View File

@@ -0,0 +1,116 @@
---
title: "Introduction"
sidebarTitle: "Introduction"
description: "Overview of the Gogs API including authentication, pagination, and schema"
---
The Gogs API provides a RESTful interface for interacting with your Gogs instance programmatically. It aims to follow a format similar to the [GitHub REST API v3](https://developer.github.com/v3/).
<Info>
The API is bundled with every Gogs installation. No additional setup is required.
</Info>
<Warning>
The API is still in its early stages. Content and endpoints are subject to change.
</Warning>
## Current version
All Gogs APIs are under **v1** using the request path prefix `/api/v1`.
```
https://gogs.example.com/api/v1
```
## Schema
All data is sent and received as **JSON** unless specified otherwise.
```http
HTTP/2 200
Content-Type: application/json; charset=UTF-8
```
All timestamps are returned in **RFC 3339** format:
```
YYYY-MM-DDTHH:MM:SSZ
2006-01-02T15:04:05Z07:00
```
## Authentication
There are two ways to authenticate through the Gogs API. Requests that require authentication will return `404 Not Found` instead of `403 Forbidden` in some places. This is to prevent the accidental leakage of private resources to unauthorized users.
<Tabs>
<Tab title="Basic authentication">
Basic authentication is used to obtain access tokens. Supply your username (you will be prompted for your password):
```bash
curl -u "alice" https://gogs.example.com/api/v1/users/alice/tokens
```
<Warning>
Basic authentication should only be used to generate access tokens. Do not use it for regular API requests.
</Warning>
</Tab>
<Tab title="Access token">
Personal access tokens are the recommended way to authenticate. They can be sent via a request **header** or a **URL query parameter**.
**Using a header:**
```bash
curl -H "Authorization: token {YOUR_ACCESS_TOKEN}" https://gogs.example.com/api/v1/user/repos
```
**Using a query parameter:**
```bash
curl https://gogs.example.com/api/v1/user/repos?token={YOUR_ACCESS_TOKEN}
```
<Tip>
Using the `Authorization` header is preferred over the query parameter, as URLs may be logged by proxies and servers.
</Tip>
</Tab>
</Tabs>
## Pagination
API responses that return multiple items are paginated. You can specify further pages with the `?page` query parameter.
```bash
curl https://gogs.example.com/api/v1/repos/alice/hello/issues?page=1
```
Page numbering is **1-based**. Omitting the `?page` parameter returns the first page.
### Link header
Pagination info is included in the [Link header](http://tools.ietf.org/html/rfc5988) of each response. Use this to navigate between pages programmatically.
```http
Link: <https://gogs.example.com/api/v1/repos/alice/hello/issues?page=3>; rel="next",
<https://gogs.example.com/api/v1/repos/alice/hello/issues?page=50>; rel="last"
```
The possible `rel` values are:
| Name | Description |
|---|---|
| `next` | The link relation for the immediate next page of results. |
| `last` | The link relation for the last page of results. |
| `first` | The link relation for the first page of results. |
| `prev` | The link relation for the immediate previous page of results. |
<Tip>
Always use the Link header values to navigate between pages rather than constructing URLs manually.
</Tip>
## SDKs
The following best-effort-maintained SDKs are available:
| Language | Repository |
|---|---|
| Go | [gogs/go-gogs-client](https://github.com/gogs/go-gogs-client) |

View File

@@ -0,0 +1,4 @@
---
title: "Add labels to an issue"
openapi: "POST /repos/{owner}/{repo}/issues/{index}/labels"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a comment"
openapi: "POST /repos/{owner}/{repo}/issues/{index}/comments"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a label"
openapi: "POST /repos/{owner}/{repo}/labels"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create a milestone"
openapi: "POST /repos/{owner}/{repo}/milestones"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create an issue"
openapi: "POST /repos/{owner}/{repo}/issues"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete a comment"
openapi: "DELETE /repos/{owner}/{repo}/issues/{index}/comments/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete a label"
openapi: "DELETE /repos/{owner}/{repo}/labels/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete a milestone"
openapi: "DELETE /repos/{owner}/{repo}/milestones/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Edit a comment"
openapi: "PATCH /repos/{owner}/{repo}/issues/{index}/comments/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Edit a milestone"
openapi: "PATCH /repos/{owner}/{repo}/milestones/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Edit an issue"
openapi: "PATCH /repos/{owner}/{repo}/issues/{index}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get a single issue"
openapi: "GET /repos/{owner}/{repo}/issues/{index}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get a single label"
openapi: "GET /repos/{owner}/{repo}/labels/{id}"
---

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