Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit ea8a656

Browse files
edaenaEdaena SalinasEdaena Salinas
authored
Check that repository exits for installing pipeline (#440)
* Check that repository exits for installing pipeline * Add repository validation to other commands * Remove repositoryExists function * Update unit tests Co-authored-by: Edaena Salinas <[email protected]> Co-authored-by: Edaena Salinas <[email protected]>
1 parent 1cc3263 commit ea8a656

File tree

8 files changed

+96
-18
lines changed

8 files changed

+96
-18
lines changed

src/commands/hld/pipeline.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ afterAll(() => {
5959
disableVerboseLogging();
6060
});
6161

62-
jest.spyOn(azdo, "repositoryHasFile").mockReturnValue(Promise.resolve());
62+
jest.spyOn(azdo, "validateRepository").mockReturnValue(Promise.resolve());
6363

6464
describe("test emptyStringIfUndefined function", () => {
6565
it("pass in undefined", () => {

src/commands/hld/pipeline.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from "azure-devops-node-api/interfaces/BuildInterfaces";
77
import commander from "commander";
88
import { Config } from "../../config";
9-
import { repositoryHasFile } from "../../lib/azdoClient";
9+
import { validateRepository } from "../../lib/azdoClient";
1010
import { build as buildCmd, exit as exitCmd } from "../../lib/commandBuilder";
1111
import {
1212
BUILD_SCRIPT_URL,
@@ -200,7 +200,8 @@ export const execute = async (
200200
};
201201

202202
// By default the version descriptor is for the master branch
203-
await repositoryHasFile(
203+
await validateRepository(
204+
opts.devopsProject,
204205
RENDER_HLD_PIPELINE_FILENAME,
205206
opts.yamlFileBranch ? opts.yamlFileBranch : "master",
206207
opts.hldName,

src/commands/project/pipeline.test.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ const mockValues: CommandOptions = {
3636
personalAccessToken: "PAT",
3737
pipelineName: "pipelineName",
3838
repoName: "repoName",
39-
repoUrl: "repoUrl",
39+
repoUrl: "https://dev.azure.com/myOrg/myProject/_git/myRepo",
4040
yamlFileBranch: "master",
4141
};
4242

43-
jest.spyOn(azdo, "repositoryHasFile").mockReturnValue(Promise.resolve());
43+
jest.spyOn(azdo, "validateRepository").mockReturnValue(Promise.resolve());
4444

4545
const mockMissingValues: CommandOptions = {
4646
buildScriptUrl: undefined,
@@ -123,12 +123,6 @@ describe("installLifecyclePipeline and execute tests", () => {
123123
expect(exitFn).toBeCalledTimes(1);
124124
expect(exitFn.mock.calls).toEqual([[0]]);
125125
});
126-
it("test execute function: missing repo url and pipeline name", async () => {
127-
const exitFn = jest.fn();
128-
await execute(mockMissingValues, "", exitFn);
129-
expect(exitFn).toBeCalledTimes(1);
130-
expect(exitFn.mock.calls).toEqual([[1]]);
131-
});
132126
it("test execute function: github repos not supported", async () => {
133127
const exitFn = jest.fn();
134128
await execute(nullValues, "", exitFn);

src/commands/project/pipeline.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from "azure-devops-node-api/interfaces/BuildInterfaces";
77
import commander from "commander";
88
import { Config } from "../../config";
9-
import { repositoryHasFile } from "../../lib/azdoClient";
9+
import { validateRepository } from "../../lib/azdoClient";
1010
import { fileInfo as bedrockFileInfo } from "../../lib/bedrockYaml";
1111
import {
1212
build as buildCmd,
@@ -77,14 +77,16 @@ export const fetchValidateValues = (
7777
if (!opts.repoUrl) {
7878
throw Error(`Repo url not defined`);
7979
}
80+
8081
const values: CommandOptions = {
8182
buildScriptUrl: opts.buildScriptUrl || BUILD_SCRIPT_URL,
8283
devopsProject: opts.devopsProject || azureDevops?.project,
8384
orgName: opts.orgName || azureDevops?.org,
8485
personalAccessToken: opts.personalAccessToken || azureDevops?.access_token,
8586
pipelineName:
8687
opts.pipelineName || getRepositoryName(gitOriginUrl) + "-lifecycle",
87-
repoName: getRepositoryName(gitOriginUrl),
88+
repoName:
89+
getRepositoryName(opts.repoUrl) || getRepositoryName(gitOriginUrl),
8890
repoUrl: opts.repoUrl || getRepositoryUrl(gitOriginUrl),
8991
yamlFileBranch: opts.yamlFileBranch,
9092
};
@@ -233,10 +235,11 @@ export const execute = async (
233235
personalAccessToken: values.personalAccessToken,
234236
project: values.devopsProject,
235237
};
236-
await repositoryHasFile(
238+
await validateRepository(
239+
values.devopsProject!,
237240
PROJECT_PIPELINE_FILENAME,
238241
values.yamlFileBranch ? opts.yamlFileBranch : "master",
239-
values.repoName!,
242+
values.repoName,
240243
accessOpts
241244
);
242245
await installLifecyclePipeline(values);

src/commands/service/pipeline.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const getMockedValues = (): CommandOptions => {
4646
return deepClone(MOCKED_VALUES);
4747
};
4848

49-
jest.spyOn(azdo, "repositoryHasFile").mockReturnValue(Promise.resolve());
49+
jest.spyOn(azdo, "validateRepository").mockReturnValue(Promise.resolve());
5050

5151
describe("test fetchValues function", () => {
5252
it("with all values set", async () => {

src/commands/service/pipeline.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import commander from "commander";
99
import path from "path";
1010
import { Config } from "../../config";
11-
import { repositoryHasFile } from "../../lib/azdoClient";
11+
import { validateRepository } from "../../lib/azdoClient";
1212
import { build as buildCmd, exit as exitCmd } from "../../lib/commandBuilder";
1313
import {
1414
BUILD_SCRIPT_URL,
@@ -90,7 +90,8 @@ export const execute = async (
9090
path.join(serviceName, SERVICE_PIPELINE_FILENAME);
9191

9292
// By default the version descriptor is for the master branch
93-
await repositoryHasFile(
93+
await validateRepository(
94+
opts.devopsProject,
9495
pipelinesYamlPath,
9596
opts.yamlFileBranch ? opts.yamlFileBranch : "master",
9697
opts.repoName,

src/lib/azdoClient.test.ts

+52
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
getWebApi,
1313
invalidateWebApi,
1414
repositoryHasFile,
15+
validateRepository,
1516
} from "./azdoClient";
1617
import * as azdoClient from "./azdoClient";
1718
import { AzureDevOpsOpts } from "./git";
@@ -144,6 +145,57 @@ describe("test getBuildApi function", () => {
144145
});
145146
});
146147

148+
describe("validateRepository", () => {
149+
test("repository exists", async () => {
150+
const getRepositoryFunc = jest.spyOn(azure, "GitAPI");
151+
getRepositoryFunc.mockReturnValueOnce(
152+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
153+
Promise.resolve({ getRepository: () => ({ id: "3839fjfkj" }) } as any)
154+
);
155+
const getItemFunc = jest.spyOn(azure, "GitAPI");
156+
getItemFunc.mockReturnValueOnce(
157+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
158+
Promise.resolve({ getItem: () => ({ commitId: "3839fjfkj" }) } as any)
159+
);
160+
const accessOpts: AzureDevOpsOpts = {
161+
orgName: "testOrg",
162+
personalAccessToken: "mytoken",
163+
project: "testProject",
164+
};
165+
166+
await expect(
167+
validateRepository(
168+
"my-project",
169+
"myFile",
170+
"master",
171+
"my-repo",
172+
accessOpts
173+
)
174+
).resolves.not.toThrow();
175+
});
176+
test("repository does not exist", async () => {
177+
const createPullRequestFunc = jest.spyOn(azure, "GitAPI");
178+
createPullRequestFunc.mockReturnValueOnce(
179+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
180+
Promise.resolve({ getRepository: () => null } as any)
181+
);
182+
const accessOpts: AzureDevOpsOpts = {
183+
orgName: "testOrg",
184+
personalAccessToken: "mytoken",
185+
project: "testProject",
186+
};
187+
await expect(
188+
validateRepository(
189+
"my-project",
190+
"myFile",
191+
"master",
192+
"my-repo",
193+
accessOpts
194+
)
195+
).rejects.toThrow();
196+
});
197+
});
198+
147199
describe("repositoryHasFile", () => {
148200
test("repository contains the given file", async () => {
149201
const createPullRequestFunc = jest.spyOn(azure, "GitAPI");

src/lib/azdoClient.ts

+27
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,30 @@ export const repositoryHasFile = async (
157157
);
158158
}
159159
};
160+
161+
/**
162+
* Validates if a repository exists and if it contains the given file
163+
* @param project The Azure DevOps project name
164+
* @param fileName The name of the file
165+
* @param branch The branch name
166+
* @param repoName The name of the repository
167+
* @param accessOpts The Azure DevOps access options to the repository
168+
*/
169+
export const validateRepository = async (
170+
project: string,
171+
fileName: string,
172+
branch: string,
173+
repoName: string,
174+
accessOpts: AzureDevOpsOpts
175+
): Promise<void> => {
176+
const gitApi = await GitAPI(accessOpts);
177+
const repo = await gitApi.getRepository(repoName, project);
178+
179+
if (!repo) {
180+
throw Error(
181+
`Project '${project}' does not contain repository '${repoName}'.`
182+
);
183+
}
184+
185+
await repositoryHasFile(fileName, branch, repoName, accessOpts);
186+
};

0 commit comments

Comments
 (0)