Automatically trigger builds ONLY for PR branches in VSTS - azure-devops

I am trying to do the following:
A developer (e.g.: James) could be working on this private branch (e.g.: james/add-custom-logger) for a while before sending out a PR.
Once James sends out a PR, I would like to automatically trigger a build for that PR branch.
I am struggling to figure out how to do this in VSTS builds.
I know that I could setup build triggers based on branches like feature/* and could ask all developers to follow that pattern, so in this case it would be feature/james/add-custom-logger.
But I don't want to trigger those branches until a pull request is sent for those branches.
Any ideas on how to achieve this?

Maybe branch policies fit your scenario. If james always creates the PR to the same branch - for example 'master' - you can create a branch policy for 'master'. Go to Repos > Branches > ... (More Actions) > Branch policies > Build validation > Add build policy
https://learn.microsoft.com/en-us/vsts/repos/git/branch-policies?view=vsts#build-validation
https://learn.microsoft.com/en-us/vsts/pipelines/build/ci-build-git?view=vsts&tabs=yaml#validate-pull-requests

Related

PR validation pipeline without merge

GitHub creates a new ref when a pull request is created. The ref points to a merge commit, which is the merged code between the source and target branches of the pull request. The PR validation pipeline builds the commit this ref points to. (from here)
This causes a problem for my pipeline with Chromatic: these commits are problematic for a bunch of reasons. The biggest one is as they don't exist in the git history, we lose track of baseline acceptances you do on them.
Is there a way to configure GitHub and/or Azure DevOps build pipeline to trigger build for PR but for normal linear commit in PR branch, not merge of it with target branch?
Is there a way to configure GitHub and/or Azure DevOps build pipeline to trigger build for PR but for normal linear commit in PR branch, not merge of it with target branch?
I am afraid there is no such way to trigger build for PR but for normal linear commit in PR branch.
Just like what you pointed, PR validation pipeline is used to build the merged code between the source and target branches.
If you do not want to build the code merge of it with target branch, you can just set the build pipeline with CI trigger enable for the source branch instead of the PR build for the PR validation pipeline.

github security alerts on more than master branch

I would like to configure my github repository such that I can receive security alerts if a vulnerability is detected on any branch, not just the master branch. Does anyone know how and where to make this configuration.
The workflow we use to introduce new changes to our project is the following
Create a feature branch to develop a change
By way of pull request, merge the feature branch changes into a develop branch
Build a test instance of the application from the develop branch
Verify the change in the test instance
Cherry pick the change from the develop branch.
Deploy the production instance from master branch
in a recent change we introduced a security vulnerability and we only received a github alert when the change was cherry-picked to the master branch. Can I configure github to do security scans on all the branches, or perhaps the develop branch along with master?
It looks like my question was previously asked, and there is an answer here: github vulnerable dependencies per branch
GitHub security scans occur on the default branch of a repository.

Is it possible to set source dynamically in Azure Repos Git?

I'm looking for a solution to dynamically select a branch to build in the Azure pipeline. I have Azure Repos Git where I select project, repository and default branch. I would like to be able to select branch based on a variable.
What I'm trying now is to use the Command Line task and fire a git checkout command (e.g. branch is a variable):
git checkout $(branch)
I can't confirm it working yet but still I confirm it works but I feel that there is a better option than checking out default branch and then switching branch with the command line.
Update:
If you want to have single pipeline that can build different branches (version branches) for different branches, you could just specify them in the trigger of branch filters. This will not build all branches.
The branch you select in build definition is just the default branch used when you Queue New Build manually. OTOH the build trigger establish which branch to download, e.g. if the build has been triggered by a git push on branch develop then that is the one checkout'ed and built. Take a look at this link: Get the sources from the branch that triggered the build in Team Services
Besides, you could disable the default get source step.Then use you own powershell script and git command to get source code manually(just what you want) and check out branch, finally build based on your variable.
For YAML, to disable the default "Get Sources" just specify none in
the checkout:
checkout: none
For UI, please refer my reply in this question:
Is it able to ignore/disable the first step Get source in vNext Build?
Assuming you're choosing the default branch. That doesn't mean that
it's the only branch that can be built by that build definition.
You can choose which branches to monitor for CI (on the Triggers tab,
you can add multiple branch filters to represent the branches you wish
to build on commit), and the appropriate branch will be checked out
when the build is triggered. You can also choose an alternate branch
when manually queuing the build.
Source Link: Get Sources from multiple branches
If you want to dynamically select default branch as below, this is not available at present.
This is the branch that you want to be the default when you manually
queue this build. If you set a scheduled trigger for the build, this
is the branch from which your build will get the latest sources.
The default branch has no bearing when the build is triggered
through continuous integration (CI). Usually you'll set this to be
the same as the default branch of the repository (for example,
"master").
There is a related user voice here: When triggering a build, use the same branch as the trigger build. You could kindly vote up and track the process.

TeamCity Multiple VCS Roots

We are using a private GitHub Organization as version control. When a task is assigned to a developer, they fork the primary repository, make their code changes, and submit a pull request to have the changes merged into the master branch of the primary repository.
We are also using TeamCity for CI. It is currently configured to kick off a build for a VCS commit, which builds, tests, and deploys the artifact to an artifact repository internally. To accomplish this, the Team City build configuration has multiple VCS roots installed; one for the primary and 1 for each developer's fork.
The problem is that Team City pulls from all of them when a commit is made assuming they are all necessary for the build instead of allowing you to only pull from the single repository that triggered the build. Any thoughts on how we can accomplish this without having to create n build configurations in Team City for each project (where n == number of developers working on a project)?
I see way to do this with preserving current workflow is turning off automatic checkout (VCS Checkout Mode), and checking out code manually in an additional command-line build step, with a parameter %teamcity.build.branch% (logical branch name).
I.e.:
git clone ...
git checkout %teamcity.build.branch%
Triggers will just start the job if there are changes in developer's VCS root, fulfill branch env variable; no automatic checkout will happen and then build step will check out only needed branch. Only works with one git URL.
After posting in the JetBrains forums, I was pointed to a blog that answers my question.
TL;DR: my approach of using feature branches does not work with GitHub's workflow. Instead, Forks and Pull Requests should be used. The blog referenced shows how you can use Team City to trigger off of a Pull Request. Simply add +:refs/pull/*/head to "Branch Specification" in your VCS Root and all pull requests to the Source repository will trigger your Build Configuration.

How to configure Travis-CI to build pull requests & merges to master w/o redundancy

To put it in "BDD" terms:
Background:
Given I'm contributing to a GH repo
When I create a pull request
Then Travis should build the latest commit
When I push to an existing pull request
Then Travis should build the latest commit
When I merge a pull request to master
Then Travis should build master
I was confused by Travis-CI's "build pushes" and "build PRs" settings, as:
Enabling both causes each Pull Request to be build twice by Travis
once for the commit on that branch
and once again for the merge commit of that branch into its destination
Enabling just "build PRs" causes PRs to be built, but doesn't result in post-merge builds (i.e. on master).
Enabling "pushes" brute-force satisfies the above criteria by building all pushes to the repo. You can try to finagle things by white- & black-listing branches, but that will probably bite you unless you're rigorously disciplined with branch names.
This is explained more in Travis-CI docs and GH issue #3241.
Anyone know a configuration that satisfies the above criteria?
I eventually found another GH issue (#2111) which gave me the idea to try enabling both PRs & pushes, but with a whitelist to restrict pushes to a specific branch. This seems to satisfy the criteria for my workflow. Here's what I did:
Enable both PRs & branch pushes in the Travis settings for the repo:
Change .travis.yml to white-list master branch (i.e. only build pushes to master):
branches:
only:
- master
Test it by creating a PR with the .travis.yml change, and another PR with some empty commits to verify it works for forks too.
Verify successful merge commit build from master.
Just found in travis docs
Add to .travis.yml
if: type = push
alternatively:
if: type = pull_request
Assuming you want to build all PRs, something like the following will do the trick. Enable both branch and PR builds on the settings page, and put this line as the first line in your travis.yml:
if: (type = push AND branch IN (master, dev)) OR (type = pull_request AND NOT branch =~ /no-ci/)
This will attempt a push build on all pushes and a PR build on all pushes to an open PR, but will filter out any that don't meet the condition. You might need to modify this a bit - the clause about not building branches with no-ci somewhere in their name is obviously optional, and you may not have two branches that you always want to run builds on.
You can read more on conditions and conditional builds on Travis's site.
The whitelist approach described in the accepted answer has some significant limitations. In particular, it doesn't support non-redundantly building arbitrary branches without opening a PR.
I opened an issue asking for a better solution.
You can use next workflow if you want to test not only master branch but some others branches too:
Keep both "Build pushes" and "Build pull requests" ON
Add branches:except directive to your .travis.yml:
branches:
except:
- /^pr\..*/
In this configuration:
any commit to branch feature-A will trigger the build
any commit to branch pr.feature-A will not trigger the build
if branch pr.feature-A is used in opened pull request then build will be triggered
Workflow example
temporary WIP branch shared between several developers: wip.feature-A, any commit to this branch will trigger the build
when branch is ready to be merged to master you can rename it from wip.feature-A to pr.feature-A and open pull request
if while reviewing pull request you want to apply new fixes, just push to pr.feature-A
On all the steps above only one build will be triggered.
For one of the repositories, I was working with, here is what I wanted:
There is an origin repo which is the main repo which does all the releases.
I wanted that all the pull requests coming to master branch of origin should be built with Travis only once irrespective of the fact that it comes from a forked repo or any other branch of the origin itself.
For this case, this works like a charm
if: (type == push) OR (type == pull_request AND fork == true)