Azure Pipeline runs not automatically deleting - tfs

We have two build YAML pipelines to run tests on TFS one for front-end and one for back-end tests. We use two self-hosted windows agents to run these builds and we are on Azure DevOps Server 2020. Ever since we started running the pipeline we noticed our TFS database size ballooning up. We've tried editing our retention settings to only keep the most recent builds but they are still saved no matter what we change.
Below are our retention settings:
Collection Settings
Project Pipeline Settings
Project Pipeline Release Retention:
EDIT: Test Retention Settings:
END EDIT
Our YAML pipelines don't have any specific retention settings so my understanding would be that it defaults to the project pipeline settings. However, this doesn't seem to be the case. We have runs that go as far back as November, which is when we first created the pipelines. I can also manually check which builds are and aren't retained:
Example of retained build
Example of not retained build
However, these runs are just never getting deleted. Is my understanding of how retention works just incorrect and the builds shouldn't be getting automatically deleted by TFS? Or do I need to change my Azure DevOps settings somehow to automatically delete the builds once the retention settings no longer apply to it?
It's also worth mentioning we do have a release pipeline, although we've been experiencing these problems since way before we created it and the release pipeline only has dependencies on master but no feature runs are getting deleted either.
I did find this SO post that seems to only apply to classic UI pipeline editor. Is there a way I can apply this to my YAML pipeline?
Edit 2
So I did make some more progress on this. I wrote a script that would delete all the runs that weren't held by retention settings:
$token = "{PAT}"
$url="https://{instance}/{collection}/{project}/_apis/build/builds/?api-version=6.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
ForEach( $build in $response.value )
{
if ((-not $build.keepForever) -and (-not $build.retainedByRelease)) {
$url="https://{instance}/{collection}/{project}/_apis/build/builds/$($build.id)?api-version=6.0"
$deleteResponse = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Delete -ContentType application/json
Write-Host "Deleted" $url
}
}
This deletes all the runs just fine. However, from what I can tell in the docs, this should happen automatically by TFS. Are there any event log sources I could filter for or any specific times of day to check that may lead me to where the actual deletion of the runs should be taking place?

It seems your problem was fixed in the Azure DevOps 2020.0.1 Patch 2 Release. I recommend looking at this thread in detail to see whether the solution applies in your case.

Related

Using Rest API to trigger a specific stage within a yaml pipeline

Is there a way to execute a specific stage within a running yaml pipeline which uses an environment with approvals?
I have an on-prem deploy and an on-prem destroy stage both have manual approvals.
What I would like to do is run on-prem destroy stage in the past builds using rest api.
What I achieved so far is get 10 recent builds in descending order for a specific source branch lets call it feature/on-prem-enterprise. Then I do some parsing and find past builds that had a successful deployment but failed, cancelled, or skipped destroy stage, using these results from timeline endpoint, I want to use rest api to run/re-run a destroy stage in those builds.
We get into a situation where we have several deployments but nobody is manually running the destroy stage and because this pipeline is shared amongst all developers for dev builds, its very difficult to find those older builds manually.
If it cannot be achieved, then other solution may be to compile this list of builds and send an email out, but would prefer to have less manual intervention here.
Is there a way to execute a specific stage within a running yaml pipeline which uses an environment with approvals?
The answer is yes.
You could use the REST API Runs - Run Pipeline with below request body to skip other stages to trigger stage which you wanted:
POST https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineId}/runs?api-version=6.0-preview.1
Request Body:
{
"stagesToSkip":["Dev","Test"]
}
Postman test result:
And the test result for the pipeline runs:
You can use the Stages - Update REST API method. This is part of the Build resource methods but works fine for YAML Pipelines as well.
PATCH https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/stages/{stageRefName}?api-version=7.1-preview.1
It sounds like you're already getting the buildId programmatically. The stageRefName is the name of the stage as defined in your YAML. Your URI will look something like:
https://dev.azure.com/myorg/myproject/_apis/build/builds/1234/stages/DestroyStageName?api-version=7.1-preview.1
In the request body you'll need:
{
forceRetryAllJobs = $false
state = 1 # state 1 is retry
}
forceRetryAllJobs may be unnecessary. There's an example implementation in PowerShell here.
If you're struggling to identify the appropriate API method to replicate something you do in the Azure DevOps GUI opening your browser's debugger tools and inspecting the requests in the network tab can often help you identify the call that's being used.

Retrieving Azure artifacts recent version from the azure feed

I am looking for an option, how to identify the version of artifact which is being stored in azure devops artifactory. Can someone please throw light on this.
Also i need to push artifact from 1 subscription (example ASubscrip) to another subscription (BSubscrip).
BSubscrip is obviously more strict in terms of security as PROD is being configured there, however our builds are done only on ASubScrip.
Hence I need to come up with a logic that if version available in BSubscrip is lower than version of ASubScrip, then only trigger the copy pipeline from ASubScrip to BSubScrip.
Please advise how it can be done via pipeline.
I was able to perform the operation with the help of below set of commands.
$response = invoke-RestMethod -Uri https://feeds.dev.azure.com/{Org}/{Project name}/_apis/packaging/Feeds//
The response would be json object and required property can be referred $response.versions.version
Please note that while reviewing the output of response object, my focus was only to retrieve version parameter and above approach helped me to get it.
Also note here TOKEN is PAT and there we need to perform some transformation as well.
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))

Azure DevOps Server 2019 - How to select multiple builds

In TFS 2018 we were able to select multiple builds in the build results page.
After we upgraded to 2019, it seems we can no longer multi-select completed builds and perform an action on these, such as removing builds.
Can this still be done, or should this now be done using the API ? which would of course not be nice.
How to select multiple builds
I'm afraid this feature can not be done in azure devops 2019 now, also there's no directly api can let you get the feature e.g batch delete.
In fact, in TFS 2018, when you multi-select the builds and delete them, you could see the detailed progress from F12:
Actually, it executes the delete api in a loop to achieve the effect of a batch delete.
So, as a work around since there's no directly api to achieve such batch action, you can make use of foreach in powershell.
For example of batch delete,
DELETE https://{instance name}/{collection name}/{project name}/_apis/build/builds/{buildId}?api-version=5.0
You could make use the for loop with the powershell scripts into buildid(s) to delete them.
Simple delete script:
$url = https://{instance name}/{collection name}/{project name}/_apis/build/builds/{buildId}?api-version=5.0
Invoke-RestMethod -Uri $url -Method Delete -ContentType application/json

Status not triggering job

This plugin has been working great for about a year until today. This is the workflow we have in JIRA:
At either "QA on dev" and "QA on stage", we trigger a build in our pipeline. Since we set this up a year ago, both statuses would trigger the build but today, only "QA on dev" triggers the build successfully. When we reach "QA on stage", the Jenkins log returns us an error:
https://gist.github.com/patrickng/8c77e8360290c7c0073b1f7adfbae18e
Is it possible that Atlassian changed their API all of a sudden? How can we fix this? Our workflow is now disrupted and I can't seem to think of a workaround.
It seems like Atlassian made a few changes to the payload that's being posted to the webhook. If you do not have a Description set in the specific workflow in JIRA, it will not be included in the POST request. After adding a description to the QA on stage status, the pipeline works again.
There is a separate issue with this plugin now in that comments don't trigger builds, but it looks like the plugin will need an update because JIRA now provides new events and payload for comments created/updated/edited actions.

Trigger TFS Release Management with Artifact Version Number

I am excited to see TFS Update 2 available for on premise and including the Release Management Feature part of the web experience. We have been waiting for this.
I need some help on how best to trigger the release.
A release can be triggered in 3 ways:
Continuous Deployment Trigger based on linking to TFS Build Definition
Manually
REST API
This is great but I don't think it fits what I would expect. I need help in a technical solve or in how I think about the problem.
My Thinking:
I believe the Build should create an artifact and put the artifact in a Drop location to be released now or a year from now. (need to rebuild or add a server later)
I feel the continuous deployment trigger breaks down as it depends on the artifact being in the TFS Build and the TFS Build will be deleted depending on your settings.
Possible Solution:
I believe the solution I need is to create a draft release using the REST Api and then pass in the path to the artifact in the drop location. In my case I would simply provide a version number and build the path inside the release.
Problem:
At this point the REST api is not documented.
I appreciate your thoughts on my thinking. It could be that I'm thinking about the problem in the wrong way.
Also, If anyone knows how to create a release using the REST api that would likely get me to where I need to be.
I see the REST api is to be documented at the following spot but is is not yet. I really want to get going, I have over 100 apps to deploy.
https://msdn.microsoft.com/en-us/library/vs/alm/release/managing-releases/create-release#CreateareleasebyusingtheRESTAPI
We also use TFS 2015 update 2 on-prem and use PowerShell to interface with TFS REST API.
As stated in comments on this thread the REST API documentation is live and to create a release refer to the following link: https://www.visualstudio.com/en-us/docs/integrate/api/rm/releases#create-a-release
To answer your question: - to create a release using a PowerShell script try the following:
$filePath = "C:\PATH_TO_JSON"
$username = 'DOMAIN\USRNAME'
$password = 'PASSWORD'
$body = Get-Content $filePath
$resource = "http://TFS_URL/_apis/release/releases`?api-version=2.2-preview.1"
$cred = New-Object System.Management.Automation.PSCredential($username, (ConvertTo-SecureString -String $password -AsPlainText -Force))
Invoke-RestMethod -Method Post -Uri "$resource" -Credential $cred -ContentType "application/json" -Body $body
The $filePath variable should point to a file containing the following JSON markup. Be sure to alter the variables within the example JSON to fit your on-prem Release Definition:
{
"definitionId": 12,
"description": "M 98 release",
"artifacts": [
{
"alias": "Fabrikam.CI",
"instanceReference": {
"id": "90"
}
}
]
}
You could also use JavaScript to interface with TFS REST API. See the post by #Elmar here: TFS 2015 REST API Authentication
The Release Management API docs for VSTS are live here. Most of the APIs should work for TFS 2015.2 also.
For creating a new release, refer to my earlier answer for the same.
You can retain a build indefinitely so it will always be available when you need it.
ReleaseManagement REST API got public at
https://www.visualstudio.com/integrate/api/rm/releases#Createarelease. Please have a look. While creating the release pass three things in the artifact :- alias, instanceReference (name and Id).

Resources