mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
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 <jordi.van.liempt@sap.com> Co-authored-by: aibaend1 <106729492+aibaend1@users.noreply.github.com> Co-authored-by: asadu <aibyn_sadu@epam.com>
This commit is contained in:
parent
9189ab37b5
commit
d01c161822
@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/buildsettings"
|
||||
@ -24,7 +23,6 @@ import (
|
||||
"github.com/SAP/jenkins-library/pkg/versioning"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -341,26 +339,11 @@ func prepareGolangEnvironment(config *golangBuildOptions, goModFile *modfile.Fil
|
||||
// pass private repos to go process
|
||||
os.Setenv("GOPRIVATE", config.PrivateModules)
|
||||
|
||||
repoURLs, err := lookupGolangPrivateModulesRepositories(goModFile, config.PrivateModules, utils)
|
||||
|
||||
err = gitConfigurationForPrivateModules(config.PrivateModules, config.PrivateModulesGitToken, utils)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// configure credentials git shall use for pulling repos
|
||||
for _, repoURL := range repoURLs {
|
||||
if match, _ := regexp.MatchString("(?i)^https?://", repoURL); !match {
|
||||
continue
|
||||
}
|
||||
|
||||
authenticatedRepoURL := strings.Replace(repoURL, "://", fmt.Sprintf("://%s@", config.PrivateModulesGitToken), 1)
|
||||
|
||||
err = utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -539,36 +522,6 @@ func runGolangBuildPerArchitecture(config *golangBuildOptions, goModFile *modfil
|
||||
return binaryNames, nil
|
||||
}
|
||||
|
||||
// lookupPrivateModulesRepositories returns a slice of all modules that match the given glob pattern
|
||||
func lookupGolangPrivateModulesRepositories(goModFile *modfile.File, globPattern string, utils golangBuildUtils) ([]string, error) {
|
||||
if globPattern == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
if goModFile == nil {
|
||||
return nil, fmt.Errorf("couldn't find go.mod file")
|
||||
} else if goModFile.Require == nil {
|
||||
return []string{}, nil // no modules referenced, nothing to do
|
||||
}
|
||||
|
||||
privateModules := []string{}
|
||||
|
||||
for _, goModule := range goModFile.Require {
|
||||
if !module.MatchPrefixPatterns(globPattern, goModule.Mod.Path) {
|
||||
continue
|
||||
}
|
||||
|
||||
repo, err := utils.GetRepositoryURL(goModule.Mod.Path)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privateModules = append(privateModules, repo)
|
||||
}
|
||||
return privateModules, nil
|
||||
}
|
||||
|
||||
func runBOMCreation(utils golangBuildUtils, outputFilename string) error {
|
||||
|
||||
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) {
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func gitConfigurationForPrivateModules(privateMod string, token string, utils golangBuildUtils) error {
|
||||
privateMod = strings.ReplaceAll(privateMod, "/*", "")
|
||||
privateMod = strings.ReplaceAll(privateMod, "*.", "")
|
||||
modules := strings.Split(privateMod, ",")
|
||||
for _, v := range modules {
|
||||
authenticatedRepoURL := fmt.Sprintf("https://%s@%s", token, v)
|
||||
repoBaseURL := fmt.Sprintf("https://%s", v)
|
||||
err := utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoBaseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -911,8 +911,7 @@ go 1.17`
|
||||
expect: expectations{
|
||||
envVars: []string{"GOPRIVATE=*.example.com"},
|
||||
commandsExecuted: [][]string{
|
||||
{"git", "config", "--global", "url.https://secret@private1.example.com/private/repo.git.insteadOf", "https://private1.example.com/private/repo.git"},
|
||||
{"git", "config", "--global", "url.https://secret@private2.example.com/another/repo.git.insteadOf", "https://private2.example.com/another/repo.git"},
|
||||
{"git", "config", "--global", "url.https://secret@example.com.insteadOf", "https://example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -943,89 +942,6 @@ go 1.17`
|
||||
}
|
||||
}
|
||||
|
||||
func TestLookupGolangPrivateModulesRepositories(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
modTestFile := `
|
||||
module private.example.com/m
|
||||
|
||||
require (
|
||||
example.com/public/module v1.0.0
|
||||
private1.example.com/private/repo v0.1.0
|
||||
private2.example.com/another/repo v0.2.0
|
||||
)
|
||||
|
||||
go 1.17`
|
||||
|
||||
type expectations struct {
|
||||
repos []string
|
||||
errorMessage string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
modFileContent string
|
||||
globPattern string
|
||||
expect expectations
|
||||
}{
|
||||
{
|
||||
name: "Does nothing if glob pattern is empty",
|
||||
modFileContent: modTestFile,
|
||||
expect: expectations{
|
||||
repos: []string{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Does nothing if there is no go.mod file",
|
||||
globPattern: "private.example.com",
|
||||
modFileContent: "",
|
||||
expect: expectations{
|
||||
repos: []string{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Detects all private repos using a glob pattern",
|
||||
modFileContent: modTestFile,
|
||||
globPattern: "*.example.com",
|
||||
expect: expectations{
|
||||
repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Detects all private repos",
|
||||
modFileContent: modTestFile,
|
||||
globPattern: "private1.example.com,private2.example.com",
|
||||
expect: expectations{
|
||||
repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Detects a dedicated repo",
|
||||
modFileContent: modTestFile,
|
||||
globPattern: "private2.example.com",
|
||||
expect: expectations{
|
||||
repos: []string{"https://private2.example.com/another/repo.git"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
utils := newGolangBuildTestsUtils()
|
||||
|
||||
goModFile, _ := modfile.Parse("", []byte(tt.modFileContent), nil)
|
||||
|
||||
repos, err := lookupGolangPrivateModulesRepositories(goModFile, tt.globPattern, utils)
|
||||
|
||||
if tt.expect.errorMessage == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expect.repos, repos)
|
||||
} else {
|
||||
assert.EqualError(t, err, tt.expect.errorMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunGolangciLint(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@ -1153,3 +1069,59 @@ func TestRetrieveGolangciLint(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_gitConfigurationForPrivateModules(t *testing.T) {
|
||||
type args struct {
|
||||
privateMod string
|
||||
token string
|
||||
}
|
||||
type expectations struct {
|
||||
commandsExecuted [][]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
|
||||
expected expectations
|
||||
}{
|
||||
{
|
||||
name: "with one private module",
|
||||
args: args{
|
||||
privateMod: "example.com/*",
|
||||
token: "mytoken",
|
||||
},
|
||||
expected: expectations{
|
||||
commandsExecuted: [][]string{
|
||||
{"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with multiple private modules",
|
||||
args: args{
|
||||
privateMod: "example.com/*,test.com/*",
|
||||
token: "mytoken",
|
||||
},
|
||||
expected: expectations{
|
||||
commandsExecuted: [][]string{
|
||||
{"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"},
|
||||
{"git", "config", "--global", "url.https://mytoken@test.com.insteadOf", "https://test.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
utils := newGolangBuildTestsUtils()
|
||||
|
||||
err := gitConfigurationForPrivateModules(tt.args.privateMod, tt.args.token, utils)
|
||||
|
||||
if assert.NoError(t, err) {
|
||||
for i, expectedCommand := range tt.expected.commandsExecuted {
|
||||
assert.Equal(t, expectedCommand[0], utils.Calls[i].Exec)
|
||||
assert.Equal(t, expectedCommand[1:], utils.Calls[i].Params)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user