prevent the bitbucket pipline from tirggering when bitbucket-pipelines.yml is updated - bitbucket

I am new to bitbuckt pipeline. To my node project I have added bitbucket-pipelines.yml in the pipeline I have a step to build and push container to ECR and another step to deploy.
Now each time I make a change to bitbucket-pipelines.yml it build and pushes a new image to ECR and deploys.
I do not what the piepline to trigger when I make changes to bitbucket-pipelines.yml. I only want the pipeline to trigger when I make changes to my application. Am I setting up the project wrong?
my project structure.
.
├── bitbucket-pipelines.yml
├── Dockerfile
├── index.js
├── node_modules
├── package.json
├── package-lock.json
└── README.md

There are a few possible options:
1. Add [skip ci] to your git commit message
Whenever you change the bitbucket-pipelines.yml on its own, add "[skip ci]" (without quotes) somewhere in your Git commit message. This will prevent the pipeline from running when you push to the Bitbucket remote.
Advantages:
It's easy and simple.
Disadvantages:
You have to remember to manually write the "[skip ci]" text. It's easy to forget, or perhaps a new team member will not know about it.
2. Use a Git Hook to automatically modify your git commit message
Write a Git Hook script that will automatically insert the "[skip ci]" text into the Git commit message. The script will have to do something like this:
After a local commit, check the latest commit to see which files were changed. Use something like git diff --name-only HEAD~0 HEAD~1
If bitbucket-pipelines.yml was the only file changed, modify the commit to insert "[skip ci]" into the commit message.
More info about Git Hooks:
https://githooks.com/
https://www.atlassian.com/git/tutorials/git-hooks
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
Advantages:
It's fully automatic. No need to manually tag your commit messages.
Disadvantages:
Creating the script may not be easy.
Each cloned repo needs to configure the git hooks. See: Can Git hook scripts be managed along with the repository?
3. Make the bitbucket-pipelines.yml check for the file changes
Add a section in the yml build script to check which file was changed in the latest commit.
The script in the yml will have to do something like this:
Check the latest commit to see which files were changed. Use something like git diff --name-only HEAD~0 HEAD~1
If bitbucket-pipelines.yml was the only file changed, abort the CI build immediately, with an exit 0 statement.
Advantages:
It's fully automatic. No need to manually tag your commit messages.
No need to write Git Hook scripts.
Disadvantages:
The Docker image of your CI build will take 1-5 minutes to load, and then abort itself. This is a bit ineffecient and it will consume some of your build minutes.
Because the CI build will still run for a few minutes, it will pollute your CI build history with build runs that didn't do anything.
4. Use a Conditional Step with "changesets" and "includePaths"
Define a changesets with an includePaths to execute a step only if one of the modified files matches the expression in includePaths.
pipelines:
default:
- step:
name: build-frontend-artifact
condition:
changesets:
includePaths:
# only xml files directly under resources directory
- "src/main/resources/*.xml"
# any changes in frontend directory
- "src/site/**"
script:
- echo "Building frontend artifact"
Source and more info here: https://bitbucket.org/blog/conditional-steps-and-improvements-to-logs-in-bitbucket-pipelines

Related

Bitbucket pipelines - Run or skip step based on build output

We have a monorepo that contains about 5 projects. All these projects are build based on the git change history, so if project A is not changed, it is not build. This is al managed by Nx monorepo.
We are using Bitbucket Pipelines to build and deploy our projects. We want to split every deploy into it's own step so that we have more control over each project's deployment.
In order to achieve this we need to change our build step so that it only executes if the dist folder contains the portal it is ment to deploy. I've read about the condition configuration, but i cannot find anything about checking build artifacts in a condition instead of the git commit that triggerd the change. So is there a way to skip (or directly pass) a step if the portal is not in the build artifact?
Build step
- step: &build
name: Build
caches:
- node
script:
- git fetch origin master:refs/remotes/master
- npm run build
artifacts:
- dist/**
Example Dist artifact
.
├── dist/
│ ├── login-portal
│ ├── Portal-Y
Our deploy step
- step: &deployLoginPortal
image: amazon/aws-cli:2.4.17
deployment: test
trigger: manual
script:
- aws s3 sync $LOGIN_OUTPUT_PATH s3://$LOGIN_S3_BUCKET/ --acl public-read # Sync the portal
# $LOGIN_OUTPUT_PATH = 'dist/login-portal'
Example condition (does not work)
condition:
changesets:
includePaths:
- $LOGIN_OUTPUT_PATH/** # only run if dist contains changes in $LOGIN_BUILD_PATH
Am I missing something or is there an other way of only executing the step if the build artifact (dist/) contains the portal the step is ment to deploy?
You can manually check the presence of an artifact before doing aws s3 sync and gracefully exit the step if condition is not satisfied:
script:
- [ ! -d "$LOGIN_OUTPUT_PATH" ] && echo "Directory $LOGIN_OUTPUT_PATH is not present; gracefully exiting" && exit 0
- aws s3 sync $LOGIN_OUTPUT_PATH s3://$LOGIN_S3_BUCKET/ --acl public-read
Be advised that your step will still technically be triggered, so its startup time (usually about 40 seconds) will be affecting your quotas.

How to save Jenkins configuration?

Is there any way to save a pipeline configuration or an item configuration in Git or anywhere else, so that when my Jenkins machine is crashed, i can migrate the saved configuration in the new Jenkins instance?
I would ( as a start ) get yourself - https://wiki.jenkins.io/display/JENKINS/JobConfigHistory+Plugin which keeps history of all Changes made to Jobs , System config etc - has saved me multiple times.
Also , you could setup a cron job outside Jenkins to git push your Job config.
I setup to push the Jobs folder content ( including Build history - but you could exclude that - Correctly ignore all files recursively under a specific folder except for a specific file type ref ) .
My script ( i had SSH stuff previously setup )
cd /this/that/other/jenkins_data/jobs/
NOW=$(date +"%m-%d-%Y-%r")
git add .
git commit -m "Jenkins Backup $NOW"
git push -u origin jenkins-backup
This way gives me piece of mind , I have RSYNC to another box and I also have a Backup plugin running too... ( i was stung once - not again! )
Hope this helps.
All your jobs is stored in config.xml files inside $JENKINS_HOME/jobs/<path_to_your_job> folders. So, you can just backup these config.xml files (or you can backup all Jenkins configuration by saving full $JENKINS_HOME folder).
Hi you can write the pipeline script in file and publish that file into the git.
After that just create the pipeline job in the jenkins and use Pipeline script from SCM option for pipeline script.
The other option is take backup of Jenkins home directory to external hard disk(keep project workspace outside the jenkins home to reduce backup size).

How to write the git change log for two particular builds in a file in jenkins

I wish to write the git change log for two particular builds in a file in Jenkins.
I have used " git change log " plugin it shows the difference between latest one and the previous one and follows;
Not for the particular two builds.
Eg:
input : build1, build10
Output should be the git change log between build1 and build10
You need to get the GIT_COMMIT Environment variable from the two build you wanted and then do a git log between those commits.
Example: git log --pretty=oneline COMMIT_X COMMIT_Y
If you want the difference in the repo files itself you have to do git diff between those commits.
Example:git diff COMMIT_X COMMIT_Y

Let Jenkins build project from a Mercurial commit

Is there a way to specify a hook in the single repository?
Now we have specified the hook in the "/etc/mercurial/hgrc" file, but every time it builds twice, and it builds for each commit in each repository.
So we want to specify a build per repository.
This is how we implemented the hook:
[hooks]
changegroup = curl --silent http://jenkins:8080/job/ourProject/build
It's on a Ubuntu server.
Select the Poll SCM option under Build Triggers.
Make sure that schedule form is empty.
You should be creating in the .hg directory, /home/user/mercurial/.hg/hgrc and add hooks as:
[hooks]
commit.jenkins = wget -q http://localhost:8080/mercurial/notifyCommit?url=file:///home/user/mercurial > /dev/null
incoming.jenkins = wget -q http://localhost:8080/mercurial/notifyCommit?url=file:///home/user/mercurial > /dev/null
You should make sure that
Your Jenkins project doesn't poll
You use the proper notifyCommit URLs for your Mercurial hooks: https://wiki.jenkins-ci.org/display/JENKINS/Mercurial+Plugin
Ok, I found what I looked for (I'm the bounty; my case is Mercurial with a specific branch).
In the main/origin repository, place a hook with your desired build script. Pregroupchange is to maintain the incoming changes. I have a rhodecode installed on the main repository and itself has its own hooks.
In this way, I still trigger Jenkins and still have the changes afther the trigger for rhodecode push notifications and others.
[hooks]
pregroupchange = /path/to/script.extention
In the script, place your desired actions, also a trigger for Jenkins. Don't forget to enable in Jenkins:Job:Configure:Build Triggers:checkbox Trigger builds remotely + put here your desired_token (for my case: Mercurial).
Because you can't trigger only to a specific branch in Mercurial, I found the branch name in this way. Also, to trigger from a remote script, you need to give in Jenkins read permission for anonymous overall, or create a specific user with credentials and put them into the trigger URL.
Bash example:
#!/bin/bash
BRANCH_NAME=`hg tip --template "{branch}"`
if [ $BRANCH_NAME = "branch_name" ]; then
curl --silent http://jenkins_domain:port/path/to/job?token=desired_token
fi
For the original question:
In this way you only execute one build, for a desired branch. Hooks are meant only for the main repository in case you work with multiple clones and multiple developers. You may have your local hooks, but don't trigger Jenkins from you local, for every developer. Trigger Jenkins only from the main repository when a push came (commit, incoming, and groupchange). Your local hooks are for other things, like email, logs, configuration, etc.

Make jenkins auto build one a day but build only when there are source code changed

I have problem in configure jenkins to auto build and deploy java project. I want to build and deploy once a day. However this build only there are changes during the day. IF there is no changes, I don't want jenkins to auto build and deploy.
Note: that I used gitlab as source code management.
Can you help me with this configuration.?
Firstly, you should configure the Git SCM section at the top of the job config page to point to your GitLab repository.
Then you can use the built-in "Poll SCM" build trigger — this will periodically check whether your source code repository has changed — and if it has, a build of this job will be started.
If the repository has not changed since the last build, then no build will be started.
You can configure this trigger — whether using a cron-like syntax, or a shortcut like #daily or #midnight — so that Jenkins only checks the source repository once a day.
Additionally, you should make sure that the "ignore post-commit hooks" option is enabled. If you're using webhooks from your Git repository to start Jenkins jobs whenever a commit occurs, this option prevents your once-per-day job from being triggered for every Git commit.
Here's the detail document: "Jenkins CI integration"
http://doc.gitlab.com/ee/integration/jenkins.html
Update to match your comment.
You don't want to trigger the Jenkins build via webhook. It's ok.
You want to check the code change 1 time a day.
Example on Linux, build at 6:00 AM if there's any code change.
Install
https://wiki.jenkins-ci.org/display/JENKINS/PostBuildScript+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/Text-finder+Plugin
Build Triggers
Build periodically: 0 6 * * *
Execute shell
Like this
SINCE=`curl http://192.168.0.1:8080/job/MyJava/lastStableBuild/buildTimestamp?format=dd-MMM-yyyy`
cd /opt/code/myjava/
git log --pretty="%h - %s" --author=gitster --since=$SINCE --before=$SINCE --no-merges -- t/
Post Build actions
Post build task
Log text: commit
Operation: AND
Script: Your script to build your Java
Jenkins text finder
Also search the console output
Regular expression: Could not match
Unstable if found

Resources