Merge remote-tracking branch 'forgejo/v1.20/forgejo-branding' into v1.20/forgejo

This commit is contained in:
Earl Warren 2023-07-17 08:01:16 +02:00
commit c37099723e
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
81 changed files with 1068 additions and 228 deletions

View file

@ -77,6 +77,7 @@ ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/bin/s6-svscan", "/etc/s6"] CMD ["/bin/s6-svscan", "/etc/s6"]
COPY docker/root / COPY docker/root /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

View file

@ -67,6 +67,7 @@ RUN mkdir -p /var/lib/gitea /etc/gitea
RUN chown git:git /var/lib/gitea /etc/gitea RUN chown git:git /var/lib/gitea /etc/gitea
COPY docker/rootless / COPY docker/rootless /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

View file

@ -150,6 +150,7 @@ SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEs
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_EXCLUDE := code.gitea.io/sdk SWAGGER_EXCLUDE := code.gitea.io/sdk
SWAGGER_NEWLINE_COMMAND := -e '$$a\' SWAGGER_NEWLINE_COMMAND := -e '$$a\'
SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|g
TEST_MYSQL_HOST ?= mysql:3306 TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea TEST_MYSQL_DBNAME ?= testgitea
@ -335,6 +336,7 @@ $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA)
$(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' $(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)' $(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_BRANDING)' './$(SWAGGER_SPEC)'
.PHONY: swagger-check .PHONY: swagger-check
swagger-check: generate-swagger swagger-check: generate-swagger

View file

@ -1,5 +1,5 @@
<div align="center"> <div align="center">
<img src="https://codeberg.org/forgejo/meta/raw/branch/readme/logo/forgejo.svg" alt="" width="192" align="center" /> <img src="./assets/logo.svg" alt="" width="192" align="center" />
<h1 align="center">Welcome to Forgejo</h1> <h1 align="center">Welcome to Forgejo</h1>
</div> </div>

View file

@ -1,31 +1,27 @@
<?xml version="1.0" encoding="utf-8"?> <svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg">
<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" <style type="text/css">
y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve"> circle {
<g> fill: none;
<path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8 stroke: #000;
c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4 stroke-width: 15;
c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/> }
<g> path {
<g> fill: none;
<path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2 stroke: #000;
c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5 stroke-width: 25;
c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5 }
c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3 .orange {
c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1 stroke:#ff6600;
C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4 }
c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7 .red {
S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55 stroke:#d40000;
c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8 }
l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/> </style>
<path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4 <g transform="translate(6,6)">
c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1 <path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" class="orange" />
c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9 <path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" class="red" />
c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3 <circle cx="142" cy="20" r="18" class="orange" />
c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3 <circle cx="142" cy="88" r="18" class="red" />
c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29 <circle cx="58" cy="180" r="18" class="red" />
c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8 </g>
C343.2,346.5,335,363.3,326.8,380.1z"/>
</g>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 677 B

View file

@ -1,31 +1,27 @@
<?xml version="1.0" encoding="utf-8"?> <svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg">
<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" <style type="text/css">
y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve"> circle {
<g> fill: none;
<path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8 stroke: #000;
c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4 stroke-width: 15;
c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/> }
<g> path {
<g> fill: none;
<path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2 stroke: #000;
c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5 stroke-width: 25;
c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5 }
c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3 .orange {
c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1 stroke:#ff6600;
C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4 }
c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7 .red {
S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55 stroke:#d40000;
c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8 }
l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/> </style>
<path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4 <g transform="translate(6,6)">
c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1 <path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" class="orange" />
c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9 <path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" class="red" />
c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3 <circle cx="142" cy="20" r="18" class="orange" />
c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3 <circle cx="142" cy="88" r="18" class="red" />
c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29 <circle cx="58" cy="180" r="18" class="red" />
c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8 </g>
C343.2,346.5,335,363.3,326.8,380.1z"/>
</g>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 677 B

View file

@ -98,14 +98,14 @@ var outputTypeEnum = &outputType{
// CmdDump represents the available dump sub-command. // CmdDump represents the available dump sub-command.
var CmdDump = cli.Command{ var CmdDump = cli.Command{
Name: "dump", Name: "dump",
Usage: "Dump Gitea files and database", Usage: "Dump Forgejo files and database",
Description: `Dump compresses all related files and database into zip file. Description: `Dump compresses all related files and database into zip file.
It can be used for backup and capture Gitea server image to send to maintainer`, It can be used for backup and capture Forgejo server image to send to maintainer`,
Action: runDump, Action: runDump,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "file, f", Name: "file, f",
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()), Value: fmt.Sprintf("forgejo-dump-%d.zip", time.Now().Unix()),
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.", Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
}, },
cli.BoolFlag{ cli.BoolFlag{
@ -202,7 +202,7 @@ func runDump(ctx *cli.Context) error {
if !setting.InstallLock { if !setting.InstallLock {
log.Error("Is '%s' really the right config path?\n", setting.CustomConf) log.Error("Is '%s' really the right config path?\n", setting.CustomConf)
return fmt.Errorf("gitea is not initialized") return fmt.Errorf("forgejo is not initialized")
} }
setting.LoadSettings() // cannot access session settings otherwise setting.LoadSettings() // cannot access session settings otherwise
@ -281,7 +281,7 @@ func runDump(ctx *cli.Context) error {
fatal("Path does not exist: %s", tmpDir) fatal("Path does not exist: %s", tmpDir)
} }
dbDump, err := os.CreateTemp(tmpDir, "gitea-db.sql") dbDump, err := os.CreateTemp(tmpDir, "forgejo-db.sql")
if err != nil { if err != nil {
fatal("Failed to create tmp file: %v", err) fatal("Failed to create tmp file: %v", err)
} }
@ -303,8 +303,8 @@ func runDump(ctx *cli.Context) error {
fatal("Failed to dump database: %v", err) fatal("Failed to dump database: %v", err)
} }
if err := addFile(w, "gitea-db.sql", dbDump.Name(), verbose); err != nil { if err := addFile(w, "forgejo-db.sql", dbDump.Name(), verbose); err != nil {
fatal("Failed to include gitea-db.sql: %v", err) fatal("Failed to include forgejo-db.sql: %v", err)
} }
if len(setting.CustomConf) > 0 { if len(setting.CustomConf) > 0 {

View file

@ -171,13 +171,13 @@ func runServ(c *cli.Context) error {
} }
switch key.Type { switch key.Type {
case asymkey_model.KeyTypeDeploy: case asymkey_model.KeyTypeDeploy:
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.") println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Forgejo does not provide shell access.")
case asymkey_model.KeyTypePrincipal: case asymkey_model.KeyTypePrincipal:
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.") println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Forgejo does not provide shell access.")
default: default:
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.") println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Forgejo does not provide shell access.")
} }
println("If this is unexpected, please log in with password and setup Gitea under another user.") println("If this is unexpected, please log in with password and setup Forgejo under another user.")
return nil return nil
} else if c.Bool("debug") { } else if c.Bool("debug") {
log.Debug("SSH_ORIGINAL_COMMAND: %s", os.Getenv("SSH_ORIGINAL_COMMAND")) log.Debug("SSH_ORIGINAL_COMMAND: %s", os.Getenv("SSH_ORIGINAL_COMMAND"))

View file

@ -16,15 +16,15 @@ func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "environment-to-ini" app.Name = "environment-to-ini"
app.Usage = "Use provided environment to update configuration ini" app.Usage = "Use provided environment to update configuration ini"
app.Description = `As a helper to allow docker users to update the gitea configuration app.Description = `As a helper to allow docker users to update the forgejo configuration
through the environment, this command allows environment variables to through the environment, this command allows environment variables to
be mapped to values in the ini. be mapped to values in the ini.
Environment variables of the form "GITEA__SECTION_NAME__KEY_NAME" Environment variables of the form "FORGEJO__SECTION_NAME__KEY_NAME"
will be mapped to the ini section "[section_name]" and the key will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value as provided. "KEY_NAME" with the value as provided.
Environment variables of the form "GITEA__SECTION_NAME__KEY_NAME__FILE" Environment variables of the form "FORGEJO__SECTION_NAME__KEY_NAME__FILE"
will be mapped to the ini section "[section_name]" and the key will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value loaded from the specified file. "KEY_NAME" with the value loaded from the specified file.
@ -42,8 +42,8 @@ func main() {
... ...
""" """
You would set the environment variables: "GITEA__LOG_0x2E_CONSOLE__COLORIZE=false" You would set the environment variables: "FORGEJO__LOG_0x2E_CONSOLE__COLORIZE=false"
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found and "FORGEJO__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
on the configuration cheat sheet.` on the configuration cheat sheet.`
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
@ -59,7 +59,7 @@ func main() {
cli.StringFlag{ cli.StringFlag{
Name: "work-path, w", Name: "work-path, w",
Value: setting.AppWorkPath, Value: setting.AppWorkPath,
Usage: "Set the gitea working path", Usage: "Set the forgejo working path",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "out, o", Name: "out, o",

View file

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Gitea (Git with a cup of tea) Description=Forgejo (Beyond coding. We forge.)
After=syslog.target After=syslog.target
After=network.target After=network.target
### ###
@ -25,21 +25,21 @@ After=network.target
# If using socket activation for main http/s # If using socket activation for main http/s
### ###
# #
#After=gitea.main.socket #After=forgejo.main.socket
#Requires=gitea.main.socket #Requires=forgejo.main.socket
# #
### ###
# (You can also provide gitea an http fallback and/or ssh socket too) # (You can also provide forgejo an http fallback and/or ssh socket too)
# #
# An example of /etc/systemd/system/gitea.main.socket # An example of /etc/systemd/system/forgejo.main.socket
### ###
## ##
## [Unit] ## [Unit]
## Description=Gitea Web Socket ## Description=Forgejo Web Socket
## PartOf=gitea.service ## PartOf=forgejo.service
## ##
## [Socket] ## [Socket]
## Service=gitea.service ## Service=forgejo.service
## ListenStream=<some_port> ## ListenStream=<some_port>
## NoDelay=true ## NoDelay=true
## ##
@ -52,32 +52,31 @@ After=network.target
# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that # Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
# LimitNOFILE=524288:524288 # LimitNOFILE=524288:524288
RestartSec=2s RestartSec=2s
Type=notify Type=simple
User=git User=git
Group=git Group=git
WorkingDirectory=/var/lib/gitea/ WorkingDirectory=/var/lib/forgejo/
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file # If using Unix socket: tells systemd to create the /run/forgejo folder, which will contain the forgejo.sock file
# (manually creating /run/gitea doesn't work, because it would not persist across reboots) # (manually creating /run/forgejo doesn't work, because it would not persist across reboots)
#RuntimeDirectory=gitea #RuntimeDirectory=forgejo
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=always Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo
WatchdogSec=30s
# If you install Git to directory prefix other than default PATH (which happens # If you install Git to directory prefix other than default PATH (which happens
# for example if you install other versions of Git side-to-side with # for example if you install other versions of Git side-to-side with
# distribution version), uncomment below line and add that prefix to PATH # distribution version), uncomment below line and add that prefix to PATH
# Don't forget to place git-lfs binary on the PATH below if you want to enable # Don't forget to place git-lfs binary on the PATH below if you want to enable
# Git LFS support # Git LFS support
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin #Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
# If you want to bind Gitea to a port below 1024, uncomment # If you want to bind Forgejo to a port below 1024, uncomment
# the two values below, or use socket activation to pass Gitea its ports as above # the two values below, or use socket activation to pass Forgejo its ports as above
### ###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE #CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE #AmbientCapabilities=CAP_NET_BIND_SERVICE
### ###
# In some cases, when using CapabilityBoundingSet and AmbientCapabilities option, you may want to # In some cases, when using CapabilityBoundingSet and AmbientCapabilities option, you may want to
# set the following value to false to allow capabilities to be applied on gitea process. The following # set the following value to false to allow capabilities to be applied on Forgejo process. The following
# value if set to true sandboxes gitea service and prevent any processes from running with privileges # value if set to true sandboxes Forgejo service and prevent any processes from running with privileges
# in the host user namespace. # in the host user namespace.
### ###
#PrivateUsers=false #PrivateUsers=false

View file

@ -1,42 +1,42 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# This is an update script for gitea installed via the binary distribution # This is an update script for forgejo installed via the binary distribution
# from dl.gitea.com on linux as systemd service. It performs a backup and updates # from codeberg.org/forgejo/forgejo on linux as systemd service. It
# Gitea in place. # performs a backup and updates Forgejo in place.
# NOTE: This adds the GPG Signing Key of the Gitea maintainers to the keyring. # NOTE: This adds the GPG Signing Key of the Forgejo maintainers to the keyring.
# Depends on: bash, curl, xz, sha256sum. optionally jq, gpg # Depends on: bash, curl, xz, sha256sum. optionally jq, gpg
# See section below for available environment vars. # See section below for available environment vars.
# When no version is specified, updates to the latest release. # When no version is specified, updates to the latest release.
# Examples: # Examples:
# upgrade.sh 1.15.10 # upgrade.sh 1.15.10
# giteahome=/opt/gitea giteaconf=$giteahome/app.ini upgrade.sh # forgejohome=/opt/forgejo forgejoconf=$forgejohome/app.ini upgrade.sh
# Check if gitea service is running # Check if forgejo service is running
if ! pidof gitea &> /dev/null; then if ! pidof forgejo &> /dev/null; then
echo "Error: gitea is not running." echo "Error: forgejo is not running."
exit 1 exit 1
fi fi
# Continue with rest of the script if gitea is running # Continue with rest of the script if forgejo is running
echo "Gitea is running. Continuing with rest of script..." echo "Forgejo is running. Continuing with rest of script..."
# apply variables from environment # apply variables from environment
: "${giteabin:="/usr/local/bin/gitea"}" : "${forgejobin:="/usr/local/bin/forgejo"}"
: "${giteahome:="/var/lib/gitea"}" : "${forgejohome:="/var/lib/forgejo"}"
: "${giteaconf:="/etc/gitea/app.ini"}" : "${forgejoconf:="/etc/forgejo/app.ini"}"
: "${giteauser:="git"}" : "${forgejouser:="git"}"
: "${sudocmd:="sudo"}" : "${sudocmd:="sudo"}"
: "${arch:="linux-amd64"}" : "${arch:="linux-amd64"}"
: "${service_start:="$sudocmd systemctl start gitea"}" : "${service_start:="$sudocmd systemctl start forgejo"}"
: "${service_stop:="$sudocmd systemctl stop gitea"}" : "${service_stop:="$sudocmd systemctl stop forgejo"}"
: "${service_status:="$sudocmd systemctl status gitea"}" : "${service_status:="$sudocmd systemctl status forgejo"}"
: "${backupopts:=""}" # see `gitea dump --help` for available options : "${backupopts:=""}" # see `forgejo dump --help` for available options
function giteacmd { function forgejocmd {
if [[ $sudocmd = "su" ]]; then if [[ $sudocmd = "su" ]]; then
# `-c` only accept one string as argument. # `-c` only accept one string as argument.
"$sudocmd" - "$giteauser" -c "$(printf "%q " "$giteabin" "--config" "$giteaconf" "--work-path" "$giteahome" "$@")" "$sudocmd" - "$forgejouser" -c "$(printf "%q " "$forgejobin" "--config" "$forgejoconf" "--work-path" "$forgejohome" "$@")"
else else
"$sudocmd" --user "$giteauser" "$giteabin" --config "$giteaconf" --work-path "$giteahome" "$@" "$sudocmd" --user "$forgejouser" "$forgejobin" --config "$forgejoconf" --work-path "$forgejohome" "$@"
fi fi
} }
@ -49,7 +49,7 @@ function require {
# parse command line arguments # parse command line arguments
while true; do while true; do
case "$1" in case "$1" in
-v | --version ) giteaversion="$2"; shift 2 ;; -v | --version ) forgejoversion="$2"; shift 2 ;;
-y | --yes ) no_confirm="yes"; shift ;; -y | --yes ) no_confirm="yes"; shift ;;
--ignore-gpg) ignore_gpg="yes"; shift ;; --ignore-gpg) ignore_gpg="yes"; shift ;;
"" | -- ) shift; break ;; "" | -- ) shift; break ;;
@ -65,9 +65,9 @@ if [[ -f /etc/os-release ]]; then
if [[ "$os_release" =~ "OpenWrt" ]]; then if [[ "$os_release" =~ "OpenWrt" ]]; then
sudocmd="su" sudocmd="su"
service_start="/etc/init.d/gitea start" service_start="/etc/init.d/forgejo start"
service_stop="/etc/init.d/gitea stop" service_stop="/etc/init.d/forgejo stop"
service_status="/etc/init.d/gitea status" service_status="/etc/init.d/forgejo status"
else else
require systemctl require systemctl
fi fi
@ -76,31 +76,31 @@ fi
require curl xz sha256sum "$sudocmd" require curl xz sha256sum "$sudocmd"
# select version to install # select version to install
if [[ -z "${giteaversion:-}" ]]; then if [[ -z "${forgejoversion:-}" ]]; then
require jq require jq
giteaversion=$(curl --connect-timeout 10 -sL https://dl.gitea.com/gitea/version.json | jq -r .latest.version) forgejoversion=$(curl --connect-timeout 10 -sL 'https://codeberg.org/api/v1/repos/forgejo/forgejo/releases?draft=false&pre-release=false&limit=1' -H 'accept: application/json' | jq -r '.[0].tag_name | sub("v"; "")')
echo "Latest available version is $giteaversion" echo "Latest available version is $forgejoversion"
fi fi
# confirm update # confirm update
echo "Checking currently installed version..." echo "Checking currently installed version..."
current=$(giteacmd --version | cut -d ' ' -f 3) current=$(forgejocmd --version | cut -d ' ' -f 3)
[[ "$current" == "$giteaversion" ]] && echo "$current is already installed, stopping." && exit 1 [[ "$current" == "$forgejoversion" ]] && echo "$current is already installed, stopping." && exit 1
if [[ -z "${no_confirm:-}" ]]; then if [[ -z "${no_confirm:-}" ]]; then
echo "Make sure to read the changelog first: https://github.com/go-gitea/gitea/blob/main/CHANGELOG.md" echo "Make sure to read the changelog first: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CHANGELOG.md"
echo "Are you ready to update Gitea from ${current} to ${giteaversion}? (y/N)" echo "Are you ready to update forgejo from ${current} to ${forgejoversion}? (y/N)"
read -r confirm read -r confirm
[[ "$confirm" == "y" ]] || [[ "$confirm" == "Y" ]] || exit 1 [[ "$confirm" == "y" ]] || [[ "$confirm" == "Y" ]] || exit 1
fi fi
echo "Upgrading gitea from $current to $giteaversion ..." echo "Upgrading forgejo from $current to $forgejoversion ..."
pushd "$(pwd)" &>/dev/null pushd "$(pwd)" &>/dev/null
cd "$giteahome" # needed for gitea dump later cd "$forgejohome" # needed for forgejo dump later
# download new binary # download new binary
binname="gitea-${giteaversion}-${arch}" binname="forgejo-${forgejoversion}-${arch}"
binurl="https://dl.gitea.com/gitea/${giteaversion}/${binname}.xz" binurl="https://codeberg.org/forgejo/forgejo/releases/download/v${forgejoversion}/${binname}.xz"
echo "Downloading $binurl..." echo "Downloading $binurl..."
curl --connect-timeout 10 --silent --show-error --fail --location -O "$binurl{,.sha256,.asc}" curl --connect-timeout 10 --silent --show-error --fail --location -O "$binurl{,.sha256,.asc}"
@ -108,28 +108,28 @@ curl --connect-timeout 10 --silent --show-error --fail --location -O "$binurl{,.
sha256sum -c "${binname}.xz.sha256" sha256sum -c "${binname}.xz.sha256"
if [[ -z "${ignore_gpg:-}" ]]; then if [[ -z "${ignore_gpg:-}" ]]; then
require gpg require gpg
gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2 gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
gpg --verify "${binname}.xz.asc" "${binname}.xz" || { echo 'Signature does not match'; exit 1; } gpg --verify "${binname}.xz.asc" "${binname}.xz" || { echo 'Signature does not match'; exit 1; }
fi fi
rm "${binname}".xz.{sha256,asc} rm "${binname}".xz.{sha256,asc}
# unpack binary + make executable # unpack binary + make executable
xz --decompress --force "${binname}.xz" xz --decompress --force "${binname}.xz"
chown "$giteauser" "$binname" chown "$forgejouser" "$binname"
chmod +x "$binname" chmod +x "$binname"
# stop gitea, create backup, replace binary, restart gitea # stop forgejo, create backup, replace binary, restart forgejo
echo "Flushing gitea queues at $(date)" echo "Flushing forgejo queues at $(date)"
giteacmd manager flush-queues forgejocmd manager flush-queues
echo "Stopping gitea at $(date)" echo "Stopping forgejo at $(date)"
$service_stop $service_stop
echo "Creating backup in $giteahome" echo "Creating backup in $forgejohome"
giteacmd dump $backupopts forgejocmd dump $backupopts
echo "Updating binary at $giteabin" echo "Updating binary at $forgejobin"
cp -f "$giteabin" "$giteabin.bak" && mv -f "$binname" "$giteabin" cp -f "$forgejobin" "$forgejobin.bak" && mv -f "$binname" "$forgejobin"
$service_start $service_start
$service_status $service_status
echo "Upgrade to $giteaversion successful!" echo "Upgrade to $forgejoversion successful!"
popd popd

View file

@ -365,7 +365,7 @@ USER = root
;; SQLite Configuration ;; SQLite Configuration
;; ;;
;DB_TYPE = sqlite3 ;DB_TYPE = sqlite3
;PATH= ; defaults to data/gitea.db ;PATH= ; defaults to data/forgejo.db
;SQLITE_TIMEOUT = ; Query timeout defaults to: 500 ;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode ;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
;; ;;
@ -2541,9 +2541,8 @@ LEVEL = Info
; [actions] ; [actions]
;; Enable/Disable actions capabilities ;; Enable/Disable actions capabilities
;ENABLED = false ;ENABLED = false
;; ;; Default address to get action plugins, e.g. the default value means downloading from "https://code.forgejo.org/actions/checkout" for "uses: actions/checkout@v3"
;; Default address to get action plugins, e.g. the default value means downloading from "https://gitea.com/actions/checkout" for "uses: actions/checkout@v3" ;DEFAULT_ACTIONS_URL = https://code.forgejo.org
;DEFAULT_ACTIONS_URL = https://gitea.com
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -32,7 +32,7 @@ if [ ! -f ${GITEA_CUSTOM}/conf/app.ini ]; then
fi fi
# Substitute the environment variables in the template # Substitute the environment variables in the template
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \ APP_NAME=${APP_NAME:-"Forgejo: Beyond coding. We forge."} \
RUN_MODE=${RUN_MODE:-"prod"} \ RUN_MODE=${RUN_MODE:-"prod"} \
DOMAIN=${DOMAIN:-"localhost"} \ DOMAIN=${DOMAIN:-"localhost"} \
SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \ SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \

View file

@ -26,7 +26,7 @@ if [ ! -f ${GITEA_APP_INI} ]; then
fi fi
# Substitute the environment variables in the template # Substitute the environment variables in the template
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \ APP_NAME=${APP_NAME:-"Forgejo: Beyond coding. We forge."} \
RUN_MODE=${RUN_MODE:-"prod"} \ RUN_MODE=${RUN_MODE:-"prod"} \
RUN_USER=${USER:-"git"} \ RUN_USER=${USER:-"git"} \
SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \ SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \

16
main.go
View file

@ -83,6 +83,14 @@ DEFAULT CONFIGURATION:
}, },
} }
func forgejoEnv() {
for _, k := range []string{"CUSTOM", "WORK_DIR"} {
if v, ok := os.LookupEnv("FORGEJO_" + k); ok {
os.Setenv("GITEA_"+k, v)
}
}
}
func main() { func main() {
path, err := os.Executable() path, err := os.Executable()
if err != nil { if err != nil {
@ -117,10 +125,12 @@ func main() {
} }
func mainApp(subCmds ...cli.Command) { func mainApp(subCmds ...cli.Command) {
forgejoEnv()
app := cli.NewApp() app := cli.NewApp()
app.Name = "Gitea" app.Name = "Forgejo"
app.Usage = "A painless self-hosted Git service" app.Usage = "Beyond coding. We forge."
app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".` app.Description = `By default, forgejo will start serving using the web-server with no
argument - which can alternatively be run by running the subcommand web.`
app.Version = Version + formatBuiltWith() app.Version = Version + formatBuiltWith()
app.EnableBashCompletion = true app.EnableBashCompletion = true

View file

@ -540,7 +540,7 @@ func EnsureUpToDate(x *xorm.Engine) error {
expected := ExpectedVersion() expected := ExpectedVersion()
if currentDB != expected { if currentDB != expected {
return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "gitea [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected) return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
} }
return nil return nil

View file

@ -548,6 +548,7 @@ var (
"user", "user",
"v2", "v2",
"gitea-actions", "gitea-actions",
"forgejo-actions",
} }
// DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS! // DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS!

View file

@ -37,9 +37,9 @@ func NewReplaceUser(name string) *User {
const ( const (
ActionsUserID = -2 ActionsUserID = -2
ActionsUserName = "gitea-actions" ActionsUserName = "forgejo-actions"
ActionsFullName = "Gitea Actions" ActionsFullName = "Forgejo Actions"
ActionsEmail = "teabot@gitea.io" ActionsEmail = "noreply@forgejo.org"
) )
// NewActionsUser creates and returns a fake user for running the actions. // NewActionsUser creates and returns a fake user for running the actions.

View file

@ -197,13 +197,20 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) {
} }
} }
func getOtpHeader(header http.Header) string {
otpHeader := header.Get("X-Gitea-OTP")
if forgejoHeader := header.Get("X-Forgejo-OTP"); forgejoHeader != "" {
otpHeader = forgejoHeader
}
return otpHeader
}
// CheckForOTP validates OTP // CheckForOTP validates OTP
func (ctx *APIContext) CheckForOTP() { func (ctx *APIContext) CheckForOTP() {
if skip, ok := ctx.Data["SkipLocalTwoFA"]; ok && skip.(bool) { if skip, ok := ctx.Data["SkipLocalTwoFA"]; ok && skip.(bool) {
return // Skip 2FA return // Skip 2FA
} }
otpHeader := ctx.Req.Header.Get("X-Gitea-OTP")
twofa, err := auth.GetTwoFactorByUID(ctx.Doer.ID) twofa, err := auth.GetTwoFactorByUID(ctx.Doer.ID)
if err != nil { if err != nil {
if auth.IsErrTwoFactorNotEnrolled(err) { if auth.IsErrTwoFactorNotEnrolled(err) {
@ -212,7 +219,7 @@ func (ctx *APIContext) CheckForOTP() {
ctx.Error(http.StatusInternalServerError, "GetTwoFactorByUID", err) ctx.Error(http.StatusInternalServerError, "GetTwoFactorByUID", err)
return return
} }
ok, err := twofa.ValidateTOTP(otpHeader) ok, err := twofa.ValidateTOTP(getOtpHeader(ctx.Req.Header))
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "ValidateTOTP", err) ctx.Error(http.StatusInternalServerError, "ValidateTOTP", err)
return return

View file

@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
package context
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetOtpHeader(t *testing.T) {
header := http.Header{}
assert.EqualValues(t, "", getOtpHeader(header))
// Gitea
giteaOtp := "123456"
header.Set("X-Gitea-OTP", giteaOtp)
assert.EqualValues(t, giteaOtp, getOtpHeader(header))
// Forgejo has precedence
forgejoOtp := "abcdef"
header.Set("X-Forgejo-OTP", forgejoOtp)
assert.EqualValues(t, forgejoOtp, getOtpHeader(header))
}

View file

@ -30,6 +30,7 @@ func SetCacheControlInHeader(h http.Header, maxAge time.Duration, additionalDire
// to remind users they are using non-prod setting. // to remind users they are using non-prod setting.
h.Set("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) h.Set("X-Gitea-Debug", "RUN_MODE="+setting.RunMode)
h.Set("X-Forgejo-Debug", "RUN_MODE="+setting.RunMode)
} }
h.Set("Cache-Control", strings.Join(append(directives, additionalDirectives...), ", ")) h.Set("Cache-Control", strings.Join(append(directives, additionalDirectives...), ", "))

View file

@ -18,6 +18,9 @@ func countFormalHeaders(h http.Header) (c int) {
if strings.HasPrefix(k, "X-Gitea-") { if strings.HasPrefix(k, "X-Gitea-") {
continue continue
} }
if strings.HasPrefix(k, "X-Forgejo-") {
continue
}
c++ c++
} }
return c return c

View file

@ -16,7 +16,7 @@ var (
DefaultActionsURL string `ini:"DEFAULT_ACTIONS_URL"` DefaultActionsURL string `ini:"DEFAULT_ACTIONS_URL"`
}{ }{
Enabled: false, Enabled: false,
DefaultActionsURL: "https://gitea.com", DefaultActionsURL: "https://code.forgejo.org",
} }
) )

View file

@ -13,7 +13,7 @@ import (
) )
const ( const (
EnvConfigKeyPrefixGitea = "GITEA__" EnvConfigKeyPrefixGitea = "^(FORGEJO|GITEA)__"
EnvConfigKeySuffixFile = "__FILE" EnvConfigKeySuffixFile = "__FILE"
) )
@ -96,19 +96,21 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
// decodeEnvironmentKey decode the environment key to section and key // decodeEnvironmentKey decode the environment key to section and key
// The environment key is in the form of GITEA__SECTION__KEY or GITEA__SECTION__KEY__FILE // The environment key is in the form of GITEA__SECTION__KEY or GITEA__SECTION__KEY__FILE
func decodeEnvironmentKey(prefixGitea, suffixFile, envKey string) (ok bool, section, key string, useFileValue bool) { func decodeEnvironmentKey(prefixRegexp *regexp.Regexp, suffixFile, envKey string) (ok bool, section, key string, useFileValue bool) {
if !strings.HasPrefix(envKey, prefixGitea) {
return false, "", "", false
}
if strings.HasSuffix(envKey, suffixFile) { if strings.HasSuffix(envKey, suffixFile) {
useFileValue = true useFileValue = true
envKey = envKey[:len(envKey)-len(suffixFile)] envKey = envKey[:len(envKey)-len(suffixFile)]
} }
ok, section, key = decodeEnvSectionKey(envKey[len(prefixGitea):]) loc := prefixRegexp.FindStringIndex(envKey)
if loc == nil {
return false, "", "", false
}
ok, section, key = decodeEnvSectionKey(envKey[loc[1]:])
return ok, section, key, useFileValue return ok, section, key, useFileValue
} }
func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) { func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) {
prefixRegexp := regexp.MustCompile(EnvConfigKeyPrefixGitea)
for _, kv := range envs { for _, kv := range envs {
idx := strings.IndexByte(kv, '=') idx := strings.IndexByte(kv, '=')
if idx < 0 { if idx < 0 {
@ -118,7 +120,7 @@ func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) {
// parse the environment variable to config section name and key name // parse the environment variable to config section name and key name
envKey := kv[:idx] envKey := kv[:idx]
envValue := kv[idx+1:] envValue := kv[idx+1:]
ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(EnvConfigKeyPrefixGitea, EnvConfigKeySuffixFile, envKey) ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(prefixRegexp, EnvConfigKeySuffixFile, envKey)
if !ok { if !ok {
continue continue
} }

View file

@ -5,6 +5,7 @@ package setting
import ( import (
"os" "os"
"regexp"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -33,7 +34,7 @@ func TestDecodeEnvSectionKey(t *testing.T) {
} }
func TestDecodeEnvironmentKey(t *testing.T) { func TestDecodeEnvironmentKey(t *testing.T) {
prefix := "GITEA__" prefix := regexp.MustCompile(EnvConfigKeyPrefixGitea)
suffix := "__FILE" suffix := "__FILE"
ok, section, key, file := decodeEnvironmentKey(prefix, suffix, "SEC__KEY") ok, section, key, file := decodeEnvironmentKey(prefix, suffix, "SEC__KEY")
@ -54,6 +55,12 @@ func TestDecodeEnvironmentKey(t *testing.T) {
assert.Equal(t, "KEY", key) assert.Equal(t, "KEY", key)
assert.False(t, file) assert.False(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "FORGEJO__SEC__KEY")
assert.True(t, ok)
assert.Equal(t, "sec", section)
assert.Equal(t, "KEY", key)
assert.False(t, file)
// with "__FILE" suffix, it doesn't support to write "[sec].FILE" to config (no such key FILE is used in Gitea) // with "__FILE" suffix, it doesn't support to write "[sec].FILE" to config (no such key FILE is used in Gitea)
// but it could be fixed in the future by adding a new suffix like "__VALUE" (no such key VALUE is used in Gitea either) // but it could be fixed in the future by adding a new suffix like "__VALUE" (no such key VALUE is used in Gitea either)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__FILE") ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__FILE")

View file

@ -75,7 +75,7 @@ func loadDBSetting(rootCfg ConfigProvider) {
log.Error(`Deprecated database mysql charset utf8 support, please use utf8mb4 and convert utf8 database to utf8mb4 by "gitea convert".`) log.Error(`Deprecated database mysql charset utf8 support, please use utf8mb4 and convert utf8 database to utf8mb4 by "gitea convert".`)
} }
Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db")) Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "forgejo.db"))
Database.Timeout = sec.Key("SQLITE_TIMEOUT").MustInt(500) Database.Timeout = sec.Key("SQLITE_TIMEOUT").MustInt(500)
Database.SQLiteJournalMode = sec.Key("SQLITE_JOURNAL_MODE").MustString("") Database.SQLiteJournalMode = sec.Key("SQLITE_JOURNAL_MODE").MustString("")

View file

@ -129,6 +129,14 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
} }
} }
envWorkPath = getEnvFn("FORGEJO_WORK_DIR")
if envWorkPath != "" {
tmpWorkPath.Set(envWorkPath)
if !filepath.IsAbs(tmpWorkPath.Value) {
log.Fatal("FORGEJO_WORK_DIR (work path) must be absolute path")
}
}
envCustomPath := getEnvFn("GITEA_CUSTOM") envCustomPath := getEnvFn("GITEA_CUSTOM")
if envCustomPath != "" { if envCustomPath != "" {
tmpCustomPath.Set(envCustomPath) tmpCustomPath.Set(envCustomPath)
@ -136,6 +144,14 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
log.Fatal("GITEA_CUSTOM (custom path) must be absolute path") log.Fatal("GITEA_CUSTOM (custom path) must be absolute path")
} }
} }
envCustomPath = getEnvFn("FORGEJO_CUSTOM")
if envCustomPath != "" {
tmpCustomPath.Set(envCustomPath)
if !filepath.IsAbs(tmpCustomPath.Value) {
log.Fatal("FORGEJO_CUSTOM (custom path) must be absolute path")
}
}
} }
readFromArgs := func() { readFromArgs := func() {
@ -180,7 +196,7 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
log.Fatal("WORK_PATH in %q must be absolute path", configWorkPath) log.Fatal("WORK_PATH in %q must be absolute path", configWorkPath)
} }
configWorkPath = filepath.Clean(configWorkPath) configWorkPath = filepath.Clean(configWorkPath)
if tmpWorkPath.Value != "" && (getEnvFn("GITEA_WORK_DIR") != "" || args.WorkPath != "") { if tmpWorkPath.Value != "" && (getEnvFn("GITEA_WORK_DIR") != "" || getEnvFn("FORGEJO_WORK_DIR") != "" || args.WorkPath != "") {
fi1, err1 := os.Stat(tmpWorkPath.Value) fi1, err1 := os.Stat(tmpWorkPath.Value)
fi2, err2 := os.Stat(configWorkPath) fi2, err2 := os.Stat(configWorkPath)
if err1 != nil || err2 != nil || !os.SameFile(fi1, fi2) { if err1 != nil || err2 != nil || !os.SameFile(fi1, fi2) {

View file

@ -60,6 +60,22 @@ func TestInitWorkPathAndCommonConfig(t *testing.T) {
assert.Equal(t, fp(dirXxx, "custom/conf/app.ini"), CustomConf) assert.Equal(t, fp(dirXxx, "custom/conf/app.ini"), CustomConf)
}) })
t.Run("WorkDir(env)", func(t *testing.T) {
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirBar, AppWorkPath)
assert.Equal(t, fp(dirBar, "custom"), CustomPath)
assert.Equal(t, fp(dirBar, "custom/conf/app.ini"), CustomConf)
})
t.Run("WorkDir(env,arg)", func(t *testing.T) {
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{WorkPath: dirXxx})
assert.Equal(t, dirXxx, AppWorkPath)
assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
assert.Equal(t, fp(dirXxx, "custom/conf/app.ini"), CustomConf)
})
t.Run("CustomPath(env)", func(t *testing.T) { t.Run("CustomPath(env)", func(t *testing.T) {
testInit(dirFoo, "", "") testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"GITEA_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{}) InitWorkPathAndCommonConfig(envVars{"GITEA_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{})
@ -76,6 +92,22 @@ func TestInitWorkPathAndCommonConfig(t *testing.T) {
assert.Equal(t, fp(dirFoo, "custom2/conf/app.ini"), CustomConf) assert.Equal(t, fp(dirFoo, "custom2/conf/app.ini"), CustomConf)
}) })
t.Run("CustomPath(env)", func(t *testing.T) {
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirFoo, AppWorkPath)
assert.Equal(t, fp(dirBar, "custom1"), CustomPath)
assert.Equal(t, fp(dirBar, "custom1/conf/app.ini"), CustomConf)
})
t.Run("CustomPath(env,arg)", func(t *testing.T) {
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{CustomPath: "custom2"})
assert.Equal(t, dirFoo, AppWorkPath)
assert.Equal(t, fp(dirFoo, "custom2"), CustomPath)
assert.Equal(t, fp(dirFoo, "custom2/conf/app.ini"), CustomConf)
})
t.Run("CustomConf", func(t *testing.T) { t.Run("CustomConf", func(t *testing.T) {
testInit(dirFoo, "", "") testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: "app1.ini"}) InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: "app1.ini"})
@ -115,6 +147,32 @@ func TestInitWorkPathAndCommonConfig(t *testing.T) {
assert.True(t, AppWorkPathMismatch) assert.True(t, AppWorkPathMismatch)
}) })
t.Run("CustomConfOverrideWorkPath", func(t *testing.T) {
iniWorkPath := fp(tmpDir, "app-workpath.ini")
_ = os.WriteFile(iniWorkPath, []byte("WORK_PATH="+dirXxx), 0o644)
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
assert.Equal(t, dirXxx, AppWorkPath)
assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
assert.Equal(t, iniWorkPath, CustomConf)
assert.False(t, AppWorkPathMismatch)
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
assert.Equal(t, dirXxx, AppWorkPath)
assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
assert.Equal(t, iniWorkPath, CustomConf)
assert.True(t, AppWorkPathMismatch)
testInit(dirFoo, "", "")
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{WorkPath: dirBar, CustomConf: iniWorkPath})
assert.Equal(t, dirXxx, AppWorkPath)
assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
assert.Equal(t, iniWorkPath, CustomConf)
assert.True(t, AppWorkPathMismatch)
})
t.Run("Builtin", func(t *testing.T) { t.Run("Builtin", func(t *testing.T) {
testInit(dirFoo, dirBar, dirXxx) testInit(dirFoo, dirBar, dirXxx)
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{}) InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
@ -148,4 +206,38 @@ func TestInitWorkPathAndCommonConfig(t *testing.T) {
assert.Equal(t, fp(dirXxx, "custom1"), CustomPath) assert.Equal(t, fp(dirXxx, "custom1"), CustomPath)
assert.Equal(t, iniWorkPath, CustomConf) assert.Equal(t, iniWorkPath, CustomConf)
}) })
t.Run("Builtin", func(t *testing.T) {
testInit(dirFoo, dirBar, dirXxx)
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirFoo, AppWorkPath)
assert.Equal(t, dirBar, CustomPath)
assert.Equal(t, dirXxx, CustomConf)
testInit(dirFoo, "custom1", "cfg.ini")
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirFoo, AppWorkPath)
assert.Equal(t, fp(dirFoo, "custom1"), CustomPath)
assert.Equal(t, fp(dirFoo, "custom1/cfg.ini"), CustomConf)
testInit(dirFoo, "custom1", "cfg.ini")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_WORK_DIR": dirYyy}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirYyy, AppWorkPath)
assert.Equal(t, fp(dirYyy, "custom1"), CustomPath)
assert.Equal(t, fp(dirYyy, "custom1/cfg.ini"), CustomConf)
testInit(dirFoo, "custom1", "cfg.ini")
InitWorkPathAndCommonConfig(envVars{"FORGEJO_CUSTOM": dirYyy}.Getenv, ArgWorkPathAndCustomConf{})
assert.Equal(t, dirFoo, AppWorkPath)
assert.Equal(t, dirYyy, CustomPath)
assert.Equal(t, fp(dirYyy, "cfg.ini"), CustomConf)
iniWorkPath := fp(tmpDir, "app-workpath.ini")
_ = os.WriteFile(iniWorkPath, []byte("WORK_PATH="+dirXxx), 0o644)
testInit(dirFoo, "custom1", "cfg.ini")
InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
assert.Equal(t, dirXxx, AppWorkPath)
assert.Equal(t, fp(dirXxx, "custom1"), CustomPath)
assert.Equal(t, iniWorkPath, CustomConf)
})
} }

View file

@ -276,7 +276,7 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
Repository.GoGetCloneURLProtocol = sec.Key("GO_GET_CLONE_URL_PROTOCOL").MustString("https") Repository.GoGetCloneURLProtocol = sec.Key("GO_GET_CLONE_URL_PROTOCOL").MustString("https")
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1) Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch) Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories")) RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "forgejo-repositories"))
if !filepath.IsAbs(RepoRootPath) { if !filepath.IsAbs(RepoRootPath) {
RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath) RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath)
} else { } else {

View file

@ -168,7 +168,7 @@ func MakeAbsoluteAssetURL(appURL, staticURLPrefix string) string {
func loadServerFrom(rootCfg ConfigProvider) { func loadServerFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("server") sec := rootCfg.Section("server")
AppName = rootCfg.Section("").Key("APP_NAME").MustString("Gitea: Git with a cup of tea") AppName = rootCfg.Section("").Key("APP_NAME").MustString("Forgejo: Beyond coding. We Forge.")
Domain = sec.Key("DOMAIN").MustString("localhost") Domain = sec.Key("DOMAIN").MustString("localhost")
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")

View file

@ -76,11 +76,11 @@ var UI = struct {
CodeCommentLines: 4, CodeCommentLines: 4,
ReactionMaxUserNum: 10, ReactionMaxUserNum: 10,
MaxDisplayFileSize: 8388608, MaxDisplayFileSize: 8388608,
DefaultTheme: `auto`, DefaultTheme: `forgejo-auto`,
Themes: []string{`auto`, `gitea`, `arc-green`}, Themes: []string{`forgejo-auto`, `forgejo-light`, `forgejo-dark`, `auto`, `gitea`, `arc-green`},
Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`}, Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`},
CustomEmojis: []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`}, CustomEmojis: []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`, `forgejo`},
CustomEmojisMap: map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:"}, CustomEmojisMap: map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:", "forgejo": ":forgejo:"},
Notification: struct { Notification: struct {
MinTimeout time.Duration MinTimeout time.Duration
TimeoutStep time.Duration TimeoutStep time.Duration
@ -123,9 +123,9 @@ var UI = struct {
Description string Description string
Keywords string Keywords string
}{ }{
Author: "Gitea - Git with a cup of tea", Author: "Forgejo Beyond coding. We forge.",
Description: "Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go", Description: "Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.",
Keywords: "go,git,self-hosted,gitea", Keywords: "git,forge,forgejo",
}, },
} }

View file

@ -35,7 +35,7 @@ func loadWebhookFrom(rootCfg ConfigProvider) {
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("") Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("")
Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"} Webhook.Types = []string{"forgejo", "gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"}
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("") Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("")
if Webhook.ProxyURL != "" { if Webhook.ProxyURL != "" {

View file

@ -40,7 +40,7 @@ type CreateHookOptionConfig map[string]string
// CreateHookOption options when create a hook // CreateHookOption options when create a hook
type CreateHookOption struct { type CreateHookOption struct {
// required: true // required: true
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist // enum: forgejo,dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
Type string `json:"type" binding:"Required"` Type string `json:"type" binding:"Required"`
// required: true // required: true
Config CreateHookOptionConfig `json:"config" binding:"Required"` Config CreateHookOptionConfig `json:"config" binding:"Required"`

View file

@ -72,6 +72,7 @@ type HookType = string
// Types of webhooks // Types of webhooks
const ( const (
FORGEJO HookType = "forgejo"
GITEA HookType = "gitea" GITEA HookType = "gitea"
GOGS HookType = "gogs" GOGS HookType = "gogs"
SLACK HookType = "slack" SLACK HookType = "slack"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640" xml:space="preserve" width="32" height="32"><path style="fill:#fff" d="m395.9 484.2-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12z"/><path style="fill:#609926" d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9 0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6zM125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1zm300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1z"/><path style="fill:#609926" d="M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8-1.9 8 2 16.3 9.1 20 7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3 7.8 4 17.4 1.7 22.5-5.3 5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8l-24.6 50.4z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" width="32" height="32"><style>circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}</style><g transform="translate(6 6)"><path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange"/><path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red"/><circle cx="142" cy="20" r="18" class="orange"/><circle cx="142" cy="88" r="18" class="red"/><circle cx="58" cy="180" r="18" class="red"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 503 B

View file

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212">
<style>
@keyframes draw-orange{0%{stroke-dashoffset:200}25%{stroke-dashoffset:200;stroke-width:0}50%{stroke-dashoffset:0;stroke-width:25}to{stroke-dashoffset:0}}@keyframes draw-red{0%{stroke-dashoffset:130;stroke-width:0}25%{stroke-dashoffset:0;stroke-width:25}50%,to{stroke-dashoffset:0}}@keyframes red-circle{0%{opacity:0}20%{opacity:0;stroke-width:0}25%{opacity:1;stroke-width:15}to{opacity:1}}@keyframes orange-circle{0%{opacity:0}45%{opacity:0;stroke-width:0}50%{opacity:1;stroke-width:15}to{opacity:1}}@keyframes fade{0%,90%{opacity:1}to{opacity:0}}circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}
</style>
<g transform="translate(6 6)">
<g style="animation:fade 2000ms ease-in-out 5ms infinite">
<path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange" style="stroke-dasharray:200;stroke-dashoffset:200;animation:draw-orange 2000ms ease-out 5ms infinite"/>
<path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red" style="stroke-dasharray:130;stroke-dashoffset:130;animation:draw-red 2000ms ease-out 5ms infinite"/>
<circle cx="142" cy="20" r="18" class="orange" style="opacity:0;animation:orange-circle 2000ms ease-out 5ms infinite"/>
<circle cx="142" cy="88" r="18" class="red" style="opacity:0;animation:red-circle 2000ms ease-out 5ms infinite"/>
</g>
<circle cx="58" cy="180" r="18" class="red"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

1
public/img/forgejo.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" width="32" height="32"><style>circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}</style><g transform="translate(6 6)"><path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange"/><path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red"/><circle cx="142" cy="20" r="18" class="orange"/><circle cx="142" cy="88" r="18" class="red"/><circle cx="58" cy="180" r="18" class="red"/></g></svg>

After

Width:  |  Height:  |  Size: 503 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width="32" height="32"><path d="M395.9 484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12z" fill="#fff"/><g fill="#609926"><path d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9 0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6zM125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1zm300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1z"/><path d="M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8-1.9 8 2 16.3 9.1 20 7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3 7.8 4 17.4 1.7 22.5-5.3 5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8l-24.6 50.4z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width="32" height="32"><path d="M395.9 484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12z" fill="#fff"/><g fill="#609926"><path d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9 0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6zM125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1zm300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1z"/><path d="M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8-1.9 8 2 16.3 9.1 20 7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3 7.8 4 17.4 1.7 22.5-5.3 5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8l-24.6 50.4z"/></g></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" width="32" height="32"><style>circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}</style><g transform="translate(6 6)"><path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange"/><path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red"/><circle cx="142" cy="20" r="18" class="orange"/><circle cx="142" cy="88" r="18" class="red"/><circle cx="58" cy="180" r="18" class="red"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640" xml:space="preserve" width="32" height="32"><path style="fill:#fff" d="m395.9 484.2-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12z"/><path style="fill:#609926" d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9 0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6zM125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1zm300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1z"/><path style="fill:#609926" d="M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8-1.9 8 2 16.3 9.1 20 7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3 7.8 4 17.4 1.7 22.5-5.3 5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8l-24.6 50.4z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" width="32" height="32"><style>circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}</style><g transform="translate(6 6)"><path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange"/><path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red"/><circle cx="142" cy="20" r="18" class="orange"/><circle cx="142" cy="88" r="18" class="red"/><circle cx="58" cy="180" r="18" class="red"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 503 B

View file

@ -56,7 +56,7 @@
// description: Sudo API request as the user provided as the key. Admin privileges are required. // description: Sudo API request as the user provided as the key. Admin privileges are required.
// TOTPHeader: // TOTPHeader:
// type: apiKey // type: apiKey
// name: X-GITEA-OTP // name: X-FORGEJO-OTP
// in: header // in: header
// description: Must be used in combination with BasicAuth if two-factor authentication is enabled. // description: Must be used in combination with BasicAuth if two-factor authentication is enabled.
// //
@ -716,7 +716,7 @@ func Routes(ctx gocontext.Context) *web.Route {
// setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option // setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option
AllowedMethods: setting.CORSConfig.Methods, AllowedMethods: setting.CORSConfig.Methods,
AllowCredentials: setting.CORSConfig.AllowCredentials, AllowCredentials: setting.CORSConfig.AllowCredentials,
AllowedHeaders: append([]string{"Authorization", "X-Gitea-OTP"}, setting.CORSConfig.Headers...), AllowedHeaders: append([]string{"Authorization", "X-Gitea-OTP", "X-Forgejo-OTP"}, setting.CORSConfig.Headers...),
MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), MaxAge: int(setting.CORSConfig.MaxAge.Seconds()),
})) }))
} }

View file

@ -65,10 +65,10 @@ func NodeInfo(ctx *context.APIContext) {
nodeInfo := &structs.NodeInfo{ nodeInfo := &structs.NodeInfo{
Version: "2.1", Version: "2.1",
Software: structs.NodeInfoSoftware{ Software: structs.NodeInfoSoftware{
Name: "gitea", Name: "forgejo",
Version: setting.AppVer, Version: setting.AppVer,
Repository: "https://github.com/go-gitea/gitea.git", Repository: "https://codeberg.org/forgejo/forgejo.git",
Homepage: "https://gitea.io/", Homepage: "https://forgejo.org/",
}, },
Protocols: []string{"activitypub"}, Protocols: []string{"activitypub"},
Services: structs.NodeInfoServices{ Services: structs.NodeInfoServices{

View file

@ -33,7 +33,10 @@ import (
files_service "code.gitea.io/gitea/services/repository/files" files_service "code.gitea.io/gitea/services/repository/files"
) )
const giteaObjectTypeHeader = "X-Gitea-Object-Type" const (
giteaObjectTypeHeader = "X-Gitea-Object-Type"
forgejoObjectTypeHeader = "X-Forgejo-Object-Type"
)
// GetRawFile get a file by path on a repository // GetRawFile get a file by path on a repository
func GetRawFile(ctx *context.APIContext) { func GetRawFile(ctx *context.APIContext) {
@ -80,6 +83,7 @@ func GetRawFile(ctx *context.APIContext) {
} }
ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry))) ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
ctx.RespHeader().Set(forgejoObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil { if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil {
ctx.Error(http.StatusInternalServerError, "ServeBlob", err) ctx.Error(http.StatusInternalServerError, "ServeBlob", err)
@ -129,6 +133,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
} }
ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry))) ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
ctx.RespHeader().Set(forgejoObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
// LFS Pointer files are at most 1024 bytes - so any blob greater than 1024 bytes cannot be an LFS file // LFS Pointer files are at most 1024 bytes - so any blob greater than 1024 bytes cannot be an LFS file
if blob.Size() > 1024 { if blob.Size() > 1024 {

View file

@ -51,7 +51,7 @@ func migrateWithSetting(x *xorm.Engine) error {
return migrations.Migrate(x) return migrations.Migrate(x)
} else if expected := migrations.ExpectedVersion(); current != expected { } else if expected := migrations.ExpectedVersion(); current != expected {
log.Fatal(`"database.AUTO_MIGRATION" is disabled, but current database version %d is not equal to the expected version %d.`+ log.Fatal(`"database.AUTO_MIGRATION" is disabled, but current database version %d is not equal to the expected version %d.`+
`You can set "database.AUTO_MIGRATION" to true or migrate manually by running "gitea [--config /path/to/app.ini] migrate"`, current, expected) `You can set "database.AUTO_MIGRATION" to true or migrate manually by running "forgejo [--config /path/to/app.ini] migrate"`, current, expected)
} }
return nil return nil
} }

View file

@ -185,7 +185,7 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool {
if err = db.InitEngine(ctx); err != nil { if err = db.InitEngine(ctx); err != nil {
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
ctx.Data["Err_DbType"] = true ctx.Data["Err_DbType"] = true
ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/en-us/install-from-binary/"), tplInstall, form) ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://forgejo.org/download#installation-from-binary"), tplInstall, form)
} else { } else {
ctx.Data["Err_DbSetting"] = true ctx.Data["Err_DbSetting"] = true
ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, form) ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, form)

View file

@ -309,6 +309,34 @@ func editWebhook(ctx *context.Context, params webhookParams) {
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
} }
// ForgejoHooksNewPost response for creating Forgejo webhook
func ForgejoHooksNewPost(ctx *context.Context) {
createWebhook(ctx, forgejoHookParams(ctx))
}
// ForgejoHooksEditPost response for editing Forgejo webhook
func ForgejoHooksEditPost(ctx *context.Context) {
editWebhook(ctx, forgejoHookParams(ctx))
}
func forgejoHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewWebhookForm)
contentType := webhook.ContentTypeJSON
if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
contentType = webhook.ContentTypeForm
}
return webhookParams{
Type: webhook_module.FORGEJO,
URL: form.PayloadURL,
ContentType: contentType,
Secret: form.Secret,
HTTPMethod: form.HTTPMethod,
WebhookForm: form.WebhookForm,
}
}
// GiteaHooksNewPost response for creating Gitea webhook // GiteaHooksNewPost response for creating Gitea webhook
func GiteaHooksNewPost(ctx *context.Context) { func GiteaHooksNewPost(ctx *context.Context) {
createWebhook(ctx, giteaHookParams(ctx)) createWebhook(ctx, giteaHookParams(ctx))

View file

@ -286,6 +286,7 @@ func registerRoutes(m *web.Route) {
addWebhookAddRoutes := func() { addWebhookAddRoutes := func() {
m.Get("/{type}/new", repo.WebhooksNew) m.Get("/{type}/new", repo.WebhooksNew)
m.Post("/forgejo/new", web.Bind(forms.NewWebhookForm{}), repo.ForgejoHooksNewPost)
m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost)
m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksNewPost)
m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksNewPost)
@ -300,6 +301,7 @@ func registerRoutes(m *web.Route) {
} }
addWebhookEditRoutes := func() { addWebhookEditRoutes := func() {
m.Post("/forgejo/{id}", web.Bind(forms.NewWebhookForm{}), repo.ForgejoHooksEditPost)
m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksEditPost)
m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksEditPost)
m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksEditPost)

View file

@ -415,6 +415,16 @@ func generateAdditionalHeaders(ctx *mailCommentContext, reason string, recipient
"X-Gitea-Issue-ID": strconv.FormatInt(ctx.Issue.Index, 10), "X-Gitea-Issue-ID": strconv.FormatInt(ctx.Issue.Index, 10),
"X-Gitea-Issue-Link": ctx.Issue.HTMLURL(), "X-Gitea-Issue-Link": ctx.Issue.HTMLURL(),
"X-Forgejo-Reason": reason,
"X-Forgejo-Sender": ctx.Doer.DisplayName(),
"X-Forgejo-Recipient": recipient.DisplayName(),
"X-Forgejo-Recipient-Address": recipient.Email,
"X-Forgejo-Repository": repo.Name,
"X-Forgejo-Repository-Path": repo.FullName(),
"X-Forgejo-Repository-Link": repo.HTMLURL(),
"X-Forgejo-Issue-ID": strconv.FormatInt(ctx.Issue.Index, 10),
"X-Forgejo-Issue-Link": ctx.Issue.HTMLURL(),
"X-GitHub-Reason": reason, "X-GitHub-Reason": reason,
"X-GitHub-Sender": ctx.Doer.DisplayName(), "X-GitHub-Sender": ctx.Doer.DisplayName(),
"X-GitHub-Recipient": recipient.DisplayName(), "X-GitHub-Recipient": recipient.DisplayName(),

View file

@ -123,6 +123,10 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
event := t.EventType.Event() event := t.EventType.Event()
eventType := string(t.EventType) eventType := string(t.EventType)
req.Header.Add("X-Forgejo-Delivery", t.UUID)
req.Header.Add("X-Forgejo-Event", event)
req.Header.Add("X-Forgejo-Event-Type", eventType)
req.Header.Add("X-Forgejo-Signature", signatureSHA256)
req.Header.Add("X-Gitea-Delivery", t.UUID) req.Header.Add("X-Gitea-Delivery", t.UUID)
req.Header.Add("X-Gitea-Event", event) req.Header.Add("X-Gitea-Event", event)
req.Header.Add("X-Gitea-Event-Type", eventType) req.Header.Add("X-Gitea-Event-Type", eventType)

View file

@ -69,7 +69,7 @@ var webhooks = map[webhook_module.HookType]*webhook{
// IsValidHookTaskType returns true if a webhook registered // IsValidHookTaskType returns true if a webhook registered
func IsValidHookTaskType(name string) bool { func IsValidHookTaskType(name string) bool {
if name == webhook_module.GITEA || name == webhook_module.GOGS { if name == webhook_module.FORGEJO || name == webhook_module.GITEA || name == webhook_module.GOGS {
return true return true
} }
_, ok := webhooks[name] _, ok := webhooks[name]
@ -172,7 +172,7 @@ func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook
// Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.). // Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.).
// Integration webhooks (e.g. drone) still receive the required data. // Integration webhooks (e.g. drone) still receive the required data.
if pushEvent, ok := p.(*api.PushPayload); ok && if pushEvent, ok := p.(*api.PushPayload); ok &&
w.Type != webhook_module.GITEA && w.Type != webhook_module.GOGS && w.Type != webhook_module.FORGEJO && w.Type != webhook_module.GITEA && w.Type != webhook_module.GOGS &&
len(pushEvent.Commits) == 0 { len(pushEvent.Commits) == 0 {
return nil return nil
} }

View file

@ -129,11 +129,11 @@
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.verify_group_membership"}}</label> <label>{{.locale.Tr "admin.auths.verify_group_membership"}}</label>
<input name="group_filter" value="{{$cfg.GroupFilter}}" placeholder="e.g. (|(cn=gitea_users)(cn=admins))"> <input name="group_filter" value="{{$cfg.GroupFilter}}" placeholder="e.g. (|(cn=forgejo_users)(cn=admins))">
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.map_group_to_team"}}</label> <label>{{.locale.Tr "admin.auths.map_group_to_team"}}</label>
<textarea name="group_team_map" rows="5" placeholder='e.g. {"cn=my-group,cn=groups,dc=example,dc=org": {"MyGiteaOrganization": ["MyGiteaTeam1", "MyGiteaTeam2"]}}'>{{$cfg.GroupTeamMap}}</textarea> <textarea name="group_team_map" rows="5" placeholder='e.g. {"cn=my-group,cn=groups,dc=example,dc=org": {"MyForgejoOrganization": ["MyForgejoTeam1", "MyForgejoTeam2"]}}'>{{$cfg.GroupTeamMap}}</textarea>
</div> </div>
<div class="ui checkbox"> <div class="ui checkbox">
<label>{{.locale.Tr "admin.auths.map_group_to_team_removal"}}</label> <label>{{.locale.Tr "admin.auths.map_group_to_team_removal"}}</label>
@ -360,7 +360,7 @@
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team"}}</label> <label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team"}}</label>
<textarea name="oauth2_group_team_map" rows="5" placeholder='e.g. {"Developer": {"MyGiteaOrganization": ["MyGiteaTeam1", "MyGiteaTeam2"]}}'>{{$cfg.GroupTeamMap}}</textarea> <textarea name="oauth2_group_team_map" rows="5" placeholder='e.g. {"Developer": {"MyForgejoOrganization": ["MyForgejoTeam1", "MyForgejoTeam2"]}}'>{{$cfg.GroupTeamMap}}</textarea>
</div> </div>
<div class="ui checkbox"> <div class="ui checkbox">
<label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team_removal"}}</label> <label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team_removal"}}</label>

View file

@ -102,11 +102,11 @@
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.verify_group_membership"}}</label> <label>{{.locale.Tr "admin.auths.verify_group_membership"}}</label>
<input name="group_filter" value="{{.group_filter}}" placeholder="e.g. (|(cn=gitea_users)(cn=admins))"> <input name="group_filter" value="{{.group_filter}}" placeholder="e.g. (|(cn=forgejo_users)(cn=admins))">
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.map_group_to_team"}}</label> <label>{{.locale.Tr "admin.auths.map_group_to_team"}}</label>
<textarea name="group_team_map" rows="5" placeholder='e.g. {"cn=my-group,cn=groups,dc=example,dc=org": {"MyGiteaOrganization": ["MyGiteaTeam1", "MyGiteaTeam2"]}}'>{{.group_team_map}}</textarea> <textarea name="group_team_map" rows="5" placeholder='e.g. {"cn=my-group,cn=groups,dc=example,dc=org": {"MyForgejoOrganization": ["MyForgejoTeam1", "MyForgejoTeam2"]}}'>{{.group_team_map}}</textarea>
</div> </div>
<div class="ui checkbox"> <div class="ui checkbox">
<label>{{.locale.Tr "admin.auths.map_group_to_team_removal"}}</label> <label>{{.locale.Tr "admin.auths.map_group_to_team_removal"}}</label>

View file

@ -100,7 +100,7 @@
</div> </div>
<div class="field"> <div class="field">
<label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team"}}</label> <label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team"}}</label>
<textarea name="oauth2_group_team_map" rows="5" placeholder='e.g. {"Developer": {"MyGiteaOrganization": ["MyGiteaTeam1", "MyGiteaTeam2"]}}'>{{.oauth2_group_team_map}}</textarea> <textarea name="oauth2_group_team_map" rows="5" placeholder='e.g. {"Developer": {"MyForgejoOrganization": ["MyForgejoTeam1", "MyForgejoTeam2"]}}'>{{.oauth2_group_team_map}}</textarea>
</div> </div>
<div class="ui checkbox"> <div class="ui checkbox">
<label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team_removal"}}</label> <label>{{.locale.Tr "admin.auths.oauth2_map_group_to_team_removal"}}</label>

View file

@ -11,8 +11,10 @@
{{.locale.Tr "admin.defaulthooks.update_webhook"}} {{.locale.Tr "admin.defaulthooks.update_webhook"}}
{{end}} {{end}}
<div class="ui right"> <div class="ui right">
{{if eq .HookType "gitea"}} {{if eq .HookType "forgejo"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg">
{{else if eq .HookType "gitea"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg">
{{else if eq .HookType "gogs"}} {{else if eq .HookType "gogs"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico">
{{else if eq .HookType "slack"}} {{else if eq .HookType "slack"}}
@ -37,6 +39,7 @@
</div> </div>
</h4> </h4>
<div class="ui attached segment"> <div class="ui attached segment">
{{template "repo/settings/webhook/forgejo" .}}
{{template "repo/settings/webhook/gitea" .}} {{template "repo/settings/webhook/gitea" .}}
{{template "repo/settings/webhook/gogs" .}} {{template "repo/settings/webhook/gogs" .}}
{{template "repo/settings/webhook/slack" .}} {{template "repo/settings/webhook/slack" .}}

View file

@ -1,6 +1,6 @@
<footer class="page-footer" role="group" aria-label="{{.locale.Tr "aria.footer"}}"> <footer class="page-footer" role="group" aria-label="{{.locale.Tr "aria.footer"}}">
<div class="left-links" role="contentinfo" aria-label="{{.locale.Tr "aria.footer.software"}}"> <div class="left-links" role="contentinfo" aria-label="{{.locale.Tr "aria.footer.software"}}">
<a target="_blank" rel="noopener noreferrer" href="https://gitea.io">{{.locale.Tr "powered_by" "Gitea"}}</a> <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org">{{.locale.Tr "powered_by" "Forgejo"}}</a>
{{if (or .ShowFooterVersion .PageIsAdmin)}} {{if (or .ShowFooterVersion .PageIsAdmin)}}
{{.locale.Tr "version"}}: {{.locale.Tr "version"}}:
{{if .IsAdmin}} {{if .IsAdmin}}

View file

@ -49,7 +49,7 @@
{{template "custom/extra_links" .}} {{template "custom/extra_links" .}}
{{if not .IsSigned}} {{if not .IsSigned}}
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.locale.Tr "help"}}</a> <a class="item" target="_blank" rel="noopener noreferrer" href="https://forgejo.org/docs/latest/">{{.locale.Tr "help"}}</a>
{{end}} {{end}}
<!-- the full dropdown menus --> <!-- the full dropdown menus -->
@ -171,7 +171,7 @@
{{svg "octicon-tools"}} {{svg "octicon-tools"}}
{{.locale.Tr "your_settings"}} {{.locale.Tr "your_settings"}}
</a> </a>
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io"> <a class="item" target="_blank" rel="noopener noreferrer" href="https://forgejo.org/docs/latest/">
{{svg "octicon-question"}} {{svg "octicon-question"}}
{{.locale.Tr "help"}} {{.locale.Tr "help"}}
</a> </a>

View file

@ -124,7 +124,7 @@
</div> </div>
<div class="inline required field"> <div class="inline required field">
<label for="domain">{{.locale.Tr "install.domain"}}</label> <label for="domain">{{.locale.Tr "install.domain"}}</label>
<input id="domain" name="domain" value="{{.domain}}" placeholder="e.g. try.gitea.io" required> <input id="domain" name="domain" value="{{.domain}}" placeholder="e.g. next.forgejo.org" required>
<span class="help">{{.locale.Tr "install.domain_helper"}}</span> <span class="help">{{.locale.Tr "install.domain_helper"}}</span>
</div> </div>
<div class="inline field"> <div class="inline field">
@ -139,7 +139,7 @@
</div> </div>
<div class="inline required field"> <div class="inline required field">
<label for="app_url">{{.locale.Tr "install.app_url"}}</label> <label for="app_url">{{.locale.Tr "install.app_url"}}</label>
<input id="app_url" name="app_url" value="{{.app_url}}" placeholder="e.g. https://try.gitea.io" required> <input id="app_url" name="app_url" value="{{.app_url}}" placeholder="e.g. https://next.forgejo.org" required>
<span class="help">{{.locale.Tr "install.app_url_helper"}}</span> <span class="help">{{.locale.Tr "install.app_url_helper"}}</span>
</div> </div>
<div class="inline required field"> <div class="inline required field">
@ -351,5 +351,5 @@
</div> </div>
</div> </div>
</div> </div>
<img class="gt-hidden" src="{{AssetUrlPrefix}}/img/loading.png"> <img class="gt-hidden" src="{{AssetUrlPrefix}}/img/forgejo-loading.svg" width="256" height="256">
{{template "base/footer" .}} {{template "base/footer" .}}

View file

@ -3,8 +3,10 @@
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}} {{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}}
<div class="ui right"> <div class="ui right">
{{if eq .HookType "gitea"}} {{if eq .HookType "forgejo"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg">
{{else if eq .HookType "gitea"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg">
{{else if eq .HookType "gogs"}} {{else if eq .HookType "gogs"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico">
{{else if eq .HookType "slack"}} {{else if eq .HookType "slack"}}

View file

@ -7,7 +7,7 @@
<div class="ui stackable middle very relaxed page grid"> <div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center aligned centered column"> <div class="sixteen wide center aligned centered column">
<div> <div>
<img src="{{AssetUrlPrefix}}/img/loading.png" alt="{{.locale.Tr "loading"}}"> <img src="{{AssetUrlPrefix}}/img/forgejo-loading.svg" alt="{{.locale.Tr "loading"}}" width="256" height="256">
</div> </div>
</div> </div>
</div> </div>

View file

@ -9,12 +9,12 @@
<div class="ui stackable middle very relaxed page grid"> <div class="ui stackable middle very relaxed page grid">
<div id="repo_migrating" class="sixteen wide center aligned centered column" data-migrating-task-id="{{.MigrateTask.ID}}"> <div id="repo_migrating" class="sixteen wide center aligned centered column" data-migrating-task-id="{{.MigrateTask.ID}}">
<div> <div>
<img src="{{AssetUrlPrefix}}/img/loading.png"> <img src="{{AssetUrlPrefix}}/img/forgejo-loading.svg" width="256" height="256">
</div> </div>
</div> </div>
<div id="repo_migrating_failed_image" class="sixteen wide center aligned centered column gt-hidden"> <div id="repo_migrating_failed_image" class="sixteen wide center aligned centered column gt-hidden">
<div> <div>
<img src="{{AssetUrlPrefix}}/img/failed.png"> <span class="red">{{svg "octicon-git-pull-request-closed" 256 "ui red icon"}}</span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -4,8 +4,11 @@
<div class="ui jump dropdown"> <div class="ui jump dropdown">
<div class="ui primary tiny button">{{.locale.Tr "repo.settings.add_webhook"}}</div> <div class="ui primary tiny button">{{.locale.Tr "repo.settings.add_webhook"}}</div>
<div class="menu"> <div class="menu">
<a class="item" href="{{.BaseLinkNew}}/forgejo/new">
<img width="20" height="20" src="{{AssetUrlPrefix}}/img/forgejo.svg">{{.locale.Tr "repo.settings.web_hook_name_forgejo"}}
</a>
<a class="item" href="{{.BaseLinkNew}}/gitea/new"> <a class="item" href="{{.BaseLinkNew}}/gitea/new">
<img width="20" height="20" src="{{AssetUrlPrefix}}/img/gitea.svg">{{.locale.Tr "repo.settings.web_hook_name_gitea"}} <img width="20" height="20" src="{{AssetUrlPrefix}}/img/gitea-original.svg">{{.locale.Tr "repo.settings.web_hook_name_gitea"}}
</a> </a>
<a class="item" href="{{.BaseLinkNew}}/gogs/new"> <a class="item" href="{{.BaseLinkNew}}/gogs/new">
<img width="20" height="20" src="{{AssetUrlPrefix}}/img/gogs.ico">{{.locale.Tr "repo.settings.web_hook_name_gogs"}} <img width="20" height="20" src="{{AssetUrlPrefix}}/img/gogs.ico">{{.locale.Tr "repo.settings.web_hook_name_gogs"}}

View file

@ -0,0 +1,40 @@
{{if eq .HookType "forgejo"}}
<p>{{.locale.Tr "repo.settings.add_web_hook_desc" "https://docs.gitea.io/en-us/webhooks/" (.locale.Tr "repo.settings.web_hook_name_forgejo") | Str2html}}</p>
<form class="ui form" action="{{.BaseLink}}/forgejo/{{or .Webhook.ID "new"}}" method="post">
{{template "base/disable_form_autofill"}}
{{.CsrfTokenHtml}}
<div class="required field {{if .Err_PayloadURL}}error{{end}}">
<label for="payload_url">{{.locale.Tr "repo.settings.payload_url"}}</label>
<input id="payload_url" name="payload_url" type="url" value="{{.Webhook.URL}}" autofocus required>
</div>
<div class="field">
<label>{{.locale.Tr "repo.settings.http_method"}}</label>
<div class="ui selection dropdown">
<input type="hidden" id="http_method" name="http_method" value="{{if .Webhook.HTTPMethod}}{{.Webhook.HTTPMethod}}{{else}}POST{{end}}">
<div class="default text"></div>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="item" data-value="POST">POST</div>
<div class="item" data-value="GET">GET</div>
</div>
</div>
</div>
<div class="field">
<label>{{.locale.Tr "repo.settings.content_type"}}</label>
<div class="ui selection dropdown">
<input type="hidden" id="content_type" name="content_type" value="{{if .Webhook.ContentType}}{{.Webhook.ContentType}}{{else}}1{{end}}">
<div class="default text"></div>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="item" data-value="1">application/json</div>
<div class="item" data-value="2">application/x-www-form-urlencoded</div>
</div>
</div>
</div>
<div class="field {{if .Err_Secret}}error{{end}}">
<label for="secret">{{.locale.Tr "repo.settings.secret"}}</label>
<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
</div>
{{template "repo/settings/webhook/settings" .}}
</form>
{{end}}

View file

@ -3,8 +3,10 @@
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}} {{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}}
<div class="ui right"> <div class="ui right">
{{if eq .HookType "gitea"}} {{if eq .HookType "forgejo"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg">
{{else if eq .HookType "gitea"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg">
{{else if eq .HookType "gogs"}} {{else if eq .HookType "gogs"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico">
{{else if eq .HookType "slack"}} {{else if eq .HookType "slack"}}
@ -29,6 +31,7 @@
</div> </div>
</h4> </h4>
<div class="ui attached segment"> <div class="ui attached segment">
{{template "repo/settings/webhook/forgejo" .}}
{{template "repo/settings/webhook/gitea" .}} {{template "repo/settings/webhook/gitea" .}}
{{template "repo/settings/webhook/gogs" .}} {{template "repo/settings/webhook/gogs" .}}
{{template "repo/settings/webhook/slack" .}} {{template "repo/settings/webhook/slack" .}}

View file

@ -11,7 +11,7 @@
<div class="menu"> <div class="menu">
<div class="item"> <div class="item">
{{/* TODO: replece the document link when there's a better one than the README of act_runner */}} {{/* TODO: replece the document link when there's a better one than the README of act_runner */}}
<a href="https://gitea.com/gitea/act_runner/src/branch/main/README.md">{{.locale.Tr "actions.runners.new_notice"}}</a> <a href="https://forgejo.org/docs/next/admin/actions/#forgejo-runner">{{.locale.Tr "actions.runners.new_notice"}}</a>
</div> </div>
<div class="divider"></div> <div class="divider"></div>
<div class="header"> <div class="header">

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Gitea API</title> <title>Forgejo API</title>
<link href="{{AssetUrlPrefix}}/css/swagger.css?v={{AssetVersion}}" rel="stylesheet"> <link href="{{AssetUrlPrefix}}/css/swagger.css?v={{AssetVersion}}" rel="stylesheet">
</head> </head>
<body> <body>

View file

@ -13,8 +13,8 @@
], ],
"swagger": "2.0", "swagger": "2.0",
"info": { "info": {
"description": "This documentation describes the Gitea API.", "description": "This documentation describes the Forgejo API.",
"title": "Gitea API.", "title": "Forgejo API.",
"license": { "license": {
"name": "MIT", "name": "MIT",
"url": "http://opensource.org/licenses/MIT" "url": "http://opensource.org/licenses/MIT"
@ -16735,6 +16735,7 @@
"type": { "type": {
"type": "string", "type": "string",
"enum": [ "enum": [
"forgejo",
"dingtalk", "dingtalk",
"discord", "discord",
"gitea", "gitea",
@ -22894,7 +22895,7 @@
"TOTPHeader": { "TOTPHeader": {
"description": "Must be used in combination with BasicAuth if two-factor authentication is enabled.", "description": "Must be used in combination with BasicAuth if two-factor authentication is enabled.",
"type": "apiKey", "type": "apiKey",
"name": "X-GITEA-OTP", "name": "X-FORGEJO-OTP",
"in": "header" "in": "header"
}, },
"Token": { "Token": {

View file

@ -4,7 +4,9 @@
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}} {{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}}
<div class="ui right"> <div class="ui right">
{{if eq .HookType "gitea"}} {{if eq .HookType "forgejo"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg">
{{else if eq .HookType "gitea"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg">
{{else if eq .HookType "gogs"}} {{else if eq .HookType "gogs"}}
<img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico">

View file

@ -32,7 +32,7 @@ func TestNodeinfo(t *testing.T) {
var nodeinfo api.NodeInfo var nodeinfo api.NodeInfo
DecodeJSON(t, resp, &nodeinfo) DecodeJSON(t, resp, &nodeinfo)
assert.True(t, nodeinfo.OpenRegistrations) assert.True(t, nodeinfo.OpenRegistrations)
assert.Equal(t, "gitea", nodeinfo.Software.Name) assert.Equal(t, "forgejo", nodeinfo.Software.Name)
assert.Equal(t, 25, nodeinfo.Usage.Users.Total) assert.Equal(t, 25, nodeinfo.Usage.Users.Total)
assert.Equal(t, 18, nodeinfo.Usage.LocalPosts) assert.Equal(t, 18, nodeinfo.Usage.LocalPosts)
assert.Equal(t, 2, nodeinfo.Usage.LocalComments) assert.Equal(t, 2, nodeinfo.Usage.LocalComments)

View file

@ -173,3 +173,33 @@ func TestLinksLogin(t *testing.T) {
testLinksAsUser("user2", t) testLinksAsUser("user2", t)
} }
func TestRedirectsWebhooks(t *testing.T) {
defer tests.PrepareTestEnv(t)()
//
// A redirect means the route exists but not if it performs as intended.
//
for _, kind := range []string{"forgejo", "gitea"} {
redirects := []struct {
from string
to string
verb string
}{
{from: "/user2/repo1/settings/hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
{from: "/user/settings/hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
{from: "/admin/system-hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
{from: "/admin/default-hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
{from: "/user2/repo1/settings/hooks/" + kind + "/new", to: "/", verb: "POST"},
{from: "/admin/system-hooks/" + kind + "/new", to: "/", verb: "POST"},
{from: "/admin/default-hooks/" + kind + "/new", to: "/", verb: "POST"},
{from: "/user2/repo1/settings/hooks/" + kind + "/1", to: "/", verb: "POST"},
{from: "/admin/hooks/" + kind + "/1", to: "/", verb: "POST"},
}
for _, info := range redirects {
req := NewRequest(t, info.verb, info.from)
resp := MakeRequest(t, req, http.StatusSeeOther)
assert.EqualValues(t, path.Join(setting.AppSubURL, info.to), test.RedirectURL(resp), info.from)
}
}
}

View file

@ -21,7 +21,7 @@
} }
.home .hero .svg { .home .hero .svg {
color: var(--color-green); color: var(--color-primary);
height: 40px; height: 40px;
width: 50px; width: 50px;
vertical-align: bottom; vertical-align: bottom;
@ -40,7 +40,7 @@
} }
.home a { .home a {
color: var(--color-green); color: var(--color-primary);
} }
.page-footer { .page-footer {

View file

@ -0,0 +1,2 @@
@import "theme-forgejo-light.css";
@import "theme-forgejo-dark.css" (prefers-color-scheme: dark);

View file

@ -0,0 +1,281 @@
@import "../chroma/dark.css";
@import "../codemirror/dark.css";
:root {
--steel-900: #10161D;
--steel-850: #131A21;
--steel-800: #171E26;
--steel-750: #1D262F;
--steel-700: #242D38;
--steel-650: #2B3642;
--steel-600: #374351;
--steel-550: #445161;
--steel-500: #515F70;
--steel-450: #5F6E80;
--steel-400: #6D7D8F;
--steel-350: #7C8C9F;
--steel-300: #8C9CAF;
--steel-250: #9DADC0;
--steel-200: #AEBED0;
--steel-150: #C0CFE0;
--steel-100: #D2E0F0;
--is-dark-theme: true;
--color-primary: #fb923c;
--color-primary-contrast: #000;
--color-primary-dark-1: #fdba74;
--color-primary-dark-2: #fdba74;
--color-primary-dark-3: #fed7aa;
--color-primary-dark-4: #fed7aa;
--color-primary-dark-5: #ffedd5;
--color-primary-dark-6: #ffedd5;
--color-primary-dark-7: #fff7ed;
--color-primary-light-1: #f97316;
--color-primary-light-2: #ea580c;
--color-primary-light-3: #c2410c;
--color-primary-light-4: #9a3412;
--color-primary-light-5: #9a3412;
--color-primary-light-6: #7c2d12;
--color-primary-light-7: #7c2d12;
--color-primary-alpha-10: #ea580c19;
--color-primary-alpha-20: #ea580c33;
--color-primary-alpha-30: #ea580c4b;
--color-primary-alpha-40: #ea580c66;
--color-primary-alpha-50: #ea580c80;
--color-primary-alpha-60: #ea580c99;
--color-primary-alpha-70: #ea580cb3;
--color-primary-alpha-80: #ea580ccc;
--color-primary-alpha-90: #ea580ce1;
--color-secondary: var(--steel-700);
--color-secondary-dark-1: var(--steel-550);
--color-secondary-dark-2: var(--steel-500);
--color-secondary-dark-3: var(--steel-450);
--color-secondary-dark-4: var(--steel-400);
--color-secondary-dark-5: var(--steel-350);
--color-secondary-dark-6: var(--steel-300);
--color-secondary-dark-7: var(--steel-250);
--color-secondary-dark-8: var(--steel-200);
--color-secondary-dark-9: var(--steel-150);
--color-secondary-dark-10: var(--steel-100);
--color-secondary-dark-11: var(--steel-100);
--color-secondary-dark-12: var(--steel-100);
--color-secondary-dark-13: var(--steel-100);
--color-secondary-light-1: var(--steel-650);
--color-secondary-light-2: var(--steel-700);
--color-secondary-light-3: var(--steel-750);
--color-secondary-light-4: var(--steel-800);
--color-secondary-alpha-10: #2B364219;
--color-secondary-alpha-20: #2B364233;
--color-secondary-alpha-30: #2B36424b;
--color-secondary-alpha-40: #2B364266;
--color-secondary-alpha-50: #2B364280;
--color-secondary-alpha-60: #2B364299;
--color-secondary-alpha-70: #2B3642b3;
--color-secondary-alpha-80: #2B3642cc;
--color-secondary-alpha-90: #2B3642e1;
/* colors */
--color-red: #b91c1c;
--color-orange: #ea580c;
--color-yellow: #ca8a04;
--color-olive: #91a313;
--color-green: #15803d;
--color-teal: #0d9488;
--color-blue: #2563eb;
--color-violet: #7c3aed;
--color-purple: #9333ea;
--color-pink: #db2777;
--color-brown: #a47252;
--color-grey: var(--steel-500);
--color-black: #111827;
/* light variants */
--color-red-light: #dc2626;
--color-orange-light: #f97316;
--color-yellow-light: #eab308;
--color-olive-light: #839311;
--color-green-light: #16a34a;
--color-teal-light: #14b8a6;
--color-blue-light: #3b82f6;
--color-violet-light: #8b5cf6;
--color-purple-light: #a855f7;
--color-pink-light: #ec4899;
--color-brown-light: #94674a;
--color-grey-light: var(--steel-300);
--color-black-light: #1f2937;
/* other colors */
--color-gold: #b1983b;
--color-white: #ffffff;
--color-diff-removed-word-bg: #783030;
--color-diff-added-word-bg: #255C39;
--color-diff-removed-row-bg: #432121;
--color-diff-moved-row-bg: #825718;
--color-diff-added-row-bg: #1B3625;
--color-diff-removed-row-border: #783030;
--color-diff-moved-row-border: #A67A1D;
--color-diff-added-row-border: #255C39;
--color-diff-inactive: var(--steel-650);
--color-error-border: #783030;
--color-error-bg: #5F2525;
--color-error-bg-active: #783030;
--color-error-bg-hover: #783030;
--color-error-text: #fef2f2;
--color-success-border: #1F6E3C;
--color-success-bg: #1D462C;
--color-success-text: #f0fdf4;
--color-warning-border: #A67A1D;
--color-warning-bg: #644821;
--color-warning-text: #fefce8;
--color-info-border: #2E50B0;
--color-info-bg: #2A396B;
--color-info-text: var(--steel-100);
--color-red-badge: #B91C1C;
--color-red-badge-bg: #B91C1C22;
--color-red-badge-hover-bg: #B91C1C44;
--color-green-badge: #16a34a;
--color-green-badge-bg: #16a34a22;
--color-green-badge-hover-bg: #16a34a44;
--color-yellow-badge: #ca8a04;
--color-yellow-badge-bg: #ca8a0422;
--color-yellow-badge-hover-bg: #ca8a0444;
--color-orange-badge: #ea580c;
--color-orange-badge-bg: #ea580c22;
--color-orange-badge-hover-bg: #ea580c44;
--color-git: #f05133;
/* target-based colors */
--color-body: var(--steel-800);
--color-box-header: var(--steel-700);
--color-box-body: var(--steel-750);
--color-box-body-highlight: var(--steel-650);
--color-text-dark: #fff;
--color-text: var(--steel-100);
--color-text-light: var(--steel-150);
--color-text-light-1: var(--steel-150);
--color-text-light-2: var(--steel-200);
--color-text-light-3: var(--steel-200);
--color-footer: var(--steel-900);
--color-timeline: var(--steel-650);
--color-input-text: var(--steel-100);
--color-input-background: var(--steel-650);
--color-input-toggle-background: var(--steel-650);
--color-input-border: var(--steel-550);
--color-input-border-hover: var(--steel-450);
--color-header-wrapper: var(--steel-850);
--color-header-wrapper-transparent: #242D3800;
--color-light: #00000028;
--color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled)));
--color-light-border: #ffffff28;
--color-hover: var(--steel-600);
--color-active: var(--steel-650);
--color-menu: var(--steel-700);
--color-card: var(--steel-700);
--color-markup-table-row: #ffffff06;
--color-markup-code-block: var(--steel-800);
--color-button: var(--steel-600);
--color-code-bg: var(--steel-750);
--color-code-sidebar-bg: var(--steel-600);
--color-shadow: #00000060;
--color-secondary-bg: var(--steel-700);
--color-text-focus: #fff;
--color-expand-button: #3c404d;
--color-placeholder-text: var(--steel-450);
--color-editor-line-highlight: var(--steel-700);
--color-project-board-bg: var(--color-secondary-light-3);
--color-project-board-dark-label: var(--color-text-light-3);
--color-caret: var(--color-text);
/* should ideally be --color-text-dark, see #15651 */
--color-reaction-bg: #ffffff12;
--color-reaction-active-bg: var(--color-primary-alpha-30);
--color-nav-bg: var(--steel-900);
--color-nav-hover-bg: var(--steel-900);
--color-label-active-bg: #4c525e;
--color-label-text: #fff;
--color-accent: var(--color-primary-light-1);
--color-small-accent: var(--color-primary-light-5);
--color-active-line: var(--color-primary-alpha-20);
accent-color: var(--color-accent);
color-scheme: dark;
}
/* invert emojis that are hard to read otherwise */
.emoji[aria-label="check mark"],
.emoji[aria-label="currency exchange"],
.emoji[aria-label="TOP arrow"],
.emoji[aria-label="END arrow"],
.emoji[aria-label="ON! arrow"],
.emoji[aria-label="SOON arrow"],
.emoji[aria-label="heavy dollar sign"],
.emoji[aria-label="copyright"],
.emoji[aria-label="registered"],
.emoji[aria-label="trade mark"],
.emoji[aria-label="multiply"],
.emoji[aria-label="plus"],
.emoji[aria-label="minus"],
.emoji[aria-label="divide"],
.emoji[aria-label="curly loop"],
.emoji[aria-label="double curly loop"],
.emoji[aria-label="wavy dash"],
.emoji[aria-label="paw prints"],
.emoji[aria-label="musical note"],
.emoji[aria-label="musical notes"] {
filter: invert(100%) hue-rotate(180deg);
}
.following.bar.light {
border-bottom-color: #ffffff11 !important;
}
.text.green.svg {
color: #16a34a !important;
}
i.grey.icon.icon.icon.icon {
color: var(--steel-350) !important;
}
.ui.red.button,
.ui.negative.button {
background-color: #7f1d1d !important;
color: #fff !important;
border-color: var(--color-light-border) !important;
}
.ui.red.button:hover,
.ui.negative.button:hover {
background-color: #991b1b !important;
}
.ui.secondary.vertical.menu {
border-radius: 0.28571429rem !important;
overflow: hidden;
}
.ui.secondary.vertical.menu > .item {
border-radius: 0 !important;
}
.ui.basic.primary.button.item {
background-color: var(--color-active) !important;
color: var(--color-text) !important;
box-shadow: none !important;
}
.ui.red.label.notification_count,
.ui.primary.label,
.ui.primary.labels .label {
background-color: var(--color-primary-light-3) !important;
}
.repository.view.issue .comment-list .code-comment + .code-comment {
margin: 1.25rem 0 !important;
padding-top: 1.25rem !important;
border-top-color: var(--steel-650) !important;
}
.ui.labeled.icon.buttons > .button > .icon,
.ui.labeled.icon.button > .icon {
background-color: rgba(0, 0, 0, 0.05) !important;
}
#review-box .review-comments-counter {
background-color: #00000088 !important;
color: #fff !important;
margin-left: 0.5em;
}
.ui.tabs .ui.primary.label,
.ui.menu .ui.primary.label {
background-color: rgba(192, 192, 255, 0.2) !important;
color: var(--color-text-dark) !important;
}
.ui.basic.yellow.label.pending-label {
background: var(--color-light) !important;
}
.ui.tertiary.button {
color: #fff9;
}
.ui.tertiary.button:hover {
color: #ccc;
}

View file

@ -0,0 +1,251 @@
:root {
--steel-900: #10161D;
--steel-850: #131A21;
--steel-800: #171E26;
--steel-750: #1D262F;
--steel-700: #242D38;
--steel-650: #2B3642;
--steel-600: #374351;
--steel-550: #445161;
--steel-500: #515F70;
--steel-450: #5F6E80;
--steel-400: #6D7D8F;
--steel-350: #7C8C9F;
--steel-300: #8C9CAF;
--steel-250: #9DADC0;
--steel-200: #AEBED0;
--steel-150: #C0CFE0;
--steel-100: #D2E0F0;
--zinc-50: #FAFAFA;
--zinc-100: #F4F4F5;
--zinc-150: #ECECEE;
--zinc-200: #E4E4E7;
--zinc-250: #DCDCE0;
--zinc-300: #D4D4D8;
--zinc-350: #BABAC1;
--zinc-400: #A1A1AA;
--zinc-450: #898992;
--zinc-500: #71717A;
--zinc-550: #61616A;
--zinc-600: #52525B;
--zinc-650: #484850;
--zinc-700: #3F3F46;
--zinc-750: #333338;
--zinc-800: #27272A;
--zinc-850: #1F1F23;
--zinc-900: #18181B;
--color-primary: #c2410c;
--color-primary-contrast: #ffffff;
--color-primary-dark-1: #c2410c;
--color-primary-dark-2: #9a3412;
--color-primary-dark-3: #9a3412;
--color-primary-dark-4: #7c2d12;
--color-primary-dark-5: #7c2d12;
--color-primary-dark-6: #7c2d12;
--color-primary-dark-7: #7c2d12;
--color-primary-light-1: #ea580c;
--color-primary-light-2: #f97316;
--color-primary-light-3: #fb923c;
--color-primary-light-4: #fdba74;
--color-primary-light-5: #fed7aa;
--color-primary-light-6: #ffedd5;
--color-primary-light-7: #fff7ed;
--color-primary-alpha-10: #c2410c19;
--color-primary-alpha-20: #c2410c33;
--color-primary-alpha-30: #c2410c4b;
--color-primary-alpha-40: #c2410c66;
--color-primary-alpha-50: #c2410c80;
--color-primary-alpha-60: #c2410c99;
--color-primary-alpha-70: #c2410cb3;
--color-primary-alpha-80: #c2410ccc;
--color-primary-alpha-90: #c2410ce1;
--color-secondary: var(--zinc-200);
--color-secondary-dark-1: var(--zinc-200);
--color-secondary-dark-2: var(--zinc-300);
--color-secondary-dark-3: var(--zinc-300);
--color-secondary-dark-4: var(--zinc-400);
--color-secondary-dark-5: var(--zinc-400);
--color-secondary-dark-6: var(--zinc-500);
--color-secondary-dark-7: var(--zinc-500);
--color-secondary-dark-8: var(--zinc-600);
--color-secondary-dark-9: var(--zinc-600);
--color-secondary-dark-10: var(--zinc-700);
--color-secondary-dark-11: var(--zinc-700);
--color-secondary-dark-12: var(--zinc-800);
--color-secondary-dark-13: var(--zinc-800);
--color-secondary-light-1: var(--zinc-200);
--color-secondary-light-2: var(--zinc-100);
--color-secondary-light-3: var(--zinc-100);
--color-secondary-light-4: var(--zinc-50);
--color-secondary-alpha-10: #d4d4d819;
--color-secondary-alpha-20: #d4d4d833;
--color-secondary-alpha-30: #d4d4d84b;
--color-secondary-alpha-40: #d4d4d866;
--color-secondary-alpha-50: #d4d4d880;
--color-secondary-alpha-60: #d4d4d899;
--color-secondary-alpha-70: #d4d4d8b3;
--color-secondary-alpha-80: #d4d4d8cc;
--color-secondary-alpha-90: #d4d4d8e1;
/* colors */
--color-red: #dc2626;
--color-orange: #ea580c;
--color-yellow: #ca8a04;
--color-olive: #91a313;
--color-green: #15803d;
--color-teal: #0d9488;
--color-blue: #2563eb;
--color-violet: #7c3aed;
--color-purple: #9333ea;
--color-pink: #db2777;
--color-brown: #a47252;
--color-grey: #4b5563;
--color-black: #000000;
/* light variants */
--color-red-light: #ef4444;
--color-orange-light: #f97316;
--color-yellow-light: #eab308;
--color-olive-light: #839311;
--color-green-light: #16a34a;
--color-teal-light: #14b8a6;
--color-blue-light: #3b82f6;
--color-violet-light: #8b5cf6;
--color-purple-light: #a855f7;
--color-pink-light: #ec4899;
--color-brown-light: #94674a;
--color-grey-light: #6b7280;
--color-black-light: #181818;
/* other colors */
--color-gold: #b1983b;
--color-white: #ffffff;
--color-diff-removed-word-bg: #fca5a5;
--color-diff-added-word-bg: #86efac;
--color-diff-removed-row-bg: #fee2e2;
--color-diff-moved-row-bg: #fef9c3;
--color-diff-added-row-bg: #dcfce7;
--color-diff-removed-row-border: #fca5a5;
--color-diff-moved-row-border: #fde047;
--color-diff-added-row-border: #86efac;
--color-diff-inactive: var(--zinc-100);
--color-error-border: #fecaca;
--color-error-bg: #fee2e2;
--color-error-bg-active: #fca5a5;
--color-error-bg-hover: #fecaca;
--color-error-text: #7f1d1d;
--color-success-border: #bbf7d0;
--color-success-bg: #dcfce7;
--color-success-text: #14532d;
--color-warning-border: #fde047;
--color-warning-bg: #fef3c7;
--color-warning-text: #78350f;
--color-info-border: #bae6fd;
--color-info-bg: #e0f2fe;
--color-info-text: #0c4a6e;
--color-red-badge: #B91C1C;
--color-red-badge-bg: #B91C1C22;
--color-red-badge-hover-bg: #B91C1C44;
--color-green-badge: #16a34a;
--color-green-badge-bg: #16a34a22;
--color-green-badge-hover-bg: #16a34a44;
--color-yellow-badge: #ca8a04;
--color-yellow-badge-bg: #ca8a0422;
--color-yellow-badge-hover-bg: #ca8a0444;
--color-orange-badge: #ea580c;
--color-orange-badge-bg: #ea580c22;
--color-orange-badge-hover-bg: #ea580c44;
--color-git: #f05133;
/* target-based colors */
--color-body: #fff;
--color-box-header: var(--zinc-100);
--color-box-body: var(--zinc-50);
--color-box-body-highlight: var(--zinc-200);
--color-text-dark: #000;
--color-text: var(--zinc-900);
--color-text-light: var(--zinc-700);
--color-text-light-1: var(--zinc-650);
--color-text-light-2: var(--zinc-600);
--color-text-light-3: var(--zinc-550);
--color-footer: var(--zinc-100);
--color-timeline: var(--zinc-200);
--color-input-text: var(--zinc-800);
--color-input-background: #fff;
--color-input-toggle-background: #fff;
--color-input-border: var(--zinc-300);
--color-input-border-hover: var(--zinc-400);
--color-header-wrapper: var(--zinc-50);
--color-header-wrapper-transparent: #D2E0F000;
--color-light: #ffffffcc;
--color-light-mimic-enabled: rgba(0, 0, 0, calc(6 / 255 * 222 / 255 / var(--opacity-disabled)));
--color-light-border: #0000001d;
--color-hover: #e4e4e4aa;
--color-active: #d4d4d8aa;
--color-menu: var(--zinc-100);
--color-card: var(--zinc-50);
--color-markup-table-row: #ffffff06;
--color-markup-code-block: var(--zinc-150);
--color-button: var(--zinc-150);
--color-code-bg: var(--zinc-50);
--color-code-sidebar-bg: var(--zinc-100);
--color-shadow: #00000060;
--color-secondary-bg: var(--zinc-100);
--color-text-focus: #fff;
--color-expand-button: var(--zinc-200);
--color-placeholder-text: var(--zinc-400);
--color-editor-line-highlight: var(--zinc-100);
--color-project-board-bg: var(--color-secondary-light-2);
--color-project-board-dark-label: var(--color-text-light-3);
--color-caret: var(--color-text);
/* should ideally be --color-text-dark, see #15651 */
--color-reaction-bg: #0000000a;
--color-reaction-active-bg: var(--color-primary-alpha-20);
--color-nav-bg: var(--zinc-100);
--color-nav-hover-bg: var(--zinc-100);
--color-label-active-bg: #4c525e;
--color-accent: var(--color-primary-light-1);
--color-small-accent: var(--color-primary-light-5);
--color-active-line: var(--color-primary-light-6);
accent-color: var(--color-accent);
color-scheme: light;
}
.text.green.svg {
color: #16a34a !important;
}
.ui.secondary.vertical.menu {
border-radius: 0.28571429rem !important;
overflow: hidden;
}
.ui.secondary.vertical.menu > .item {
border-radius: 0 !important;
}
.ui.basic.primary.button.item {
background-color: var(--color-active) !important;
color: var(--color-text) !important;
box-shadow: none !important;
}
.ui.red.label.notification_count,
.ui.primary.labels .label {
background-color: var(--color-primary-dark-1) !important;
}
.repository.view.issue .comment-list .code-comment + .code-comment {
margin: 1.25rem 0 !important;
padding-top: 1.25rem !important;
border-top-color: var(--zinc-250) !important;
}
.ui.labeled.icon.buttons > .button > .icon,
.ui.labeled.icon.button > .icon {
background-color: rgba(0, 0, 0, 0.05) !important;
}
#review-box .review-comments-counter {
background-color: #ffffffaa !important;
color: #000 !important;
margin-left: 0.5em;
}
.ui.tabs .ui.primary.label,
.ui.menu .ui.primary.label {
background-color: rgba(0, 0, 0, 0.15) !important;
color: var(--color-text-dark) !important;
}
.ui.basic.yellow.label.pending-label {
background: var(--color-warning-bg) !important;
color: var(--color-warning-text) !important;
border-color: #eab308 !important;
}

View file

@ -14,8 +14,8 @@ export function initInstall() {
} }
function initPreInstall() { function initPreInstall() {
const defaultDbUser = 'gitea'; const defaultDbUser = 'forgejo';
const defaultDbName = 'gitea'; const defaultDbName = 'forgejo';
const defaultDbHosts = { const defaultDbHosts = {
mysql: '127.0.0.1:3306', mysql: '127.0.0.1:3306',