How to trigger azure pipeline via API in a way it does not report it was manually triggered - azure-devops

We have an Azure pipeline building a static site. When there is a change in a content repository the site needs to be rebuilt. For that, we're using webhooks and Azure DevOps API. The request to queue the build is very simple and is illustrated for example here.
What I don't like about this is that int the build listing it says "Manually triggered for person XY", where the person XY is the one who generated the credentials used in the API request. It seems quite confusing because any API request seems strange to be labeled as "manually requested". What would be the best way how to achieve more semantically correct message?
I've found there is a reason property which can be sent in the request. But none of the values seems to represent what I want and some of them do not work (probably need additional properties and there is no documentation for that).

Based on my test, when you use the Rest API to queue a build and set the build reason, the reason could be shown in the Build(except:batchedCI and buildCompletion).
Here is the Rest API example:
Post https://dev.azure.com/Organization/Project/_apis/build/builds?api-version=4.1
Request Body:
{
"definition": {
"id": 372
},
"reason":"pullRequest"
}
The value : checkInShelveset individualCI pullRequest schedule could show their own names.
The value: manual and none could show manually trigger.
The other value(e.g. All, userCreated) will show Other Build Reason.
For the value: batchedCI and buildCompletion.
BatchedCI: Continuous integration (CI) triggered by a Git push or a TFVC check-in, and the Batch changes was selected.
This means that batch changes are required to achieve this trigger. So it doesn't support to queue build in Rest API .
buildCompletion: you could refer to this ticket This reason doesn't support in Rest API-queue Build.
Note: If you enter a custom value or misspelling, it will always display manual trigger.

In the end, I went with all value and also overriding the person via requestedFor property. This leads to the message "Other build reason", which seems usable to me.
{
"definition": {
"id": 17
},
"reason":"all",
"requestedFor": {
"id": "4f9ff423-0e0d-4bfb-9f6b-e76d2e9cd3ae"
}
}
However, I'm not sure if there aren't any unwanted consequences of this "All reasons" value.

Related

GitHub REST and GraphQL API are returning different data

I am scraping some data from GitHub. The RESTful URL to this particular PR shows that it has a merge_commit_sha value: https://api.github.com/repos/ansible/ansible/pulls/15088
However, when I try to get the same PR using GitHub GraphQL API, it shows it does not have any mergedCommit value.
resource(
url: "https://github.com/ansible/ansible/pull/15088"
) {
...on PullRequest {
id
number
title
merged
mergeCommit {
message
}
}
}
For context, the PR of interest is actually merged and should have a merged-commit value. I am looking for an explanation of the difference between these two APIs.
This link posted in the other answer contains the explanation:
As in, Git doesn’t have the originalCommit (which makes sense).
Presumably the original commit SHA is there, but the graphQL API actually checks to see if git has it, whereas the REST API doesn’t?
If you search for the commit SHA the API returns, you can't find it in the repo.
https://github.com/ansible/ansible/commit/d7b54c103050d9fc4965e57b7611a70cb964ab25
Since this is a very old pull request on an active repo, there's a good chance some old commits were cleaned up or other maintenance on the repo. It's hard to tell as that kind of maintenance obviously isn't version controlled.
Another option is the pull request was merged with fast-forward, which does not involve a merge commit. But that wouldn't explain the SHA on the REST API response.
So probably at some point they removed old merge commits to save some space, or something similar. Some objects still point to removed SHAs, but GraphQL API filters on existing objects.
Feel like it is a bug to me because if you query another PR such as 45454 , it can return the mergeCommit:
{
"data": {
"resource": {
"id": "MDExOlB1bGxSZXF1ZXN0MjE0NDYyOTY2",
"number": 45454,
"title": "win_say - fix up syntax and test issues (#45450)",
"merged": true,
"mergeCommit": {
"message": "win_say - fix up syntax and test issues (#45450)\n\n\n(cherry picked from commit c9c141fb6a51d6b77274958a2340fa54754db692)",
"oid": "f2d5954d11a1707cdb70b01dfb27c722b6416295"
}
}
}
}
Also find out other encountered the same problem at this and another similar issue at this. I suggest you can try to raise this issue to them at this.

Copy pull request description to work item comments on Azure Devops

When PR is approved, there is message "Completing Pull Request 123 and the associated work items." added to associated work item's comments area.
Is there any way how to append PR description?
I have zapier webhook attached to comments and I wont to get PR message in another app.
When PR is approved, there is message "Completing Pull Request 123 and
the associated work items." added to associated work item's comments
area.
Based on this description, I guess you are attempting to append the PR description to work item comment while the Pull Request is completing, right?
Afraid to say that there's no such out-of-box feature can let you direct to use. But you can consider to run powershell scripts along with rest api in build pipeline to achieve such goal.
The logic of my suggestion is:
Step 1: Prepare environment.
Create one build pipeline, and make its trigger type as Continues Integration(CI). Only this, the pull request completing can trigger this pipeline processing, then do next job.
Step 2: Get the PR completing node id, then get corresponding Pull request ID by calling this PRs query api.
For the build which run by CI, there has one environment variable Build.SourceVersion can represents the merge node id which generated by Pull request complete.
POST https://dev.azure.com/{org}/{project name}/_apis/git/repositories/{repo name}/PullRequestQuery?api-version=6.0-preview.1
{
"queries": [
{
"type": 1,
"items": [
"$(Build.SourceVersion)" // Put the $(Build.SourceVersion) value here.
]
}
]
}
Then, in its response body, you will see there has one parameter pullRequestId which target to the Pull request this commit id associated with.
Step 3: Get detailed PR description and work item id by using the pull request id we get in step 2.
Get https://dev.azure.com/{org}/{project name}/_apis/git/repositories/{repo name}/pullrequests/{pull request id}?includeWorkItemRefs=true&api-version=5.1
Put the pull reqeust id we got from step 2 into this api, then you can see the description contents along with the work item id from its response body:
Step 4: Add this description contents to corresponding work item comment area.
POST https://dev.azure.com/{org}/{project name}/_apis/wit/workItems/{WorkItem Id}?api-version=5.1-preview.3
[
{
"op": "add",
"path": "/fields/System.History",
"Value": $(description) // put the description here
}
]
As I mentioned firstly, make sure this pipeline is triggered by CI. Then you will get the description contents be added into WIT comment once the Pull request is completing.

Unable to flag / trigger "Merge when pipeline succeeds" via Gitlab Api (v3/v4)

So as a part of some tests to automatically accept / merge successful pipelines in our git repository i was running some tests to flag the "merge when pipeline succeeds" feature when the pipeline is still running:
So this button is available when the pipeline is still running and will convert to a green 'Accept merge' button when the pipeline succeeds:
(note that this picture was taken afterwards not to confuse the use-case)
additionally i have set these general settings:
So when checking the Gitlab API Documentation it says i should use the following endpoint:
PUT /projects/:id/merge_requests/:merge_request_iid/merge
when using the parameter ?merge_when_pipleline_succeeds=true it should flag the button.
However when i call this endpoint when the pipeline is still running (i built in a wait for 10 mins while testing this) i get the following result:
i am getting a Method Not Allowed. My assumption is that the endpoint i am using is correct because otherwise i would've gotten a bad request / not found return code.
when checking the gitlab merge request i am seeing that indeed the flag is not set to true:
However, when i manually click the blue button the mergerequest looks like this:
Also if i let the pipeline finish and then proceed to call the merge api (w/ or w/o the merge when pipeline succeeds flag) it will accept the merge. It just does not work when the pipeline is running (which is odd because even the button itself only shows when the pipeline is running)
so i am wondering what I am doing wrong here.
I am using a Powershell module to call the GitLab API. The Accept part of the module is not official and was made by myself because i found this feature missing.
I am using the same credentials for the API w/ a personal access token to authenticate to the API. Other functionality of the API work with this token like creating merge requests, retrieving status of a current MR and accepting a MR when the pipeline is finished.
I have tried the following variants :
Use the V3 api with merge_when_build_succeeds=true --> nets the same
result
Uncheck the "Only allow merge request to be merged if the
pipeline succeeds" --> nets the same result
Use ID of the merge request instead of IID
use /merge_when_pipeline_succeeds instead of ?merge_when_pipeline_succeeds=true
use True instead of true --> nets the same result
I get a similar issue with the python-gitlab library on v4. It works sometimes when I use:
mr.merge(merge_when_pipeline_succeeds=True)
Where mr is a ProjectMergeRequest object. However, if the MR has a merge conflict in it I get that 405 Method Not Allowed error back.
My best guess is to see if I can apply logic before calling mr.merge() to check for problems. Will update this if that works.
UPDATE: Looks like there is no feature to check for conflicts as of today. https://gitlab.com/gitlab-org/gitlab-ce/issues/41762
UPDATE 2: You can check merge_status when looking at the MR information, so either that attribute or an exception then mr.merge() fails would let you identify when it won't work.

Get if pull request passed all required status checks using GitHub API

I need to check via GitHub API if a pull request passed all required status checks. I use GitHub Enterprise 2.8 at this moment.
I know that I can get all status checks for last commit (following statuses_url in pull request). However, I don't know which status checks are set up to be required in a given repository. This is my main problem.
I also need to aggregate these status checks, group them by context and take latest in each context. It's ok, but seems to be reimplementation of logic, that GitHub performs internally when decides if a pull request can be merged.
For my case, it would be ideal to have something like can_be_merged in pull request fields, which meaning is mergeable && all required status checks passed && approved, but as far as I know there is no such field.
Finally solved this! You actually need to get the information off the protected branch, not off the check itself. Here are some API details: https://developer.github.com/v3/repos/branches/#list-required-status-checks-contexts-of-protected-branch.
So the flow to solve this is:
Check if the base branch for the PR is protected, and if so;
Use the above endpoint to determine which checks are required;
Compare the checks on the latest PR commit to the required checks determined in step 2.
Based on #moustachio's answer, if you are using v4 graphql API, you may use
pullRequest(...) {
baseRef {
refUpdateRule {
requiredStatusCheckContexts
}
}
}
to get the same info without additional API request

How do I determine branch name or id in webhook push event?

I was ecstatic when I got a simple webhook event listener working with GitHub push events on my Azure site, but I realize now I'm not seeing the branch name or id in the json payload (example here https://developer.github.com/v3/activity/events/types/#pushevent)
I thought maybe "tree_id" would be it, but it doesn't seem to be. I couldn't find any info about this in GitHubs's doc. Maybe I need to take one of the id's from the event and make another api call to get the branch? The reason for this is I want to be able to link GitHub push events with my app portfolio, which has branches defined. So, the push events are a way to see code change activity on my different apps -- and knowing the branch is therefore important.
I wrote to GitHub support, and they told me that the branch name is part of the "ref" element in the root of the json payload. When parsing from a JToken object called jsonBody, the C# looks like this
var branchName = jsonBody["ref"].ToString().Split('/').Last();
For example in "refs/heads/master", the branch name is "master"
You need to pay closer look on WEBHOOK response mainly. Here is the trick for JSONPATH ( at-least what I did with my jenkins job):
first read your webhook whole response with character "$". You can catch it is some variable like:
$webhookres='$'
echo $webhookres
Once you have response printed, copy it and paste here: https://jsonpath.com/
Now create your pattern. For example if you want branch name (if event is push):
$.ref
Once you have the branch name( it will have extra string with /), simply trim the unwanted part using awk or cut (linux commands).
You are not limited to this only. All you need to work on pattern and you can make use of this approach for getting other values as well like, author, git repo url etc. and then these can be used in your automation further.
even if you are using any other platform like Azure, JSONPATH concept will be same. because as suggested in accepted answer, "jsonBody["ref"]", it is equivalent to $.ref, as altogether you have to identify the PATTERN ( as here PATTERN is 'ref')