How to trigger multibranch downstream job with jobname/{env.BRANCH_NAME} - jenkins-pipeline

I've 2 multibranch jenkins pipeline jobs connecting same github project. I'm triggering first MB job ex. dev. branch, now on success of this job I want to trigger second MB job with same branch name. (I've separate Jenkinsfile fot both MB job).
I've tried below options but didn't work:
(1)
build job: 'jobName', parameters: [[$class: 'StringParameterValue', name: 'BRANCH_NAME', value: env.BRANCH_NAME]]
This gives me error "Waiting for non-job items is not supported"
(2)
build job: 'jobName/${branch_name}'
This gives me jobname/${branch_name} does not exist means variable here is not resolving, I've created this variable in environment directive
Simple jobName/dev if I'd give hardcode in Jenkinsfile then it's working, but I'd need it with automatically selecting branch name.
please advise, thanks.

When you want to use variables inside your string you need to use double quotes, example:
$"BRANCH_NAME"
From the groovy docs:
"Any Groovy expression can be interpolated in all string literals,
apart from single and triple-single-quoted strings. "
More here:
https://docs.groovy-lang.org/latest/html/documentation/#all-strings
An alternative could also be to use concatenation:
build job:'job/'+somebranchvariable, parameters:[string(name: 'BUILD_NAME', value: build_name)]

I have tried this format, it is working.
build(job: "JOBNAME" + "/" + "${BRANCH_NAME}".replaceAll('/', '%2F'))
Forward slash (/) is converted to %2f in the job name:
It’s a common practice to use a forward slash (/) when creating feature branches within developer teams, so whenever a new Pipeline gets created automatically with the creation of a new branch, / will get converted into %2f.
Whenever you are referencing the branch name in the job or calling any job as a downstream, you will have to make sure of this conversion. Look at the below example where we are trying to call a downstream project.

I've found another solution for this issue:
In the jenkinsfile triggering pipeline job with gitParameter:
build job: 'jobName', parameters: [gitParameter(name: 'GITBRANCH', value: env.BRANCH_NAME)]
Installed "git parameter" plugin, and configure in job which is being triggered in jenkinsfile
parameters {
gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'GITBRANCH', type: 'PT_BRANCH'
}
And calling this parameter while checkout code
stage("Checkout Branch wise"){
steps{
git branch: "${params.GITBRANCH}", url: 'https://xxx/xxx/xxxx.git'
}
}
which solved the problem.

Related

Travis: how to execute stage on specific commit message

I would like to execute a travis stage only on specific commit message (finally on a text tag in a commit message, but let's simplify for now).
Travis allows conditional execution using if statement (and I prefer to use that, because of the structure of my travis file). Travis documentation mentions 2 variables that could be used to get commit message:
commit_message and TRAVIS_COMMIT_MESSAGE
I tried using both of them. In these cases:
- stage: Deploy
if: commit_message = "deploy" AND type = push
- stage: Deploy
if: $TRAVIS_COMMIT_MESSAGE = "deploy" AND type = push
the stage is executed always, no matter what is the content of the commit message.
In that case:
- stage: Deploy
if: env(TRAVIS_COMMIT_MESSAGE) = "deploy" AND type = push
The stage is never executed, no matter what is the content of the commit message.
I also tried adding conditions: v1 in the root of the .travis file, but with no effect.
It seems like comparison operator is not working as expected (especially in first two cases - how can it always be true if strings are not equal??).

Azure Pipeline Nuget Package Versioning Scheme, How to Get "1.0.$(Rev:r)"

I'm setting up an Azure Pipelines build that needs to package a C# .NET class library into a NuGet package.
In this documentation, it lists a couple different ways to automatically generate SemVer strings. In particular, I want to implement this one:
$(Major).$(Minor).$(rev:.r), where Major and Minor are two variables
defined in the build pipeline. This format will automatically
increment the build number and the package version with a new patch
number. It will keep the major and minor versions constant, until you
change them manually in the build pipeline.
But that's all they say about it, no example is provided. A link to learn more takes you to this documentation, where it says this:
For byBuildNumber, the version will be set to the build number, ensure
that your build number is a proper SemVer e.g. 1.0.$(Rev:r). If you
select byBuildNumber, the task will extract a dotted version, 1.2.3.4
and use only that, dropping any label. To use the build number as is,
you should use byEnvVar as described above, and set the environment
variable to BUILD_BUILDNUMBER.
Again, no example is provided. It looks like I want to use versioningScheme: byBuildNumber, but I'm not quite sure how to set the build number, I think it pulls it from the BUILD_BUILDNUMBER environment variable, but I can't find a way to set environment variables, only script variables. Furthermore, am I suppose to just set that to 1.0.$(Rev:r), or to $(Major).$(Minor).$(rev:.r)? I'm afraid that would just interpret it literally.
Googling for the literal string "versioningScheme: byBuildNumber" returns a single result... Does anyone have a working azure-pipelines.yml with this versioning scheme?
Working YAML example for Packaging/Versioning using byBuildNumber
NOTE the second parameter of the counter - it is a seed value, really useful when migrating builds from other build systems like TeamCity; It allows you to set the next build version explicitly upon migration. After the migration and initial build in Azure DevOps, the seed value can be set back to zero or whatever start value (like 100) you may prefer every time majorMinorVersion is changed:
reference: counter expression
name: $(majorMinorVersion).$(semanticVersion) # $(rev:r) # NOTE: rev resets when the default retention period expires
pool:
vmImage: 'vs2017-win2016'
# pipeline variables
variables:
majorMinorVersion: 1.0
# semanticVersion counter is automatically incremented by one in each execution of pipeline
# second parameter is seed value to reset to every time the referenced majorMinorVersion is changed
semanticVersion: $[counter(variables['majorMinorVersion'], 0)]
projectName: 'MyProjectName'
buildConfiguration: 'Release'
# Only run against master
trigger:
- master
# Build
- task: DotNetCoreCLI#2
displayName: Build
inputs:
projects: '**/*.csproj'
arguments: '--configuration $(BuildConfiguration)'
# Package
- task: DotNetCoreCLI#2
displayName: 'NuGet pack'
inputs:
command: 'pack'
configuration: $(BuildConfiguration)
packagesToPack: '**/$(ProjectName)*.csproj'
packDirectory: '$(build.artifactStagingDirectory)'
versioningScheme: byBuildNumber # https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops#yaml-snippet
# Publish
- task: DotNetCoreCLI#2
displayName: 'Publish'
inputs:
command: 'push'
nuGetFeedType: 'internal'
packagesToPush: '$(build.artifactStagingDirectory)/$(ProjectName)*.nupkg'
publishVstsFeed: 'MyPackageFeedName'
byBuildNumber uses the build number you define in your YAML with the name field.
Ex: name: $(Build.DefinitionName)-$(date:yyyyMMdd)$(rev:.r)
So if you set your build format to name: 1.0.$(rev:.r), it should work as you expect.
I had the similar issue and now let me make it clear.
Firstly, what is the definition of Build Number?
By the official document of Azure Pipeline YAML scheme, it is
name: string # build numbering format
resources:
containers: [ containerResource ]
repositories: [ repositoryResource ]
variables: { string: string } | [ variable | templateReference ]
trigger: trigger
pr: pr
stages: [ stage | templateReference ]
Look at the first line:
name: string # build numbering format
Yes, that's it!
So you could define it like
name: 1.0.$(Rev:r)
if you prefer to Semantic Versioning. Then
Secondly, what's the meaning of versioningScheme: 'byBuildNumber' in task NuGetCommand#2?
It's really straightforward: just use the format defined by name!
Last but not least
The official document on Package Versioning and Pack NuGet packages don't make it clear that what a build number really is and how to define it. It's really misleading. And I'm so sad as an MS employee as I'd to resort to external resource to make all that clear.
Azure Pipeline Nuget Package Versioning Scheme, How to Get “1.0.$(Rev:r)”
This should be a issue in the documentation. I reproduced this issue when I set $(Major).$(Minor).$(rev:.r) in the Build number format in the Options of build pipeline:
However, I suddenly noticed that the build number is not correct with that format after many build tests:
There are two points . between 0 and 2 (Open above image in a new tab). Obviously this is very strange. So, I changed the Build number format to:
$(Major).$(Minor)$(rev:.r)
Or
$(Major).$(Minor).$(rev:r)
Now, everything is working fine.
As test, I just set the Build number format to $(rev:.r), and the build number is .x. So, we could confirm that the value of $(rev:.r) including the . by default.
Note: Since where Major and Minor are two variables defined in the build pipeline, so we need defined them in the variables manually.
Hope this helps.
Issues
My issues:
when trying the answer by #Emil, my first package started at 2.0 (I did no further testing to investigate)
when trying the answer by #Leo Liu-MSFT, I was unable to find the matching "Options" tab.
I therefore used this solution by #LanceMcCarthy.
Fix
Set the variables:
variables:
major: '1'
minor: '0'
revision: $[counter(variables['minor'], 1)] # This will get reset every time minor gets bumped.
nugetVersion: '$(major).$(minor).$(revision)'
then use nugetVersion as an environment variable when packing:
- task: NuGetCommand#2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
packDestination: '$(Build.ArtifactStagingDirectory)'
versionEnvVar: 'nugetVersion'
versioningScheme: 'byEnvVar'
I think the issue many of use have is that there is no option menu. I upvoted SHarpC's post as this worked for me.
I have a workaround to add a suffix (i.e. '-beta'), since it's for some reason ignored by the Nuget pack command when using the Classic editor and setting auto versioning by build number:
Set a new environment variable, set the value as the predefined $(Build.BuildNumber) variable:
Set the build number:
Set NuGet pack command to auto-name by environment variable and specify newly added variable name:
If you're interested in the whole build/release pipeline design and YAML, have a look at my article here
The core of the problem is solved in the approved answer and refined in #Emils answer, so this is just another approach to the azure-pipelines.yml that works for us with DevOps artifacts.
name: $(majorMinorVersion).$(semanticVersion)
trigger:
- main
variables:
majorMinorVersion: 1.0
semanticVersion: $[counter(variables['majorMinorVersion'], 0)]
pool:
vmImage: windows-latest
steps:
- task: DotNetCoreCLI#2
displayName: 'Create Packages'
inputs:
command: pack
configuration: 'Release'
packagesToPack: '**/<VS projectname>.csproj'
versioningScheme: byBuildNumber
- task: NuGetAuthenticate#0
displayName: 'NuGet Authenticate'
- task: NuGetCommand#2
displayName: 'NuGet Push to feed'
inputs:
command: push
publishVstsFeed: '<DevOps projectname>/<feed name>'
BTW: Don't forget this little hinch

Jenkins Pipeline emailext: How to access build object in pre-send script

I'm using Jenkins ver. 2.150.1 and have some freestyle jobs and some pipeline jobs.
In both job types I am using the emailext plugin, with template and pre-send scripts.
It seems that the build variable, which is available in the freestyle projects, is null in the pipeline projects.
The pre-send script is the following (just an example, my script is more complex):
msg.setSubject(msg.getSubject() + " [" + build.getUrl() + "]")
There is no problem with the msg variable.
In the freestyle job, this script adds the build url to the mail subject.
In the pipeline job, the following is given in the job console:
java.lang.NullPointerException: Cannot invoke method getUrl() on null object
The invocation of emailext in the pipeline job is:
emailext body: '${SCRIPT, template="groovy-html.custom.pipeline.sandbox.template"}',
presendScript: '${SCRIPT, template="presend.sandbox.groovy"}',
subject: '$DEFAULT_SUBJECT',
to: 'user#domain.com'
I would rather find a general solution to this problem (i.e. Access the build variable in a pipeline pre-send script), but would also appreciate any workarounds to my current needs:
Access job name, job number, and workspace folder in a pipeline pre-send script.
I have finally found the answer -
Apparently for presend script in pipeline jobs, the build object does not exist, and instead the run object does. At the time I posted this question this was still undocumented!
Found the answer in this thread
Which got the author to update the description in the wiki:
run - the build this message belongs to (may be used with FreeStyle or Pipeline jobs)
build - the build this message belongs to (only use with FreeStyle jobs)
You can access the build in a script like this:
// findUrl.groovy
def call(script) {
println script.currentBuild.rawBuild.url
// or if you just need the build url
println script.env.BUILD_URL
}
and would call the script like this from the pipeline:
stage('Get build URL') {
steps {
findUrl this
}
}
The currentBuild gives you a RunWrapper object and the rawBuild a Run. Hope this helps.

How to cancel/not execute Bitbucket Pipelines builds based on a condition?

I want to update my yml file to ignore commits from certain users. Is this possible? Is there a similar solution? Ideally I wouldn't even want to trigger the build in the first place.
Pseudo code example of yml file (ignore syntax, I'm just showcasing what I'm trying to do)
user: git show -s --format='%ae' $BITBUCKET_COMMIT
unwantedUser: "person#mail.com"
pipelines:
tags:
'**' && user != unwantedUser: # any tags by wanted users
- step:
script:
(...)
What would be the actual syntax to achieve that?
I ended up including the [skip ci] string in my commit messages to avoid triggering the pipeline.
From the documentation:
Can I commit without triggering the pipeline? Yes. If you don't want
to run a pipeline on a commit that would normally trigger one, you can
include [skip ci] or [ci skip] anywhere in your commit message of the
HEAD commit. Any commits that include [skip ci] or [ci skip] in the
message are ignored by Pipelines.
Alternatively, if you want to trigger pipeline manualy you can use 'custom' tag.
From the documentation
pipelines:
custom: # Pipelines that can only be triggered manually
sonar:
- step:
script:
- echo "Manual triggers for Sonar are awesome!"
Custom pipelines do not run automatically on a commit to a branch. You can run a pipeline with commits view page or branches view page.

How to send an email from Jenkins only in a release?

I was trying to resolve this issue, and searching forums etc. and trying for myself, without success.
We have a jenkins job and there we use the Release Plugin (with a standard configuration)
In the job then we have the "Perform Maven Release" in the left side to generate a version (tag, change poms, etc.) This work perfect.
We want to send an email to the team when the release has been done.
I tried the enviroment variable that the release plugin sets (IS_M2RELEASEBUILD by default) and combine with the email-ext plugin plugin where I can attach a groovy script (advanced=>trigger=>script trigger)
And I tried a lot of scripts to active the email, and none works, my last chance was:
def env = System.getenv()
env['IS_M2RELEASEBUILD'] == 'true'
but when I perform the release we have not the email sent (so this script evaluate the conditional to false or whatever)
Anyone has this setup in his Jenkins?
Thanks a lot!
You need to use "Editable Email Notification" as "Post-build Action" and paste
def env = build.getEnvironment();
String isRelease = env['IS_M2RELEASEBUILD'];
logger.println "IS_M2RELEASEBUILD="+isRelease;
if ( isRelease == null || isRelease.equals('false')) {
logger.println "cancel=true;";
cancel=true;
}
as Pre-send Script, fill in your E-Mail(s) in "Project Recipient List" and add an "Success"-Trigger.
(precondition is you have not changed the default "Release envrionment variable" in "Maven release build")
https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin
This plugin allows you to configure every aspect of email notifications. You can customize when an email is sent, who should receive it, and what the email says.
This is not an answer, just a suggestion (I can't add comments). Have you tried echoing that environment variable in a post-build and pre-build step?
Have you tried having another build run when the release build completes successfully and have that job send the email, perhaps by running a shell script.

Resources