mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
fix (pythonBuild) run as root and generate build settings info (#3695)
* adding PIP to BuildTool.groovy * trying to run the container with root * only creating sdist * including wheel distribution * adding settings info Co-authored-by: anilkeshav27 <you@example.com>
This commit is contained in:
parent
3c55d3c99c
commit
aa74e090d5
@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/buildsettings"
|
||||||
"github.com/SAP/jenkins-library/pkg/command"
|
"github.com/SAP/jenkins-library/pkg/command"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
@ -35,16 +36,16 @@ func newPythonBuildUtils() pythonBuildUtils {
|
|||||||
return &utils
|
return &utils
|
||||||
}
|
}
|
||||||
|
|
||||||
func pythonBuild(config pythonBuildOptions, telemetryData *telemetry.CustomData) {
|
func pythonBuild(config pythonBuildOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *pythonBuildCommonPipelineEnvironment) {
|
||||||
utils := newPythonBuildUtils()
|
utils := newPythonBuildUtils()
|
||||||
|
|
||||||
err := runPythonBuild(&config, telemetryData, utils)
|
err := runPythonBuild(&config, telemetryData, utils, commonPipelineEnvironment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPythonBuild(config *pythonBuildOptions, telemetryData *telemetry.CustomData, utils pythonBuildUtils) error {
|
func runPythonBuild(config *pythonBuildOptions, telemetryData *telemetry.CustomData, utils pythonBuildUtils, commonPipelineEnvironment *pythonBuildCommonPipelineEnvironment) error {
|
||||||
|
|
||||||
installFlags := []string{"-m", "pip", "install", "--upgrade"}
|
installFlags := []string{"-m", "pip", "install", "--upgrade"}
|
||||||
|
|
||||||
@ -59,6 +60,25 @@ func runPythonBuild(config *pythonBuildOptions, telemetryData *telemetry.CustomD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Entry().Debugf("creating build settings information...")
|
||||||
|
stepName := "pythonBuild"
|
||||||
|
dockerImage, err := GetDockerImageValue(stepName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pythonConfig := buildsettings.BuildOptions{
|
||||||
|
CreateBOM: config.CreateBOM,
|
||||||
|
Publish: config.Publish,
|
||||||
|
BuildSettingsInfo: config.BuildSettingsInfo,
|
||||||
|
DockerImage: dockerImage,
|
||||||
|
}
|
||||||
|
buildSettingsInfo, err := buildsettings.CreateBuildSettingsInfo(&pythonConfig, stepName)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().Warnf("failed to create build settings info: %v", err)
|
||||||
|
}
|
||||||
|
commonPipelineEnvironment.custom.buildSettingsInfo = buildSettingsInfo
|
||||||
|
|
||||||
if config.Publish {
|
if config.Publish {
|
||||||
if err := publishWithTwine(config, utils, installFlags); err != nil {
|
if err := publishWithTwine(config, utils, installFlags); err != nil {
|
||||||
return fmt.Errorf("failed to publish: %w", err)
|
return fmt.Errorf("failed to publish: %w", err)
|
||||||
|
@ -5,10 +5,12 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
||||||
"github.com/SAP/jenkins-library/pkg/splunk"
|
"github.com/SAP/jenkins-library/pkg/splunk"
|
||||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||||
"github.com/SAP/jenkins-library/pkg/validation"
|
"github.com/SAP/jenkins-library/pkg/validation"
|
||||||
@ -22,6 +24,35 @@ type pythonBuildOptions struct {
|
|||||||
TargetRepositoryPassword string `json:"targetRepositoryPassword,omitempty"`
|
TargetRepositoryPassword string `json:"targetRepositoryPassword,omitempty"`
|
||||||
TargetRepositoryUser string `json:"targetRepositoryUser,omitempty"`
|
TargetRepositoryUser string `json:"targetRepositoryUser,omitempty"`
|
||||||
TargetRepositoryURL string `json:"targetRepositoryURL,omitempty"`
|
TargetRepositoryURL string `json:"targetRepositoryURL,omitempty"`
|
||||||
|
BuildSettingsInfo string `json:"buildSettingsInfo,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type pythonBuildCommonPipelineEnvironment struct {
|
||||||
|
custom struct {
|
||||||
|
buildSettingsInfo string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pythonBuildCommonPipelineEnvironment) persist(path, resourceName string) {
|
||||||
|
content := []struct {
|
||||||
|
category string
|
||||||
|
name string
|
||||||
|
value interface{}
|
||||||
|
}{
|
||||||
|
{category: "custom", name: "buildSettingsInfo", value: p.custom.buildSettingsInfo},
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, param := range content {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting piper environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
log.Entry().Error("failed to persist Piper environment")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PythonBuildCommand Step build a python project
|
// PythonBuildCommand Step build a python project
|
||||||
@ -31,6 +62,7 @@ func PythonBuildCommand() *cobra.Command {
|
|||||||
metadata := pythonBuildMetadata()
|
metadata := pythonBuildMetadata()
|
||||||
var stepConfig pythonBuildOptions
|
var stepConfig pythonBuildOptions
|
||||||
var startTime time.Time
|
var startTime time.Time
|
||||||
|
var commonPipelineEnvironment pythonBuildCommonPipelineEnvironment
|
||||||
var logCollector *log.CollectorHook
|
var logCollector *log.CollectorHook
|
||||||
var splunkClient *splunk.Splunk
|
var splunkClient *splunk.Splunk
|
||||||
telemetryClient := &telemetry.Telemetry{}
|
telemetryClient := &telemetry.Telemetry{}
|
||||||
@ -84,6 +116,7 @@ func PythonBuildCommand() *cobra.Command {
|
|||||||
stepTelemetryData := telemetry.CustomData{}
|
stepTelemetryData := telemetry.CustomData{}
|
||||||
stepTelemetryData.ErrorCode = "1"
|
stepTelemetryData.ErrorCode = "1"
|
||||||
handler := func() {
|
handler := func() {
|
||||||
|
commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
||||||
config.RemoveVaultSecretFiles()
|
config.RemoveVaultSecretFiles()
|
||||||
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
||||||
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
||||||
@ -104,7 +137,7 @@ func PythonBuildCommand() *cobra.Command {
|
|||||||
GeneralConfig.HookConfig.SplunkConfig.Index,
|
GeneralConfig.HookConfig.SplunkConfig.Index,
|
||||||
GeneralConfig.HookConfig.SplunkConfig.SendLogs)
|
GeneralConfig.HookConfig.SplunkConfig.SendLogs)
|
||||||
}
|
}
|
||||||
pythonBuild(stepConfig, &stepTelemetryData)
|
pythonBuild(stepConfig, &stepTelemetryData, &commonPipelineEnvironment)
|
||||||
stepTelemetryData.ErrorCode = "0"
|
stepTelemetryData.ErrorCode = "0"
|
||||||
log.Entry().Info("SUCCESS")
|
log.Entry().Info("SUCCESS")
|
||||||
},
|
},
|
||||||
@ -121,6 +154,7 @@ func addPythonBuildFlags(cmd *cobra.Command, stepConfig *pythonBuildOptions) {
|
|||||||
cmd.Flags().StringVar(&stepConfig.TargetRepositoryPassword, "targetRepositoryPassword", os.Getenv("PIPER_targetRepositoryPassword"), "Password for the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
cmd.Flags().StringVar(&stepConfig.TargetRepositoryPassword, "targetRepositoryPassword", os.Getenv("PIPER_targetRepositoryPassword"), "Password for the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
||||||
cmd.Flags().StringVar(&stepConfig.TargetRepositoryUser, "targetRepositoryUser", os.Getenv("PIPER_targetRepositoryUser"), "Username for the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
cmd.Flags().StringVar(&stepConfig.TargetRepositoryUser, "targetRepositoryUser", os.Getenv("PIPER_targetRepositoryUser"), "Username for the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
||||||
cmd.Flags().StringVar(&stepConfig.TargetRepositoryURL, "targetRepositoryURL", os.Getenv("PIPER_targetRepositoryURL"), "URL of the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
cmd.Flags().StringVar(&stepConfig.TargetRepositoryURL, "targetRepositoryURL", os.Getenv("PIPER_targetRepositoryURL"), "URL of the target repository where the compiled binaries shall be uploaded - typically provided by the CI/CD environment.")
|
||||||
|
cmd.Flags().StringVar(&stepConfig.BuildSettingsInfo, "buildSettingsInfo", os.Getenv("PIPER_buildSettingsInfo"), "build settings info is typically filled by the step automatically to create information about the build settings that were used during the maven build . This information is typically used for compliance related processes.")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,10 +238,35 @@ func pythonBuildMetadata() config.StepData {
|
|||||||
Aliases: []config.Alias{},
|
Aliases: []config.Alias{},
|
||||||
Default: os.Getenv("PIPER_targetRepositoryURL"),
|
Default: os.Getenv("PIPER_targetRepositoryURL"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "buildSettingsInfo",
|
||||||
|
ResourceRef: []config.ResourceReference{
|
||||||
|
{
|
||||||
|
Name: "commonPipelineEnvironment",
|
||||||
|
Param: "custom/buildSettingsInfo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
|
||||||
|
Type: "string",
|
||||||
|
Mandatory: false,
|
||||||
|
Aliases: []config.Alias{},
|
||||||
|
Default: os.Getenv("PIPER_buildSettingsInfo"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Containers: []config.Container{
|
Containers: []config.Container{
|
||||||
{Name: "python", Image: "python:3.9", WorkingDir: "/home/node"},
|
{Name: "python", Image: "python:3.9", Options: []config.Option{{Name: "-u", Value: "0"}}},
|
||||||
|
},
|
||||||
|
Outputs: config.StepOutputs{
|
||||||
|
Resources: []config.StepResources{
|
||||||
|
{
|
||||||
|
Name: "commonPipelineEnvironment",
|
||||||
|
Type: "piperEnvironment",
|
||||||
|
Parameters: []map[string]interface{}{
|
||||||
|
{"name": "custom/buildSettingsInfo"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ func (f *pythonBuildMockUtils) GetConfig() *pythonBuildOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRunPythonBuild(t *testing.T) {
|
func TestRunPythonBuild(t *testing.T) {
|
||||||
|
cpe := pythonBuildCommonPipelineEnvironment{}
|
||||||
t.Run("success - build", func(t *testing.T) {
|
t.Run("success - build", func(t *testing.T) {
|
||||||
config := pythonBuildOptions{}
|
config := pythonBuildOptions{}
|
||||||
utils := newPythonBuildTestsUtils()
|
utils := newPythonBuildTestsUtils()
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
||||||
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
||||||
@ -58,7 +58,7 @@ func TestRunPythonBuild(t *testing.T) {
|
|||||||
utils.ShouldFailOnCommand = map[string]error{"python3 setup.py sdist bdist_wheel": fmt.Errorf("build failure")}
|
utils.ShouldFailOnCommand = map[string]error{"python3 setup.py sdist bdist_wheel": fmt.Errorf("build failure")}
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.EqualError(t, err, "Python build failed with error: build failure")
|
assert.EqualError(t, err, "Python build failed with error: build failure")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ func TestRunPythonBuild(t *testing.T) {
|
|||||||
utils := newPythonBuildTestsUtils()
|
utils := newPythonBuildTestsUtils()
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
||||||
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
||||||
@ -91,7 +91,7 @@ func TestRunPythonBuild(t *testing.T) {
|
|||||||
utils := newPythonBuildTestsUtils()
|
utils := newPythonBuildTestsUtils()
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
assert.Equal(t, "python3", utils.ExecMockRunner.Calls[0].Exec)
|
||||||
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
assert.Equal(t, []string{"setup.py", "sdist", "bdist_wheel"}, utils.ExecMockRunner.Calls[0].Params)
|
||||||
@ -109,7 +109,7 @@ func TestRunPythonBuild(t *testing.T) {
|
|||||||
utils.ShouldFailOnCommand = map[string]error{"python3 -m pip install --upgrade cyclonedx-bom": fmt.Errorf("install failure")}
|
utils.ShouldFailOnCommand = map[string]error{"python3 -m pip install --upgrade cyclonedx-bom": fmt.Errorf("install failure")}
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.EqualError(t, err, "BOM creation failed: install failure")
|
assert.EqualError(t, err, "BOM creation failed: install failure")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ func TestRunPythonBuild(t *testing.T) {
|
|||||||
utils.ShouldFailOnCommand = map[string]error{"python3 -m pip install --upgrade twine": fmt.Errorf("install failure")}
|
utils.ShouldFailOnCommand = map[string]error{"python3 -m pip install --upgrade twine": fmt.Errorf("install failure")}
|
||||||
telemetryData := telemetry.CustomData{}
|
telemetryData := telemetry.CustomData{}
|
||||||
|
|
||||||
err := runPythonBuild(&config, &telemetryData, utils)
|
err := runPythonBuild(&config, &telemetryData, utils, &cpe)
|
||||||
assert.EqualError(t, err, "failed to publish: install failure")
|
assert.EqualError(t, err, "failed to publish: install failure")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,26 @@ spec:
|
|||||||
resourceRef:
|
resourceRef:
|
||||||
- name: commonPipelineEnvironment
|
- name: commonPipelineEnvironment
|
||||||
param: custom/repositoryUrl
|
param: custom/repositoryUrl
|
||||||
|
- name: buildSettingsInfo
|
||||||
|
type: string
|
||||||
|
description: build settings info is typically filled by the step automatically to create information about the build settings that were used during the maven build . This information is typically used for compliance related processes.
|
||||||
|
scope:
|
||||||
|
- STEPS
|
||||||
|
- STAGES
|
||||||
|
- PARAMETERS
|
||||||
|
resourceRef:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
param: custom/buildSettingsInfo
|
||||||
|
outputs:
|
||||||
|
resources:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
type: piperEnvironment
|
||||||
|
params:
|
||||||
|
- name: custom/buildSettingsInfo
|
||||||
containers:
|
containers:
|
||||||
- name: python
|
- name: python
|
||||||
image: python:3.9
|
image: python:3.9
|
||||||
workingDir: /home/node
|
# workingDir: /home/node
|
||||||
|
options:
|
||||||
|
- name: -u
|
||||||
|
value: "0"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package com.sap.piper
|
package com.sap.piper
|
||||||
|
|
||||||
enum BuildTool {
|
enum BuildTool {
|
||||||
MAVEN, NPM, MTA
|
MAVEN, NPM, MTA, PIP
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user