Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion cmd/golangBuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package cmd

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"path"
"path/filepath"
"strings"

"github.com/SAP/jenkins-library/pkg/build"
"github.com/SAP/jenkins-library/pkg/buildsettings"
"github.com/SAP/jenkins-library/pkg/certutils"
"github.com/SAP/jenkins-library/pkg/command"
Expand Down Expand Up @@ -265,7 +267,6 @@ func runGolangBuild(config *golangBuildOptions, telemetryData *telemetry.CustomD
}

artifactVersion, err = artifact.GetVersion()

if err != nil {
return err
}
Expand All @@ -286,6 +287,8 @@ func runGolangBuild(config *golangBuildOptions, telemetryData *telemetry.CustomD
utils.SetOptions(repoClientOptions)

var binaryArtifacts piperenv.Artifacts
buildCoordinates := []versioning.Coordinates{}

for _, binary := range binaries {

targetPath := fmt.Sprintf("go/%s/%s/%s", goModFile.Module.Mod.Path, artifactVersion, binary)
Expand All @@ -312,14 +315,51 @@ func runGolangBuild(config *golangBuildOptions, telemetryData *telemetry.CustomD
binaryArtifacts = append(binaryArtifacts, piperenv.Artifact{
Name: binary,
})

if config.CreateBuildArtifactsMetadata {
err, coordinate := createGoBuildArtifactsMetadata(binary, config.TargetRepositoryURL, artifactVersion, utils)
if err != nil {
log.Entry().Warnf("unable to create build artifact metadata : %v", err)
}
buildCoordinates = append(buildCoordinates, coordinate)
}
}
commonPipelineEnvironment.custom.artifacts = binaryArtifacts

if len(buildCoordinates) == 0 {
log.Entry().Warnf("unable to identify artifact coordinates for the go binary(s) published")
return nil
}

var buildArtifacts build.BuildArtifacts
buildArtifacts.Coordinates = buildCoordinates
jsonResult, _ := json.Marshal(buildArtifacts)
commonPipelineEnvironment.custom.goBuildArtifacts = string(jsonResult)

}

return nil
}

func createGoBuildArtifactsMetadata(binary string, repositoryURL string, artifactVersion string, utils golangBuildUtils) (error, versioning.Coordinates) {
options := versioning.Options{}
builtArtifact, err := versioning.GetArtifact("golang", "", &options, utils)
coordinate, err := builtArtifact.GetCoordinates()
purl := piperutils.GetPurl(filepath.Join(filepath.Dir("go.mod"), sbomFilename))
// golang purls contain the hex code for & with GOOS and GOARC and should be reomved from the PURL
purl = strings.ReplaceAll(purl, "\\u0026", "&")
if err != nil {
return err, coordinate
}
coordinate.ArtifactID = binary
coordinate.URL = repositoryURL
coordinate.BuildPath = filepath.Dir(binary)
coordinate.PURL = purl
coordinate.Version = artifactVersion

return nil, coordinate
}

func prepareGolangEnvironment(config *golangBuildOptions, goModFile *modfile.File, utils golangBuildUtils) error {
// configure truststore
err := certutils.CertificateUpdate(config.CustomTLSCertificateLinks, utils, utils, "/etc/ssl/certs/ca-certificates.crt") // TODO reimplement
Expand Down
14 changes: 14 additions & 0 deletions cmd/golangBuild_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 54 additions & 18 deletions cmd/golangBuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,11 @@ go 1.17`

t.Run("success - simple publish", func(t *testing.T) {
config := golangBuildOptions{
TargetArchitectures: []string{"linux,amd64"},
Publish: true,
TargetRepositoryURL: "https://my.target.repository.local/",
ArtifactVersion: "1.0.0",
TargetArchitectures: []string{"linux,amd64"},
Publish: true,
TargetRepositoryURL: "https://my.target.repository.local/",
ArtifactVersion: "1.0.0",
CreateBuildArtifactsMetadata: false,
}

utils := newGolangBuildTestsUtils()
Expand All @@ -223,14 +224,16 @@ go 1.17`

t.Run("success - publishes binaries", func(t *testing.T) {
config := golangBuildOptions{
TargetArchitectures: []string{"linux,amd64"},
Output: "testBin",
Publish: true,
TargetRepositoryURL: "https://my.target.repository.local",
TargetRepositoryUser: "user",
TargetRepositoryPassword: "password",
ArtifactVersion: "1.0.0",
TargetArchitectures: []string{"linux,amd64"},
Output: "testBin",
Publish: true,
CreateBuildArtifactsMetadata: false,
TargetRepositoryURL: "https://my.target.repository.local",
TargetRepositoryUser: "user",
TargetRepositoryPassword: "password",
ArtifactVersion: "1.0.0",
}

utils := newGolangBuildTestsUtils()
utils.returnFileUploadStatus = 201
utils.FilesMock.AddFile("go.mod", []byte("module example.com/my/module"))
Expand All @@ -248,13 +251,14 @@ go 1.17`

t.Run("success - publishes binaries (when TargetRepositoryURL ends with slash)", func(t *testing.T) {
config := golangBuildOptions{
TargetArchitectures: []string{"linux,amd64"},
Output: "testBin",
Publish: true,
TargetRepositoryURL: "https://my.target.repository.local/",
TargetRepositoryUser: "user",
TargetRepositoryPassword: "password",
ArtifactVersion: "1.0.0",
TargetArchitectures: []string{"linux,amd64"},
Output: "testBin",
Publish: true,
CreateBuildArtifactsMetadata: false,
TargetRepositoryURL: "https://my.target.repository.local/",
TargetRepositoryUser: "user",
TargetRepositoryPassword: "password",
ArtifactVersion: "1.0.0",
}
utils := newGolangBuildTestsUtils()
utils.returnFileUploadStatus = 200
Expand Down Expand Up @@ -1038,6 +1042,38 @@ func TestRunGolangciLint(t *testing.T) {
}
}

func TestGoCreateBuildArtifactMetadata(t *testing.T) {
config := golangBuildOptions{
TargetArchitectures: []string{"linux,amd64"},
Output: "testBin",
Publish: true,
TargetRepositoryURL: "https://my.target.repository.local",
TargetRepositoryUser: "user",
TargetRepositoryPassword: "password",
}
utils := newGolangBuildTestsUtils()
versionFile, err := os.Create("VERSION")

assert.Equal(t, err, nil)
// Ensure file is closed and deleted after function finishes
defer versionFile.Close()
defer os.Remove("VERSION") // Delete the file when the function exits

// Write something to the file
_, err = versionFile.WriteString("1.0.0")

// Create a new file
binaryFile, err := os.Create("testBin")
assert.Equal(t, err, nil)

defer binaryFile.Close()
defer os.Remove("testBin") // Delete the file when the function exits

err, version := createGoBuildArtifactsMetadata("testBin", config.TargetRepositoryURL, "1.0.0", utils)
assert.Equal(t, err, nil)
assert.Equal(t, version.ArtifactID, "testBin")
}

func TestRetrieveGolangciLint(t *testing.T) {
t.Parallel()

Expand Down
9 changes: 9 additions & 0 deletions resources/metadata/golangBuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,21 @@ spec:
- PARAMETERS
- STEPS
default: "https://github.com/golangci/golangci-lint/releases/download/v1.51.2/golangci-lint-1.51.2-linux-amd64.tar.gz"
- name: createBuildArtifactsMetadata
type: bool
default: false
description: metadata about the artifacts that are build and published , this metadata is generally used by steps downstream in the pipeline
scope:
- STEPS
- STAGES
- PARAMETERS
outputs:
resources:
- name: commonPipelineEnvironment
type: piperEnvironment
params:
- name: custom/buildSettingsInfo
- name: custom/goBuildArtifacts
- name: custom/artifacts
type: "piperenv.Artifacts"
- name: reports
Expand Down
Loading