How to publish a draft Task Group via Azure DevOps API - powershell

I am in the process of converting some tasks inside numerous task groups we have to different tasks. Instead of doing this by hand I've opted for using Powershell along with the Rest API of Azure DevOps to update the JSON bodies of these task groups and send them to the API. The conversion of the tasks is working fine sofar.
sending a PUT to the rest API in order to update the current task group of the set works but I want to build in some retention / version history if some of the new tasks end up working different than expected. So just blatantly updating the existing Task Group under the same major version is not an option.
the UI of Azure DevOps has functionality where you can save changes to a task group as a 'draft' and then publish this draft as either a completely new version (major version + 1) or as a preview
I went ahead and attempted to send a PUT to the Rest API and upticking the major version using the following URI:
PUT https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups/{taskGroupId}?api-version=5.1-preview.1
Along with the settings:
JSONObject.version.major = $currentversion + 1
JSONObject.preview = true
This results in the API returning an error saying:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"Task group {TaskGroupID} not found.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.MetaTaskDefinitionNotFoundException, Microsoft.TeamFoundation.DistributedTask.WebApi","type
Key":"MetaTaskDefinitionNotFoundException","errorCode":0,"eventId":3000}
I then went ahead and tried to see if I could create a draft version. When sending a POST to the following URI i was able to create a draft:
POST https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups?api-version=5.1-preview.1
using the following settings in JSON:
JSONObject.version.major = 1
JSONObject.version.istest = true
JSONObject.id = $null
JSONObject.parentDefinitionId = {TaskGroupID of the taskgroup of which i am trying to make a draft}
This nets in a new Task group in draft state which i am able to view in the UI and modify and publish (with or without preview). When i export the created JSON from UI from a manually made draft and compare it versus the one coming from powershell i see no differences.
This last step is where I am stuck. I can't seem to convert the created draft into a new version of the {parentdefintionid} task group. I've tried the following settings:
Calling the taskgroupid URI of the parent with put while a draft is available
JSONObject.version.major = $currentversion + 1
JSONObject.version.isTest = false
JSONObject.preview = true
Removing ParentDefinitionID from JSONObject
is resulting in the same error where it states that it cannot find the ID of the parent:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"Task group {TaskGroupID} not found.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.MetaTaskDefinitionNotFoundException, Microsoft.TeamFoundation.DistributedTask.WebApi","type
Key":"MetaTaskDefinitionNotFoundException","errorCode":0,"eventId":3000}
The same is valid with above settings and calling the draftID URI
When i try to call the draftID task group URI with the following settings :
JSONObject.version.major = $currentversion + 1
JSONObject.version.isTest = false
JSONObject.preview = true
JSONObject.id = $ParentDefinitionID
Removing ParentDefinitionID from JSONObject
it results in the following error:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"The request specifies task group ID {parentTaskGroupID} but the supplied task group has ID {DraftTaskGroupID}.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.Task
GroupIdConflictException, Microsoft.TeamFoundation.DistributedTask.WebApi","typeKey":"TaskGroupIdConflictException","errorCode":0,"eventId":3000}
i've checked the actual JSONObject to an export of a published Task Group in UI and they match exactly so i'm quite positive that content is not the issue here.
The MS documentation is seriously lacking on API usage so i'm really in the dark there hoping to find some clues / solution here

Seems you were updating a already exist task group in Azure DevOps.
If you incremented the revision property to be 1 higher than what is currently deployed.
You need to submit the JSON with the same revision property that the server has.

Related

Azure DevOps: how to update release scoped variables using REST API

I am trying to update release scoped variables for the existing release using API.
Issue: receiving exception on API call (PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases/{releaseId}?api-version=5.1-preview.8)
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"You are using an old copy of release. Refresh your copy and try
again.","typeName":"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException,
Microsoft.VisualStudio.Services.ReleaseManagement2.Data","typeKey":"InvalidRequestException","errorCode":0,"eventId":3000}
Steps to Recreate:
Create release from existing release definition without triggering any stages on the web portal: https://vsrm.dev.azure.com
Get release details by invoking:
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases/{releaseId}?api-version=5.1-preview.8
Update response from step 2 with value for release scoped variable with "allowOverride" set to true
Update response from step 2 with "modifiedOn" property set to later date than existing value
Update response from step 2 with "definitionSnapshotRevision" property set to existing value incremented by 1
Update release by invoking:
PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases/{releaseId}?api-version=5.1-preview.8
and providing json generated in steps 2-5
Observe above mentioned exception
I have updated 2 release properties (modifiedOn and definitionSnapshotRevision) because I saw that these values change if I update a release using web site (https://vsrm.dev.azure.com). It seems that I am still missing something. I cannot find any guidance in documentation on how to properly update a release deployment.
I used "Invoke-RestMethod" powershell commandlet to get release metadata. This commandlet returns custom ps object which I then updated, converted to json using "ConvertTo-Json" commandlet and provided in the body of the PUT HTTP request to DevOps to update the release. The issue is that Powershell serialization/de-serialization process of json does not result to the original json.
For example this json property:
"preDeploymentGatesSnapshot": {
"id": 0,
"gatesOptions": null,
"gates": []
},
becomes:
"preDeploymentGatesSnapshot": "#{id=0; gatesOptions=; gates=System.Object[]}"
After I used correct json in the body of the PUT request in the API call:
https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases/{releaseId}?api-version=5.1-preview.8
the release got successfully updated.

Specify Google Task ID on insert

I am working with Google Tasks, using the PHP library:
https://developers.google.com/tasks/v1/reference/tasks
I am trying to insert a task with a custom ID.
I found this topic:
Setting id to task using Google Task API returns 400 invalid value
which points to this topic:
Google tasks update error
They suggest to send the Task ID with the Task title. I think I have done that.
This is the code info from the Google API reference
$task = new Task();
$task->setTitle('New Task');
$task->setNotes('Please complete me');
$task->setDue(new TaskDateTime('2010-10-15T12:00:00.000Z'));
$result = $service->insertTasks('#default', $task);
echo $result->getId();
This is my code, I got setID() from the library itself.
$taskNew = new Google_Service_Tasks_Task();
$taskNew->setId('2013');
$taskNew->setTitle('Notify');
$taskNew->setDue(new TaskDateTime('2018-10-27T00:00:00.000Z'));
$results3 = $service->tasks->insert('.....', $taskNew);
I keep getting an error and it refuses to make the task.
Using this API tool:
https://developers.google.com/apis-explorer/#p/tasks/v1/tasks.tasks.insert
I can insert tasks successfully, so long as the system makes the ID. The Google Task API will insert the task, but assign its own ID.
If I specify a custom ID, then I get a 400 error "Invalid value".
I am making tasks to correspond to events saved in my program's database. I need to be able to find the task that matches a database event when I need to make changes to the due date or completed.
The reason I want to set my own ID, is so I can find the specific task and make changes.
I could add a new field to the database with the ID that google generates. But I would prefer to not have to change the database and the rest of the program as well.
Thanks so much for any help,
- Jon
Task Id is the read-only parameter.
I solved this question by using a prefix for the task`s Title.
For example: "[my_id] Task Title".

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.

Azure Batch - Setting custom user identity for tasks

I am using Azure Batch C# Client API 6.1. I am trying to have all my runs using the same user identity.
I am setting a custom user identity as below, as per MSDN documentation.
var task = new CloudTask("{guid}", "command string")
{
DisplayName = "display name",
UserIdentity = new UserIdentity("customUserid")
}
However when the job runs, the task executes under a random user account.
Would anyone know how to make it work OR even if it is supported by the backend Azure Batch service?
Thanks in advance
In order to use named user accounts, you need to first specify a list of UserAccount on your CloudPool during creation.
pool.UserAccounts = new List<UserAccount>
{
new UserAccount("myadminaccount", "adminpassword", ElevationLevel.Admin),
new UserAccount("mynonadminaccount", "nonadminpassword", ElevationLevel.NonAdmin),
};
You will then be able to execute tasks assigned to this pool with UserIdentity properties as you have in your example.
Unfortunately the MSDN documentation for this feature is lagging behind currently, but should be updated soon.

Cannot access deleted builds using the TFS 2015 REST API

Using the older TFS API, it's possible to access deleted builds using the following code:
IBuildDetailSpec buildDetailSpec = buildServer.CreateBuildDetailSpec(m_teamProject, m_buildDefinition);
buildDetailSpec.BuildNumber = (string.IsNullOrEmpty(m_buildPrefixOverride))? m_buildDefinition + "*" : m_buildPrefixOverride + "*";
buildDetailSpec.MaxBuildsPerDefinition = m_maxBuildPerDefinition;
buildDetailSpec.Status = BuildStatus.All;
buildDetailSpec.QueryDeletedOption = QueryDeletedOption.IncludeDeleted;
buildDetailSpec.QueryOrder = BuildQueryOrder.StartTimeDescending;
buildDetailSpec.InformationTypes = null;
IBuildQueryResult buildQueryResult = buildServer.QueryBuilds(buildDetailSpec);
On the other hand, it seems impossible to query that same thing using the TFS 2015 Update 2 (on-premise) REST API according to the documentation.
This is the query I'm running:
http://tfsserver:8080/tfs/defaultcollection/BuildTools/_apis/build/builds?api-version=2.0&definitions=1227
Did anyone manage to query them? If so, how?
REST API doesn't include query deleted option like .Net API IBuildDetailSpec.QueryDeletedOption.
When get a list of builds for a build definition, REST API below only output the builds not deleted:
http://tfsserver:8080/tfs/defaultcollection/BuildTools/_apis/build/builds?api-version=2.0&definitions=xx
You may consider submit a user voice at website below: https://visualstudio.uservoice.com/forums/121579-visual-studio-2015