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

Commit b6759c7

Browse files
authored
Adding lifecycle pipeline flag variables, also adding to validation tests (#151)
* spk project install-lifecycle-pipeline now deployes required pipelines variables. * comment on smoketests * docs * Verifying install-lifecycle-pipeline inputs, allowing no config file, deploying pipeline in validation scripts * Adding spk project install-lifecycle-pipeline to validation tests. Adding .gitignore to spk hld init output * adding lifecycle pipeline validation. Adding pipeline name to polling logs * single pipeline_exists * increasing frontend pipeline timeout * adding back TODO * logging to log.txt
1 parent 8785f1f commit b6759c7

File tree

7 files changed

+183
-66
lines changed

7 files changed

+183
-66
lines changed

docs/project-management.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ Options:
9595

9696
Deploy the HLD Lifecycle pipeline for the bedrock project. This should be run
9797
after merging the `hld-lifecycle.yaml` generated by `spk project init` to the
98-
project repository to master. Before the pipeline can be sucessfully run, the
99-
pipeline variables need to be in place.
98+
project repository to master. The command will add the required pipeline
99+
variables.
100100

101101
```
102102
Usage: project install-lifecycle-pipeline|p [options]
@@ -109,6 +109,7 @@ Options:
109109
-o, --org-name <org-name> Organization Name for Azure DevOps
110110
-r, --repo-name <repo-name> Repository Name in Azure DevOps
111111
-u, --repo-url <repo-url> Repository URL
112+
-e, --hld-url <hld-url> HLD Repository URL
112113
-d, --devops-project <devops-project> Azure DevOps Project
113114
-h, --help output usage information
114115
```

src/commands/hld/init.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import commander from "commander";
22

33
import {
44
generateDefaultHldComponentYaml,
5+
generateGitIgnoreFile,
56
generateHldAzurePipelinesYaml
67
} from "../../lib/fileutils";
78
import { checkoutCommitPushCreatePRLink } from "../../lib/gitutils";
@@ -50,6 +51,8 @@ export const initialize = async (rootProjectPath: string, gitPush: boolean) => {
5051

5152
generateHldAzurePipelinesYaml(rootProjectPath);
5253
generateDefaultHldComponentYaml(rootProjectPath);
54+
// Create .gitignore file in directory ignoring spk.log, if one doesn't already exist.
55+
generateGitIgnoreFile(rootProjectPath, "spk.log");
5356

5457
// If requested, create new git branch, commit, and push
5558
if (gitPush) {

src/commands/project/pipeline.test.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ describe("create hld to manifest pipeline test", () => {
2424

2525
const exitFn = jest.fn();
2626
await installPipeline(
27-
"foo",
28-
"bar",
29-
"wow",
30-
"amazing",
31-
"meow",
32-
"baz",
27+
"orgName",
28+
"PAT",
29+
"pipelineName",
30+
"repoName",
31+
"repoUrl",
32+
"hldRepoUrl",
33+
"azDoProject",
3334
exitFn
3435
);
3536

@@ -40,7 +41,16 @@ describe("create hld to manifest pipeline test", () => {
4041
(getBuildApiClient as jest.Mock).mockReturnValue(Promise.reject());
4142

4243
const exitFn = jest.fn();
43-
await installPipeline("foo", "bar", "baz", "wow", "wao", "baz", exitFn);
44+
await installPipeline(
45+
"orgName",
46+
"PAT",
47+
"pipelineName",
48+
"repoName",
49+
"repoUrl",
50+
"hldRepoUrl",
51+
"azDoProject",
52+
exitFn
53+
);
4454

4555
expect(exitFn).toBeCalledTimes(1);
4656
});
@@ -52,7 +62,16 @@ describe("create hld to manifest pipeline test", () => {
5262
);
5363

5464
const exitFn = jest.fn();
55-
await installPipeline("foo", "bar", "baz", "wow", "wao", "baz", exitFn);
65+
await installPipeline(
66+
"orgName",
67+
"PAT",
68+
"pipelineName",
69+
"repoName",
70+
"repoUrl",
71+
"hldRepoUrl",
72+
"azDoProject",
73+
exitFn
74+
);
5675

5776
expect(exitFn).toBeCalledTimes(1);
5877
});
@@ -63,7 +82,16 @@ describe("create hld to manifest pipeline test", () => {
6382
(queueBuild as jest.Mock).mockReturnValue(Promise.reject());
6483

6584
const exitFn = jest.fn();
66-
await installPipeline("foo", "bar", "baz", "wow", "wao", "baz", exitFn);
85+
await installPipeline(
86+
"orgName",
87+
"PAT",
88+
"pipelineName",
89+
"repoName",
90+
"repoUrl",
91+
"hldRepoUrl",
92+
"azDoProject",
93+
exitFn
94+
);
6795

6896
expect(exitFn).toBeCalledTimes(1);
6997
});

src/commands/project/pipeline.ts

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { IBuildApi } from "azure-devops-node-api/BuildApi";
2-
import { BuildDefinition } from "azure-devops-node-api/interfaces/BuildInterfaces";
2+
import {
3+
BuildDefinition,
4+
BuildDefinitionVariable
5+
} from "azure-devops-node-api/interfaces/BuildInterfaces";
36
import commander from "commander";
47
import { Config } from "../../config";
58
import {
@@ -35,34 +38,88 @@ export const deployLifecyclePipelineCommandDecorator = (
3538
.option("-o, --org-name <org-name>", "Organization Name for Azure DevOps")
3639
.option("-r, --repo-name <repo-name>", "Repository Name in Azure DevOps")
3740
.option("-u, --repo-url <repo-url>", "Repository URL")
41+
.option("-e, --hld-url <hld-url>", "HLD Repository URL")
3842
.option("-d, --devops-project <devops-project>", "Azure DevOps Project")
3943
.action(async opts => {
40-
const { azure_devops } = Config();
41-
42-
if (!azure_devops) {
43-
logger.error("Azure DevOps config section not found");
44-
process.exit(1);
45-
return;
46-
}
47-
4844
const gitOriginUrl = await getOriginUrl();
45+
const { azure_devops } = Config();
4946

5047
const {
5148
orgName = azure_devops && azure_devops.org,
5249
personalAccessToken = azure_devops && azure_devops.access_token,
5350
devopsProject = azure_devops && azure_devops.project,
5451
pipelineName = getRepositoryName(gitOriginUrl) + "-lifecycle",
5552
repoName = getRepositoryName(gitOriginUrl),
56-
repoUrl = getRepositoryUrl(gitOriginUrl)
53+
repoUrl = getRepositoryUrl(gitOriginUrl),
54+
hldUrl = azure_devops && azure_devops.hld_repository
5755
} = opts;
5856

57+
logger.debug(`orgName: ${orgName}`);
58+
logger.debug(`personalAccessToken: XXXXXXXXXXXXXXXXX`);
59+
logger.debug(`pipelineName: ${pipelineName}`);
60+
logger.debug(`repoName: ${repoName}`);
61+
logger.debug(`repoUrl: ${repoUrl}`);
62+
logger.debug(`hldUrl: ${hldUrl}`);
63+
logger.debug(`devopsProject: ${devopsProject}`);
64+
65+
try {
66+
if (typeof pipelineName !== "string") {
67+
throw new Error(
68+
`--pipeline-name must be of type 'string', ${typeof pipelineName} given.`
69+
);
70+
}
71+
72+
if (typeof personalAccessToken !== "string") {
73+
throw new Error(
74+
`--personal-access-token must be of type 'string', ${typeof personalAccessToken} given.`
75+
);
76+
}
77+
78+
if (typeof orgName !== "string") {
79+
throw new Error(
80+
`--org-url must be of type 'string', ${typeof orgName} given.`
81+
);
82+
}
83+
84+
if (typeof repoName !== "string") {
85+
throw new Error(
86+
`--repo-name must be of type 'string', ${typeof repoName} given.`
87+
);
88+
}
89+
90+
if (typeof repoUrl !== "string") {
91+
throw new Error(
92+
`--repo-url must be of type 'string', ${typeof repoUrl} given.`
93+
);
94+
}
95+
96+
if (typeof hldUrl !== "string") {
97+
throw new Error(
98+
`--hld-url must be of type 'string', ${typeof hldUrl} given.`
99+
);
100+
}
101+
102+
if (typeof devopsProject !== "string") {
103+
throw new Error(
104+
`--devops-project must be of type 'string', ${typeof devopsProject} given.`
105+
);
106+
}
107+
} catch (err) {
108+
logger.error(
109+
`Error occurred validating inputs for install-lifecycle-pipeline`
110+
);
111+
logger.error(err);
112+
process.exit(1);
113+
}
114+
59115
try {
60116
await installPipeline(
61117
orgName,
62118
personalAccessToken,
63119
pipelineName,
64120
repoName,
65121
repoUrl,
122+
hldUrl,
66123
devopsProject,
67124
process.exit
68125
);
@@ -84,6 +141,7 @@ export const deployLifecyclePipelineCommandDecorator = (
84141
* @param pipelineName
85142
* @param repositoryName
86143
* @param repositoryUrl
144+
* @param hldRepoUrl
87145
* @param project
88146
* @param exitFn
89147
*/
@@ -93,6 +151,7 @@ export const installPipeline = async (
93151
pipelineName: string,
94152
repositoryName: string,
95153
repositoryUrl: string,
154+
hldRepoUrl: string,
96155
project: string,
97156
exitFn: (status: number) => void
98157
) => {
@@ -114,6 +173,7 @@ export const installPipeline = async (
114173
pipelineName,
115174
repositoryName,
116175
repositoryUrl,
176+
variables: requiredPipelineVariables(personalAccessToken, hldRepoUrl),
117177
yamlFileBranch: "master",
118178
yamlFilePath: "hld-lifecycle.yaml"
119179
});
@@ -152,3 +212,27 @@ export const installPipeline = async (
152212
return exitFn(1);
153213
}
154214
};
215+
216+
/**
217+
* Builds and returns variables required for the lifecycle pipeline.
218+
* @param accessToken Access token with access to the HLD repository.
219+
* @param hldRepoUrl to the HLD repository.
220+
* @returns Object containing the necessary run-time variables for the lifecycle repository.
221+
*/
222+
export const requiredPipelineVariables = (
223+
accessToken: string,
224+
hldRepoUrl: string
225+
): { [key: string]: BuildDefinitionVariable } => {
226+
return {
227+
HLD_REPO: {
228+
allowOverride: true,
229+
isSecret: false,
230+
value: hldRepoUrl
231+
},
232+
PAT: {
233+
allowOverride: true,
234+
isSecret: true,
235+
value: accessToken
236+
}
237+
};
238+
};

tests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tests.
3535
| -------------------------------------- | -------- |
3636
| spk project init ||
3737
| spk project create-variable-group ||
38-
| spk project install-lifecycle-pipeline | 🚫 |
38+
| spk project install-lifecycle-pipeline | |
3939

4040
## Service Management
4141

tests/functions.sh

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -151,30 +151,13 @@ function variable_group_exists () {
151151
}
152152

153153
function pipeline_exists () {
154-
FrontEnd=$3
154+
echo "Checking if pipeline: ${3} already exists."
155155
pipeline_results=$(az pipelines list --org $1 --p $2)
156-
pipeline_exists=$(tr '"\""' '"\\"' <<< "$pipeline_results" | jq -r --arg FrontEnd "$FrontEnd-pipeline" '.[].name | select(. == $FrontEnd ) != null')
157-
156+
pipeline_exists=$(tr '"\""' '"\\"' <<< "$pipeline_results" | jq -r --arg pipeline_name ${3} '.[].name | select(. == $pipeline_name ) != null')
158157
if [ "$pipeline_exists" = "true" ]; then
159-
echo "The pipeline '$FrontEnd-pipeline' already exists "
158+
echo "The pipeline '${3}' already exists."
160159
# Get the pipeline id. We have to replace single "\" with "\\"
161-
pipeline_id=$(tr '"\""' '"\\"' <<<"$pipeline_results" | jq -r --arg FrontEnd "$FrontEnd-pipeline" '.[] | select(.name == $FrontEnd) | .id')
162-
echo "pipeline_id to delete is $pipeline_id"
163-
# Delete the repo
164-
az pipelines delete --id "$pipeline_id" --yes --org $1 --p $2
165-
fi
166-
}
167-
168-
function hld_pipeline_exists () {
169-
echo "Checking if the HLD pipeline already exists."
170-
hld_pipeline_name="${3}-to-${4}"
171-
echo "Looking for pipeline of name: $hld_pipeline_name"
172-
pipeline_results=$(az pipelines list --org $1 --p $2)
173-
pipeline_exists=$(tr '"\""' '"\\"' <<< "$pipeline_results" | jq -r --arg pipeline_name $hld_pipeline_name '.[].name | select(. == $pipeline_name ) != null')
174-
if [ "$pipeline_exists" = "true" ]; then
175-
echo "The pipeline '$hld_pipeline_name' already exists."
176-
# Get the pipeline id. We have to replace single "\" with "\\"
177-
pipeline_id=$(tr '"\""' '"\\"' <<<"$pipeline_results" | jq -r --arg pipeline_name $hld_pipeline_name '.[] | select(.name == $pipeline_name) | .id')
160+
pipeline_id=$(tr '"\""' '"\\"' <<<"$pipeline_results" | jq -r --arg pipeline_name ${3} '.[] | select(.name == $pipeline_name) | .id')
178161
echo "pipeline_id to delete is $pipeline_id"
179162
# Delete the repo
180163
az pipelines delete --id "$pipeline_id" --yes --org $1 --p $2
@@ -199,31 +182,32 @@ function verify_pipeline_with_poll () {
199182
# We expect only 1 build right now
200183
build_count=$(tr '"\""' '"\\"' <<< "$pipeline_builds" | jq '. | length')
201184
if [ "$build_count" != "1" ]; then
202-
echo "Expected 1 build for pipeline id $pipeline_id but found $build_count"
185+
echo "Expected 1 build for pipeline: $pipeline_name-$pipeline_id but found $build_count"
203186
exit 1
204187
fi
205188

206189
# We use grep because of string matching issues
207190
echo "Get the build status for build..."
208191
pipeline_status=$(tr '"\""' '"\\"' <<< "$pipeline_builds" | jq .[0].status)
192+
echo "pipeline: $pipeline_name-$pipeline_id:"
209193
echo "pipeline_status this iteration --> $pipeline_status"
210194
if [ "$(echo $pipeline_status | grep 'completed')" != "" ]; then
211195
pipeline_result=$(tr '"\""' '"\\"' <<< "$pipeline_builds" | jq .[0].result)
212196
if [ "$(echo $pipeline_result | grep 'succeeded')" != "" ]; then
213-
echo "Successful build for pipeline id $pipeline_id!"
197+
echo "Successful build for pipeline: $pipeline_name-$pipeline_id!"
214198
loop_result=$pipeline_result
215199
break
216200
else
217-
echo "Expected successful build for pipeline id $pipeline_id but result is $pipeline_result"
201+
echo "Expected successful build for pipeline: $pipeline_name-$pipeline_id but result is $pipeline_result"
218202
exit 1
219203
fi
220204
else
221-
echo "Pipeline Id $pipeline_id status is $pipeline_status. Sleeping for $poll_interval seconds"
205+
echo "pipeline: $pipeline_name-$pipeline_id status is $pipeline_status. Sleeping for $poll_interval seconds"
222206
sleep $poll_interval
223207
fi
224208
done
225209
if [ "$loop_result" = "unknown" ]; then
226-
echo "Polling the build timed out after $poll_timeout seconds!"
210+
echo "Polling pipeline: $pipeline_name-$pipeline_id timed out after $poll_timeout seconds!"
227211
exit 1
228212
fi
229213
}
@@ -247,4 +231,4 @@ function approve_pull_request () {
247231
echo "Issue approving PR $pull_request_id"
248232
exit 1
249233
fi
250-
}
234+
}

0 commit comments

Comments
 (0)