Skip to content

Commit 747378b

Browse files
committed
Merge branch 'main' of https://github.com/go-gitea/gitea into fix-26130
2 parents 48912a6 + c1c83db commit 747378b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+792
-234
lines changed

cmd/main.go

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package cmd
66
import (
77
"fmt"
88
"os"
9-
"reflect"
109
"strings"
1110

1211
"code.gitea.io/gitea/modules/log"
@@ -58,7 +57,6 @@ func appGlobalFlags() []cli.Flag {
5857
return []cli.Flag{
5958
// make the builtin flags at the top
6059
helpFlag,
61-
cli.VersionFlag,
6260

6361
// shared configuration flags, they are for global and for each sub-command at the same time
6462
// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
@@ -120,38 +118,12 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context)
120118
}
121119
}
122120

123-
func reflectGet(v any, fieldName string) any {
124-
e := reflect.ValueOf(v).Elem()
125-
return e.FieldByName(fieldName).Interface()
126-
}
127-
128-
// https://cli.urfave.org/migrate-v1-to-v2/#flag-aliases-are-done-differently
129-
// Sadly v2 doesn't warn you if a comma is in the name. (https://github.com/urfave/cli/issues/1103)
130-
func checkCommandFlags(c any) bool {
131-
var cmds []*cli.Command
132-
if app, ok := c.(*cli.App); ok {
133-
cmds = app.Commands
134-
} else {
135-
cmds = c.(*cli.Command).Subcommands
136-
}
137-
ok := true
138-
for _, cmd := range cmds {
139-
for _, flag := range cmd.Flags {
140-
flagName := reflectGet(flag, "Name").(string)
141-
if strings.Contains(flagName, ",") {
142-
ok = false
143-
log.Error("cli.Flag can't have comma in its Name: %q, use Aliases instead", flagName)
144-
}
145-
}
146-
if !checkCommandFlags(cmd) {
147-
ok = false
148-
}
149-
}
150-
return ok
151-
}
152-
153-
func NewMainApp() *cli.App {
121+
func NewMainApp(version, versionExtra string) *cli.App {
154122
app := cli.NewApp()
123+
app.Name = "Gitea"
124+
app.Usage = "A painless self-hosted Git service"
125+
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".`
126+
app.Version = version + versionExtra
155127
app.EnableBashCompletion = true
156128

157129
// these sub-commands need to use config file
@@ -187,6 +159,7 @@ func NewMainApp() *cli.App {
187159
app.DefaultCommand = CmdWeb.Name
188160

189161
globalFlags := appGlobalFlags()
162+
app.Flags = append(app.Flags, cli.VersionFlag)
190163
app.Flags = append(app.Flags, globalFlags...)
191164
app.HideHelp = true // use our own help action to show helps (with more information like default config)
192165
app.Before = PrepareConsoleLoggerLevel(log.INFO)
@@ -196,8 +169,20 @@ func NewMainApp() *cli.App {
196169
app.Commands = append(app.Commands, subCmdWithConfig...)
197170
app.Commands = append(app.Commands, subCmdStandalone...)
198171

199-
if !checkCommandFlags(app) {
200-
panic("some flags are incorrect") // this is a runtime check to help developers
201-
}
202172
return app
203173
}
174+
175+
func RunMainApp(app *cli.App, args ...string) error {
176+
err := app.Run(args)
177+
if err == nil {
178+
return nil
179+
}
180+
if strings.HasPrefix(err.Error(), "flag provided but not defined:") {
181+
// the cli package should already have output the error message, so just exit
182+
cli.OsExiter(1)
183+
return err
184+
}
185+
_, _ = fmt.Fprintf(app.ErrWriter, "Command error: %v\n", err)
186+
cli.OsExiter(1)
187+
return err
188+
}

cmd/main_test.go

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ package cmd
55

66
import (
77
"fmt"
8+
"io"
89
"os"
910
"path/filepath"
1011
"strings"
1112
"testing"
1213

1314
"code.gitea.io/gitea/models/unittest"
1415
"code.gitea.io/gitea/modules/setting"
16+
"code.gitea.io/gitea/modules/test"
1517

1618
"github.com/stretchr/testify/assert"
1719
"github.com/urfave/cli/v2"
@@ -27,21 +29,38 @@ func makePathOutput(workPath, customPath, customConf string) string {
2729
return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
2830
}
2931

30-
func newTestApp() *cli.App {
31-
app := NewMainApp()
32-
testCmd := &cli.Command{
33-
Name: "test-cmd",
34-
Action: func(ctx *cli.Context) error {
35-
_, _ = fmt.Fprint(app.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
36-
return nil
37-
},
38-
}
32+
func newTestApp(testCmdAction func(ctx *cli.Context) error) *cli.App {
33+
app := NewMainApp("version", "version-extra")
34+
testCmd := &cli.Command{Name: "test-cmd", Action: testCmdAction}
3935
prepareSubcommandWithConfig(testCmd, appGlobalFlags())
4036
app.Commands = append(app.Commands, testCmd)
4137
app.DefaultCommand = testCmd.Name
4238
return app
4339
}
4440

41+
type runResult struct {
42+
Stdout string
43+
Stderr string
44+
ExitCode int
45+
}
46+
47+
func runTestApp(app *cli.App, args ...string) (runResult, error) {
48+
outBuf := new(strings.Builder)
49+
errBuf := new(strings.Builder)
50+
app.Writer = outBuf
51+
app.ErrWriter = errBuf
52+
exitCode := -1
53+
defer test.MockVariableValue(&cli.ErrWriter, app.ErrWriter)()
54+
defer test.MockVariableValue(&cli.OsExiter, func(code int) {
55+
if exitCode == -1 {
56+
exitCode = code // save the exit code once and then reset the writer (to simulate the exit)
57+
app.Writer, app.ErrWriter, cli.ErrWriter = io.Discard, io.Discard, io.Discard
58+
}
59+
})()
60+
err := RunMainApp(app, args...)
61+
return runResult{outBuf.String(), errBuf.String(), exitCode}, err
62+
}
63+
4564
func TestCliCmd(t *testing.T) {
4665
defaultWorkPath := filepath.Dir(setting.AppPath)
4766
defaultCustomPath := filepath.Join(defaultWorkPath, "custom")
@@ -92,7 +111,10 @@ func TestCliCmd(t *testing.T) {
92111
},
93112
}
94113

95-
app := newTestApp()
114+
app := newTestApp(func(ctx *cli.Context) error {
115+
_, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
116+
return nil
117+
})
96118
var envBackup []string
97119
for _, s := range os.Environ() {
98120
if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") {
@@ -120,12 +142,39 @@ func TestCliCmd(t *testing.T) {
120142
_ = os.Setenv(k, v)
121143
}
122144
args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
123-
out := new(strings.Builder)
124-
app.Writer = out
125-
err := app.Run(args)
145+
r, err := runTestApp(app, args...)
126146
assert.NoError(t, err, c.cmd)
127147
assert.NotEmpty(t, c.exp, c.cmd)
128-
outStr := out.String()
129-
assert.Contains(t, outStr, c.exp, c.cmd)
148+
assert.Contains(t, r.Stdout, c.exp, c.cmd)
130149
}
131150
}
151+
152+
func TestCliCmdError(t *testing.T) {
153+
app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") })
154+
r, err := runTestApp(app, "./gitea", "test-cmd")
155+
assert.Error(t, err)
156+
assert.Equal(t, 1, r.ExitCode)
157+
assert.Equal(t, "", r.Stdout)
158+
assert.Equal(t, "Command error: normal error\n", r.Stderr)
159+
160+
app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) })
161+
r, err = runTestApp(app, "./gitea", "test-cmd")
162+
assert.Error(t, err)
163+
assert.Equal(t, 2, r.ExitCode)
164+
assert.Equal(t, "", r.Stdout)
165+
assert.Equal(t, "exit error\n", r.Stderr)
166+
167+
app = newTestApp(func(ctx *cli.Context) error { return nil })
168+
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
169+
assert.Error(t, err)
170+
assert.Equal(t, 1, r.ExitCode)
171+
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout)
172+
assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr ....
173+
174+
app = newTestApp(func(ctx *cli.Context) error { return nil })
175+
r, err = runTestApp(app, "./gitea", "test-cmd")
176+
assert.NoError(t, err)
177+
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
178+
assert.Equal(t, "", r.Stdout)
179+
assert.Equal(t, "", r.Stderr)
180+
}

cmd/web.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,18 @@ func createPIDFile(pidPath string) {
107107
}
108108
}
109109

110-
func serveInstall(ctx *cli.Context) error {
110+
func showWebStartupMessage(msg string) {
111111
log.Info("Gitea version: %s%s", setting.AppVer, setting.AppBuiltWith)
112-
log.Info("App path: %s", setting.AppPath)
113-
log.Info("Work path: %s", setting.AppWorkPath)
114-
log.Info("Custom path: %s", setting.CustomPath)
115-
log.Info("Config file: %s", setting.CustomConf)
116-
log.Info("Prepare to run install page")
112+
log.Info("* RunMode: %s", setting.RunMode)
113+
log.Info("* AppPath: %s", setting.AppPath)
114+
log.Info("* WorkPath: %s", setting.AppWorkPath)
115+
log.Info("* CustomPath: %s", setting.CustomPath)
116+
log.Info("* ConfigFile: %s", setting.CustomConf)
117+
log.Info("%s", msg)
118+
}
119+
120+
func serveInstall(ctx *cli.Context) error {
121+
showWebStartupMessage("Prepare to run install page")
117122

118123
routers.InitWebInstallPage(graceful.GetManager().HammerContext())
119124

@@ -150,29 +155,24 @@ func serveInstalled(ctx *cli.Context) error {
150155
setting.LoadCommonSettings()
151156
setting.MustInstalled()
152157

153-
log.Info("Gitea version: %s%s", setting.AppVer, setting.AppBuiltWith)
154-
log.Info("App path: %s", setting.AppPath)
155-
log.Info("Work path: %s", setting.AppWorkPath)
156-
log.Info("Custom path: %s", setting.CustomPath)
157-
log.Info("Config file: %s", setting.CustomConf)
158-
log.Info("Run mode: %s", setting.RunMode)
159-
log.Info("Prepare to run web server")
158+
showWebStartupMessage("Prepare to run web server")
160159

161160
if setting.AppWorkPathMismatch {
162161
log.Error("WORK_PATH from config %q doesn't match other paths from environment variables or command arguments. "+
163-
"Only WORK_PATH in config should be set and used. Please remove the other outdated work paths from environment variables and command arguments", setting.CustomConf)
162+
"Only WORK_PATH in config should be set and used. Please make sure the path in config file is correct, "+
163+
"remove the other outdated work paths from environment variables and command arguments", setting.CustomConf)
164164
}
165165

166166
rootCfg := setting.CfgProvider
167167
if rootCfg.Section("").Key("WORK_PATH").String() == "" {
168168
saveCfg, err := rootCfg.PrepareSaving()
169169
if err != nil {
170-
log.Error("Unable to prepare saving WORK_PATH=%s to config %q: %v\nYou must set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err)
170+
log.Error("Unable to prepare saving WORK_PATH=%s to config %q: %v\nYou should set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err)
171171
} else {
172172
rootCfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath)
173173
saveCfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath)
174174
if err = saveCfg.Save(); err != nil {
175-
log.Error("Unable to update WORK_PATH=%s to config %q: %v\nYou must set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err)
175+
log.Error("Unable to update WORK_PATH=%s to config %q: %v\nYou should set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err)
176176
}
177177
}
178178
}

docs/content/usage/actions/act-runner.en-us.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ You can find more useful images on [act images](https://github.com/nektos/act/bl
245245
If you want to run jobs in the host directly, you can change it to `ubuntu-22.04:host` or just `ubuntu-22.04`, the `:host` is optional.
246246
However, we suggest you to use a special name like `linux_amd64:host` or `windows:host` to avoid misusing it.
247247

248-
One more thing is that it is recommended to register the runner if you want to change the labels.
249-
It may be annoying to do this, so we may provide a better way to do it in the future.
248+
Starting with Gitea 1.21, you can change labels by modifying `container.labels` in the runner configuration file (if you don't have a configuration file, please refer to [configuration tutorials](#configuration)).
249+
The runner will use these new labels as soon as you restart it, i.e., by calling `./act_runner daemon --config config.yaml`.
250250

251251
## Running
252252

@@ -261,3 +261,34 @@ After you have registered the runner, you can run it by running the following co
261261
The runner will fetch jobs from the Gitea instance and run them automatically.
262262

263263
Since act runner is still in development, it is recommended to check the latest version and upgrade it regularly.
264+
265+
## Configuration variable
266+
267+
You can create configuration variables on the user, organization and repository level.
268+
The level of the variable depends on where you created it.
269+
270+
### Naming conventions
271+
272+
The following rules apply to variable names:
273+
274+
- Variable names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed.
275+
276+
- Variable names must not start with the `GITHUB_` and `GITEA_` prefix.
277+
278+
- Variable names must not start with a number.
279+
280+
- Variable names are case-insensitive.
281+
282+
- Variable names must be unique at the level they are created at.
283+
284+
- Variable names must not be `CI`.
285+
286+
### Using variable
287+
288+
After creating configuration variables, they will be automatically filled in the `vars` context.
289+
They can be accessed through expressions like `{{ vars.VARIABLE_NAME }}` in the workflow.
290+
291+
### Precedence
292+
293+
If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence:
294+
A repository variable will always be chosen over an organization/user variable.

docs/content/usage/actions/act-runner.zh-cn.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们
241241
如果您想直接在主机上运行Job,您可以将其更改为`ubuntu-22.04:host`或仅`ubuntu-22.04`,`:host`是可选的。
242242
然而,我们建议您使用类似`linux_amd64:host`或`windows:host`的特殊名称,以避免误用。
243243

244-
还有一点需要注意的是,建议在更改标签时注册Runner。
245-
这可能会有些麻烦,所以我们可能会在将来提供更好的方法来处理。
244+
从 Gitea 1.21 开始,您可以通过修改 runner 的配置文件中的 `container.labels` 来更改标签(如果没有配置文件,请参考 [配置教程](#配置)),通过执行 `./act_runner daemon --config config.yaml` 命令重启 runner 之后,这些新定义的标签就会生效。
246245

247246
## 运行
248247

@@ -257,3 +256,32 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们
257256
Runner将从Gitea实例获取Job并自动运行它们。
258257

259258
由于Act Runner仍处于开发中,建议定期检查最新版本并进行升级。
259+
260+
## 变量
261+
262+
您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。
263+
264+
### 命名规则
265+
266+
以下规则适用于变量名:
267+
268+
- 变量名称只能包含字母数字字符 (`[a-z]`, `[A-Z]`, `[0-9]`) 或下划线 (`_`)。不允许使用空格。
269+
270+
- 变量名称不能以 `GITHUB_` 和 `GITEA_` 前缀开头。
271+
272+
- 变量名称不能以数字开头。
273+
274+
- 变量名称不区分大小写。
275+
276+
- 变量名称在创建它们的级别上必须是唯一的。
277+
278+
- 变量名称不能为 “CI”。
279+
280+
### 使用
281+
282+
创建配置变量后,它们将自动填充到 `vars` 上下文中。您可以在工作流中使用类似 `{{ vars.VARIABLE_NAME }}` 这样的表达式来使用它们。
283+
284+
### 优先级
285+
286+
如果同名变量存在于多个级别,则级别最低的变量优先。
287+
仓库级别的变量总是比组织或者用户级别的变量优先被选中。

docs/content/usage/actions/quickstart.zh-cn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ jobs:
127127

128128
请注意,演示文件中包含一些表情符号。
129129
请确保您的数据库支持它们,特别是在使用MySQL时。
130-
如果字符集不是`utf8mb4,将出现错误,例如`Error 1366 (HY000): Incorrect string value: '\\xF0\\x9F\\x8E\\x89 T...' for column 'name' at row 1`。
130+
如果字符集不是`utf8mb4`,将出现错误,例如`Error 1366 (HY000): Incorrect string value: '\\xF0\\x9F\\x8E\\x89 T...' for column 'name' at row 1`。
131131
有关更多信息,请参阅[数据库准备工作](installation/database-preparation.md#mysql)。
132132

133133
或者,您可以从演示文件中删除所有表情符号,然后再尝试一次。

docs/content/usage/agit-support.en-us.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ In Gitea `1.13`, support for [agit](https://git-repo.info/en/2020/03/agit-flow-a
2121

2222
## Creating PRs with Agit
2323

24-
Agit allows to create PRs while pushing code to the remote repo. \
25-
This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git). \
24+
Agit allows to create PRs while pushing code to the remote repo.
25+
This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git).
2626
The following example illustrates this:
2727

2828
```shell

0 commit comments

Comments
 (0)