Specify checkout location using agent (not node) - jenkins

Is there a way to specify the location of the checkout using "agent" (not "node") in a Jenkinsfile?
pipeline {
agent { label 'my_label' }
stages {
stage('Checkout') {
steps {
// Dang. my_repo has already been checked out
dir('my_repo') {
checkout scm
}
}
}
}
}
It seems if you use "node" you have the ability to do this, but I can't seem to find a way to do with "agent".

If you set skipDefaultCheckout(), then you can checkout your SCM when you want:
pipeline {
agent { label 'my_label' }
options {
skipDefaultCheckout()
}
stages {
stage('Checkout') {
steps {
// SWEET! my_repo has not been checked out
dir('my_repo') {
checkout scm
}
}
}
}
}
Alternatively, some of the SCMs offer advanced checkout options that let you do the checkout into a different path.
Be aware, though, if you use multiple agents, you will need to manually do the checkout each time you use another agent. If MAY use the same workspace, but there is no guarantee. You should always run checkout scm, just in case it doesn't.

Related

Job DSL plugin | Shared Library | Pipeline jobs | Github Hook not working

Please bear with me the description might be long but it might give a clean picture of the intent and issue.
I have used Job DSL Plugin to create a seeder job, which in turns creates two new Jobs. I have 2 separate repositories
For maintaining jenkins pipeline scripts.
For actual code to build.
First I have created a pipeline job in jenkins which in turns creates view and 2 jobs. Config shown below:
The Jenkinsfile given below uses Job DSL plugin api, reads the groovy script and creates the required 2 jobs.
node('master') {
checkout scm
jobDsl targets: ['dsl/seedJobBuilder.groovy'].join('\n'),
removedJobAction: 'IGNORE',
removedViewAction: 'IGNORE',
lookupStrategy: 'SEED_JOB'
}
seedJobBuilder.groovy creates a dsl pipeline job whose task would be to build the actual codebase.
listView('Build Pipelines') {
description('All build and deploy jobs')
jobs {
names(
'build',
'deploy',
)
}
columns {
status()
weather()
name()
lastSuccess()
lastFailure()
lastDuration()
buildButton()
}
}
def buildCommerce = pipelineJob('build') {
properties {
githubProjectUrl("${projectRepo}") // url of actual code repo not the jenkins script repo
}
definition {
cpsScm {
scm {
git {
remote {
url("${pipelineRepo}") // jenkins script repo url
credentials("somecredentials")
}
branch('${JENKINS_SCRIPT_BRANCH}')
}
scriptPath('pipelines/pipelineBuildEveryDay.groovy')
lightweight(false)
}
}
}
triggers {
githubPush()
}
}
Config of the above job created by Job DSL:
This job reads the pipelineBuildEveryDay groovy script, checkout the actual codebase and build and deploy.
The place where I am struggling is how do we trigger build on this second job through github hook or through ghprb. Since I don't want to manipulate manually the second job and the git url of the job is the script repo URL not the codebase URL. Is it possible to do this even? If yes what am I missing?
I have the webhook configured
pipelineBuildEveryDay.groovy
pipeline {
libraries {
lib("shared-library#${params.JENKINS_SCRIPT_BRANCH}")
}
agent {
node {
label 'master'
}
}
options {
skipDefaultCheckout(true) // No more 'Declarative: Checkout' stage
}
stages {
stage('Crazy Build Pipeline') {
tools {
jdk 'java11'
}
stages {
stage('Prepare build name') {
steps{
script{
currentBuild.displayName = "${currentBuild.number}-build"
}
}
}
stage('Checkout') {
steps {
cleanWs()
script {
checkoutRepository("${projectDir}", "${params.PROJECT_TAG}", "${params.PROJECT_REPO}")
}
}
}
stage('Run Tests') {
steps {
echo "Running test coming soon..."
}
}
}
}
}
// post build actions
post {
success {
echo "success"
}
failure {
echo "failure"
}
}
}
Well the suffering comes to an end. Posting this answer for anyone struggling with similar sort of issues.
Make sure you uncheck all other types of trigger, the only checked one should be pull request builder.
The part which screwed me was the Project URL. In my case in SCM part the github url was of the Jenkins-scripts repository URL not the URL of the codebase I want to build. So I tried to use my codebase repository URL in Github Project URL textbox.
But the real problem was using repository URL in the format 'https://code-base-repo-url.git' instead it should be 'https://code-base-repo-url'. Sounds stupid? Yeah I know!
Finally the complete Job config pipeline script if it helps:
def pipelineRepo = 'https://jenkins-script-repo'
def projectRepo = 'https://code-base-repo-url'
def projectTag = '${GIT_BRANCH}'
def buildCommerce = pipelineJob('build') {
properties {
githubProjectUrl("${projectRepo}")
}
definition {
cpsScm {
scm {
git {
remote {
url("${pipelineRepo}")
credentials("use-your-own-user-pass-cred")
}
branch('${JENKINS_SCRIPT_BRANCH}')
}
scriptPath('pipelines/pipelineBuildEveryDay.groovy')
lightweight(false)
}
}
}
triggers {
githubPullRequest {
admin('use_your_own_admin')
triggerPhrase('build please')
useGitHubHooks()
permitAll()
displayBuildErrorsOnDownstreamBuilds()
extensions {
commitStatus {
context('Jenkins')
completedStatus('SUCCESS', 'All is well')
completedStatus('FAILURE', 'Something went wrong. Investigate!')
completedStatus('ERROR', 'Something went really wrong. Investigate!')
}
}
}
}
}

is there any easy way to remove (clean) the pipeline ws, when using another node?

When using a jenkins pipeline, on an ephemeral node (e.g. fargate):
pipeline {
agent {
label 'build-swarm'
}
stages {
...
}
post {
always {
cleanWs()
}
}
the ws cleanup [plugin][1] will try and remove the ws on the ephemeral node, which is pointless.
In an ideal world, we would use lightweight checkout on the controller, but because reasons this is not possible. So we have a fairly large repo checkout, that is not cleaned up.
This is the best thing I've managed to come up with:
pipeline {
...
}
node('master') {
folder = JOB_NAME.split('/')[0]
job = JOB_NAME.split('/')[1]
ws("${JENKINS_HOME}/jobs/${folder}/jobs/${job}/workspace#script") {
stage('clean up ws') {
cleanWs()
}
}
}
which seems to work, but feels very fragile. Am I missing something obvious?
[1]: https://plugins.jenkins.io/ws-cleanup/
https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#node-allocate-node
If I got you right you need to run cleanWs() step before pipeline run. Use:
pipeline {
agent any
options {
// This is required if you want to clean before build
skipDefaultCheckout(true)
}
stages {
stage('Build') {
steps {
// Clean before build
cleanWs()
// We need to explicitly checkout from SCM here
checkout scm
echo "Building ${env.JOB_NAME}..."
}
}
}
}

Multibranch Pipeline job configuration with logrotator using DSL

I'm using jenkins job dsl to configure my multibranch pipeline jobs. Actually my all settings are working except logRotator. My aim is to delete the old builds and keep a particular number of build. I can use
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
}
in freestyle job for this purpose. The multibranch pipeline job configure section not having discardold build section as an option in UI. Is there any way I can use the logRotator without adding this to my jenkins file.
I've added the following section in my code to implement the buildDiscarder functionality in multibranch pipeline jobs.
multibranchPipelineJob("job") {
branchSources {
branchSource {
source {
bitbucket {
credentialsId("myid")
repoOwner("iam")
repository("job")
traits {
headWildcardFilter {
includes("branchestoinclude")
excludes("toexclude")
}
}
}
}
strategy {
defaultBranchPropertyStrategy {
props {
buildRetentionBranchProperty {
buildDiscarder {
logRotator {
daysToKeepStr("-1")
numToKeepStr("8")
artifactDaysToKeepStr("-1")
artifactNumToKeepStr("-1")
}
}
}
}
}
}
}
}
In Jenkins job dsl, the multibranchPipelineJob has an option to add the following lines for discarding old builds.
orphanedItemStrategy {
discardOldItems { numToKeep(10) }
}

How to ensure that parallel stages use a copy of a workspace from a previous stage?

I am writing a pipeline for a cross-platform application. The goal is to have a single stage for checking out the source code from SCM and then having a number of slaves build the application for each platform from that checkout.
Here is a rough overview of what I have:
pipeline {
agent none
stages {
stage('Checkout') {
agent any
steps {
checkout([extensions: [[$class: 'CleanBeforeCheckout']], ...]]])
}
}
stage('Build') {
parallel {
stage('win') {
agent { label 'win' }
steps { ... }
}
stage('mac') {
agent { label 'mac' }
steps { ... }
}
}
}
}
}
The problem is that the parallel stages are not using the clean checkout from the first stage. They are simply reusing the workspace from the previous build.
How would I go about fixing this?
Stash the workspace in the checkout stage and then unstash in each subsequent stage.
https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-unstash-code-restore-files-previously-stashed

Job DSL to create "Pipeline" type job

I have installed Pipeline Plugin which used to be called as Workflow Plugin earlier.
https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin
I want to know how can i use Job Dsl to create and configure a job which is of type Pipeline
You should use pipelineJob:
pipelineJob('job-name') {
definition {
cps {
script('logic-here')
sandbox()
}
}
}
You can define the logic by inlining it:
pipelineJob('job-name') {
definition {
cps {
script('''
pipeline {
agent any
stages {
stage('Stage 1') {
steps {
echo 'logic'
}
}
stage('Stage 2') {
steps {
echo 'logic'
}
}
}
}
}
'''.stripIndent())
sandbox()
}
}
}
or load it from a file located in workspace:
pipelineJob('job-name') {
definition {
cps {
script(readFileFromWorkspace('file-seedjob-in-workspace.jenkinsfile'))
sandbox()
}
}
}
Example:
Seed-job file structure:
jobs
\- productJob.groovy
logic
\- productPipeline.jenkinsfile
then productJob.groovy content:
pipelineJob('product-job') {
definition {
cps {
script(readFileFromWorkspace('logic/productPipeline.jenkinsfile'))
sandbox()
}
}
}
I believe this question is asking something how to use the Job DSL to create a pipeline job which references the Jenkinsfile for the project, and doesn't combine the job creation with the detailed step definitions as has been given in the answers to date. This makes sense: the Jenkins job creation and metadata configuration (description, triggers, etc) could belong to Jenkins admins, but the dev team should have control over what the job actually does.
#meallhour, is the below what you're after? (works as at Job DSL 1.64)
pipelineJob('DSL_Pipeline') {
def repo = 'https://github.com/path/to/your/repo.git'
triggers {
scm('H/5 * * * *')
}
description("Pipeline for $repo")
definition {
cpsScm {
scm {
git {
remote { url(repo) }
branches('master', '**/feature*')
scriptPath('misc/Jenkinsfile.v2')
extensions { } // required as otherwise it may try to tag the repo, which you may not want
}
// the single line below also works, but it
// only covers the 'master' branch and may not give you
// enough control.
// git(repo, 'master', { node -> node / 'extensions' << '' } )
}
}
}
}
Ref the Job DSL pipelineJob: https://jenkinsci.github.io/job-dsl-plugin/#path/pipelineJob, and hack away at it on http://job-dsl.herokuapp.com/ to see the generated config.
This example worked for me. Here's another example based on what worked for me:
pipelineJob('Your App Pipeline') {
def repo = 'https://github.com/user/yourApp.git'
def sshRepo = 'git#git.company.com:user/yourApp.git'
description("Your App Pipeline")
keepDependencies(false)
properties{
githubProjectUrl (repo)
rebuild {
autoRebuild(false)
}
}
definition {
cpsScm {
scm {
git {
remote { url(sshRepo) }
branches('master')
scriptPath('Jenkinsfile')
extensions { } // required as otherwise it may try to tag the repo, which you may not want
}
}
}
}
If you build the pipeline first through the UI, you can use the config.xml file and the Jenkins documentation https://jenkinsci.github.io/job-dsl-plugin/#path/pipelineJob to create your pipeline job.
In Job DSL, pipeline is still called workflow, see workflowJob.
The next Job DSL release will contain some enhancements for pipelines, e.g. JENKINS-32678.
First you need to install Job DSL plugin and then create a freestyle project in jenkins and select Process job DSLs from the dropdown in the build section.
Select Use the provided DSL script and provide following script.
pipelineJob('job-name') {
definition {
cps {
script('''
pipeline {
agent any
stages {
stage('Stage name 1') {
steps {
// your logic here
}
}
stage('Stage name 2') {
steps {
// your logic here
}
}
}
}
}
''')
}
}
}
Or you can create your job by pointing the jenkinsfile located in remote git repository.
pipelineJob("job-name") {
definition {
cpsScm {
scm {
git {
remote {
url("<REPO_URL>")
credentials("<CREDENTIAL_ID>")
}
branch('<BRANCH>')
}
}
scriptPath("<JENKINS_FILE_PATH>")
}
}
}
If you are using a git repo, add a file called Jenkinsfile at the root directory of your repo. This should contain your job dsl.

Resources