Devops Pull Request workflow validations - azure-devops

We are using Azure devops with the workflow for each task as:
Task branch to Release branch
Then Release branch to master
The reviewer will approve each pull request.
However, a user creating a PR can also create one from task branch directly to master.
Is there any way, by policies/validations that the system can prevent creation of the PR itself, which is from task to master.

Currently azure devops doesnot have the policies/validations to prevent creating a pr which is task to master.
However, there is workaround to prevent merging the PR which is task to master.
You can create a pipeline with a script task to check the source branch of the PR. See below:
$sourceBranch = "$(System.PullRequest.SourceBranch)"
if($sourceBranch -ne "refs/heads/release")
{
exit 1
}
For example add a powershell task with above script. The script will check if the PR source branch is release branch, and fail the pipeline if it is not.
Then you can add above pipeline to the branch policy of master branch. See below:
Then any PR which is not release to master will fail to be validated and cannot be completed. (But it still cannot prevent creating a PR from test to master)
You can also click here to submit a feature request(Click Suggest a feature and select Azure Devops. ) to Microsoft development team. Hopefully they will consider adding this feature in the future.
See below screenshot from my test pipeline.

If you only want a subset of users to manage the merge to master, you can setup branch security on the master branch that prevents contributing to pull requests that would target that branch.

Related

Azure DevOps - Automatic merge after deployment

We have a development branch that is fed from feature branches through pull requests. After merge a build occurs and the artifact created triggers the release pipeline with some deployments happening automatically and others happening after manual approval.
After the approval happens for production, and after successful deployment, we would like to merge the PR that was was merge to develop to our main branch. I was wondering if this could be achieved automatically from the pipeline.
Note that not all the PR are going to make its way to production and the latest may not be the one being deployed in production.
Assuming that you must complete the PR to trigger the CI build and release pipelines, you won't be able to re-use the existing PR to merge into another branch because PRs are specific to branches and once completed they can't be re-opened.
In theory, you could add logic to your release pipeline to create a new PR after successfully deploying into production but this is dangerous because PRs are based on branches and not individual commits. So if the develop branch changes while you're deploying into production the new PR would contain changes that haven't been deployed. If you have a small team and the number of PullRequests are low, this might not be a problem for you.
However, if you have a large team and dozens of pull-requests a day, you might benefit by adjusting your a gitflow branching strategy. In that model you would create a release branch and deploy that into other environments. Creating the pull request at the end of that pipeline flow makes total sense because you're deploying and merging a static branch.
For example, you could add a step in your release pipeline to create the PR using the Azure CLI:
$pr = az repos pr create `
--source-branch develop `
--target-branch main `
--title 'merge $(Build.BuildId) into main' |
ConvertFrom-Json
Write-Host 'Created PR $($pr.pullRequestId)'
There's another question where they're doing something similar.
Alternatively, look at the "Github flow" model. They use a trunk-based branching strategy where the PR is king and changes in the PR ultimately go to production or they don't get merged. The GitHub team had a model where they concentrated on a single PR at a time with a flow that looked like:
Designate a PR as a candidate for production
Automation would lock the target branch and create a temporary merge of the PR and the target branch
Automation would build this branch and deploy it to various environments.
Upon successful build into the environment, the automation would unlock the target branch and complete the PR.
It's worth pointing out that Azure DevOps does support triggering Releases from Pull Requests, and each PR-triggered build is a temporary merge of the target branch, so you could create a release and deploy it into your environments with your approval gates. You could add automation to your release to approve the PR:
az repos pr set-vote --id $pr.pullRequestId --vote approve

How to retrieve artifacts from AZ pipeline triggered by PR in subsequent pipeline triggered by merge from the PR branch

When a developer raises a PR to a branch we have a branch policy that runs a build/test pipeline. If the pipeline is successful and the dev gets an approver they can merge to master.
There is a policy on master branch that kicks off a similar build/test/deploy pipeline. It would seem safe and quicker to pull the built artifact from the PR build pipeline since that actually built based off a git MERGE target to master. But I can't work out if there is an inherent relationship in Azure Devops between what is essentially the last green pipeline on a branch and the pipeline triggered by that branches merge to master.
Any pointers?

How to trigger a task on merged pull requests only?

In Azure Devops, I have a repo that's in Bitbucket. I'd like to trigger a package publish on every approved pr that gets merged to the develop branch.
I've figured out how to conditionally run a task if the build is a pr or not, and how to trigger if the pr is to develop, but that means that the task is run for every PR created to develop. I'd like the task to only run when the pr has been merged to develop.
I noticed the following variables in my pipeline:
SYSTEM_PULLREQUEST_ISFORK=False
SYSTEM_PULLREQUEST_MERGEDAT=
SYSTEM_PULLREQUEST_PULLREQUESTID=139
SYSTEM_PULLREQUEST_PULLREQUESTNUMBER=139
SYSTEM_PULLREQUEST_SOURCEBRANCH=source-branch
SYSTEM_PULLREQUEST_SOURCECOMMITID=e55835e7e2e65ad87fd09a03959fefcfcc4d475f
SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI=[repoURL]
SYSTEM_PULLREQUEST_TARGETBRANCH=develop
And the SYSTEM_PULLREQUEST_MERGEDAT= variable stood out. Anyone have suggestions? Am I overly complicating this?
It is possible to achieve this with just conditions. Let's say you were merging from feature branch to develop branch. And you only want a task to be executed when the pr has been merged to develop.
First of all you should know the default CI triggers and PR triggers for Bitbucket repository on Azure pipeline.
1, CI triggers
If you don't specify any triggers, the default is as if you wrote below, which means commit to any branch will trigger the pipeline.
trigger:
branches:
include:
- '*'
When you specify a trigger, it replaces the default implicit trigger, and only pushes to branches that are explicitly configured to be included will trigger a pipeline. Includes are processed first, and then excludes are removed from that list.
2, PR triggers
If no pr triggers appear in your YAML file, pull request validations are automatically enabled for all branches.
When you specify a pr trigger, it replaces the default implicit pr trigger, and only pushes to branches that are explicitly configured to be included will trigger a pipeline.
Each new run builds the latest commit from the source branch of the pull request. This is different from how Azure Pipelines builds pull requests in other repositories (e.g., Azure Repos or GitHub), where it builds the merge commit,
See the document for more information.
So if you don't specify any CI triggers or PR Triggers. The default behavior is to enable the triggers for all branches. And the PR triggers will only trigger the pipeline to build the last commit from the source branch(ie. Feature branch) instead of develop branch.
So it will explain why there are two triggered builds on an update to a pr. one is CI trigger(ie. IndividualCI), another is PullRequest. Both builds were against the source branch (ie.feature).
When the pr was merged to develop. what happened was a new commit being added to develop branch, which will trigger the CI build. So the task you want to trigger should be run against develop branch.
As for above case of yours. I suggest you disable the pr triggers and only enable the CI triggers.(for pr triggers will only build the latest commit from the source branch, which is the same with CI trigger. )
You can disable the pr trigger like below:
pr: none
So you can just set the condition like below for the task
- task: taskname
input:
condition: and(eq(variables['Build.SourceBranchName'], 'develop'), eq(variables['Build.Reason'], 'IndividualCI'))
You can also use Webhook to trigger the azure pipeline. And set the condtion to eq(variables['Build.Reason'], 'ResourceTrigger')
resources:
webhooks:
- webhook: bitbucketwebhook
connection: bitbucketwebhook
Please see this thread for more information.

How to limit associated work items in Azure DevOps YAML pipeline once PR is merged?

I've been migrating build/release pipelines in Azure DevOps to the unified YAML format. Everything works as expected apart from the work items which are associated with CI builds once a PR is merged to the master branch. Here is the workflow:
Developer raises PR to merge changes from feature branch into the master branch
The PR has a build policy which executes the YAML pipeline against a test environment
The PR is completed and the feature branch is merged into the master branch
The YAML pipeline has a CI trigger for deployments to higher environments
For step 2 the triggered build shows whichever work items are associated with the PR:
However, for Step 4 the triggered CI build lists all work items in the master branch rather than just those associated with the PR:
Is there a way to only associate the work items which are associated with the PR to the CI build which is triggered once the feature branch is merged into master?
I can reproduce this issue and I found a similar ticket, they have reported it, you could follow this ticket to get the latest news.
If the build status is queue or running, then we create a new build, the new build will contain before build link work item. This is why the step 4 the triggered CI build lists all work items in the master branch rather than just those associated with the PR.
If all builds are completed, then we complete the pull request to trigger the CI build, it will be associated with the expected work items.
When all the builds were completed, I merged the PR to trigger the CI build, it just contain the pull request link work item.
Test result

How can I block PR completion until a release succeeds in Azure DevOps?

My goal is to block a PR completion until a change has gone through a CI pipeline and been deployed in a test release pipeline successfully. Additionally, I want to control which CI pipeline builds enter the release pipeline, so release entries don't get added with every PR commit.
I currently have the CI pipeline setup and working and I have a release pipeline working with manual additions.
To solve my problem, I tried to modify the Release pipelines Build Artifacts settings to use Pull request triggers for a specific target branch. Then, in the Release pipeline stage's pre-deployment conditions, I've selected a trigger of "After release" with pull request deployment enabled. However, I'm not seeing releases automatically created.
Is what I want possible? Are there other steps to execute this?
How can I block PR completion until a release succeeds in Azure DevOps?
To achieve this, you could add the release pipeline as Status Checks in the Branch Policies:
Detailed steps:
Add the CI pipeline as Build Validation in the Branch Policies for the specific target branch.
Do the same release pipeline settings as you, enable Pull request triggers for the specific target branch and enable pull request deployment.
Add the release pipeline as Status Checks in the Branch Policies for the specific target branch.
Note:
If you could not see the release pipeline in the list when you add
the Status Checks:
Please try to change the Source type of the release from Build Artifacts to Azure devops repos for the specific target branch, and also enable Pull request triggers for the specific target branch. Then, create a pull request to trigger this release pipeline. After that, we refresh the Branch Policies, we will see the release pipeline.
Now, we change the Source type of the release back to Build Artifacts and enable Pull request triggers for the specific target branch and enable pull request deployment.
The reason why you did not see releases automatically created may be that your build pipeline is not triggered by PR (maybe manually).
Mytest result :
If I do not set the release pipeline as Status Checks, just enable Pull request triggers and pull request deployment, it will set as Optional, it will not block PR completion: