2018-10-30 17:49:53 +02:00
import static com . sap . piper . Prerequisites . checkScript
2019-03-29 13:46:25 +02:00
import com.sap.piper.GenerateDocumentation
2018-10-25 16:56:09 +02:00
import com.sap.piper.Utils
import com.sap.piper.ConfigurationHelper
import groovy.transform.Field
2018-11-29 10:54:05 +02:00
@Field String STEP_NAME = getClass ( ) . getName ( )
2019-03-29 13:46:25 +02:00
@Field Set GENERAL_CONFIG_KEYS = [
/** Allows to overwrite the GitHub API url.*/
'githubApiUrl' ,
/ * *
* Allows to overwrite the GitHub token credentials id .
* @possibleValues Jenkins credential id
* /
'githubTokenCredentialsId' ,
/** Allows to overwrite the GitHub url.*/
'githubServerUrl'
]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS . plus ( [
/ * *
* If it is set to ` true ` , a list of all closed issues and merged pull - requests since the last release will added below the ` releaseBodyHeader ` .
* @possibleValues ` true ` , ` false `
* /
2018-10-25 16:56:09 +02:00
'addClosedIssues' ,
2019-03-29 13:46:25 +02:00
/ * *
* If you set ` addDeltaToLastRelease ` to ` true ` , a link will be added to the relese information that brings up all commits since the last release .
* @possibleValues ` true ` , ` false `
* /
2018-10-25 16:56:09 +02:00
'addDeltaToLastRelease' ,
2019-03-29 13:46:25 +02:00
/** Allows to pass additional filter criteria for retrieving closed issues since the last release. Additional criteria could be for example specific `label`, or `filter` according to [GitHub API documentation](https://developer.github.com/v3/issues/).*/
2018-10-25 16:56:09 +02:00
'customFilterExtension' ,
2019-03-29 13:46:25 +02:00
/** Allows to exclude issues with dedicated labels. Usage is like `excludeLabels: ['label1', 'label2']`.*/
2018-10-25 16:56:09 +02:00
'excludeLabels' ,
2019-03-29 13:46:25 +02:00
/** Allows to overwrite the GitHub organitation.*/
2018-10-25 16:56:09 +02:00
'githubOrg' ,
2019-03-29 13:46:25 +02:00
/** Allows to overwrite the GitHub repository.*/
2018-10-25 16:56:09 +02:00
'githubRepo' ,
2019-03-29 13:46:25 +02:00
/** Allows to specify the content which will appear for the release.*/
2018-10-25 16:56:09 +02:00
'releaseBodyHeader' ,
2019-03-29 13:46:25 +02:00
/** Defines the version number which will be written as tag as well as release name.*/
2018-10-25 16:56:09 +02:00
'version'
2019-03-29 13:46:25 +02:00
] )
2018-10-25 16:56:09 +02:00
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
2019-03-29 13:46:25 +02:00
/ * *
* This step creates a tag in your GitHub repository together with a release .
*
* The release can be filled with text plus additional information like:
*
* * Closed pull request since last release
* * Closed issues since last release
* * link to delta information showing all commits since last release
*
* The result looks like
*
* ! [ Example release ] ( . . /images/ githubRelease . png )
* /
@GenerateDocumentation
2018-10-25 16:56:09 +02:00
void call ( Map parameters = [ : ] ) {
handlePipelineStepErrors ( stepName: STEP_NAME , stepParameters: parameters ) {
2018-10-31 09:40:12 +02:00
def script = checkScript ( this , parameters ) ? : this
2018-10-25 16:56:09 +02:00
// load default & individual configuration
Map config = ConfigurationHelper . newInstance ( this )
. loadStepDefaults ( )
. mixinGeneralConfig ( script . commonPipelineEnvironment , GENERAL_CONFIG_KEYS )
. mixinStepConfig ( script . commonPipelineEnvironment , STEP_CONFIG_KEYS )
. mixinStageConfig ( script . commonPipelineEnvironment , parameters . stageName ? : env . STAGE_NAME , STEP_CONFIG_KEYS )
. mixin ( parameters , PARAMETER_KEYS )
. addIfEmpty ( 'githubOrg' , script . commonPipelineEnvironment . getGithubOrg ( ) )
. addIfEmpty ( 'githubRepo' , script . commonPipelineEnvironment . getGithubRepo ( ) )
. addIfEmpty ( 'version' , script . commonPipelineEnvironment . getArtifactVersion ( ) )
. withMandatoryProperty ( 'githubOrg' )
. withMandatoryProperty ( 'githubRepo' )
. withMandatoryProperty ( 'githubTokenCredentialsId' )
. withMandatoryProperty ( 'version' )
. use ( )
new Utils ( ) . pushToSWA ( [ step: STEP_NAME ] , config )
withCredentials ( [ string ( credentialsId: config . githubTokenCredentialsId , variable: 'TOKEN' ) ] ) {
def releaseBody = config . releaseBodyHeader ? "${config.releaseBodyHeader}<br />" : ''
def content = getLastRelease ( config , TOKEN )
if ( config . addClosedIssues )
releaseBody + = addClosedIssue ( config , TOKEN , content . published_at )
if ( config . addDeltaToLastRelease )
releaseBody + = addDeltaToLastRelease ( config , content . tag_name )
postNewRelease ( config , TOKEN , releaseBody )
}
}
}
Map getLastRelease ( config , TOKEN ) {
def result = [ : ]
def response = httpRequest "${config.githubApiUrl}/repos/${config.githubOrg}/${config.githubRepo}/releases/latest?access_token=${TOKEN}"
if ( response . status = = 200 ) {
result = readJSON text: response . content
} else {
echo "[${STEP_NAME}] This is the first release - no previous releases available"
config . addDeltaToLastRelease = false
}
return result
}
String addClosedIssue ( config , TOKEN , publishedAt ) {
if ( config . customFilterExtension ) {
config . customFilterExtension = "&${config.customFilterExtension}"
}
def publishedAtFilter = publishedAt ? "&since=${publishedAt}" : ''
def response = httpRequest "${config.githubApiUrl}/repos/${config.githubOrg}/${config.githubRepo}/issues?access_token=${TOKEN}&per_page=100&state=closed&direction=asc${publishedAtFilter}${config.customFilterExtension}"
def result = ''
content = readJSON text: response . content
//list closed pull-requests
result + = '<br />**List of closed pull-requests since last release**<br />'
for ( def item : content ) {
if ( item . pull_request & & ! isExcluded ( item , config . excludeLabels ) ) {
result + = "[#${item.number}](${item.html_url}): ${item.title}<br />"
}
}
//list closed issues
result + = '<br />**List of closed issues since last release**<br />'
for ( def item : content ) {
if ( ! item . pull_request & & ! isExcluded ( item , config . excludeLabels ) ) {
result + = "[#${item.number}](${item.html_url}): ${item.title}<br />"
}
}
return result
}
String addDeltaToLastRelease ( config , latestTag ) {
def result = ''
//add delta link to previous release
result + = '<br />**Changes**<br />'
result + = "[${latestTag}...${config.version}](${config.githubServerUrl}/${config.githubOrg}/${config.githubRepo}/compare/${latestTag}...${config.version}) <br />"
return result
}
void postNewRelease ( config , TOKEN , releaseBody ) {
releaseBody = releaseBody . replace ( '"' , '\\"' )
//write release information
def data = "{\"tag_name\": \"${config.version}\",\"target_commitish\": \"master\",\"name\": \"${config.version}\",\"body\": \"${releaseBody}\",\"draft\": false,\"prerelease\": false}"
try {
httpRequest httpMode: 'POST' , requestBody: data , url: "${config.githubApiUrl}/repos/${config.githubOrg}/${config.githubRepo}/releases?access_token=${TOKEN}"
} catch ( e ) {
echo "" " [ $ { STEP_NAME } ] Error occured when writing release information
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Request body was:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$ { data }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "" "
throw e
}
}
boolean isExcluded ( item , excludeLabels ) {
def result = false
excludeLabels . each { labelName - >
item . labels . each { label - >
if ( label . name = = labelName ) {
result = true
}
}
}
return result
}