Jenkins declarative pipe, download latest upload (build) from Artifactory and get properties - jenkins-pipeline

Any sugesstions on this litle problem is very welcome! :)
It works fine to download the latest build but the object does not contain any properties.
Is it possible to get the properties from a downloaded build?
The gool is to get an inputbox with a predefined value displaying previous version i.e. "R1G" and give the user the option to edit the value to i.e. R2A or any other value or only abort (abort meaning there will be no version).
The user also have the option to do nothing withch will led to a timeoute and finaly an abort.
I want to
download latest build from Artifactory repo
store the build.number in "def prev_build"
display the prev_build in an input for the user to be updated (a customized number)
'''some code
echo 'Publiching Artifact.....'
script{
def artifactory_server_down=Artifactory.server 'Artifactory'
def downLoad = """{
"files":
[
{
"pattern": "reponame/",
"target": "${WORKSPACE}/prev/",
"recursive": "false",
"flat" : "false"
}
]
}"""
def buildInfodown=artifactory_server_down.download(downLoad)
//Dont need to publish because I only need the properties
//Grab the latest revision name here and use it again
echo 'Retriving revision from last uploaded build.....'
env.LAST_BUILD_NAME=buildInfodown.build.number
//Yes its a map and I have tried with ['build.number'] but the map is empty
}
echo "Previous build name is $env.LAST_BUILD_NAME" //Will not contain the old (latest)
''' End of snipet
The output is null or the default value I have given the var, not the expected version number.

Yes, firstly the properties should be present in the artifacts you are trying to download.
The build.number etc are part of the buildinfo.json file of the artifacts. these are not properties but metadata of some kind. this info would be visible under "Builds" menu in artifactory. Select the repo and build number.
At the last column/tab there would be buildinfo. Click on that - this file will hold all the info you need corresponding to the artifacts.
The build.number and other info will be pushed/uploaded to artifactory by the CI.
For example in case of Jenkins there is an option available when trying to push to artifactory "Capture and publish build info" --> this step does the work

Thanks a lot for your help.
I see your suggestion works but I had when I got your answer already implemented another solution that also works well
I am using the available query language.
https://www.jfrog.com/confluence/display/RTF/Artifactory+Query+Language
Just before my pipeline declaration in the pipeline file I added
def artifactory_url = 'https://lote.corp.saab.se:8443/artifactory/api/search/aql'
def artifactory_search = 'items.find({ "repo":"my_repo"},{"#product.productNumber":
{"$match":"produktname"}}).sort({"$desc":["created"]})'
pipeline
{
and ...
stage('Get latest revision') {
steps {
script {
def json_text = sh(script: "curl -H 'X-JFrog-Art-Api:${env.RECIPE_API_KEY}' -X POST '${artifactory_url}' -d '${artifactory_search}' -H 'Content-Type: text/plain' -k", returnStdout: true).trim()
def response = readJSON text: json_text
VERSION = response.results[0].path;
echo "${VERSION}"
println 'using each & entry'
response[0].each{ entry ->
println 'Key:' + entry.key + ', Value:' +
entry.value
}
}
}
}
stage('Do relesase on master')
{
when
{
branch "master"
}
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
script{
RELEASE_SCOPE = input message: 'User input
required', ok: 'Ok to go?!',
parameters: [
choice(name: 'RELEASE_TYPE', choices:
'Artifactory\nClearCaseAndArtifactory\nAbort',
description: 'What is the release scope?'),
string(name: 'VERSION', defaultValue:
VERSION, description: '''Edit release name please!!''',
trim: false)
]
}
echo 'Build both RPM and Zip packages'
... gradlew -Pversion=${RELEASE_SCOPE['VERSION']} clean buildPackages"
script {
def artifactory_server = Artifactory.server 'Artifactory'
def buildInfo = Artifactory.newBuildInfo()
def uploadSpec = """{
"files":[
{
"pattern": "${env.WORKSPACE}/prodname/release/build/distributions/prodname*.*",
"target": "test_repo/${RELEASE_SCOPE['VERSION']}/",
"props": "product.name=ProdName;build.name=${JOB_NAME};build.number=${env.BUILD_NUMBER};product.revision=${RELEASE_SCOPE['VERSION']};product.productNumber=produktname"
}
]
}"""
println(uploadSpec)
artifactory_server.upload(uploadSpec)
}
}
}

Related

Using Function in JenkinsFile Parameter Description

I am trying to add a function in JenkinsFile Declarative pipelines parameter's description but struggling to make it work.
Idea is to have a Jenkins Job specific for the environment. and would like to see the choice parameter to show environment name in the description of the variable.
My pipeline looks like this
def check_env = app_env(ENVS, env.JOB_NAME)
pipeline {
agent { label 'master' }
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
timestamps()
}
parameters{
string(name: 'myVariable', defaultValue: "/", description: 'Enter Path To App e.g / OR /dummy_path for ' {check_env} )
}
stages{
stage('Running App') {
agent {
docker {
image 'myApp:latest'
}
}
steps{
script{
sh label: 'App', script: "echo "App is running in ${check_env} "
}
}
}
}
}
}
I have tried multiple combinations for check_env e.g check_env, check_env(), ${check_env} function but none of them worked.
String Interpolation
I believe this is simply a String Interpolation issue. Notice my use of double quotes below
parameters{
string(name: 'myVariable', defaultValue: "/", description: "Enter Path To App e.g / OR /dummy_path for ${check_env}")
}
Your build page should then interpolate your variable
To test I simply set def check_env = 'live' since I do not have the code for your method

How to configure jenkins pipeline with logstash plugin?

Usecase: I want to send jenkins job console log to elasticsearch, from there to kibana so that i can visualise the data.
I am using logstash plugin to achieve this. For freestyle job logstash plugin configuration is working fine but for jenkins pipeline jobs I am getting all required data like build number, job name, build duration and all but it is not showing the build result i.e., success or failure it is not showing.
I tried in two ways:
1.
stage('send to ES') {
logstashSend failBuild: true, maxLines: -1
}
2.
timestamps {
logstash {
node() {
sh'''
echo 'Hello, World!'
'''
try {
stage('GitSCM')
{
git url: 'github repo.git'
}
stage('Initialize')
{
jdk = tool name: 'jdk'
env.JAVA_HOME = "${jdk}"
echo "jdk installation path is: ${jdk}"
sh "${jdk}/bin/java -version"
sh '$JAVA_HOME/bin/java -version'
def mvnHome = tool 'mvn'
}
stage('Build Stage')
{
def mvnHome = tool 'mvn'
sh "${mvnHome}/bin/mvn -B verify"
}
currentBuild.result = 'SUCCESS'
} catch (Exception err) {
currentBuild.result = 'FAILURE'
}
}
}
}
But in both ways I am not getting build result i.e., success or failure in my elasticsearch or kibana.
Can someone help.
I didn't find a clear way to do that, my solution was add those lines at the end of the Jenkinsfile:
echo "Current result: ${currentBuild.currentResult}"
logstashSend failBuild: true, maxLines: 3
In my case, I dont need it to send all console logs, only one log with the result per job.

Jenkins custom pipeline and how to add property to be set in jenkinsfile

I'm trying to create a custom pipeline with groovy but I can't find anywhere on the web where it is discussed how to add a property that can be set in the jenkinsfile. I'm trying to add a curl command but need the URL to be set in the jenkinsfile because it will be different for each build.
Can anyone explain how that should be done or links where it has been discussed?
Example Jenkinsfile:
msBuildPipelinePlugin
{
curl_url = "http://webhook.url.com"
}
custom pipeline groovy code:
def response = sh(script: 'curl -i -X POST -H 'Content-Type: application/json' -d '{"text","Jenkins Info.\nThis is more text"}' curl_url, returnStdout: true)
Thanks
If you want to specify the URL as a string during every build, you can do either of the following:
Declarative Pipeline
Use the parameters {} directive:
pipeline {
agent {
label 'rhel-7'
}
parameters {
string(
name: 'CURL_URL',
defaultValue: 'http://www.google.com',
description: 'Enter the URL for file download'
)
}
stages {
stage('download-file') {
steps {
echo "The URL is ${params.CURL_URL}"
}
}
}
}
Scripted Pipeline
Use the properties([parameters([...])]) step:
parameters([
string(
name: 'CURL_URL',
defaultValue: 'http://www.google.com',
description: 'Enter the URL for file download'
)
])
node('rhel-7') {
stage('download-file') {
echo "The URL is ${params.CURL_URL}"
}
}
You can choose to leave the values of defaultValue and description empty.
Job GUI
Either of the above syntax will be rendered in the GUI as:
I got it to work using
//response is just the output of the curl statement
def response = ["curl", "-i", "-v", "-X", "POST", "--data-urlencode", "payload={\"text\":\"message body\"}", "curl url goes here"].execute().text
Thanks

How to ask user input only when branch matches master in Jenkinsfile pipeline?

I tried to use the following Jenkinsfile to ask input only on master branch and can't get the groovy grammer pass validation:
pipeline {
stage('Deploy') {
when {
branch 'master'
}
steps {
input(message: "Please input", parameters: [string(name: "VERSION", defaultValue="", description="")]
}
}
}
The error is:
java.lang.IllegalArgumentException: Expected named arguments but got [{name=VERSION, description=""}, null]
I searched a lot but didn't find a single one example about using input step in the Jenkinsfile with parameters.
Can anyone shed some light on this? Thanks in advance!
Finally find a way to do this, we should wrap the input with the script keyword.
stage('Deploy to k8s prod') {
when {
branch 'release-prod'
}
steps {
script {
env.VERSION = input message: '请输入参数', ok: '确定', parameters: [
string(name:'VERSION', description: "版本号")]
}
sh "echo ${env.VERSION}"
}
}
}

Groovy SwingBuilder() apple.awt.CToolkit exception

I am using newest Mac OS X and I am creating a GUI element inside a Gradle file. I am currently using jdk1.7.0_55 and I have imported groovy.swing.SwingBuilder, when I run the project I am getting the following error:
java.awt.AWTError: "Toolkit not found: apple.awt.CToolkit
I have tried running the script as a headless server using System.setProperty('java.awt.headless', 'true')
I would like to have a solution that I can include directly in the Gradle project file, instead of trying to figure out what is in my accesibilities.properties file (that may not exist on a particular system, like it does not on my system).
Also the project must use an internal solution, external libraries are not allowed.
Would really appreciate any help on this matter.
Edited: Sample Code
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(':CustomApp:assembleRelease')) {
def pass = ''
if(System.console() == null) {
new SwingBuilder().edt { // Error occurs here.
dialog(modal: true,
alwaysOnTop: true,
resizable: false,
locationRelativeTo: null,
pack: true,
show: true
)
{
vbox {
label(text: "Enter password:")
input = passwordField()
button(defaultButton: true, text: 'OK', actionPerformed: {
pass = input.password;
dispose();
})
}
}
}
}
}
I've faced same issue with Android Studio 0.8.6 and solved it with custom gradle installation.
Just downloaded gradle 1.12 and set path to it in preferences.
The question is a few years old, but with the following gradle build file (which is essentially the same as the OPs):
import groovy.swing.SwingBuilder
task doit {}
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(doit)) {
def pass = ''
new SwingBuilder().edt { // Error occurs here.
dialog(modal: true,
alwaysOnTop: true,
resizable: false,
locationRelativeTo: null,
pack: true,
show: true)
{ vbox
{ label(text: "Enter password:")
input = passwordField()
button(defaultButton: true, text: 'OK', actionPerformed: {
pass = input.password;
dispose();
})
}
}
}
}
}
executing:
~> gradle doit
results in the following screen:
in other words, at least with this version of gradle, operating system, java etc this seems to work.

Resources