return new Promise<Deployment>(async (resolve, reject) => { let mostRecentDeployment: Deployment = null; try { // Gets the latest successful deployments - the api returns the deployments in the correct order var successfulDeployments = await releaseApi.getDeployments(teamProject, releaseDefinitionId, environmentId, null, null, null, DeploymentStatus.Succeeded, null, true, null, null, null, null).catch((reason) => { reject(reason); return; }); if (successfulDeployments && successfulDeployments.length > 0) { mostRecentDeployment = successfulDeployments[0]; } else { // There have been no recent successful deployments } resolve(mostRecentDeployment); } catch (err) { reject(err); } });
var promise = new Promise<void>(async (resolve, reject) => { try { agentApi.logDebug("Starting Tag XplatGenerateReleaseNotes task"); let tpcUri = tl.getVariable("System.TeamFoundationCollectionUri"); let teamProject = tl.getVariable("System.TeamProject"); let releaseId: number = parseInt(tl.getVariable("Release.ReleaseId")); let releaseDefinitionId: number = parseInt(tl.getVariable("Release.DefinitionId")); // Inputs let environmentName: string = (tl.getInput("overrideStageName") || tl.getVariable("Release_EnvironmentName")).toLowerCase(); var templateLocation = tl.getInput("templateLocation", true); var templateFile = tl.getInput("templatefile"); var inlineTemplate = tl.getInput("inlinetemplate"); var outputfile = tl.getInput("outputfile", true); var outputVariableName = tl.getInput("outputVariableName"); var emptyDataset = tl.getInput("emptySetText"); let credentialHandler: vstsInterfaces.IRequestHandler = util.getCredentialHandler(); let vsts = new webApi.WebApi(tpcUri, credentialHandler); var releaseApi: IReleaseApi = await vsts.getReleaseApi(); var buildApi: IBuildApi = await vsts.getBuildApi(); agentApi.logInfo("Getting the current release details"); var currentRelease = await releaseApi.getRelease(teamProject, releaseId); if (!currentRelease) { reject(`Unable to locate the current release with id ${releaseId}`); return; } var environmentId = util.getReleaseDefinitionId(currentRelease.environments, environmentName); let mostRecentSuccessfulDeployment = await util.getMostRecentSuccessfulDeployment(releaseApi, teamProject, releaseDefinitionId, environmentId); let mostRecentSuccessfulDeploymentRelease: Release; agentApi.logInfo(`Getting all artifacts in the current release...`); var arifactsInThisRelease = util.getSimpleArtifactArray(currentRelease.artifacts); agentApi.logInfo(`Found ${arifactsInThisRelease.length}`); let arifactsInMostRecentRelease: util.SimpleArtifact[] = []; var mostRecentSuccessfulDeploymentName: string = ""; if (mostRecentSuccessfulDeployment) { // Get the release that the deployment was a part of - This is required for the templating. mostRecentSuccessfulDeploymentRelease = await releaseApi.getRelease(teamProject, mostRecentSuccessfulDeployment.release.id); agentApi.logInfo(`Getting all artifacts in the most recent successful release [${mostRecentSuccessfulDeployment.release.name}]...`); arifactsInMostRecentRelease = util.getSimpleArtifactArray(mostRecentSuccessfulDeployment.release.artifacts); mostRecentSuccessfulDeploymentName = mostRecentSuccessfulDeployment.release.name; agentApi.logInfo(`Found ${arifactsInMostRecentRelease.length}`); } else { agentApi.logInfo(`Skipping fetching artifact in the most recent successful release as there isn't one.`); // we need to set the last successful as the current release to templates can get some data mostRecentSuccessfulDeploymentRelease = currentRelease; } var globalCommits: Change[] = []; var globalWorkItems: ResourceRef[] = []; for (var artifactInThisRelease of arifactsInThisRelease) { agentApi.logInfo(`Looking at artifact [${artifactInThisRelease.artifactAlias}]`); agentApi.logInfo(`Build Number: [${artifactInThisRelease.buildNumber}]`); var buildNumberFromMostRecentBuild = null; if (arifactsInMostRecentRelease.length > 0) { agentApi.logInfo(`Looking for the [${artifactInThisRelease.artifactAlias}] in the most recent successful release [${mostRecentSuccessfulDeploymentName}]`); for (var artifactInMostRecentRelease of arifactsInMostRecentRelease) { if (artifactInThisRelease.artifactAlias.toLowerCase() === artifactInMostRecentRelease.artifactAlias.toLowerCase()) { agentApi.logInfo(`Found artifact [${artifactInThisRelease.artifactAlias}] with build number [${artifactInThisRelease.buildNumber}] in release [${mostRecentSuccessfulDeploymentName}]`); // Only get the commits and workitems if the builds are different if (artifactInMostRecentRelease.buildNumber.toLowerCase() !== artifactInThisRelease.buildNumber.toLowerCase()) { agentApi.logInfo(`Checking what commits and workitems have changed from [${artifactInMostRecentRelease.buildNumber}] => [${artifactInThisRelease.buildNumber}]`); var commits = await buildApi.getChangesBetweenBuilds(teamProject, parseInt(artifactInMostRecentRelease.buildId), parseInt(artifactInThisRelease.buildId), 5000); var workitems = await buildApi.getWorkItemsBetweenBuilds(teamProject, parseInt(artifactInMostRecentRelease.buildId), parseInt(artifactInThisRelease.buildId), 5000); var commitCount: number = 0; var workItemCount: number = 0; if (commits) { commitCount = commits.length; globalCommits = globalCommits.concat(commits); } if (workitems) { workItemCount = workitems.length; globalWorkItems = globalWorkItems.concat(workitems); } agentApi.logInfo(`Detected ${commitCount} commits/changesets and ${workItemCount} workitems between the builds.`); } else { agentApi.logInfo(`Build for artifact [${artifactInThisRelease.artifactAlias}] has not changed. Nothing to do`); } } } } agentApi.logInfo(``); } // remove duplicates globalCommits = globalCommits.filter((thing, index, self) => index === self.findIndex((t) => ( t.id === thing.id )) ); globalWorkItems = globalWorkItems.filter((thing, index, self) => index === self.findIndex((t) => ( t.id === thing.id )) ); let expandedGlobalCommits = await util.expandTruncatedCommitMessages(vsts.rest, globalCommits); if (!expandedGlobalCommits || expandedGlobalCommits.length !== globalCommits.length) { reject("Failed to expand the global commits."); return; } // get an array of workitem ids var workItemIds = globalWorkItems.map(wi => parseInt(wi.id)); var workItemTrackingApi: IWorkItemTrackingApi = await vsts.getWorkItemTrackingApi(); let fullWorkItems: void | WorkItem[]; if (workItemIds.length > 0) { fullWorkItems = await workItemTrackingApi.getWorkItems(workItemIds, null, null, WorkItemExpand.Fields, null); } if (!fullWorkItems) { fullWorkItems = []; } agentApi.logInfo(`Total commits: [${globalCommits.length}]`); agentApi.logInfo(`Total workitems: [${globalWorkItems.length}]`); var template = util.getTemplate (templateLocation, templateFile, inlineTemplate); var outputString = util.processTemplate(template, fullWorkItems, globalCommits, currentRelease, mostRecentSuccessfulDeploymentRelease, emptyDataset); util.writeFile(outputfile, outputString); agentApi.writeVariable(outputVariableName, outputString.toString()); resolve(); } catch (err) { agentApi.logError(err); reject(err); } });
var promise = new Promise<void>(async (resolve, reject) => { tl.setResourcePath(path.join(__dirname, "task.json")); tl.debug("Starting Tag ChangedBuildArtifacts task"); let tpcUri = tl.getVariable("System.TeamFoundationCollectionUri"); let teamProject = tl.getVariable("System.TeamProject"); let hostType = tl.getVariable("system.hostType"); let releaseId: number = parseInt(tl.getVariable("Release.ReleaseId")); let releaseDefinitionId: number = parseInt(tl.getVariable("Release.DefinitionId")); let releaseDefinitionEnvironmentId: number = parseInt(tl.getVariable("Release.DefinitionEnvironmentId")); let releaseEnvironmentName = tl.getVariable("Release.EnvironmentName"); // Get the credential handler var accessToken: string = tl.getVariable("System.AccessToken"); let credHandler: vstsInterfaces.IRequestHandler; if (!accessToken || accessToken.length === 0) { reject("Unable to locate access token. Please make sure you have enabled the \"Allow scripts to access OAuth token\" setting."); return; } else { tl.debug("Creating the credential handler"); // used for local debugging. Allows switching between PAT token and Bearer Token for debugging credHandler = accessToken.length === 52 ? webApi.getPersonalAccessTokenHandler(accessToken) : webApi.getBearerHandler(accessToken); } let vsts = new webApi.WebApi(tpcUri, credHandler); var releaseApi: IReleaseApi = await vsts.getReleaseApi(); console.log("Getting the current release details"); var currentRelease = await releaseApi.getRelease(teamProject, releaseId).catch((reason) => { reject(reason); return; }); console.log(`Getting the all the successful deployments to release definition id ${releaseDefinitionEnvironmentId}`); // Gets the latest successful deployments in order var successfulDeployments = await releaseApi.getDeployments(teamProject, releaseDefinitionId, releaseDefinitionEnvironmentId, null, null, null, DeploymentStatus.Succeeded, null, true, null, null, null, null).catch((reason) => { reject(reason); return; }); // We want to compare the artifacts between the two definitions to see which ones are different. if (currentRelease) { console.log(`Getting all artifacts in the current release...`); var arifactsInThisRelease = getArtifactArray(currentRelease.artifacts); console.log(`Found ${arifactsInThisRelease.length}`); if (successfulDeployments && successfulDeployments.length > 0) { // loop through every artifact in this release for (var artifactInCurrentRelease of arifactsInThisRelease) { console.log(`Looking for artifact ${artifactInCurrentRelease.buildNumber} in previous successful deployments...`); for (var deployment of successfulDeployments) { // We need to check the status of this release var releaseForDeployment = await releaseApi.getRelease(teamProject, deployment.release.id).catch((reason) => { reject(reason); return; }); if (releaseForDeployment && releaseForDeployment.status !== ReleaseStatus.Active) { // the release is not active console.log(`Skipping this deployment because release [${deployment.release.name}] has a status of [${ReleaseStatus[releaseForDeployment.status]}]`); continue; } if (!artifactInCurrentRelease.previouslyDeployed) { console.log(`Searching for artifact ${artifactInCurrentRelease.buildNumber} in release ${deployment.release.name}`); var artifactsInDeployment = getArtifactArray(deployment.release.artifacts); for (var artifactInDeployment of artifactsInDeployment) { if (artifactInCurrentRelease.buildDefinitionId === artifactInDeployment.buildDefinitionId && artifactInCurrentRelease.buildNumber === artifactInDeployment.buildNumber) { console.log(`Found artifact ${artifactInCurrentRelease.buildNumber} deployed in ${deployment.release.name}`); artifactInCurrentRelease.previouslyDeployed = true; break; } } } else { console.log(`Skipping remaining releases because the property previouslyDeployed for artifact ${artifactInCurrentRelease.buildNumber} was false.`); break; } } } } else { // There are no successful releases - we need to add all the artifacts console.log(`Past successful releases for id ${releaseDefinitionId} and environment id ${releaseDefinitionEnvironmentId} not found.`); } for (var artifactInCurrentRelease2 of arifactsInThisRelease) { var safeAlias = artifactInCurrentRelease2.artifactAlias.replace(/\./gi, "_"); var variableName = ("RELEASE_ARTIFACTS_" + safeAlias + "_PreviouslyDeployed").toUpperCase(); console.log(`Setting variable ${variableName} with value ${artifactInCurrentRelease2.previouslyDeployed}`); tl.setVariable(variableName, artifactInCurrentRelease2.previouslyDeployed.toString()); } } else { reject(`Release with id ${releaseId} was not found.`); return; } resolve(); });