diff --git a/Tasks/DownloadBuildArtifacts/main.ts b/Tasks/DownloadBuildArtifacts/main.ts index ffaccc4aea47..83323d40c7fc 100644 --- a/Tasks/DownloadBuildArtifacts/main.ts +++ b/Tasks/DownloadBuildArtifacts/main.ts @@ -6,6 +6,7 @@ import * as tl from 'vsts-task-lib/task'; import { IBuildApi } from './vso-node-api/BuildApi'; import { IRequestHandler } from './vso-node-api/interfaces/common/VsoBaseInterfaces'; import { WebApi, getHandlerFromToken } from './vso-node-api/WebApi'; +import { BuildStatus, BuildResult, BuildQueryOrder, Build } from './vso-node-api/interfaces/BuildInterfaces'; import * as models from 'artifact-engine/Models'; import * as engine from 'artifact-engine/Engine'; @@ -64,6 +65,8 @@ async function main(): Promise { var definitionIdSpecified: string = null; var definitionIdTriggered: string = null; var buildId: number = null; + var buildVersionToDownload: string = tl.getInput("buildVersionToDownload", false); + var branchName: string = tl.getInput("branchName", false);; var downloadPath: string = tl.getInput("downloadPath", true); var downloadType: string = tl.getInput("downloadType", true); @@ -126,16 +129,39 @@ async function main(): Promise { // Triggering build info not found, or requested, default to specified build info projectId = tl.getInput("project", true); definitionId = definitionIdSpecified; - buildId = parseInt(tl.getInput("buildId", true)); + buildId = parseInt(tl.getInput("buildId", buildVersionToDownload == "specific")); } } // verify that buildId belongs to the definition selected if (definitionId) { - var build = await executeWithRetries("getBuild", () => buildApi.getBuild(buildId, projectId), 4).catch((reason) => { - reject(reason); - return; - }); + var build : Build; + if (buildVersionToDownload != "specific"){ + var branchNameFilter = (buildVersionToDownload == "latest") ? null : branchName; + + // get latest successful build filtered by branch + var buildsForThisDefinition = await executeWithRetries("getBuildId", () => buildApi.getBuilds( projectId, [parseInt(definitionId)],null,null,null,null,null,null,BuildStatus.Completed,BuildResult.Succeeded,null,null,null,null,null,null, BuildQueryOrder.FinishTimeDescending,branchNameFilter), 4).catch((reason) => { + reject(reason); + return; + }); + + if (!buildsForThisDefinition || buildsForThisDefinition.length == 0){ + if (buildVersionToDownload == "latestFromBranch") reject(tl.loc("LatestBuildFromBranchNotFound", branchNameFilter)); + else reject(tl.loc("LatestBuildNotFound")); + return; + } + + build = buildsForThisDefinition[0]; + console.log(tl.loc("LatestBuildFound", build.id)); + buildId = build.id + } + + if (!build){ + build = await executeWithRetries("getBuild", () => buildApi.getBuild(buildId, projectId), 4).catch((reason) => { + reject(reason); + return; + }); + } if (build) { if (!build.definition || build.definition.id !== parseInt(definitionId)) { diff --git a/Tasks/DownloadBuildArtifacts/task.json b/Tasks/DownloadBuildArtifacts/task.json index a5b6cd12298e..c11d6da85068 100644 --- a/Tasks/DownloadBuildArtifacts/task.json +++ b/Tasks/DownloadBuildArtifacts/task.json @@ -8,7 +8,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 132, + "Minor": 133, "Patch": 0 }, "groups": [ @@ -67,13 +67,35 @@ "visibleRule": "buildType == specific", "helpMarkDown": "If checked, this build task will try to download artifacts from the triggering build. If there is no triggering build from the specified definition, it will download artifacts from the build specified in the options below." }, + { + "name": "buildVersionToDownload", + "type": "pickList", + "label": "Build version to download", + "defaultValue": "latest", + "visibleRule": "buildType == specific", + "required": true, + "options": { + "latest": "Latest", + "latestFromBranch": "Latest from specific branch", + "specific": "Specific version" + } + }, + { + "name": "branchName", + "type": "string", + "label": "Branch name", + "defaultValue": "refs/heads/master", + "visibleRule": "buildType == specific && buildVersionToDownload == latestFromBranch", + "required": true, + "helpMarkDown": "Specify to filter on branch/ref name, for example: ```refs/heads/develop```." + }, { "name": "buildId", "type": "pickList", "label": "Build", "defaultValue": "", "required": true, - "visibleRule": "buildType == specific", + "visibleRule": "buildType == specific && buildVersionToDownload == specific", "properties": { "EditableOptions": "True", "DisableManageLink": "True" @@ -196,6 +218,9 @@ "ArtifactsSuccessfullyDownloaded": "Successfully downloaded artifacts to %s", "RetryingOperation" : "Error : in %s, so retrying => retries pending : %s", "OperationFailed": "Failed in %s with error: %s", - "ArtifactNameDirectoryNotFound": "Directory '%s' does not exist. Falling back to parent directory: %s" + "ArtifactNameDirectoryNotFound": "Directory '%s' does not exist. Falling back to parent directory: %s", + "LatestBuildFound": "Latest build found: %s", + "LatestBuildNotFound":"Latest build not found", + "LatestBuildFromBranchNotFound":"Latest build from branch %s not found" } } \ No newline at end of file