CircleCi How to get name of merged branch? - circleci

How to get branch name in .circleci/config.yaml? When I merge feature/A to main, then How to get name of feature/A?
'echo $CIRCLE_BRANCH' print main name. However, I need name of feature/A!

Related

How to get only the Full name of previous Jenkins build

I would like to send the full name of the previous build that was received by using the following:
Run previousBuild = steps.currentBuild.rawBuild.getPreviousBuildInProgress()
in order to send to getItemByFullName as you can see below,
Jenkins.instance.getItemByFullName(previousBuildPath)
I tried to find it in the Run class hudson Documentation with no success.
while printing previousBuild I got the name with the build number like:
previousBuild- > project_neme/build_name #100
But I want to get only the name with no String substring cutting.
You are looking for display name property. Display name is the name given to each build (if you update it during execution) followed by a build number. The display name will only return the build name.
Jenkins.instance.getItemByFullName('JobName').getLastBuild().displayName
Read here
https://javadoc.jenkins.io/hudson/model/Job.html

Multibranch Pipeline in Jenkins with SVN

I have SVN as my SCM. The SVN Root URL structure is as follows.
https://svn.domain.com/orgName
Under this, I have a folder called "test". Then I have tags, branches and trunk. For example,
https://svn.domain.com/orgName/test/trunk
https://svn.domain.com/orgName/test/branches
Under trunk and branches, I have various modules. One module is Platform which is the core module. The URL structure for my project under Platform is as follows.
https://svn.domain.com/orgName/test/trunk/Platform/MyProject
https://svn.domain.com/orgName/test/branches/Platform/1.0.0.0/MyProject
Not sure if the above structure is correct or not. But this is how it is structured in my organization and it can't be changed. Now, I have the following questions.
At what level should I maintain the Jenkinsfile?
How should I pass the branch name (including trunk) to this file?
It will be great if someone can provide some details (if possible step by step) on how to use Multibranch pipeline with SVN. Unfortunately, I could not find any tutorial or examples to achieve this.
I figured this out on my own. Here are the details, in case, someone needs help.
For Trunk, add the Jenkinsfile inside trunk/Platform (in my case) and for Branches, add Jenkinsfile inside branches/Platform/ folder. For branches, it is better to keep the Jenkinsfile inside each version folder since it has some benefits. This approach will create a Jenkins job for each version.
In the Jenkins job (for multibranch pipeline), add the base url for Project Repository Base. In my case, it is https://svn.domain.com/orgName/test. In Include branches field, add trunk/Platform, branches/Platform/* in my case. In Jenkinsfile, to get branch name, use the built in variable $BRANCH_NAME. This gives trunk/Platform for trunk and branches/Platform/1.0.0.0 (for example) for branches.
Only challenge is that job names are created like Trunk/Platform, Branches/Platform/1.0.0.0. So the workspace gets created like Trunk%2FPlatform, Branches%2FPlatform%2F1.0.0.0 since "/" gets encoded with %2F. While using in jobs, make sure the job name is appropriately modified using the below code.
def cws = "${WORKSPACE_DIR}\\" + "${JOB_NAME}".replace("%2F","_").replace("/","\\")
echo "\u2600 workspace=${cws}"
def isTrunk = "${JOB_NAME}".toLowerCase().contains("trunk")
def version = ""
def verWithBldNum = ""
echo "\u2600 isTrunk=${isTrunk}"
if(!isTrunk)
{
version = "${JOB_NAME}".substring("${JOB_NAME}".lastIndexOf("%2F") + 3, "${JOB_NAME}".length())
echo "\u2600 version=${version}"
verWithBldNum = "${version}".substring(0, "${version}".lastIndexOf('.') + 1) + "${BUILD_NUMBER}"
echo "\u2600 verWithBldNum=${verWithBldNum}"
}
else
{
echo "\u2600 Branch is Trunk"
}

How to execute a stage only if latest commit message does not contain certain text

I am using declarative pipelines and would like to run a stage only when it matches a certain branch and the latest commit does not include certain text.
Matching the branch is the easy part:
when {
branch 'master'
}
But for checking the latest commit message, I am unsure how to add in this check.
I have come across this answer which is very much the kind of thing I am trying to achieve.
I am wondering if I need to use an expression clause that would contain the logic similar to the answer linked to above, to query the git log and parse\check the latest commit message contains my supplied regex pattern.
Can anyone point me at any snippets that would help me here?
Thanks
I answer a bit late, but it could be useful for others.
The answer you pointed us out is for Scripted Pipeline and works well.
If you want to do this in a Declarative way, you can combine changelog condition and branch condition like this:
stage("Skip release commit") {
when {
changelog "^chore\\(release\\):.*"
branch "master"
}
steps {
script {
// Abort the build to avoid build loop
currentBuild.result = "ABORTED"
error('Last commit is from Jenkins release, cancel execution')
}
}
}
My point was to skip the build when Jenkins is commiting on the master branch with a chore(release):... message.
If you have to check a more complex branch name, you can replace branch "master" by something like expression {env.BRANCH_NAME ==~ /^feat\/.+/} (to execute the stage only on branch name starting by "feat/")
Unfortunely, if the contributors on your project do git commit --amend on a previous commit with message that matches the changelog condition then the stage will be not triggered because changelog will be Branch indexing for this amend.
In this case you probably need :
environment {
CHORE_RELEASE = sh script: "git log -1 | grep 'chore(release):'", returnStatus: true
}
when {
expression { "${CHORE_RELEASE}" == "0" }
branch "master"
}
instead of
when {
changelog "^chore\\(release\\):.*"
branch "master"
}

Pass large amount of parameters between jobs

I have two Jenkins jobs that tun on separate computers. On computer 1 I read properties file and use it for environment variables. But i need the same file on PC 2 and it only exist on the first one. When the first Jenkins job finishes it starts the second one and it can pass parameters file via job but I have to receive with creation of separate parameter with Parameterized Trigger Plugin for each parameter, and I have a lot and don`t want to do so. Is there simple solution for this issue?
Forget Jenkins 1 and the plugins Parameterized Trigger Plugin. Using Jenkins 2, here's an example of your need:
node ("pc1") {
stage "step1"
stash name: "app", includes: "properties_dir/*"
}
node ("pc2") {
stage "step2"
dir("dir_to_unstash") {
unstash "app"
}
}

Jenkins Pipeline - how to get logs from parallel builds

Is it possible, and if yes: how?, to get the log output for each parallel step separately?
I.e.:
def projectBranches = [:]
for (int i = 0; i < projects.size(); i++) {
def _i = i
projectBranches[_i] = {
someFunction(_i)
}
}
parallel projectBranches
Is it now possible to get the log for each of projectBranches[_i]?
I needed to access logs from within the pipeline code
so I implemented the algorithm proposed by キキジキ (really helpful) with a few adjustments (to add branchName prefix on each line to be able to get the whole log and still figure out which branch corresponds to each line ; and to support nested branches, which I needed) in https://github.com/gdemengin/pipeline-logparser :
to get logs programmatically
to get the full logs with branch prefix (similar to what currentBuild.rawBuild.log returned before version 2.2.5 of workflow-job plugin. but in version 2.26 they got rid of the branch information and I could not find any built-in function with the same information)
String logs = logparser.getLogsWithBranchInfo()
[Pipeline] Start of Pipeline
[Pipeline] parallel
[Pipeline] { (Branch: branch1)
[Pipeline] { (Branch: branch2)
[Pipeline] }
[Pipeline] echo
[branch1] in branch1
[Pipeline] sleep
[branch1] Sleeping for 1 sec
[Pipeline] echo
[branch2] in branch2
[Pipeline] sleep
[branch2] Sleeping for 1 sec
get the logs from 'branch2' only
String logsBranch2 = logparser.getLogsWithBranchInfo(filter: ['branch2'])
[branch2] in branch2
[branch2] Sleeping for 1 sec
to archive logs (in as $JOB_URL/<runId>/artifacts) to have them available as a link for later use
to archive the full logs (with branch prefix)
logparser.archiveLogsWithBranchInfo('consoleText.txt')
to archive the logs from branch2 only
logparser.archiveLogsWithBranchInfo('logsBranch2.txt', [filter: ['branch2']])
I found a way to achieve that, but you need to access the build folder directly (for example using currentBuild.rawBuild.getLogFile().getParent()).
Parse the xml files (or the single flowNodeStore.xml file) inside the workflow directory:
Build a hierarchy of nodes using the <id> and <parentIds> values.
If <branchName> is defined associate it to the current node and recursively to all nodes that have this node as parent. If a node has multiple parents assign no branch value to it.
Read the log file as byte[].
Read each line of log-index to find log ranges to assign to each node. The format of a line can be one of the following:
offset nodeId -> start of new node range, end of the previous (if present).
offset: end of current node range.
Convert the byte range back to a utf8 string (new String(range, "UTF-8")).
You might want to strip away all embedded codes with something like replaceAll("\u001B.*?\u001B\\[0m", "")
You could get your nodes by use of Jenkins REST API: job/test/1/api/json?depth=2
Result should contain something like:
{"_class":"org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode","actions":[{},{},{}],"displayName":"Branch: 0","iconColor":"blue","id":"13","parents":["3"],"running":false,"url":"job/test/1/execution/node/13/"},
{"_class":"org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode","actions":[{},{},{}],"displayName":"Allocate node : Start","iconColor":"blue","id":"23","parents":["13"],"running":false,"url":"job/test/1/execution/node/23/"},
{"_class":"org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode","actions":[{},{}],"displayName":"Allocate node : Body : Start","iconColor":"blue","id":"33","parents":["23"],"running":false,"url":"job/test/1/execution/node/33/"},
{"_class":"org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode","actions":[{},{}],"displayName":"Print Message","iconColor":"blue","id":"37","parents":["33"],"running":false,"url":"job/test/1/execution/node/37/"}
So for your case you are interested in the child with type StepAtomNode of your Branch with name given (0-9 for this case). From this you could obtain console output address by simply adding log to the address (like: job/test/1/execution/node/37/log).
Now this is where it gets a bit ugly, you need to parse the html to get the actual log from the
<pre class="console-output">log here
</pre>

Resources