|
1 |
| -/* eslint-disable @typescript-eslint/no-non-null-assertion */ |
2 |
| - |
3 | 1 | import commander from "commander";
|
4 | 2 | import { join } from "path";
|
5 | 3 | import { Bedrock, Config } from "../../config";
|
@@ -29,6 +27,16 @@ export interface CommandOptions {
|
29 | 27 | targetBranch: string | undefined;
|
30 | 28 | }
|
31 | 29 |
|
| 30 | +export interface CommandValues { |
| 31 | + sourceBranch: string; |
| 32 | + title: string | undefined; |
| 33 | + description: string; |
| 34 | + remoteUrl: string; |
| 35 | + personalAccessToken: string; |
| 36 | + orgName: string; |
| 37 | + targetBranch: string | undefined; |
| 38 | +} |
| 39 | + |
32 | 40 | export const getRemoteUrl = async (
|
33 | 41 | remoteUrl: string | undefined
|
34 | 42 | ): Promise<string> => {
|
@@ -99,70 +107,85 @@ export const getSourceBranch = async (
|
99 | 107 | /**
|
100 | 108 | * Creates a pull request from the given source branch
|
101 | 109 | * @param defaultRings List of default rings
|
102 |
| - * @param opts option values |
| 110 | + * @param values option values |
103 | 111 | */
|
104 | 112 | export const makePullRequest = async (
|
105 | 113 | defaultRings: string[],
|
106 |
| - opts: CommandOptions |
| 114 | + values: CommandValues |
107 | 115 | ): Promise<void> => {
|
108 | 116 | for (const ring of defaultRings) {
|
109 |
| - const title = opts.title || `[SPK] ${opts.sourceBranch} => ${ring}`; |
110 |
| - await createPullRequest(title, opts.sourceBranch!, ring, { |
111 |
| - description: opts.description!, |
112 |
| - orgName: opts.orgName!, |
113 |
| - originPushUrl: opts.remoteUrl!, |
114 |
| - personalAccessToken: opts.personalAccessToken!, |
| 117 | + const title = values.title || `[SPK] ${values.sourceBranch} => ${ring}`; |
| 118 | + await createPullRequest(title, values.sourceBranch, ring, { |
| 119 | + description: values.description, |
| 120 | + orgName: values.orgName, |
| 121 | + originPushUrl: values.remoteUrl, |
| 122 | + personalAccessToken: values.personalAccessToken, |
115 | 123 | });
|
116 | 124 | }
|
117 | 125 | };
|
118 | 126 |
|
| 127 | +const populateValues = async (opts: CommandOptions): Promise<CommandValues> => { |
| 128 | + const { azure_devops } = Config(); |
| 129 | + opts.orgName = opts.orgName || azure_devops?.org; |
| 130 | + opts.personalAccessToken = |
| 131 | + opts.personalAccessToken || azure_devops?.access_token; |
| 132 | + |
| 133 | + // Default the remote to the git origin |
| 134 | + opts.remoteUrl = await getRemoteUrl(opts.remoteUrl); |
| 135 | + |
| 136 | + // default pull request source branch to the current branch |
| 137 | + opts.sourceBranch = await getSourceBranch(opts.sourceBranch); |
| 138 | + |
| 139 | + const errors = validateForRequiredValues(decorator, { |
| 140 | + orgName: opts.orgName, |
| 141 | + personalAccessToken: opts.personalAccessToken, |
| 142 | + remoteUrl: opts.remoteUrl, |
| 143 | + sourceBranch: opts.sourceBranch, |
| 144 | + }); |
| 145 | + if (errors.length > 0) { |
| 146 | + throw Error("missing required values"); |
| 147 | + } |
| 148 | + |
| 149 | + return { |
| 150 | + // validateForRequiredValues confirm that sourceBranch has value |
| 151 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 152 | + sourceBranch: opts.sourceBranch!, |
| 153 | + title: opts.title, |
| 154 | + description: opts.description || "This is automated PR generated via SPK", |
| 155 | + remoteUrl: opts.remoteUrl, |
| 156 | + // validateForRequiredValues confirm that personalAccessToken has value |
| 157 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 158 | + personalAccessToken: opts.personalAccessToken!, |
| 159 | + // validateForRequiredValues confirm that orgName has value |
| 160 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 161 | + orgName: opts.orgName!, |
| 162 | + targetBranch: opts.targetBranch, |
| 163 | + }; |
| 164 | +}; |
| 165 | + |
119 | 166 | export const execute = async (
|
120 | 167 | opts: CommandOptions,
|
121 | 168 | exitFn: (status: number) => Promise<void>
|
122 | 169 | ): Promise<void> => {
|
123 | 170 | try {
|
124 |
| - const { azure_devops } = Config(); |
125 |
| - opts.orgName = opts.orgName || azure_devops?.org; |
126 |
| - opts.personalAccessToken = |
127 |
| - opts.personalAccessToken || azure_devops?.access_token!; |
128 |
| - opts.description = |
129 |
| - opts.description || "This is automated PR generated via SPK"; |
130 |
| - |
131 |
| - //////////////////////////////////////////////////////////////////////// |
132 |
| - // Give defaults |
133 |
| - //////////////////////////////////////////////////////////////////////// |
| 171 | + const values = await populateValues(opts); |
| 172 | + |
134 | 173 | // default pull request against initial ring
|
135 | 174 | const bedrockConfig = Bedrock();
|
136 | 175 | // Default to the --target-branch for creating a revision; if not specified, fallback to default rings in bedrock.yaml
|
137 |
| - const defaultRings = getDefaultRings(opts.targetBranch, bedrockConfig); |
138 |
| - |
139 |
| - // default pull request source branch to the current branch |
140 |
| - opts.sourceBranch = await getSourceBranch(opts.sourceBranch); |
| 176 | + const defaultRings = getDefaultRings(values.targetBranch, bedrockConfig); |
141 | 177 |
|
142 | 178 | // Make sure the user isn't trying to make a PR for a branch against itself
|
143 |
| - if (defaultRings.includes(opts.sourceBranch)) { |
| 179 | + if (defaultRings.includes(values.sourceBranch)) { |
144 | 180 | throw Error(
|
145 | 181 | `A pull request for a branch cannot be made against itself. Ensure your target branch(es) '${JSON.stringify(
|
146 | 182 | defaultRings
|
147 |
| - )}' do not include your source branch '${opts.sourceBranch}'` |
| 183 | + )}' do not include your source branch '${values.sourceBranch}'` |
148 | 184 | );
|
149 | 185 | }
|
150 | 186 |
|
151 |
| - // Default the remote to the git origin |
152 |
| - opts.remoteUrl = await getRemoteUrl(opts.remoteUrl); |
153 |
| - const errors = validateForRequiredValues(decorator, { |
154 |
| - orgName: opts.orgName, |
155 |
| - personalAccessToken: opts.personalAccessToken, |
156 |
| - remoteUrl: opts.remoteUrl, |
157 |
| - sourceBranch: opts.sourceBranch, |
158 |
| - }); |
159 |
| - |
160 |
| - if (errors.length > 0) { |
161 |
| - await exitFn(1); |
162 |
| - } else { |
163 |
| - await makePullRequest(defaultRings, opts); |
164 |
| - await exitFn(0); |
165 |
| - } |
| 187 | + await makePullRequest(defaultRings, values); |
| 188 | + await exitFn(0); |
166 | 189 | } catch (err) {
|
167 | 190 | logger.error(err);
|
168 | 191 | await exitFn(1);
|
|
0 commit comments