diff --git a/package-lock.json b/package-lock.json index 57d6312da..cc2a71af7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "@octopusdeploy/api-client": "^3.0.7", + "@octopusdeploy/api-client": "^3.0.8", "azure-devops-node-api": "11.2.0", "azure-pipelines-task-lib": "3.3.1", "azure-pipelines-tool-lib": "1.3.2", @@ -1131,9 +1131,9 @@ } }, "node_modules/@octopusdeploy/api-client": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@octopusdeploy/api-client/-/api-client-3.0.7.tgz", - "integrity": "sha512-6+6/+ARTqldNVwTZGfIvPMX0ZvELo2HRSbm97VaFxFZPu8PWJOzS9yCwfugta0MWRNpPNOVjjC5wd0joSTgC+Q==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@octopusdeploy/api-client/-/api-client-3.0.8.tgz", + "integrity": "sha512-hGCt8jy3RMCCY4KsDSsMwZ9V+6o+DtYpLLTss1mQCJ4lpYBAcmNO06zEo8y9yB6inzmTrsMkAgWLiPEtIF9KuQ==", "dependencies": { "adm-zip": "^0.5.9", "axios": "^1.2.1", @@ -5402,9 +5402,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7917,9 +7917,9 @@ } }, "@octopusdeploy/api-client": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@octopusdeploy/api-client/-/api-client-3.0.7.tgz", - "integrity": "sha512-6+6/+ARTqldNVwTZGfIvPMX0ZvELo2HRSbm97VaFxFZPu8PWJOzS9yCwfugta0MWRNpPNOVjjC5wd0joSTgC+Q==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@octopusdeploy/api-client/-/api-client-3.0.8.tgz", + "integrity": "sha512-hGCt8jy3RMCCY4KsDSsMwZ9V+6o+DtYpLLTss1mQCJ4lpYBAcmNO06zEo8y9yB6inzmTrsMkAgWLiPEtIF9KuQ==", "requires": { "adm-zip": "^0.5.9", "axios": "^1.2.1", @@ -11135,9 +11135,9 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" }, "on-finished": { "version": "2.4.1", diff --git a/package.json b/package.json index ed27bba06..a63b81edb 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "yargs": "^17.5.1" }, "dependencies": { - "@octopusdeploy/api-client": "^3.0.7", + "@octopusdeploy/api-client": "^3.0.8", "azure-devops-node-api": "11.2.0", "azure-pipelines-task-lib": "3.3.1", "azure-pipelines-tool-lib": "1.3.2", diff --git a/source/tasks/CreateOctopusRelease/CreateOctopusReleaseV6/release.ts b/source/tasks/CreateOctopusRelease/CreateOctopusReleaseV6/release.ts index 94b6d9325..e73014410 100644 --- a/source/tasks/CreateOctopusRelease/CreateOctopusReleaseV6/release.ts +++ b/source/tasks/CreateOctopusRelease/CreateOctopusReleaseV6/release.ts @@ -1,4 +1,11 @@ -import { Client, CreateReleaseCommandV1, Logger, Project, ProjectRepository, Space, SpaceRepository } from "@octopusdeploy/api-client"; +import { + Client, + CreateReleaseCommandV1, + Logger, + Project, + ProjectRepository, + resolveSpaceId, +} from "@octopusdeploy/api-client"; import { OctoServerConnectionDetails } from "../../Utils/connection"; import { createReleaseFromInputs } from "./createRelease"; import { createCommandFromInputs } from "./inputCommandBuilder"; @@ -33,20 +40,16 @@ export class Release { } private async tryCreateSummary(client: Client, command: CreateReleaseCommandV1, version: string) { - const spaceRepo = new SpaceRepository(client); - const spaces = await spaceRepo.list({ partialName: command.spaceName }); - const matchedSpaces = spaces.Items.filter((s: Space) => s.Name.localeCompare(command.spaceName) === 0); - if (matchedSpaces.length === 1) { - const projectRepo = new ProjectRepository(client, command.spaceName); - const projects = await projectRepo.list({ partialName: command.ProjectName }); - const matchedProjects = projects.Items.filter((p: Project) => p.Name.localeCompare(command.ProjectName) === 0); - if (matchedProjects.length === 1) { - const link = `${this.connection.url}app#/${matchedSpaces[0].Id}/projects/${matchedProjects[0].Id}/deployments/releases/${version}`; - const markdown = `[Release ${version} created for '${matchedProjects[0].Name}'](${link})`; - const markdownFile = path.join(getVstsEnvironmentVariables().defaultWorkingDirectory, `${uuidv4()}.md`); - tasks.writeFile(markdownFile, markdown); - tasks.addAttachment("Distributedtask.Core.Summary", "Octopus Deploy", markdownFile); - } + const spaceId = await resolveSpaceId(client, command.spaceName); + const projectRepo = new ProjectRepository(client, command.spaceName); + const projects = await projectRepo.list({ partialName: command.ProjectName }); + const matchedProjects = projects.Items.filter((p: Project) => p.Name.localeCompare(command.ProjectName) === 0); + if (matchedProjects.length === 1) { + const link = `${this.connection.url}app#/${spaceId}/projects/${matchedProjects[0].Id}/deployments/releases/${version}`; + const markdown = `[Release ${version} created for '${matchedProjects[0].Name}'](${link})`; + const markdownFile = path.join(getVstsEnvironmentVariables().defaultWorkingDirectory, `${uuidv4()}.md`); + tasks.writeFile(markdownFile, markdown); + tasks.addAttachment("Distributedtask.Core.Summary", "Octopus Create Release", markdownFile); } } } diff --git a/source/tasks/Deploy/DeployV6/createDeployment.ts b/source/tasks/Deploy/DeployV6/createDeployment.ts index f5f55a63a..0ab07801b 100644 --- a/source/tasks/Deploy/DeployV6/createDeployment.ts +++ b/source/tasks/Deploy/DeployV6/createDeployment.ts @@ -4,7 +4,6 @@ import { TaskWrapper } from "../../Utils/taskInput"; import { ExecutionResult } from "../../Utils/executionResult"; export async function createDeploymentFromInputs(client: Client, command: CreateDeploymentUntenantedCommandV1, task: TaskWrapper, logger: Logger): Promise { - logger.info?.("🐙 Deploying a release in Octopus Deploy..."); try { diff --git a/source/tasks/Deploy/DeployV6/deploy.ts b/source/tasks/Deploy/DeployV6/deploy.ts index cb58bf5e9..c731732f7 100644 --- a/source/tasks/Deploy/DeployV6/deploy.ts +++ b/source/tasks/Deploy/DeployV6/deploy.ts @@ -1,10 +1,15 @@ -import { Logger } from "@octopusdeploy/api-client"; +import { Client, CreateDeploymentUntenantedCommandV1, Logger, resolveSpaceId, ServerTask, SpaceServerTaskRepository } from "@octopusdeploy/api-client"; import { OctoServerConnectionDetails } from "../../Utils/connection"; import { createDeploymentFromInputs } from "./createDeployment"; import { createCommandFromInputs } from "./inputCommandBuilder"; import os from "os"; import { TaskWrapper } from "tasks/Utils/taskInput"; import { getClient } from "../../Utils/client"; +import path from "path"; +import { getVstsEnvironmentVariables } from "../../../tasksLegacy/Utils/environment"; +import { v4 as uuidv4 } from "uuid"; +import { ExecutionResult } from "../../Utils/executionResult"; +import * as tasks from "azure-pipelines-task-lib"; export class Deploy { constructor(readonly connection: OctoServerConnectionDetails, readonly task: TaskWrapper, readonly logger: Logger) {} @@ -14,7 +19,8 @@ export class Deploy { const command = createCommandFromInputs(this.logger, this.task); const client = await getClient(this.connection, this.logger, "release", "deploy", 6); - createDeploymentFromInputs(client, command, this.task, this.logger); + const results = await createDeploymentFromInputs(client, command, this.task, this.logger); + await this.tryCreateSummary(client, command, results); this.task.setSuccess("Deployment succeeded."); } catch (error: unknown) { @@ -26,4 +32,32 @@ export class Deploy { throw error; } } + + private async tryCreateSummary(client: Client, command: CreateDeploymentUntenantedCommandV1, results: ExecutionResult[]) { + if (results.length === 0) { + return; + } + + const spaceId = await resolveSpaceId(client, command.spaceName); + const taskRepo = new SpaceServerTaskRepository(client, command.spaceName); + const allTasks = await taskRepo.getByIds<{ DeploymentId: string }>(results.map((t) => t.serverTaskId)); + const taskLookup = new Map>(); + allTasks.forEach(function (t) { + taskLookup.set(t.Id, t); + }); + + const url = this.connection.url; + let markdown = `${results[0].type} tasks\n\n`; + results.forEach(function (result) { + const task = taskLookup.get(result.serverTaskId); + if (task != null) { + const link = `${url}app#/${spaceId}/deployments/${task.Arguments.DeploymentId}`; + markdown += `[${result.environmentName}](${link})\n`; + } + }); + + const markdownFile = path.join(getVstsEnvironmentVariables().defaultWorkingDirectory, `${uuidv4()}.md`); + tasks.writeFile(markdownFile, markdown); + tasks.addAttachment("Distributedtask.Core.Summary", "Octopus Deploy", markdownFile); + } } diff --git a/source/tasks/DeployTenant/TenantedDeployV6/deploy.ts b/source/tasks/DeployTenant/TenantedDeployV6/deploy.ts index 65b0a8847..490fe929b 100644 --- a/source/tasks/DeployTenant/TenantedDeployV6/deploy.ts +++ b/source/tasks/DeployTenant/TenantedDeployV6/deploy.ts @@ -1,10 +1,15 @@ -import { Logger } from "@octopusdeploy/api-client"; +import { CreateDeploymentTenantedCommandV1, Logger, Client, resolveSpaceId, SpaceServerTaskRepository, ServerTask } from "@octopusdeploy/api-client"; import { OctoServerConnectionDetails } from "../../Utils/connection"; import { createDeploymentFromInputs } from "./createDeployment"; import { createCommandFromInputs } from "./inputCommandBuilder"; import os from "os"; import { TaskWrapper } from "tasks/Utils/taskInput"; import { getClient } from "../../Utils/client"; +import { ExecutionResult } from "../../Utils/executionResult"; +import path from "path"; +import { getVstsEnvironmentVariables } from "../../../tasksLegacy/Utils/environment"; +import { v4 as uuidv4 } from "uuid"; +import * as tasks from "azure-pipelines-task-lib"; export class Deploy { constructor(readonly connection: OctoServerConnectionDetails, readonly task: TaskWrapper, readonly logger: Logger) {} @@ -14,7 +19,9 @@ export class Deploy { const command = createCommandFromInputs(this.logger, this.task); const client = await getClient(this.connection, this.logger, "release", "deploy-tenanted", 6); - createDeploymentFromInputs(client, command, this.task, this.logger); + const results = await createDeploymentFromInputs(client, command, this.task, this.logger); + + await this.tryCreateSummary(client, command, results); this.task.setSuccess("Deployment succeeded."); } catch (error: unknown) { @@ -26,4 +33,32 @@ export class Deploy { throw error; } } + + private async tryCreateSummary(client: Client, command: CreateDeploymentTenantedCommandV1, results: ExecutionResult[]) { + if (results.length === 0) { + return; + } + + const spaceId = await resolveSpaceId(client, command.spaceName); + const taskRepo = new SpaceServerTaskRepository(client, command.spaceName); + const allTasks = await taskRepo.getByIds<{ DeploymentId: string }>(results.map((t) => t.serverTaskId)); + const taskLookup = new Map>(); + allTasks.forEach(function (t) { + taskLookup.set(t.Id, t); + }); + + const url = this.connection.url; + let markdown = `${results[0].type} tasks for '${results[0].environmentName}' environment\n\n`; + results.forEach(function (result) { + const task = taskLookup.get(result.serverTaskId); + if (task != null) { + const link = `${url}app#/${spaceId}/deployments/${task.Arguments.DeploymentId}`; + markdown += `[${result.tenantName}](${link})\n`; + } + }); + + const markdownFile = path.join(getVstsEnvironmentVariables().defaultWorkingDirectory, `${uuidv4()}.md`); + tasks.writeFile(markdownFile, markdown); + tasks.addAttachment("Distributedtask.Core.Summary", "Octopus Deploy Tenants", markdownFile); + } }