diff --git a/modules/context/context.go b/modules/context/context.go index 4f6c9f4..6cd5159 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -92,9 +92,19 @@ func InitCommand(cmd *cli.Command) *TeaContext { } } + // Create env login before repo context detection so it participates in remote URL matching + var extraLogins []config.Login + envLogin := GetLoginByEnvVar() + if envLogin != nil { + if _, err := utils.ValidateAuthenticationMethod(envLogin.URL, envLogin.Token, "", "", false, "", ""); err != nil { + log.Fatal(err.Error()) + } + extraLogins = append(extraLogins, *envLogin) + } + // try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir, // otherwise attempt PWD. if no repo is found, continue with default login - if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag); err != nil { + if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag, extraLogins); err != nil { if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists { // we can deal with that, commands needing the optional values use ctx.Ensure() } else { @@ -107,13 +117,9 @@ func InitCommand(cmd *cli.Command) *TeaContext { c.RepoSlug = repoFlag } - // override config user with env variable - envLogin := GetLoginByEnvVar() + // If env vars are set, always use the env login (but repo slug was already + // resolved by contextFromLocalRepo with the env login in the match list) if envLogin != nil { - _, err := utils.ValidateAuthenticationMethod(envLogin.URL, envLogin.Token, "", "", false, "", "") - if err != nil { - log.Fatal(err.Error()) - } c.Login = envLogin } diff --git a/modules/context/context_login.go b/modules/context/context_login.go index 5ebf7cb..76223d1 100644 --- a/modules/context/context_login.go +++ b/modules/context/context_login.go @@ -18,6 +18,7 @@ func GetLoginByEnvVar() *config.Login { giteaToken := os.Getenv("GITEA_TOKEN") githubToken := os.Getenv("GH_TOKEN") giteaInstanceURL := os.Getenv("GITEA_INSTANCE_URL") + giteaInstanceSSHHost := os.Getenv("GITEA_INSTANCE_SSH_HOST") instanceInsecure := os.Getenv("GITEA_INSTANCE_INSECURE") insecure := false if len(instanceInsecure) > 0 { @@ -38,6 +39,7 @@ func GetLoginByEnvVar() *config.Login { Name: "GITEA_LOGIN_VIA_ENV", URL: giteaInstanceURL, Token: token, + SSHHost: giteaInstanceSSHHost, Insecure: insecure, SSHKey: "", SSHCertPrincipal: "", diff --git a/modules/context/context_repo.go b/modules/context/context_repo.go index 6072d0e..ca44bfb 100644 --- a/modules/context/context_repo.go +++ b/modules/context/context_repo.go @@ -12,7 +12,7 @@ import ( ) // contextFromLocalRepo discovers login & repo slug from the default branch remote of the given local repo -func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.Login, string, error) { +func contextFromLocalRepo(repoPath, remoteValue string, extraLogins []config.Login) (*git.TeaRepo, *config.Login, string, error) { repo, err := git.RepoFromPath(repoPath) if err != nil { return nil, nil, "", err @@ -69,6 +69,10 @@ func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.L if err != nil { return repo, nil, "", err } + // Prepend extra logins (e.g. from env vars) so they are matched first + if len(extraLogins) > 0 { + logins = append(extraLogins, logins...) + } for _, u := range remoteConfig.URLs { if l, p, err := MatchLogins(u, logins); err == nil { return repo, l, p, nil diff --git a/modules/context/context_test.go b/modules/context/context_test.go index 8ffba7c..9b73f88 100644 --- a/modules/context/context_test.go +++ b/modules/context/context_test.go @@ -31,17 +31,37 @@ func Test_MatchLogins(t *testing.T) { expectedRepoPath: "owner/repo", hasError: false, }, + { + remoteURL: "git@custom-ssh.example.com:owner/repo.git", + logins: []config.Login{{Name: "env", URL: "https://gitea.example.com", SSHHost: "custom-ssh.example.com"}}, + matchedLoginName: "env", + expectedRepoPath: "owner/repo", + hasError: false, + }, + { + remoteURL: "https://gitea.example.com/owner/repo.git", + logins: []config.Login{ + {Name: "env", URL: "https://gitea.example.com"}, + {Name: "config", URL: "https://gitea.example.com"}, + }, + matchedLoginName: "env", + expectedRepoPath: "owner/repo", + hasError: false, + }, } for _, kase := range kases { t.Run(kase.remoteURL, func(t *testing.T) { - _, repoPath, err := MatchLogins(kase.remoteURL, kase.logins) + login, repoPath, err := MatchLogins(kase.remoteURL, kase.logins) if (err != nil) != kase.hasError { t.Errorf("Expected error: %v, got: %v", kase.hasError, err) } if repoPath != kase.expectedRepoPath { t.Errorf("Expected repo path: %s, got: %s", kase.expectedRepoPath, repoPath) } + if !kase.hasError && login.Name != kase.matchedLoginName { + t.Errorf("Expected login name: %s, got: %s", kase.matchedLoginName, login.Name) + } }) } }