Azure Artifacts - Download a specific version of maven artifact - azure

We are using azure devops for our CI/CD process. Many a times, in order to do some custom builds, we need to download the specific maven jar from artifact repo.
Is there a way (commandline or API) to do the same ?
Again the question is about download specific jar from azure artifacts.

Azure Artifacts - Download a specific version of maven artifact
The answer is yes. We could use the REST API Maven - Download Package to download the specific jar from azure artifacts:
GET https://pkgs.dev.azure.com/{organization}/{project}/_apis/packaging/feeds/{feedId}/maven/{groupId}/{artifactId}/{version}/{fileName}/content?api-version=5.1-preview.1
First, we need to get the feedId. We could use the REST API Feed Management - Get Feeds to get the feedId:
GET https://feeds.dev.azure.com/{organization}/{project}/_apis/packaging/feeds?api-version=5.1-preview.1
Note: The project parameter must be supplied if the feed was created in a project. If the feed is not associated with any project, omit the project parameter from the request.
For other parameters in the URL, we could get it from the overview of the package. Select the package and open the package, we could get following view:
Now, we have all the parameters, feedId, groupId, artifactId, version, fileName.
So, we could use the REST API with -OutFile $(Build.SourcesDirectory)\myFirstApp-1.0-20190818.032400-1.jar to download the package (Inline powershell task):
$url = "https://pkgs.dev.azure.com/<OrganizationName>/_apis/packaging/feeds/83cd6431-16cc-480d-bb4d-a213e17b3a2b/maven/MyGroup/myFirstApp/1.0-SNAPSHOT/myFirstApp-1.0-20190818.032400-1.jar/content?api-version=5.1-preview.1"
$buildPipeline= Invoke-RestMethod -Uri $url -OutFile $(Build.SourcesDirectory)\myFirstApp-1.0-20190818.032400-1.jar -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
} -Method Get
Since my maven feed is an organization scoped feed, I omit the project parameter from the URL.
The result:

I've found this way:
Open feed page in Azure, click Connect to feed
Choose Maven, copy the URL from Project setup > repository/url of the pom.xml sample.
That should look like:
https://pkgs.dev.azure.com/YOUR-ORGANIZATION/_packaging/YOUR-FEED-NAME/maven/v1
Append the artifact info to that link:
https://pkgs.dev.azure.com/YOUR-ORGANIZATION/_packaging/YOUR-FEED-NAME/maven/v1/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar
Hint: compare it to the one from maven repository:
https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar

Related

How to download the latest build artifacts from Azure DevOps via REST API without mentioning buildId?

URl mention in documentation:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=4.1
How to get the buildid via REST API or can we download the artifact without buildId
That worked for me, it was on preview back then:
GET https://dev.azure.com/{organization}/{project}/_apis/build/latest/{definition}?branchName={branchName}&api-version=5.0-preview.1
The following API gets a specific artifact for a build:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=5.1
You could get a list of builds, including buildid via the following API:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.1
With optional parameters:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}&minTime={minTime}&maxTime={maxTime}&requestedFor={requestedFor}&reasonFilter={reasonFilter}&statusFilter={statusFilter}&resultFilter={resultFilter}&tagFilters={tagFilters}&properties={properties}&$top={$top}&continuationToken={continuationToken}&maxBuildsPerDefinition={maxBuildsPerDefinition}&deletedFilter={deletedFilter}&queryOrder={queryOrder}&branchName={branchName}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=5.1
While the following API gets the latest build for a definition, optionally scoped to a specific branch:
GET https://dev.azure.com/{organization}/{project}/_apis/build/latest/{definition}?branchName={branchName}&api-version=5.1-preview.1
You could get a list of definitions:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions?api-version=5.1
With optional parameters:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions?name={name}&repositoryId={repositoryId}&repositoryType={repositoryType}&queryOrder={queryOrder}&$top={$top}&continuationToken={continuationToken}&minMetricsTime={minMetricsTime}&definitionIds={definitionIds}&path={path}&builtAfter={builtAfter}&notBuiltAfter={notBuiltAfter}&includeAllProperties={includeAllProperties}&includeLatestBuilds={includeLatestBuilds}&taskIdFilter={taskIdFilter}&processType={processType}&yamlFilename={yamlFilename}&api-version=5.1

Get the pull request ID of a continuous deployment release [Azure Pipelines]

I am trying to setup azure pipelines to trigger a build on every PR update, and a release on every merge. For a couple of reasons when the PR is merged, i need to access data saved by the latest validation build of the PR.
However to do that i need the PRid during the run of the Release pipeline. How can one achieve that?
From the release you can retrieve the commit Id which triggered the build.
Then you search for the commitId in the list of completed PRs and retrieve your PR number.
$commitId = "$(RELEASE.ARTIFACTS.{YOURARTIFACTALIAS}.SOURCEVERSION)"
$repoId = "$(RELEASE.ARTIFACTS.{YOURARTIFACTALIAS}.REPOSITORY.ID)"
$pullRequestsUri = "https://dev.azure.com/{organization}/{project}_apis/git/repositories/" + $repoId + "/pullrequests?searchCriteria.status=completed&api-version=5.1"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", "$(System.AccessToken)")))
$pullRequests = Invoke-RestMethod -Uri $pullRequestsUri -Method GET -ContentType "application/json" -Headers #{Authorization = "Basic $base64AuthInfo" }
foreach ($value in $pullRequests.value) {
if ($value.lastMergeCommit.commitId -eq $commitId) {
$pullRequestId = $value.pullRequestId
}
}
Write-Host $pullRequestId
Based on your scenario, to my knowledge, it is complex to get related build information in your release. Besides, it may cause unexpected result if not cover all possible scenarios.
I'd suggest that you could refer to these steps blow:
Remove publish build/pipeline artifact or unnecessary tasks, just remain tasks for validation, which will save a lot of time. (Because, in general, the validation build will be triggered too many times, waste too much time to publish useless artifact or other data)
Create a new build pipeline and enable Continuous integration for target branch (e.g. master)
Add publish build/pipeline artifact task
Edit release pipeline and link this build pipeline and enable Continuous deployment. (Could add additional filters)
With this way, after completing the pull request, this new build pipeline will be triggered and will publish necessary artifact, then the release will be triggered.
For pull request validation builds, they just do tasks to validate the code (e.g. build project), but not publish artifact.
Simple scenario for saving time:
A pull request has 50 validation builds
old way: publish artifact of each takes 1 minutes, then total time is 50 minutes
new way: the new pipeline do tasks for build and publish, it just run once and may just takes 10 minutes.
Then you can save 40 minutes.
In Release Pipeline, you could use the variable $(RELEASE.ARTIFACTS.<<Source alias name>>.PULLREQUEST.ID) to get the Pull Request ID.
Note: the Source alias name is the name set in the release artifacts.
By the way, if you use a default variable in your script, you must first replace the . in the default variable names with _.
For example: $env:RELEASE_ARTIFACTS_<<Source alias name>>_PULLREQUEST_ID
Here is a doc about the Release variables.
Hope this helps.

Trigger a release from a build queue

I have a release pipeline that triggers when there's a PR to master. I want to be able to trigger a release from a build queue (so without creating a pull request).
The proces now is to manually queue a build of a specific branch (this is fine):
Now I have to manually release the branch as well:
I want to automate this proces.
Like I said my current automated release proces is only triggered when there's a PR for master:
Any suggestions how to trigger a release from a custom build action?
If you want to trigger a release from inside the build - you can use Azure Devops rest api for that. This is the rest api call you are interested in:
https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/create?view=azure-devops-rest-5.0
you can use something like this to achieve that:
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${user}:$(PAT_TOKEN)"))
$bearerAuth = #{ Authorization = "Basic $base64AuthInfo" }
Invoke-RestMethod POST https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?api-version=5.0 -Headers $bearerAuth -ContentType "application/json" -Body xxx
I think you can choose to add a source with Build as the artifact in Release, so you can trigger a release from a build queue without creating a pull request.The solution provided by 4c74356b41 is a good method, you can also try it.You can add a powershell task to the agent job of the build pipeline, and then write the script with the above rest api provided by4c74356b41 in the Inline script to run the build.
Hope this helps.

How can I retrieve files within a repo in Azure within a Powershell script?

I need to (within a Powershell script) determine all the possible controller file names within a repository. This is for a test that will hit every controller and verify it is functioning and not missing from the startup file. (MVC app)
Since all the files are DLLs I cannot simply ask for the files in the folder nor do I want to hard code the names. How can I get a listing of files within a certain folder in order call each one to test within a powershell script?
Perhaps a better way to ask this is:
How can I list files within a folder that is inside a repo? (using a Powershell script)
You could refer to this doc:Interacting with Azure Web Apps Virtual File System using PowerShell and the Kudu API. It uses the VFS API in the wiki doc. And there is a api to list files at directory specified by path.
GET /api/vfs/{path}/
Lists files at directory specified by path.
And in the previous doc, under the title Downloading a File from an App Service, there is a scripts to download the files. I use the path without $kuduPath to list files. And you need to Getting the Kudu REST API Authorisation header via PowerShell. And then the scripts would be like this.
$kuduApiUrl="https://<webname>.scm.azurewebsites.net/api/vfs/site/wwwroot/"
Invoke-RestMethod -Uri $kuduApiUrl `
-Headers #{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
-Method GET `
-OutFile $localPath `
-ContentType "multipart/form-data"
And here is the result pic.It will list all files and the folders.
hope this could help you, if you still have other questions,please let me know.

Is it possible to get the Artifact Name in Release?

I have a requirement to get the build artifact name in release? I dont see a predefined release variables which can get this. Is there a way to fetch this?
If you mean you want to get the Artifact Name which is defined in Publish Build Artifacts task in Build process (By default it's Drop), then you can run below PowerShell script calling the REST API to retrieve the value and set a variable with logging command. After that you can use the variable in subsequent tasks...
Enable Allow scripts to access the OAuth token in Agent Phase
Add a PowerShell task to run below script
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/builds/$env:BUILD_BUILDID/artifacts?api-version=4.1"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "artifactName:" ($artifactName = $Pipeline.value.name)
#Set Variable $artifactName
Write-Host "##vso[task.setvariable variable=artifactName]$artifactName"
#Then you can use the variable $artifactName in the subsequent tasks...
This is kind of a hack/kludge, but if you name your Release to be the same as the package you are releasing, you can get the name from the variable
$(Release.DefinitionName)
So if your build creates a package called My.Cool.Package in a build pipeline called my_cool_package, that ends up being aliased in the release pipeline as _my_cool_package.
Naming the Release pipeline the same as the package (My.Cool.Package) allows you to access the package and files within it (for doing XML and JSON transforms for example in other tasks) by using
$(System.DefaultWorkingDirectory)/$(Release.PrimaryArtifactSourceAlias)/$(Release.DefinitionName)
This is well-documented under the sections General Artifact Variables and Primary Artifact Variables.
The primary artifact name is Build.DefinitionName.

Resources