How to compare branches using RegEx in CircleCI 2.0 - circleci

How can we compare CIRCLE_BRANCH with a regular expression?
In 1.0 we do it by:
branch: /feature.*/
commands:
<your commands here>
In '2.0' master branch is compared as follows:
if [ "${CIRCLE_BRANCH}" != "master" ]; then
<your commands>
fi
How can I handle /feature.*/ in CircleCI 2.0 ?

Just use a Workflow like it is described here
https://circleci.com/docs/2.0/workflows/#branch-level-job-execution
you can use
branch:
only: ....
or
branch:
ignore: ...

Related

How to read environment variables in env section of github action workflow

I'm trying to set a env variable based on another env variable in a github workflow. I've tried a couple of syntax options but none seem to work
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
BASE_VERSION: 1.0.0
FULL_VERSION: ${BASE_VERSION}-${{ github.run_number }}-${{ github.ref_name }}
jobs:
The example for BASE_VERSION above just keeps ${BASE_VERSION} as a string
$BASE_VERSION also just keeps $BASE_VERSION as a string
${{ env.BASE_VERSION }}-blabla just fails with syntax error
Is this doable?
The output I want is "1.0.0-1-master" for example
Is this doable?
It does not seem like a supported behaviour at the moment.
The docs on env mentions that
variables in the env map cannot be defined in terms of other variables in the map.
Do it like this:
- name: Set docker image env var
run: |
echo "DOCKER_IMAGE=${ARTIFACTORY_URL}/${IMAGE_NAME}:${GITHUB_REF##*/}.${{github.run_number}}" >> $GITHUB_ENV
- run: |
echo ${{ env.DOCKER_IMAGE }}
Outputs
artifactory-host/some-project/some-repo/image-name:branch.number

Jenkins multibranch pipeline triggers pipeline on unrelated branches

I have a problem with Jenkins multibranch pipleline using JenkinsFile and the GIT plugin.
The problem is that every push to staging branch triggers the pipeline of master as well.
The desired behavior is that push to staging branch only triggers the pipleine for staging, and push to master branch only triggers the pipeline for master
This is my JenkinsFile
#!/usr/bin/env bash
pipeline {
agent any
triggers {
pollSCM('*/1 * * * *')
}
environment {
GCLOUD_PATH="/var/jenkins_home/GoogleCloudSDK/google-cloud-sdk/bin"
}
stages {
stage('Git Checkout'){
steps{
// Clean Workspace
cleanWs()
// Get source from Git
git branch: 'staging',
credentialsId: ****',
url: 'git#github.com:***/****.git'
}
}
stage('Update Staging') {
when {
branch 'staging'
}
environment{
INSTANCE="***"
}
steps {
sshagent(credentials : ['****']) {
sh 'ssh -tt -o StrictHostKeyChecking=no jenkins#"${INSTANCE}" sudo /opt/webapps/****/deploy.sh firstinstance'
}
}
}
stage('Update Production') {
when {
branch 'master'
}
environment{
gzone="us-central1-a"
}
steps {
sh '''
#!/bin/bash
echo "${BRANCH_NAME}"
export instances=$("${GCLOUD_PATH}"/gcloud compute instances list --filter="status:(running) AND tags.items=web" --format="value(name)")
FIRST=1
for instance in ${instances}
do
echo "### Running Instance: ${instance} ###"
if [[ $FIRST == 1 ]]; then
echo "first instance"
${GCLOUD_PATH}/gcloud compute ssh jenkins#${instance} --zone ${gzone} '--ssh-flag=-tt -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no' --command="echo first"
else
${GCLOUD_PATH}/gcloud compute ssh jenkins#${instance} --zone ${gzone} '--ssh-flag=-tt -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no' --command="sudo uptime"
fi
FIRST=0
done
'''
}
}
}
post {
success {
cleanWs()
}
}
}
I'll share some logs:
The is a log for master branch
http://34.69.57.212:8080/job/tinytap-server/job/master/2/pollingLog/ returns
Started on Dec 10, 2019 1:42:00 PM
Using strategy: Specific revision
[poll] Last Built Revision: Revision 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d (master)
using credential ccb9a735-04d9-4aab-8bab-5c86fe0f363c
> git --version # timeout=10
using GIT_ASKPASS to set credentials
> git ls-remote -h -- https://github.com/tinytap/tinytap-web.git # timeout=10
Found 222 remote heads on https://github.com/tinytap/tinytap-web.git
[poll] Latest remote head revision on refs/heads/master is: 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d - already built by 1
Using strategy: Default
[poll] Last Built Revision: Revision f693e358ce14bc5dfc6111e62ed88e6dd1d0dfc9 (refs/remotes/origin/staging)
using credential 17f45a89-da78-4969-b18f-cb270a526347
> git --version # timeout=10
using GIT_SSH to set credentials jenkins key
> git ls-remote -h -- git#github.com:tinytap/tinytap-web.git # timeout=10
Found 222 remote heads on git#github.com:tinytap/tinytap-web.git
[poll] Latest remote head revision on refs/heads/staging is: 907899a0e7e131e9416ee65aad041c8da111e2fe
Done. Took 1 sec
Changes found
The is a log for master branch, but only staging had a new commit :
http://34.69.57.212:8080/job/tt-server/job/master/3/pollingLog/ returns
Started on Dec 10, 2019 1:55:00 PM
Using strategy: Specific revision
[poll] Last Built Revision: Revision 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d (master)
using credential ****-****-****-****-5c86fe0f363c
> git --version # timeout=10
using GIT_ASKPASS to set credentials
> git ls-remote -h -- https://github.com/tt/tt-web.git # timeout=10
Found 222 remote heads on https://github.com/tt/tt-web.git
[poll] Latest remote head revision on refs/heads/master is: 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d - already built by 2
Using strategy: Default
[poll] Last Built Revision: Revision 907899a0e7e131e9416ee65aad041c8da111e2fe (refs/remotes/origin/staging)
using credential ****-****-****-****-cb270a526347
> git --version # timeout=10
using GIT_SSH to set credentials jenkins key
> git ls-remote -h -- git#github.com:tt/tt-web.git # timeout=10
Found 222 remote heads on git#github.com:tt/tt-web.git
[poll] Latest remote head revision on refs/heads/staging is: eab6e8bc6d8586084e9fe9856dec7fd8b31dd098
Done. Took 0.98 sec
Changes found
Notice "changes found" even though head did not change on master branch
Jenkins ver. 2.190.1
Git plugin ver 4.0.0
Git client plugin ver 2.9.0
I use this plugin - https://github.com/lachie83/jenkins-pipeline and it works fine for me. You need to have separate if blocks for each branch and then the stage block inside it. Example below:
#!/usr/bin/groovy
#Library('https://github.com/lachie83/jenkins-pipeline#master')
def pipeline = new io.estrado.Pipeline()
def cloud = pipeline.getCloud(env.BRANCH_NAME)
def label = pipeline.getPodLabel(cloud)
// deploy only the staging branch
if (env.BRANCH_NAME == 'staging') {
stage ('deploy to k8s staging') {
//Deploy to staging
}
}
// deploy only the master branch
if (env.BRANCH_NAME == 'master') {
stage ('deploy to k8s production') {
//Deploy to production
}
}
I think you have some logical omissions in your Jenkinsfile. As it currently stands, you poll SCM for changes. If any change is detected, first stage 'Git Checkout' will checkout staging branch (always). Then you have another stage which does something if the branch is 'staging' (which it is, because it's hardcoded to checkout that branch above) etc. This will be the first thing to fix - if SCM changes are detected, checkout the right branch. How - there are a few options. I usually use 'skipDefaultCheckout()' in 'options' together with explicit checkout in my first pipeline stage:
steps {
sshagent(['github-creds']) {
git branch: "${env.BRANCH_NAME}", credentialsId: 'github-creds', url: 'git#github.com:x/y.git'
}
}
The second thing is that you try to squeeze handling two different branches into a single Jenkinsfile. This is not how it should be done. Jenkins wil use Jenkinsfile from a given branch - just make sure Jenkinsfile on staging contains what you want it to contain, same with Jenkinsfile on master.
Hope it helps.

Use a variable in 'git url' jenkins piplines

So when using a Jenkins pipeline I need to checkout a second git repository in a new folder:
dir('platform') {
println("\n\n\n=== === ===> gitBranch ${gitbranch} ");
dir('platform') {
deleteDir()
}
git url: 'git#gitlab.platform-automation.git', credentialsId: '1234567890', branch: 'feature/Packer-server-image-builds' // clones repo to subdir
}
When I try to use a variable to set the branch the command fails:
git url: 'git#gitlab.platform-automation.git', credentialsId: '1234567890', branch: '${gitbranch}'
What do I need to do to get this working?
use " instead of ' to use variables: "${gitbranch}"

Retrieving git branch name in prompt or Android gradle: on Jenkins it returns HEAD

In gradle I'd like to add both the current branch-name and commit-number as suffix to my versionName. (Why? Because when I build my app in Jenkins to release it in HockeyApp, it's useful to show what branch & commit that app was built from!)
So when I enter this in command prompt, my current branch name is returned:
git rev-parse --abbrev-ref HEAD
Same happens when I use this line in Android gradle, using the code in either this answer, or as shown in this piece of gradle code:
def getVersionNameSuffix = { ->
def branch = new ByteArrayOutputStream()
exec {
// The command line to request the current branch:
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = branch
}
println "My current branch: " + branch
def versionNameSuffix = "-" + branch
// ... some other suffix additions ...
return versionNameSuffix
}
buildTypes {
debug {
applicationIdSuffix ".test"
versionNameSuffix getVersionNameSuffix()
}
}
Resulting log (this is exactly what I want):
"My current branch: feature/MyFeature"
However, when I build my app in a Jenkins job, it will output a different result:
"My current branch: HEAD"
Why does this happen, and how to correctly retrieve my current branch name in Jenkins?
EDIT:
I've used a different approach, which returns the branchName correctly in most cases, also on Jenkins:
git name-rev --name-only HEAD
Example output in prompt:
"My current branch: feature/MyFeature"
Example output in Jenkins:
"My current branch: remotes/origin/feature/MyFeature"
I can remove "remotes/origin/" if i like, so that's okay!
But this approach causes different trouble (both in prompt, gradle and on Jenkins). When I have tagged the last commit, it won't output the branch-name, but this:
"My current branch: tags/MyTag^0"
EDIT 2:
A third approach can be found here.
Including the comments below the answer, I could use grep * to retrieve the branch in prompt. However, I cannot use the backslash in the gradle code. This fails:
commandLine 'git', 'branch', '|', 'grep', '\\*'
Any advice?
Try the env: BRANCH_NAME
BRANCH_NAME
For a multibranch project, this will be set to the name of the branch being built, for example in case you wish to deploy to production from master but not from feature branches.
Access it with env.BRANCH_NAME

Jenkins Workflow Checkout Accessing BRANCH_NAME and GIT_COMMIT

I cannot seem to extract $GIT_COMMIT and $BRANCH_NAME from a Jenkins Workflow Checkout step.
I would like to be able to send this information through to my Gradle scripts in order to pass it onto external sources such as Static analysis etc.
Currently I try to run this:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
And I would like to achieve the following or something similar:
// Specified variables that can be reused
def branch = ${BRANCH_NAME}
def commit = ${GIT_COMMIT}
Or maybe this would work too:
print "BRANCH: ${BRANCH_NAME}, COMMIT: ${GIT_COMMIT}"
// or the following
print "BRANCH: ${env.BRANCH_NAME}, COMMIT: ${env.GIT_COMMIT}"
I did find the following issue which seems to be resolved but it doesn't work in version 1.15:
https://issues.jenkins-ci.org/browse/JENKINS-30252
Anyone have any ideas how to workaround this or if there's a variable I cannot find?
First of all,
def branch = ${BRANCH_NAME}
is not valid Groovy, or at least not doing what you think. Perhaps you meant
def branch = "${BRANCH_NAME}"
which would just be a silly way of writing
def branch = BRANCH_NAME
Anyway environment variables are not currently accessible directly as Groovy variables in Pipeline (there is a proposal to allow it); you need to use the env global variable:
def branch = env.BRANCH_NAME
From within an external process, such as a sh step, it is an actual environment variable, so
sh 'echo $BRANCH_NAME'
works (note that ' means Groovy is not interpolating the variable).
Now, JENKINS-30252 was referring to multibranch projects. If you created a standalone Pipeline job, this variable will not be set.
Anyway in your case your checkout step is always checking out the master branch. If you actually have a multibranch project, then your Jenkinsfile should be using
checkout scm
which will check out a commit on the correct branch (always matching the revision of Jenkinsfile itself).
As to the commit hash, pending JENKINS-26100 this is not available automatically, but you can use something like
sh 'git rev-parse HEAD > commit'
def commit = readFile('commit').trim()
to access it.
I have two Jenkins instances.
In both instances, GIT_COMMIT and BRANCH_NAME environment variables are not defined.
When I try to get them from the return value of checkout() call, each instance behaves differently.
Jenkins Instance 1
Jenkins version: 2.46.1
"Pipeline: SCM Step" plugin version: 2.5
Trying to access the environment variable as explained in the checkout documentation fails.
def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']],
userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
def commitHash = scmVars.GIT_COMMIT
scmVars returns NULL, and accessing scmVars.GIT_BRANCH fails with exception java.lang.NullPointerException: Cannot get property 'GIT_BRANCH' on null object.
So I had to do the following in order to get the branch:
sh 'git name-rev --name-only HEAD > GIT_BRANCH'
sh 'cat GIT_BRANCH'
git_branch = readFile('GIT_BRANCH').trim()
env.GIT_BRANCH = git_branch
Jenkins Instance 2
Jenkins version: 2.60.2
"Pipeline: SCM Step" plugin version: 2.6
In this instance, I could do the following with success:
def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']],
userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
env.GIT_COMMIT = scmVars.GIT_COMMIT
env.GIT_BRANCH = scmVars.GIT_BRANCH
So please check which approach works for your Jenkins instance and use it.
If you want to access the BRANCH_NAME from Jenkins environment variable as a shell script, use the below snippet.
sh 'echo Branch Name: $BRANCH_NAME'
The response should be as below:
Branch Name: the_checkedout_branch

Resources