2021-12-22 16:34:36 +02:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
2022-06-07 10:24:10 +02:00
|
|
|
"bytes"
|
2022-10-25 13:17:42 +02:00
|
|
|
"encoding/json"
|
2022-04-14 14:59:09 +02:00
|
|
|
"fmt"
|
2022-06-07 10:24:10 +02:00
|
|
|
"text/template"
|
2022-03-21 11:17:03 +02:00
|
|
|
|
2021-12-22 16:34:36 +02:00
|
|
|
"github.com/SAP/jenkins-library/pkg/command"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/gradle"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/log"
|
2022-10-25 13:17:42 +02:00
|
|
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
2021-12-22 16:34:36 +02:00
|
|
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/telemetry"
|
|
|
|
)
|
|
|
|
|
2022-08-01 13:38:49 +02:00
|
|
|
const (
|
|
|
|
gradleBomFilename = "bom-gradle"
|
|
|
|
)
|
|
|
|
|
2022-06-07 10:24:10 +02:00
|
|
|
var (
|
|
|
|
bomGradleTaskName = "cyclonedxBom"
|
|
|
|
publishTaskName = "publish"
|
2022-10-25 13:17:42 +02:00
|
|
|
pathToModuleFile = "./build/publications/maven/module.json"
|
2022-06-07 10:24:10 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const publishInitScriptContentTemplate = `
|
|
|
|
rootProject {
|
|
|
|
apply plugin: 'maven-publish'
|
|
|
|
apply plugin: 'java'
|
|
|
|
|
|
|
|
publishing {
|
|
|
|
publications {
|
|
|
|
maven(MavenPublication) {
|
|
|
|
versionMapping {
|
|
|
|
usage('java-api') {
|
|
|
|
fromResolutionOf('runtimeClasspath')
|
|
|
|
}
|
|
|
|
usage('java-runtime') {
|
|
|
|
fromResolutionResult()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{{- if .ArtifactGroupID}}
|
|
|
|
groupId = '{{.ArtifactGroupID}}'
|
|
|
|
{{- end }}
|
|
|
|
{{- if .ArtifactID}}
|
|
|
|
artifactId = '{{.ArtifactID}}'
|
|
|
|
{{- end }}
|
|
|
|
{{- if .ArtifactVersion}}
|
|
|
|
version = '{{.ArtifactVersion}}'
|
|
|
|
{{- end }}
|
|
|
|
from components.java
|
|
|
|
}
|
|
|
|
}
|
|
|
|
repositories {
|
|
|
|
maven {
|
|
|
|
credentials {
|
|
|
|
username = "{{.RepositoryUsername}}"
|
|
|
|
password = "{{.RepositoryPassword}}"
|
|
|
|
}
|
|
|
|
url = "{{.RepositoryURL}}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
|
|
|
const bomInitScriptContent = `
|
|
|
|
initscript {
|
|
|
|
repositories {
|
|
|
|
mavenCentral()
|
|
|
|
maven {
|
|
|
|
url "https://plugins.gradle.org/m2/"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dependencies {
|
2022-08-01 13:38:49 +02:00
|
|
|
classpath "org.cyclonedx:cyclonedx-gradle-plugin:1.7.0"
|
2022-06-07 10:24:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rootProject {
|
|
|
|
apply plugin: 'java'
|
|
|
|
apply plugin: 'maven'
|
|
|
|
apply plugin: org.cyclonedx.gradle.CycloneDxPlugin
|
2022-08-01 13:38:49 +02:00
|
|
|
|
|
|
|
cyclonedxBom {
|
|
|
|
outputName = "` + gradleBomFilename + `"
|
|
|
|
outputFormat = "xml"
|
|
|
|
schemaVersion = "1.2"
|
|
|
|
}
|
2022-06-07 10:24:10 +02:00
|
|
|
}
|
|
|
|
`
|
|
|
|
|
2022-10-25 13:17:42 +02:00
|
|
|
// PublishedArtifacts contains information about published artifacts
|
|
|
|
type PublishedArtifacts struct {
|
|
|
|
Elements []Element `json:"variants,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Element struct {
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Artifacts []Artifact `json:"files,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Artifact struct {
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
}
|
|
|
|
|
2021-12-22 16:34:36 +02:00
|
|
|
type gradleExecuteBuildUtils interface {
|
|
|
|
command.ExecRunner
|
2022-04-14 14:59:09 +02:00
|
|
|
piperutils.FileUtils
|
2021-12-22 16:34:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type gradleExecuteBuildUtilsBundle struct {
|
|
|
|
*command.Command
|
|
|
|
*piperutils.Files
|
|
|
|
}
|
|
|
|
|
|
|
|
func newGradleExecuteBuildUtils() gradleExecuteBuildUtils {
|
|
|
|
utils := gradleExecuteBuildUtilsBundle{
|
2022-08-05 13:08:19 +02:00
|
|
|
Command: &command.Command{
|
|
|
|
StepName: "gradleExecuteBuild",
|
|
|
|
},
|
|
|
|
Files: &piperutils.Files{},
|
2021-12-22 16:34:36 +02:00
|
|
|
}
|
|
|
|
utils.Stdout(log.Writer())
|
|
|
|
utils.Stderr(log.Writer())
|
|
|
|
return &utils
|
|
|
|
}
|
|
|
|
|
2022-10-25 13:17:42 +02:00
|
|
|
func gradleExecuteBuild(config gradleExecuteBuildOptions, telemetryData *telemetry.CustomData, pipelineEnv *gradleExecuteBuildCommonPipelineEnvironment) {
|
2021-12-22 16:34:36 +02:00
|
|
|
utils := newGradleExecuteBuildUtils()
|
2022-10-25 13:17:42 +02:00
|
|
|
err := runGradleExecuteBuild(&config, telemetryData, utils, pipelineEnv)
|
2021-12-22 16:34:36 +02:00
|
|
|
if err != nil {
|
2022-04-14 14:59:09 +02:00
|
|
|
log.Entry().WithError(err).Fatalf("step execution failed: %v", err)
|
2021-12-22 16:34:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-25 13:17:42 +02:00
|
|
|
func runGradleExecuteBuild(config *gradleExecuteBuildOptions, telemetryData *telemetry.CustomData, utils gradleExecuteBuildUtils, pipelineEnv *gradleExecuteBuildCommonPipelineEnvironment) error {
|
2022-06-07 10:24:10 +02:00
|
|
|
log.Entry().Info("BOM file creation...")
|
|
|
|
if config.CreateBOM {
|
|
|
|
if err := createBOM(config, utils); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-03-21 11:17:03 +02:00
|
|
|
}
|
2021-12-22 16:34:36 +02:00
|
|
|
|
2022-06-07 10:24:10 +02:00
|
|
|
// gradle build
|
|
|
|
gradleOptions := &gradle.ExecuteOptions{
|
|
|
|
BuildGradlePath: config.Path,
|
|
|
|
Task: config.Task,
|
|
|
|
UseWrapper: config.UseWrapper,
|
|
|
|
}
|
|
|
|
if _, err := gradle.Execute(gradleOptions, utils); err != nil {
|
2022-04-14 14:59:09 +02:00
|
|
|
log.Entry().WithError(err).Errorf("gradle build execution was failed: %v", err)
|
2021-12-22 16:34:36 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-06-07 10:24:10 +02:00
|
|
|
log.Entry().Info("Publishing of artifacts to staging repository...")
|
|
|
|
if config.Publish {
|
2022-10-25 13:17:42 +02:00
|
|
|
if err := publishArtifacts(config, utils, pipelineEnv); err != nil {
|
2022-06-07 10:24:10 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func createBOM(config *gradleExecuteBuildOptions, utils gradleExecuteBuildUtils) error {
|
|
|
|
gradleOptions := &gradle.ExecuteOptions{
|
|
|
|
BuildGradlePath: config.Path,
|
|
|
|
Task: bomGradleTaskName,
|
|
|
|
UseWrapper: config.UseWrapper,
|
|
|
|
InitScriptContent: bomInitScriptContent,
|
|
|
|
}
|
|
|
|
if _, err := gradle.Execute(gradleOptions, utils); err != nil {
|
|
|
|
log.Entry().WithError(err).Errorf("failed to create BOM: %v", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-25 13:17:42 +02:00
|
|
|
func publishArtifacts(config *gradleExecuteBuildOptions, utils gradleExecuteBuildUtils, pipelineEnv *gradleExecuteBuildCommonPipelineEnvironment) error {
|
2022-06-07 10:24:10 +02:00
|
|
|
publishInitScriptContent, err := getPublishInitScriptContent(config)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to get publish init script content: %v", err)
|
|
|
|
}
|
|
|
|
gradleOptions := &gradle.ExecuteOptions{
|
|
|
|
BuildGradlePath: config.Path,
|
|
|
|
Task: publishTaskName,
|
|
|
|
UseWrapper: config.UseWrapper,
|
|
|
|
InitScriptContent: publishInitScriptContent,
|
|
|
|
}
|
|
|
|
if _, err := gradle.Execute(gradleOptions, utils); err != nil {
|
|
|
|
log.Entry().WithError(err).Errorf("failed to publish artifacts: %v", err)
|
|
|
|
return err
|
|
|
|
}
|
2022-10-25 13:17:42 +02:00
|
|
|
artifacts, err := getPublishedArtifactsNames(pathToModuleFile, utils)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to get published artifacts: %v", err)
|
|
|
|
}
|
|
|
|
pipelineEnv.custom.artifacts = artifacts
|
2021-12-22 16:34:36 +02:00
|
|
|
return nil
|
|
|
|
}
|
2022-06-07 10:24:10 +02:00
|
|
|
|
|
|
|
func getPublishInitScriptContent(options *gradleExecuteBuildOptions) (string, error) {
|
|
|
|
tmpl, err := template.New("resources").Parse(publishInitScriptContentTemplate)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
var generatedCode bytes.Buffer
|
|
|
|
err = tmpl.Execute(&generatedCode, options)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-07-21 09:04:21 +02:00
|
|
|
return generatedCode.String(), nil
|
2022-06-07 10:24:10 +02:00
|
|
|
}
|
2022-10-25 13:17:42 +02:00
|
|
|
|
|
|
|
func getPublishedArtifactsNames(file string, utils gradleExecuteBuildUtils) (piperenv.Artifacts, error) {
|
|
|
|
artifacts := piperenv.Artifacts{}
|
|
|
|
publishedArtifacts := PublishedArtifacts{}
|
|
|
|
exists, err := utils.FileExists(file)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to check existence of the file '%s': %v", file, err)
|
|
|
|
}
|
|
|
|
if !exists {
|
|
|
|
return nil, fmt.Errorf("failed to get '%s': file does not exist", file)
|
|
|
|
}
|
|
|
|
content, err := utils.ReadFile(file)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to read '%s': %v", file, err)
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(content, &publishedArtifacts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to unmarshal '%s': %v", file, err)
|
|
|
|
}
|
|
|
|
for _, element := range publishedArtifacts.Elements {
|
|
|
|
if element.Name != "apiElements" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, artifact := range element.Artifacts {
|
|
|
|
artifacts = append(artifacts, piperenv.Artifact{Name: artifact.Name})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return artifacts, nil
|
|
|
|
}
|