Skip to content

Commit

Permalink
Setup helper to stage artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
radtriste authored and rsynek committed Dec 1, 2020
1 parent 90373cd commit fe7036a
Show file tree
Hide file tree
Showing 8 changed files with 470 additions and 38 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Eclipse, Netbeans and IntelliJ files
/.*
!.gitignore
!.jenkins
/nbproject
/*.ipr
/*.iws
Expand Down
52 changes: 52 additions & 0 deletions .jenkins/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

local_lib=""

changeAuthor = env.ghprbPullAuthorLogin ?: CHANGE_AUTHOR
changeBranch = env.ghprbSourceBranch ?: CHANGE_BRANCH
changeTarget = env.ghprbTargetBranch ?: CHANGE_TARGET

repo = 'jenkins-pipeline-shared-libraries'

pipeline {
agent {
label 'kie-rhel7 && !master'
}

stages {
stage('Initialize') {
steps {
script {
local_lib = library identifier: "local-lib@${changeBranch}",
retriever: modernSCM([$class: 'GitSCMSource',
remote: "https://github.com/${changeAuthor}/${repo}",
branches: "${changeBranch}",
credentialsId: 'kie-ci']),
changelog: false

githubscm.checkoutIfExists(repo, changeAuthor, changeBranch, 'kiegroup', changeTarget, true)
}
}
}

stage('Test MavenCommand') {
steps {
script {
local_lib.org.kie.jenkins.MavenCommand.new(this).withSettingsXmlId(maven.getSubmarineSettingsXmlId()).run('clean')
}
}
}

stage('Test Maven') {
steps {
script {
maven.runMavenWithSettings(maven.getSubmarineSettingsXmlId(), 'clean', null)
}
}
}
}
post {
always {
cleanWs()
}
}
}
26 changes: 0 additions & 26 deletions Jenkinsfile

This file was deleted.

87 changes: 79 additions & 8 deletions src/org/kie/jenkins/MavenCommand.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ def class MavenCommand {

def steps

boolean returnStdout = false
String directory = ''

String settingsXmlConfigFileId = ''
String settingsXmlPath = ''
Map dependenciesRepositories = [:]

List mavenOptions = []
Map properties = [:]
String logFileName = null
String logFileName = ''
List profiles = []

boolean printSettings = false
boolean returnStdout = false

MavenCommand(steps){
this.steps = steps
}
Expand All @@ -23,9 +29,23 @@ def class MavenCommand {

def run(String goals) {
def cmdBuilder = new StringBuilder("mvn -B")
if(this.settingsXmlPath) {
cmdBuilder.append(" -s ${this.settingsXmlPath}")

// Retrieve settings file from id if given
String settingsFile = this.settingsXmlPath
if(this.settingsXmlConfigFileId){
steps.configFileProvider([steps.configFile(fileId: this.settingsXmlConfigFileId, targetLocation: 'maven-settings.xml', variable: 'MAVEN_SETTINGS_XML')]) {
settingsFile = steps.env['MAVEN_SETTINGS_XML']
}
}
if(settingsFile) {
this.dependenciesRepositories.each { setRepositoryInSettings(settingsFile, it.key, it.value) }
cmdBuilder.append(" -s ${settingsFile}")

if(this.printSettings){
steps.sh "cat ${settingsFile}"
}
}

if(this.mavenOptions.size() > 0){
cmdBuilder.append(' ').append(this.mavenOptions.join(' '))
}
Expand All @@ -39,14 +59,29 @@ def class MavenCommand {
if(this.logFileName){
cmdBuilder.append(" | tee \$WORKSPACE/${this.logFileName} ; test \${PIPESTATUS[0]} -eq 0")
}
if(directory) {
steps.dir(directory) {
return runCommand(cmdBuilder.toString())
}
} else {
return runCommand(cmdBuilder.toString())
}
}

private def runCommand(String cmd){
return steps.sh(script: cmd, returnStdout: this.returnStdout)
}

return steps.sh(script: cmdBuilder.toString(), returnStdout: this.returnStdout)
MavenCommand inDirectory(String directory) {
this.directory = directory
return this
}

/**
* IF set, override `withSettingsXmlFile`
**/
MavenCommand withSettingsXmlId(String settingsXmlId){
steps.configFileProvider([steps.configFile(fileId: settingsXmlId, targetLocation: 'maven-settings.xml', variable: 'MAVEN_SETTINGS_XML')]) {
withSettingsXmlFile(steps.env['MAVEN_SETTINGS_XML'])
}
this.settingsXmlConfigFileId = settingsXmlId
return this
}

Expand All @@ -56,6 +91,16 @@ def class MavenCommand {
return this
}

MavenCommand withDependencyRepositoryInSettings(String repoId, String repoUrl){
this.dependenciesRepositories.put(repoId, repoUrl)
return this
}

MavenCommand withDependencyRepositoriesInSettings(Map repositories = [:]){
this.dependenciesRepositories.putAll(repositories)
return this
}

MavenCommand withOptions(List opts) {
this.mavenOptions.addAll(opts)
return this
Expand Down Expand Up @@ -106,17 +151,43 @@ def class MavenCommand {
.withOptions(this.mavenOptions)
.withPropertyMap(this.properties)
.withProfiles(this.profiles)
.withDependencyRepositoriesInSettings(this.dependenciesRepositories)
if(this.settingsXmlConfigFileId){
newCmd.withSettingsXmlId(this.settingsXmlConfigFileId)
}
if(this.settingsXmlPath){
newCmd.withSettingsXmlFile(this.settingsXmlPath)
}
if(this.logFileName){
newCmd.withLogFileName(this.logFileName)
}
if(this.directory){
newCmd.inDirectory(this.directory)
}
if(this.returnStdout){
newCmd.returnOutput()
}
return newCmd
}

MavenCommand returnOutput(){
this.returnStdout = true
return this
}

MavenCommand printSettings(){
this.printSettings = true
return this
}

private void setRepositoryInSettings(String settingsFilePath, String repoId, String repoUrl) {
def depsRepositoryContent = "<id>${repoId}</id><name>${repoId}</name><url>${repoUrl}</url><layout>default</layout><snapshots><enabled>true</enabled></snapshots><releases><enabled>true</enabled></releases>"
steps.sh """
sed -i 's|<repositories>|<repositories><!-- BEGIN added repository --><repository>${depsRepositoryContent}</repository><!-- END added repository -->|g' ${settingsFilePath}
sed -i 's|<pluginRepositories>|<pluginRepositories><!-- BEGIN added repository --><pluginRepository>${depsRepositoryContent}</pluginRepository><!-- END added repository -->|g' ${settingsFilePath}
sed -i 's|</mirrorOf>|,!${repoId}</mirrorOf>|g' ${settingsFilePath}
"""

withProperty('enforcer.skip', true)
}
}
146 changes: 146 additions & 0 deletions src/org/kie/jenkins/MavenStagingHelper.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package org.kie.jenkins

/**
* Helper to stage and promote artifacts to Nexus
*
* Prerequisites: Your artifacts should be deployed locally before using this helper
*
* Actions:
* 1 - stageLocalArtifacts will create a staging repository and close it once done so your artifacts can be accessible.
* In the return properties, you can find the staging properties (id and link).
* 2 - promoteStagingRepository will promote a given staging repository to a build promotion profile.
* This is useful if you have many staging repositories, so that all of them can be accessible in one URL.
*
* More information
* - https://help.sonatype.com/repomanager2/staging-releases
* - https://github.com/sonatype/nexus-maven-plugins/tree/master/staging/maven-plugin#deploy-staged-repository
*/
def class MavenStagingHelper {

static String nexusPluginGroupId = 'org.sonatype.plugins'
static String nexusStagingPluginArtifactId = 'nexus-staging-maven-plugin'
static String nexusStagingPluginVersion = '1.6.5'

def steps

MavenCommand mvnCommand

String nexusReleaseUrl = 'https://repository.jboss.org/nexus'
String nexusReleaseRepositoryId = 'jboss-releases-repository'

// If not defined, will retrieve default from project artifactId & version
String stagingDescription

// Will be filled once `stageLocalArtifacts` is called or via the `withStagingRepositoryId` method
String stagingRepositoryId

MavenStagingHelper(steps){
this(steps, new MavenCommand(steps))
}

MavenStagingHelper(steps, mvnCommand){
this.steps = steps
this.mvnCommand = mvnCommand
}

/**
* Use this method to stage artifacts that have been deployed locally (in given `localArtifactsFolder` parameter)
* It returns a Map of staging properties
*/
Map stageLocalArtifacts(String stagingProfileId, String localArtifactsFolder){
assert stagingProfileId: 'Please provide a stagingProfileId'
assert localArtifactsFolder: 'Please provide a local folder where artifacts are stored'

steps.println "[INFO] Staging artifacts to staging profile ID ${stagingProfileId}"

getDefaultMavenCommand()
.withProperty('keepStagingRepositoryOnCloseRuleFailure', true)
.withProperty('stagingProgressTimeoutMinutes', 10)
.withProperty('repositoryDirectory', localArtifactsFolder)
.withProperty('stagingProfileId', stagingProfileId)
.run(getNexusStagingRunCommand('deploy-staged-repository'))

// Retrieve `stagingRepositoryId` and fill it
Map stagingProps = retrieveStagingProperties(localArtifactsFolder)
withStagingRepositoryId(stagingProps['stagingRepository.id'])

return stagingProps
}

/**
* Use this method to promote a staging repository to a specific build promotion profile.
* Note that if you did not execute `stageLocalArtifacts` first, you will need to provide the staging repository id via `withStagingRepositoryId`
*/
def promoteStagingRepository(String buildPromotionProfileId) {
assert this.stagingRepositoryId: 'Please provide a stagingRepositoryId via staging local artifacts or via withStagingRepositoryId method'
assert buildPromotionProfileId: 'Please provide a buildPromotionProfileId'

steps.println "[INFO] Promote artifacts from staging repository ${this.stagingRepositoryId} to build promotion profile ID ${buildPromotionProfileId}"

getDefaultMavenCommand()
.withProperty('buildPromotionProfileId', buildPromotionProfileId)
.withProperty('stagingRepositoryId', this.stagingRepositoryId)
.run(getNexusStagingRunCommand('promote'))
}

private MavenCommand getDefaultMavenCommand(){
String projectName = getProjectArtifactId()
String projectVersion = getProjectVersion()
String description = this.stagingDescription ?: "${projectName} ${projectVersion}"

return this.mvnCommand.clone()
.withOptions(["--projects :${projectName}"])
.withProperty('nexusUrl', this.nexusReleaseUrl)
.withProperty('serverId', this.nexusReleaseRepositoryId)
.withProperty('stagingDescription', "'${description}'")
}

MavenStagingHelper withNexusReleaseUrl(String nexusReleaseUrl) {
this.nexusReleaseUrl = nexusReleaseUrl
return this
}

MavenStagingHelper withNexusReleaseRepositoryId(String nexusReleaseRepositoryId) {
this.nexusReleaseRepositoryId = nexusReleaseRepositoryId
return this
}

MavenStagingHelper withStagingDescription(String stagingDescription) {
this.stagingDescription = stagingDescription
return this
}

MavenStagingHelper withStagingRepositoryId(String stagingRepositoryId) {
this.stagingRepositoryId = stagingRepositoryId
return this
}

private Properties retrieveStagingProperties(String folder){
String repositoryPropsFile = steps.sh(script: "find ${folder} -name *.properties", returnStdout: true).trim()
steps.println "[INFO] Got staging properties file ${repositoryPropsFile}"
assert repositoryPropsFile: 'No staging properties file has been found'

return steps.readProperties(file: repositoryPropsFile)
}

private String getProjectArtifactId() {
return executeMavenHelpEvaluateCommand('project.artifactId')
}
private String getProjectVersion() {
return executeMavenHelpEvaluateCommand('project.version')
}
private String executeMavenHelpEvaluateCommand(String expression){
return this.mvnCommand.clone()
.withOptions(['-q'])
.withProperty('expression', expression)
.withProperty('forceStdout')
.returnOutput()
.run('help:evaluate')
.trim()
}

private static String getNexusStagingRunCommand(String target){
return "${nexusPluginGroupId}:${nexusStagingPluginArtifactId}:${nexusStagingPluginVersion}:${target}"
}

}
Loading

0 comments on commit fe7036a

Please sign in to comment.