Skip to content

Commit a9ed1ec

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix updating user visibility (go-gitea#35036) Fix git commit committer parsing and add some tests (go-gitea#35007) Refactor OpenIDConnect to support SSH/FullName sync (go-gitea#34978) Support base64-encoded agit push options (go-gitea#35037) Also display "recently pushed branch" alert on PR view (go-gitea#35001) Make submodule link work with relative path (go-gitea#35034) Update to go 1.24.5 (go-gitea#35031) Improve CLI commands (go-gitea#34973) Tweak eslint config, fix new issues (go-gitea#35019) # Conflicts: # templates/repo/commits_list.tmpl
2 parents 8636bf7 + b46623f commit a9ed1ec

Some content is hidden

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

69 files changed

+860
-571
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ module.exports = {
326326
'@typescript-eslint/no-unnecessary-type-arguments': [0],
327327
'@typescript-eslint/no-unnecessary-type-assertion': [2],
328328
'@typescript-eslint/no-unnecessary-type-constraint': [2],
329+
'@typescript-eslint/no-unnecessary-type-conversion': [2],
329330
'@typescript-eslint/no-unsafe-argument': [0],
330331
'@typescript-eslint/no-unsafe-assignment': [0],
331332
'@typescript-eslint/no-unsafe-call': [0],
@@ -645,7 +646,7 @@ module.exports = {
645646
'no-multi-str': [2],
646647
'no-negated-condition': [0],
647648
'no-nested-ternary': [0],
648-
'no-new-func': [2],
649+
'no-new-func': [0], // handled by @typescript-eslint/no-implied-eval
649650
'no-new-native-nonconstructor': [2],
650651
'no-new-object': [2],
651652
'no-new-symbol': [2],

Dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
3939
/tmp/local/etc/s6/.s6-svscan/* \
4040
/go/src/code.gitea.io/gitea/gitea \
4141
/go/src/code.gitea.io/gitea/environment-to-ini
42-
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
4342

4443
FROM docker.io/library/alpine:3.22
4544
LABEL maintainer="[email protected]"
@@ -83,4 +82,3 @@ CMD ["/usr/bin/s6-svscan", "/etc/s6"]
8382
COPY --from=build-env /tmp/local /
8483
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
8584
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
86-
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

Dockerfile.rootless

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
3737
/tmp/local/usr/local/bin/gitea \
3838
/go/src/code.gitea.io/gitea/gitea \
3939
/go/src/code.gitea.io/gitea/environment-to-ini
40-
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
4140

4241
FROM docker.io/library/alpine:3.22
4342
LABEL maintainer="[email protected]"
@@ -72,7 +71,6 @@ RUN chown git:git /var/lib/gitea /etc/gitea
7271
COPY --from=build-env /tmp/local /
7372
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
7473
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
75-
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
7674

7775
# git:git
7876
USER 1000:1000

cmd/admin_auth_oauth.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ func oauthCLIFlags() []cli.Flag {
8787
Value: nil,
8888
Usage: "Scopes to request when to authenticate against this OAuth2 source",
8989
},
90+
&cli.StringFlag{
91+
Name: "ssh-public-key-claim-name",
92+
Usage: "Claim name that provides SSH public keys",
93+
},
94+
&cli.StringFlag{
95+
Name: "full-name-claim-name",
96+
Usage: "Claim name that provides user's full name",
97+
},
9098
&cli.StringFlag{
9199
Name: "required-claim-name",
92100
Value: "",
@@ -177,6 +185,8 @@ func parseOAuth2Config(c *cli.Command) *oauth2.Source {
177185
RestrictedGroup: c.String("restricted-group"),
178186
GroupTeamMap: c.String("group-team-map"),
179187
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
188+
SSHPublicKeyClaimName: c.String("ssh-public-key-claim-name"),
189+
FullNameClaimName: c.String("full-name-claim-name"),
180190
}
181191
}
182192

@@ -268,6 +278,12 @@ func (a *authService) runUpdateOauth(ctx context.Context, c *cli.Command) error
268278
if c.IsSet("group-team-map-removal") {
269279
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
270280
}
281+
if c.IsSet("ssh-public-key-claim-name") {
282+
oAuth2Config.SSHPublicKeyClaimName = c.String("ssh-public-key-claim-name")
283+
}
284+
if c.IsSet("full-name-claim-name") {
285+
oAuth2Config.FullNameClaimName = c.String("full-name-claim-name")
286+
}
271287

272288
// update custom URL mapping
273289
customURLMapping := &oauth2.CustomURLMapping{}

cmd/admin_auth_oauth_test.go

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ func TestAddOauth(t *testing.T) {
8888
"--restricted-group", "restricted",
8989
"--group-team-map", `{"group1": [1,2]}`,
9090
"--group-team-map-removal=true",
91+
"--ssh-public-key-claim-name", "attr_ssh_pub_key",
92+
"--full-name-claim-name", "attr_full_name",
9193
},
9294
source: &auth_model.Source{
9395
Type: auth_model.OAuth2,
@@ -104,15 +106,17 @@ func TestAddOauth(t *testing.T) {
104106
EmailURL: "https://example.com/email",
105107
Tenant: "some_tenant",
106108
},
107-
IconURL: "https://example.com/icon",
108-
Scopes: []string{"scope1", "scope2"},
109-
RequiredClaimName: "claim_name",
110-
RequiredClaimValue: "claim_value",
111-
GroupClaimName: "group_name",
112-
AdminGroup: "admin",
113-
RestrictedGroup: "restricted",
114-
GroupTeamMap: `{"group1": [1,2]}`,
115-
GroupTeamMapRemoval: true,
109+
IconURL: "https://example.com/icon",
110+
Scopes: []string{"scope1", "scope2"},
111+
RequiredClaimName: "claim_name",
112+
RequiredClaimValue: "claim_value",
113+
GroupClaimName: "group_name",
114+
AdminGroup: "admin",
115+
RestrictedGroup: "restricted",
116+
GroupTeamMap: `{"group1": [1,2]}`,
117+
GroupTeamMapRemoval: true,
118+
SSHPublicKeyClaimName: "attr_ssh_pub_key",
119+
FullNameClaimName: "attr_full_name",
116120
},
117121
TwoFactorPolicy: "skip",
118122
},
@@ -223,15 +227,17 @@ func TestUpdateOauth(t *testing.T) {
223227
EmailURL: "https://old.example.com/email",
224228
Tenant: "old_tenant",
225229
},
226-
IconURL: "https://old.example.com/icon",
227-
Scopes: []string{"old_scope1", "old_scope2"},
228-
RequiredClaimName: "old_claim_name",
229-
RequiredClaimValue: "old_claim_value",
230-
GroupClaimName: "old_group_name",
231-
AdminGroup: "old_admin",
232-
RestrictedGroup: "old_restricted",
233-
GroupTeamMap: `{"old_group1": [1,2]}`,
234-
GroupTeamMapRemoval: true,
230+
IconURL: "https://old.example.com/icon",
231+
Scopes: []string{"old_scope1", "old_scope2"},
232+
RequiredClaimName: "old_claim_name",
233+
RequiredClaimValue: "old_claim_value",
234+
GroupClaimName: "old_group_name",
235+
AdminGroup: "old_admin",
236+
RestrictedGroup: "old_restricted",
237+
GroupTeamMap: `{"old_group1": [1,2]}`,
238+
GroupTeamMapRemoval: true,
239+
SSHPublicKeyClaimName: "old_ssh_pub_key",
240+
FullNameClaimName: "old_full_name",
235241
},
236242
TwoFactorPolicy: "",
237243
},
@@ -257,6 +263,8 @@ func TestUpdateOauth(t *testing.T) {
257263
"--restricted-group", "restricted",
258264
"--group-team-map", `{"group1": [1,2]}`,
259265
"--group-team-map-removal=false",
266+
"--ssh-public-key-claim-name", "new_ssh_pub_key",
267+
"--full-name-claim-name", "new_full_name",
260268
},
261269
authSource: &auth_model.Source{
262270
ID: 1,
@@ -274,15 +282,17 @@ func TestUpdateOauth(t *testing.T) {
274282
EmailURL: "https://example.com/email",
275283
Tenant: "new_tenant",
276284
},
277-
IconURL: "https://example.com/icon",
278-
Scopes: []string{"scope1", "scope2"},
279-
RequiredClaimName: "claim_name",
280-
RequiredClaimValue: "claim_value",
281-
GroupClaimName: "group_name",
282-
AdminGroup: "admin",
283-
RestrictedGroup: "restricted",
284-
GroupTeamMap: `{"group1": [1,2]}`,
285-
GroupTeamMapRemoval: false,
285+
IconURL: "https://example.com/icon",
286+
Scopes: []string{"scope1", "scope2"},
287+
RequiredClaimName: "claim_name",
288+
RequiredClaimValue: "claim_value",
289+
GroupClaimName: "group_name",
290+
AdminGroup: "admin",
291+
RestrictedGroup: "restricted",
292+
GroupTeamMap: `{"group1": [1,2]}`,
293+
GroupTeamMapRemoval: false,
294+
SSHPublicKeyClaimName: "new_ssh_pub_key",
295+
FullNameClaimName: "new_full_name",
286296
},
287297
TwoFactorPolicy: "skip",
288298
},

cmd/hook.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var (
3232
CmdHook = &cli.Command{
3333
Name: "hook",
3434
Usage: "(internal) Should only be called by Git",
35+
Hidden: true, // internal commands shouldn't be visible
3536
Description: "Delegate commands to corresponding Git hooks",
3637
Before: PrepareConsoleLoggerLevel(log.FATAL),
3738
Commands: []*cli.Command{

cmd/keys.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
var CmdKeys = &cli.Command{
2020
Name: "keys",
2121
Usage: "(internal) Should only be called by SSH server",
22+
Hidden: true, // internal commands shouldn't not be visible
2223
Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint",
2324
Before: PrepareConsoleLoggerLevel(log.FATAL),
2425
Action: runKeys,

cmd/main.go

Lines changed: 64 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package cmd
66
import (
77
"context"
88
"fmt"
9+
"io"
910
"os"
1011
"strings"
1112

@@ -15,102 +16,63 @@ import (
1516
"github.com/urfave/cli/v3"
1617
)
1718

18-
// cmdHelp is our own help subcommand with more information
19-
// Keep in mind that the "./gitea help"(subcommand) is different from "./gitea --help"(flag), the flag doesn't parse the config or output "DEFAULT CONFIGURATION:" information
20-
func cmdHelp() *cli.Command {
21-
c := &cli.Command{
22-
Name: "help",
23-
Aliases: []string{"h"},
24-
Usage: "Shows a list of commands or help for one command",
25-
ArgsUsage: "[command]",
26-
Action: func(ctx context.Context, c *cli.Command) (err error) {
27-
lineage := c.Lineage() // The order is from child to parent: help, doctor, Gitea
28-
targetCmdIdx := 0
29-
if c.Name == "help" {
30-
targetCmdIdx = 1
31-
}
32-
if lineage[targetCmdIdx] != lineage[targetCmdIdx].Root() {
33-
err = cli.ShowCommandHelp(ctx, lineage[targetCmdIdx+1] /* parent cmd */, lineage[targetCmdIdx].Name /* sub cmd */)
34-
} else {
35-
err = cli.ShowAppHelp(c)
36-
}
37-
_, _ = fmt.Fprintf(c.Root().Writer, `
19+
var cliHelpPrinterOld = cli.HelpPrinter
20+
21+
func init() {
22+
cli.HelpPrinter = cliHelpPrinterNew
23+
}
24+
25+
// cliHelpPrinterNew helps to print "DEFAULT CONFIGURATION" for the following cases ( "-c" can apper in any position):
26+
// * ./gitea -c /dev/null -h
27+
// * ./gitea -c help /dev/null help
28+
// * ./gitea help -c /dev/null
29+
// * ./gitea help -c /dev/null web
30+
// * ./gitea help web -c /dev/null
31+
// * ./gitea web help -c /dev/null
32+
// * ./gitea web -h -c /dev/null
33+
func cliHelpPrinterNew(out io.Writer, templ string, data any) {
34+
cmd, _ := data.(*cli.Command)
35+
if cmd != nil {
36+
prepareWorkPathAndCustomConf(cmd)
37+
}
38+
cliHelpPrinterOld(out, templ, data)
39+
if setting.CustomConf != "" {
40+
_, _ = fmt.Fprintf(out, `
3841
DEFAULT CONFIGURATION:
3942
AppPath: %s
4043
WorkPath: %s
4144
CustomPath: %s
4245
ConfigFile: %s
4346
4447
`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
45-
return err
46-
},
4748
}
48-
return c
4949
}
5050

51-
func appGlobalFlags() []cli.Flag {
52-
return []cli.Flag{
53-
// make the builtin flags at the top
54-
cli.HelpFlag,
55-
56-
// shared configuration flags, they are for global and for each sub-command at the same time
57-
// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
58-
// keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
59-
&cli.StringFlag{
60-
Name: "custom-path",
61-
Aliases: []string{"C"},
62-
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
63-
},
64-
&cli.StringFlag{
65-
Name: "config",
66-
Aliases: []string{"c"},
67-
Value: setting.CustomConf,
68-
Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
69-
},
70-
&cli.StringFlag{
71-
Name: "work-path",
72-
Aliases: []string{"w"},
73-
Usage: "Set Gitea's working path (defaults to the Gitea's binary directory)",
74-
},
51+
func prepareSubcommandWithGlobalFlags(originCmd *cli.Command) {
52+
originBefore := originCmd.Before
53+
originCmd.Before = func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
54+
prepareWorkPathAndCustomConf(cmd)
55+
if originBefore != nil {
56+
return originBefore(ctx, cmd)
57+
}
58+
return ctx, nil
7559
}
7660
}
7761

78-
func prepareSubcommandWithGlobalFlags(command *cli.Command) {
79-
command.Flags = append(append([]cli.Flag{}, appGlobalFlags()...), command.Flags...)
80-
command.Action = prepareWorkPathAndCustomConf(command.Action)
81-
command.HideHelp = true
82-
if command.Name != "help" {
83-
command.Commands = append(command.Commands, cmdHelp())
62+
// prepareWorkPathAndCustomConf tries to prepare the work path, custom path and custom config from various inputs:
63+
// command line flags, environment variables, config file
64+
func prepareWorkPathAndCustomConf(cmd *cli.Command) {
65+
var args setting.ArgWorkPathAndCustomConf
66+
if cmd.IsSet("work-path") {
67+
args.WorkPath = cmd.String("work-path")
8468
}
85-
for i := range command.Commands {
86-
prepareSubcommandWithGlobalFlags(command.Commands[i])
69+
if cmd.IsSet("custom-path") {
70+
args.CustomPath = cmd.String("custom-path")
8771
}
88-
}
89-
90-
// prepareWorkPathAndCustomConf wraps the Action to prepare the work path and custom config
91-
// It can't use "Before", because each level's sub-command's Before will be called one by one, so the "init" would be done multiple times
92-
func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(context.Context, *cli.Command) error {
93-
return func(ctx context.Context, cmd *cli.Command) error {
94-
var args setting.ArgWorkPathAndCustomConf
95-
// from children to parent, check the global flags
96-
for _, curCtx := range cmd.Lineage() {
97-
if curCtx.IsSet("work-path") && args.WorkPath == "" {
98-
args.WorkPath = curCtx.String("work-path")
99-
}
100-
if curCtx.IsSet("custom-path") && args.CustomPath == "" {
101-
args.CustomPath = curCtx.String("custom-path")
102-
}
103-
if curCtx.IsSet("config") && args.CustomConf == "" {
104-
args.CustomConf = curCtx.String("config")
105-
}
106-
}
107-
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
108-
if cmd.Bool("help") || action == nil {
109-
// the default behavior of "urfave/cli": "nil action" means "show help"
110-
return cmdHelp().Action(ctx, cmd)
111-
}
112-
return action(ctx, cmd)
72+
if cmd.IsSet("config") {
73+
args.CustomConf = cmd.String("config")
11374
}
75+
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
11476
}
11577

11678
type AppVersion struct {
@@ -125,10 +87,29 @@ func NewMainApp(appVer AppVersion) *cli.Command {
12587
app.Description = `Gitea program contains "web" and other subcommands. If no subcommand is given, it starts the web server by default. Use "web" subcommand for more web server arguments, use other subcommands for other purposes.`
12688
app.Version = appVer.Version + appVer.Extra
12789
app.EnableShellCompletion = true
128-
129-
// these sub-commands need to use config file
90+
app.Flags = []cli.Flag{
91+
&cli.StringFlag{
92+
Name: "work-path",
93+
Aliases: []string{"w"},
94+
TakesFile: true,
95+
Usage: "Set Gitea's working path (defaults to the Gitea's binary directory)",
96+
},
97+
&cli.StringFlag{
98+
Name: "config",
99+
Aliases: []string{"c"},
100+
TakesFile: true,
101+
Value: setting.CustomConf,
102+
Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
103+
},
104+
&cli.StringFlag{
105+
Name: "custom-path",
106+
Aliases: []string{"C"},
107+
TakesFile: true,
108+
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
109+
},
110+
}
111+
// these sub-commands need to use a config file
130112
subCmdWithConfig := []*cli.Command{
131-
cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config"
132113
CmdWeb,
133114
CmdServ,
134115
CmdHook,
@@ -156,9 +137,6 @@ func NewMainApp(appVer AppVersion) *cli.Command {
156137
// but not sure whether it would break Windows users who used to double-click the EXE to run.
157138
app.DefaultCommand = CmdWeb.Name
158139

159-
app.Flags = append(app.Flags, cli.VersionFlag)
160-
app.Flags = append(app.Flags, appGlobalFlags()...)
161-
app.HideHelp = true // use our own help action to show helps (with more information like default config)
162140
app.Before = PrepareConsoleLoggerLevel(log.INFO)
163141
for i := range subCmdWithConfig {
164142
prepareSubcommandWithGlobalFlags(subCmdWithConfig[i])

0 commit comments

Comments
 (0)