Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"yargs": "^17.5.1"
},
"dependencies": {
"@octopusdeploy/api-client": "^3.4.1",
"@octopusdeploy/api-client": "^3.5.1",
"azure-devops-node-api": "11.2.0",
"azure-pipelines-task-lib": "3.3.1",
"azure-pipelines-tool-lib": "1.3.2",
Expand Down
29 changes: 28 additions & 1 deletion source/tasks/RunRunbook/RunRunbookV6/inputCommandBuilder.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger } from "@octopusdeploy/api-client";
import { createCommandFromInputs } from "./inputCommandBuilder";
import { createCommandFromInputs, CreateGitRunbookRunCommandV1, isCreateGitRunbookRunCommand } from "./inputCommandBuilder";
import { MockTaskWrapper } from "../../Utils/MockTaskWrapper";

describe("getInputCommand", () => {
Expand All @@ -20,6 +20,7 @@ describe("getInputCommand", () => {
task.addVariableString("Variables", "var1: value1\nvar2: value2");

const command = createCommandFromInputs(logger, task);
expect(isCreateGitRunbookRunCommand(command)).toBe(false);
expect(command.spaceName).toBe("Default");
expect(command.ProjectName).toBe("Awesome project");
expect(command.RunbookName).toBe("A runbook");
Expand All @@ -32,4 +33,30 @@ describe("getInputCommand", () => {
expect(task.lastResultMessage).toBeUndefined();
expect(task.lastResultDone).toBeUndefined();
});

test("when gitRef is supplied, the command contains the ref plus all regular fields supplied", () => {
task.addVariableString("Space", "Default");
task.addVariableString("Project", "Awesome project");
task.addVariableString("Runbook", "A runbook");
task.addVariableString("Environments", "dev\nStaging");
task.addVariableString("Tenants", "Tenant 1\nTenant 2");
task.addVariableString("TenantTags", "tag set 1/tag 1\ntag set 1/tag 2");
task.addVariableString("Variables", "var1: value1\nvar2: value2");
task.addVariableString("GitRef", "some-ref");

const command = createCommandFromInputs(logger, task);
expect(isCreateGitRunbookRunCommand(command)).toBe(true);
expect(command.spaceName).toBe("Default");
expect(command.ProjectName).toBe("Awesome project");
expect(command.RunbookName).toBe("A runbook");
expect(command.EnvironmentNames).toStrictEqual(["dev", "Staging"]);
expect(command.Tenants).toStrictEqual(["Tenant 1", "Tenant 2"]);
expect(command.TenantTags).toStrictEqual(["tag set 1/tag 1", "tag set 1/tag 2"]);
expect(command.Variables).toStrictEqual({ var1: "value1", var2: "value2" });
expect((command as CreateGitRunbookRunCommandV1).GitRef).toBe("some-ref");

expect(task.lastResult).toBeUndefined();
expect(task.lastResultMessage).toBeUndefined();
expect(task.lastResultDone).toBeUndefined();
});
});
34 changes: 33 additions & 1 deletion source/tasks/RunRunbook/RunRunbookV6/inputCommandBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { getLineSeparatedItems } from "../../Utils/inputs";
import { CreateRunbookRunCommandV1, Logger, PromptedVariableValues } from "@octopusdeploy/api-client";
import { RunGitRunbookCommand } from "@octopusdeploy/api-client/dist/features/projects/runbooks/runs/RunGitRunbookCommand";
import { TaskWrapper } from "tasks/Utils/taskInput";

export function createCommandFromInputs(logger: Logger, task: TaskWrapper): CreateRunbookRunCommandV1 {
// The api-client doesn't have a type for this command that we can differentiate from CreateRunbookRunCommandV1
// so we'll wrap it to make things easier.
export type CreateGitRunbookRunCommandV1 = RunGitRunbookCommand & {
GitRef: string;
};

export function isCreateGitRunbookRunCommand(command: CreateRunbookRunCommandV1 | CreateGitRunbookRunCommandV1): command is CreateGitRunbookRunCommandV1 {
return (command as CreateGitRunbookRunCommandV1).GitRef !== undefined;
}

export function createCommandFromInputs(logger: Logger, task: TaskWrapper): CreateRunbookRunCommandV1 | CreateGitRunbookRunCommandV1 {
const variablesMap: PromptedVariableValues | undefined = {};

const variablesField = task.getInput("Variables");
Expand All @@ -25,6 +36,27 @@ export function createCommandFromInputs(logger: Logger, task: TaskWrapper): Crea
logger.debug?.("Tenant Tags: " + tagsField);
const tags = getLineSeparatedItems(tagsField || "")?.map((t: string) => t.trim()) || [];

const gitRef = task.getInput("GitRef");
logger.debug?.("GitRef: " + gitRef);

if (gitRef) {
const command: CreateGitRunbookRunCommandV1 = {
spaceName: task.getInput("Space") || "",
ProjectName: task.getInput("Project", true) || "",
RunbookName: task.getInput("Runbook", true) || "",
EnvironmentNames: getLineSeparatedItems(environmentsField || "")?.map((t: string) => t.trim()) || [],
Tenants: getLineSeparatedItems(tenantsField || "")?.map((t: string) => t.trim()) || [],
TenantTags: tags,
UseGuidedFailure: task.getBoolean("UseGuidedFailure") || undefined,
Variables: variablesMap || undefined,
GitRef: gitRef,
};

logger.debug?.(JSON.stringify(command));

return command;
}

const command: CreateRunbookRunCommandV1 = {
spaceName: task.getInput("Space") || "",
ProjectName: task.getInput("Project", true) || "",
Expand Down
16 changes: 13 additions & 3 deletions source/tasks/RunRunbook/RunRunbookV6/runRunbook.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Client, CreateRunbookRunCommandV1, RunbookRunRepository, Logger, TenantRepository, EnvironmentRepository } from "@octopusdeploy/api-client";
import { Client, CreateRunbookRunCommandV1, RunbookRunRepository, Logger, TenantRepository, EnvironmentRepository, CreateRunbookRunResponseV1 } from "@octopusdeploy/api-client";
import os from "os";
import { TaskWrapper } from "tasks/Utils/taskInput";
import { ExecutionResult } from "../../Utils/executionResult";
import { CreateGitRunbookRunCommandV1, isCreateGitRunbookRunCommand } from "./inputCommandBuilder";
import { RunGitRunbookResponse } from "@octopusdeploy/api-client/dist/features/projects/runbooks/runs/RunGitRunbookResponse";

export async function createRunbookRunFromInputs(client: Client, command: CreateRunbookRunCommandV1, task: TaskWrapper, logger: Logger): Promise<ExecutionResult[]> {
export async function createRunbookRunFromInputs(client: Client, command: CreateRunbookRunCommandV1 | CreateGitRunbookRunCommandV1, task: TaskWrapper, logger: Logger): Promise<ExecutionResult[]> {
logger.info?.("🐙 Running a Runbook in Octopus Deploy...");

try {
const repository = new RunbookRunRepository(client, command.spaceName);
const response = await repository.create(command);

const response = await createRunbookRun(repository, command);

logger.info?.(`🎉 ${response.RunbookRunServerTasks.length} Run${response.RunbookRunServerTasks.length > 1 ? "s" : ""} queued successfully!`);

Expand Down Expand Up @@ -58,3 +61,10 @@ export async function createRunbookRunFromInputs(client: Client, command: Create
throw error;
}
}

async function createRunbookRun(repository: RunbookRunRepository, command: CreateRunbookRunCommandV1 | CreateGitRunbookRunCommandV1): Promise<CreateRunbookRunResponseV1 | RunGitRunbookResponse> {
if (isCreateGitRunbookRunCommand(command)) {
return await repository.createGit(command, command.GitRef);
}
return await repository.create(command);
}
8 changes: 8 additions & 0 deletions source/tasks/RunRunbook/RunRunbookV6/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
"required": true,
"helpMarkDown": "The environment names to run the runbook for."
},
{
"name": "GitRef",
"type": "string",
"label": "Git Reference",
"defaultValue": "",
"required": false,
"helpMarkDown": "The Git reference to run the runbook for. Only applies when runbooks are stored in a Git repository for config-as-code enabled projects."
},
{
"name": "Tenants",
"type": "multiLine",
Expand Down
23 changes: 12 additions & 11 deletions source/vsts.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,18 @@ From version 6, the deploy release step is split into two seperate functions for

#### 📥 Inputs

| Name | Description |
| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------- |
| `OctoConnectedServiceName` | **Required.** Name of the Octopus Server connection. |
| `Space` | **Required.** The Octopus space name the release is in. |
| `Project` | **Required.** The Octopus project name to deploy. |
| `Runbook` | **Required.** Runbook name to run. |
| `Environments` | **Required.** The environment names to run the runbook for. One tenant name per line. |
| `Tenants` | The tenant names to run the runbook for. One tenant name per line. |
| `TenantTags` | Run for all tenants with the given tag(s). One tenant tag per line in the format `tag set name/tag name`. |
| `Variables` | List of prompted variable values, one variable-value pair per line. Each variable should be in format `variable name: value` |
| `UseGuidedFailure` | Whether to use guided failure mode if errors occur during the run. |
| Name | Description |
| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OctoConnectedServiceName` | **Required.** Name of the Octopus Server connection. |
| `Space` | **Required.** The Octopus space name the release is in. |
| `Project` | **Required.** The Octopus project name to deploy. |
| `Runbook` | **Required.** Runbook name to run. |
| `Environments` | **Required.** The environment names to run the runbook for. One environment name per line. |
| `GitRef` | The Git reference to run the runbook for e.g. `main`. Only applies when runbooks are stored in a Git repository for config-as-code enabled projects. |
| `Tenants` | The tenant names to run the runbook for. One tenant name per line. |
| `TenantTags` | Run for all tenants with the given tag(s). One tenant tag per line in the format `tag set name/tag name`. |
| `Variables` | List of prompted variable values, one variable-value pair per line. Each variable should be in format `variable name: value` |
| `UseGuidedFailure` | Whether to use guided failure mode if errors occur during the run. |

#### 📤 Outputs

Expand Down
Loading