Skip to content

Commit d01c161

Browse files
jliemptI557621aibaend1asadu
authored
fix(golangBuild): BOM creation failed with private Go modules (#4460)
* quickly try to only specify base private repo URLs with git config * fix the test * refactoring of private modules * test * fix test * fix url * typo * Adding gitConfiguration * typo * unit test * unit test --------- Co-authored-by: I557621 <[email protected]> Co-authored-by: aibaend1 <[email protected]> Co-authored-by: asadu <[email protected]>
1 parent 9189ab3 commit d01c161

File tree

2 files changed

+75
-133
lines changed

2 files changed

+75
-133
lines changed

cmd/golangBuild.go

+18-48
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"os"
88
"path"
99
"path/filepath"
10-
"regexp"
1110
"strings"
1211

1312
"github.com/SAP/jenkins-library/pkg/buildsettings"
@@ -24,7 +23,6 @@ import (
2423
"github.com/SAP/jenkins-library/pkg/versioning"
2524

2625
"golang.org/x/mod/modfile"
27-
"golang.org/x/mod/module"
2826
)
2927

3028
const (
@@ -341,26 +339,11 @@ func prepareGolangEnvironment(config *golangBuildOptions, goModFile *modfile.Fil
341339
// pass private repos to go process
342340
os.Setenv("GOPRIVATE", config.PrivateModules)
343341

344-
repoURLs, err := lookupGolangPrivateModulesRepositories(goModFile, config.PrivateModules, utils)
345-
342+
err = gitConfigurationForPrivateModules(config.PrivateModules, config.PrivateModulesGitToken, utils)
346343
if err != nil {
347344
return err
348345
}
349346

350-
// configure credentials git shall use for pulling repos
351-
for _, repoURL := range repoURLs {
352-
if match, _ := regexp.MatchString("(?i)^https?://", repoURL); !match {
353-
continue
354-
}
355-
356-
authenticatedRepoURL := strings.Replace(repoURL, "://", fmt.Sprintf("://%s@", config.PrivateModulesGitToken), 1)
357-
358-
err = utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoURL)
359-
if err != nil {
360-
return err
361-
}
362-
}
363-
364347
return nil
365348
}
366349

@@ -539,36 +522,6 @@ func runGolangBuildPerArchitecture(config *golangBuildOptions, goModFile *modfil
539522
return binaryNames, nil
540523
}
541524

542-
// lookupPrivateModulesRepositories returns a slice of all modules that match the given glob pattern
543-
func lookupGolangPrivateModulesRepositories(goModFile *modfile.File, globPattern string, utils golangBuildUtils) ([]string, error) {
544-
if globPattern == "" {
545-
return []string{}, nil
546-
}
547-
548-
if goModFile == nil {
549-
return nil, fmt.Errorf("couldn't find go.mod file")
550-
} else if goModFile.Require == nil {
551-
return []string{}, nil // no modules referenced, nothing to do
552-
}
553-
554-
privateModules := []string{}
555-
556-
for _, goModule := range goModFile.Require {
557-
if !module.MatchPrefixPatterns(globPattern, goModule.Mod.Path) {
558-
continue
559-
}
560-
561-
repo, err := utils.GetRepositoryURL(goModule.Mod.Path)
562-
563-
if err != nil {
564-
return nil, err
565-
}
566-
567-
privateModules = append(privateModules, repo)
568-
}
569-
return privateModules, nil
570-
}
571-
572525
func runBOMCreation(utils golangBuildUtils, outputFilename string) error {
573526

574527
if err := utils.RunExecutable("cyclonedx-gomod", "mod", "-licenses", fmt.Sprintf("-verbose=%t", GeneralConfig.Verbose), "-test", "-output", outputFilename, "-output-version", "1.4"); err != nil {
@@ -631,3 +584,20 @@ func isMainPackage(utils golangBuildUtils, pkg string) (bool, error) {
631584

632585
return true, nil
633586
}
587+
588+
func gitConfigurationForPrivateModules(privateMod string, token string, utils golangBuildUtils) error {
589+
privateMod = strings.ReplaceAll(privateMod, "/*", "")
590+
privateMod = strings.ReplaceAll(privateMod, "*.", "")
591+
modules := strings.Split(privateMod, ",")
592+
for _, v := range modules {
593+
authenticatedRepoURL := fmt.Sprintf("https://%s@%s", token, v)
594+
repoBaseURL := fmt.Sprintf("https://%s", v)
595+
err := utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoBaseURL)
596+
if err != nil {
597+
return err
598+
}
599+
600+
}
601+
602+
return nil
603+
}

cmd/golangBuild_test.go

+57-85
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,7 @@ go 1.17`
911911
expect: expectations{
912912
envVars: []string{"GOPRIVATE=*.example.com"},
913913
commandsExecuted: [][]string{
914-
{"git", "config", "--global", "url.https://[email protected]/private/repo.git.insteadOf", "https://private1.example.com/private/repo.git"},
915-
{"git", "config", "--global", "url.https://[email protected]/another/repo.git.insteadOf", "https://private2.example.com/another/repo.git"},
914+
{"git", "config", "--global", "url.https://[email protected]", "https://example.com"},
916915
},
917916
},
918917
},
@@ -943,89 +942,6 @@ go 1.17`
943942
}
944943
}
945944

946-
func TestLookupGolangPrivateModulesRepositories(t *testing.T) {
947-
t.Parallel()
948-
949-
modTestFile := `
950-
module private.example.com/m
951-
952-
require (
953-
example.com/public/module v1.0.0
954-
private1.example.com/private/repo v0.1.0
955-
private2.example.com/another/repo v0.2.0
956-
)
957-
958-
go 1.17`
959-
960-
type expectations struct {
961-
repos []string
962-
errorMessage string
963-
}
964-
tests := []struct {
965-
name string
966-
modFileContent string
967-
globPattern string
968-
expect expectations
969-
}{
970-
{
971-
name: "Does nothing if glob pattern is empty",
972-
modFileContent: modTestFile,
973-
expect: expectations{
974-
repos: []string{},
975-
},
976-
},
977-
{
978-
name: "Does nothing if there is no go.mod file",
979-
globPattern: "private.example.com",
980-
modFileContent: "",
981-
expect: expectations{
982-
repos: []string{},
983-
},
984-
},
985-
{
986-
name: "Detects all private repos using a glob pattern",
987-
modFileContent: modTestFile,
988-
globPattern: "*.example.com",
989-
expect: expectations{
990-
repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"},
991-
},
992-
},
993-
{
994-
name: "Detects all private repos",
995-
modFileContent: modTestFile,
996-
globPattern: "private1.example.com,private2.example.com",
997-
expect: expectations{
998-
repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"},
999-
},
1000-
},
1001-
{
1002-
name: "Detects a dedicated repo",
1003-
modFileContent: modTestFile,
1004-
globPattern: "private2.example.com",
1005-
expect: expectations{
1006-
repos: []string{"https://private2.example.com/another/repo.git"},
1007-
},
1008-
},
1009-
}
1010-
1011-
for _, tt := range tests {
1012-
t.Run(tt.name, func(t *testing.T) {
1013-
utils := newGolangBuildTestsUtils()
1014-
1015-
goModFile, _ := modfile.Parse("", []byte(tt.modFileContent), nil)
1016-
1017-
repos, err := lookupGolangPrivateModulesRepositories(goModFile, tt.globPattern, utils)
1018-
1019-
if tt.expect.errorMessage == "" {
1020-
assert.NoError(t, err)
1021-
assert.Equal(t, tt.expect.repos, repos)
1022-
} else {
1023-
assert.EqualError(t, err, tt.expect.errorMessage)
1024-
}
1025-
})
1026-
}
1027-
}
1028-
1029945
func TestRunGolangciLint(t *testing.T) {
1030946
t.Parallel()
1031947

@@ -1153,3 +1069,59 @@ func TestRetrieveGolangciLint(t *testing.T) {
11531069
})
11541070
}
11551071
}
1072+
1073+
func Test_gitConfigurationForPrivateModules(t *testing.T) {
1074+
type args struct {
1075+
privateMod string
1076+
token string
1077+
}
1078+
type expectations struct {
1079+
commandsExecuted [][]string
1080+
}
1081+
tests := []struct {
1082+
name string
1083+
args args
1084+
1085+
expected expectations
1086+
}{
1087+
{
1088+
name: "with one private module",
1089+
args: args{
1090+
privateMod: "example.com/*",
1091+
token: "mytoken",
1092+
},
1093+
expected: expectations{
1094+
commandsExecuted: [][]string{
1095+
{"git", "config", "--global", "url.https://[email protected]", "https://example.com"},
1096+
},
1097+
},
1098+
},
1099+
{
1100+
name: "with multiple private modules",
1101+
args: args{
1102+
privateMod: "example.com/*,test.com/*",
1103+
token: "mytoken",
1104+
},
1105+
expected: expectations{
1106+
commandsExecuted: [][]string{
1107+
{"git", "config", "--global", "url.https://[email protected]", "https://example.com"},
1108+
{"git", "config", "--global", "url.https://[email protected]", "https://test.com"},
1109+
},
1110+
},
1111+
},
1112+
}
1113+
for _, tt := range tests {
1114+
t.Run(tt.name, func(t *testing.T) {
1115+
utils := newGolangBuildTestsUtils()
1116+
1117+
err := gitConfigurationForPrivateModules(tt.args.privateMod, tt.args.token, utils)
1118+
1119+
if assert.NoError(t, err) {
1120+
for i, expectedCommand := range tt.expected.commandsExecuted {
1121+
assert.Equal(t, expectedCommand[0], utils.Calls[i].Exec)
1122+
assert.Equal(t, expectedCommand[1:], utils.Calls[i].Params)
1123+
}
1124+
}
1125+
})
1126+
}
1127+
}

0 commit comments

Comments
 (0)