How to serialize VSTS CI branch builds - continuous-integration

VSTS allows you to select which branches automatically trigger a CI build by specifying a branch pattern.
However, my unit tests are using a real database which causes a problem when more than one build triggers e.g. master and feature-123 as they will clash on the database tests.
Is there a way of specifying that only one such build should be run at at time; I don't want to go away from executing tests against a real database as there are significant differences between an in-memory database and SQL Azure.

VSTS already serialize builds which are triggered by the same CI build.
Even CI build can be triggered by multiple branches, but for a certain time, only one build is running by default (unless you use pipelines to run builds concurrently).
Such as if both master branch and feature-123 branch are pushed to remote repo at the time time, the CI build definition will trriger two builds serially (not concurrently).
If you are using pipeline and need to run the triggered builds serially, you should make sure only one agent is used for the CI builds. You can use the way below:
In your CI build definition -> Options Tab -> add demands to specify which agent you want to use for the CI build.
Assume in default agent pool, there are three agents with the agent name: default1, default2 and default3.
If you need to specify default2 agent to run the CI build, then you can add the demands as below:
Now even multiple branches have been pushed at the same time, they will be triggered one by one since only one agent is available for the CI build.

If you use a YAML pipeline, you can use a deployment job in stead of a regular job.
With a deployment job you select a named Environment you want to deploy to.
You can configure the Environment in azure devops under Pipelines->Environments and you can choose to add an Exclusive Lock.
Then only one run can use the environment at a time and this serializes your runs.
Unfortunately, if you have multiple runs waiting for the environment (because one run currently has it locked), when the environment becomes unlocked only the latest run will continue. All the others waiting for the lock will be cancelled.

If you want to do it via .yml or .yaml file you can do following
- phase: Build
queue:
name: <Agent pool name>
demands:
- agent.name -equals <agent name from agent pool>
steps:
- task: <taskname>
displayName: 'some display name'
inputs:
value: '<input variable based on type of task'
variableName: '<input variable name>'

Related

Build Manual GitlabCI pipeline job using specific Commit ID

I need to build a Gitlab CI pipeline manually but not using latest of my master branch, but using a specific commitID.
I have tried running pipeline manually by using variable as below and passing its value but of no use.
Input variable key: CI_COMMIT_SHA
At the time of this writing, GitLab only supports branch/tag pipelines, merge request pipelines and scheduled pipelines. You can't run a GitLab pipeline for a specific commit, since the same commit may belong to multiple branches.
To do what you want, you need to create a branch from the commit you want to run the pipeline for. Then you can run the manual pipeline on that branch.
See this answer for step-by-step instructions on how to create a branch from a commit directly in the GitLab UI.
Use the existing (created by Gitlab CI) workspace to run the .gitlab-ci.yml and from there checkout the code again in a different directory using commitID, and perform all the operations there.

how to run a single instance of teamcity build across all agents

We have a teamcity set-up on with multiple agents. There is one particular build which uses some underlying resources and services of a particular environment. ( say uat)
We want that this build should not run n parallel to avoid resource contention. i.e. only a single running build at a time. How can I achieve this ?
Thanks
Under the project, setup a shared resource:
Then under the build configurations you don't wish to be able to run in parallel add a build feature and select the resource you just created and "Write Lock":
This will mean any extra builds triggered will stay in the build queue and will not be allowed to run concurrently.

Jenkins pipeline DSL automatically abort input

I am using the new Jenkins pipeline DSL which I really like. My Jenkinsfile is probably fairly typical and compiles / unit tests code in the master branch of GIT using maven, does a docker build, deploys to staging etc. Towards the end of the pipeline there is a manual step where a user has to confirm if a build goes to production e.g.
stage name: 'Production Deploy', concurrency:1
input 'Do you want to deploy to production?'
node {
sh "./bin/production-deploy.sh"
}
However, the build blocks until someone accepts / declines. Is there a way to automatically decline the input if someone else kicks the build off (by merging code to the master branch)?
I sugest you separate the Continuos Integration pipeline of Continuos Delivery pipeline. In the CI pipeline you build, test, deploy from develop stage to staging stage, then someone validate the staging deploy and when all staging tests are OK in a next step you execute the DC pipeline; is when you deploy to production stage. in that way you have an independent livecycle develoment process and an independent delivery process.

TeamCity: Prevent 2 builds from running simultaneously

I don't want Build Config A and Build Config B to run at the same time. This is because they share the same resource which cannot be accessed simultaneously. However each build config is run by a separate agent so it is possible for them to run simultaneously.
Instead I would like one build config, when triggered, to wait for the other to finish if it is running. For example if Build Config B begins to run but Build Config A is already running, then B would wait until A finishes and then B would run.
I don't think a snapshot dependency will work because that assumes one config has a dependency on the other which is not true in my case.
Keith, there are two plugins that can help you:
The first one is Groovy plugin. It has functionality of creating name locks over all projects.
The second one is TeamCity.SharedResources. It has functionality of definig shared resources and locking them with read and write locks. However, resources defined in this plugin, are are defined per-project. We are actively developing this plugin, so you are welcome to watch its page in our tracker
For a quick and dirty, just make a rule on the compatible agents tab for the project. That they have to run on the agent name containing xxx ( whatever that is ) then those builds can only run on that agent and will never run at the same time.
In the newest version of TeamCity, you can configure this parameter. Go to the Edit Configuration Settings -> Edit Configuration Settings and set parametr:
Limit the number of simultaneously running builds (0 — unlimited)

How can I continous deploy on jenkins, but only when a particular branch is pushed to?

I read an article describing Continuous Deployment with jenkins thusly:
Create a 'test' job that runs your tests.
Create a 'deploy' job that deploys your app.
Make the 'test' job trigger 'deploy' on successful build.
I can do that just fine. However, I have a generic 'test' job right now the runs tests for any branch that I push. Is there a way to make it only trigger the 'deploy' job if I pushed to the 'production' branch?
Otherwise, I can always add a second 'test-production' job that only triggers when I push to production, and it triggers deploy afterwards...but that's not what I want to do.
An alternative setup is to use rundeck for deployment.
The jenkins plugin has a feature that will trigger a deployment based on a SCM commit message:
The "tag" field is used to perform "on-demand" job scheduling on RunDeck : if the value is not empty, we will check if the SCM changelog (= the commit message) contains the given tag, and only schedule a job execution if it is present. For example you can set the value to "#deploy". Note that if this value is left empty, we will ALWAYS schedule a job execution.
So you can configure rundeck to trigger a Jenkins test after every successful deploy. And control those deployments, using commit messages in the code.

Resources