@salesforce/plugin-devops-center 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +649 -102
- package/lib/commands/devops/pipeline/create.d.ts +2 -1
- package/lib/commands/devops/pipeline/create.js +37 -7
- package/lib/commands/devops/pipeline/create.js.map +1 -1
- package/lib/commands/devops/pipeline/{activate.d.ts → get.d.ts} +3 -3
- package/lib/commands/devops/pipeline/get.js +81 -0
- package/lib/commands/devops/pipeline/get.js.map +1 -0
- package/lib/commands/devops/pipeline/list.d.ts +13 -0
- package/lib/commands/devops/pipeline/list.js +58 -0
- package/lib/commands/devops/pipeline/list.js.map +1 -0
- package/lib/commands/devops/pipeline/{attach-project.d.ts → project/add.d.ts} +2 -2
- package/lib/commands/devops/pipeline/{attach-project.js → project/add.js} +5 -5
- package/lib/commands/devops/pipeline/project/add.js.map +1 -0
- package/lib/commands/devops/pipeline/project/delete.d.ts +15 -0
- package/lib/commands/devops/pipeline/{activate.js → project/delete.js} +17 -28
- package/lib/commands/devops/pipeline/project/delete.js.map +1 -0
- package/lib/commands/devops/pipeline/stage/delete.d.ts +15 -0
- package/lib/commands/devops/pipeline/stage/delete.js +69 -0
- package/lib/commands/devops/pipeline/stage/delete.js.map +1 -0
- package/lib/commands/devops/pipeline/update.d.ts +18 -0
- package/lib/commands/devops/pipeline/update.js +126 -0
- package/lib/commands/devops/pipeline/update.js.map +1 -0
- package/lib/commands/devops/project/update.d.ts +17 -0
- package/lib/commands/devops/project/update.js +86 -0
- package/lib/commands/devops/project/update.js.map +1 -0
- package/lib/commands/devops/promote.d.ts +24 -0
- package/lib/commands/devops/promote.js +148 -0
- package/lib/commands/devops/promote.js.map +1 -0
- package/lib/commands/devops/promotion/complete.d.ts +20 -0
- package/lib/commands/devops/promotion/complete.js +112 -0
- package/lib/commands/devops/promotion/complete.js.map +1 -0
- package/lib/commands/devops/request/status.d.ts +14 -0
- package/lib/commands/devops/request/status.js +71 -0
- package/lib/commands/devops/request/status.js.map +1 -0
- package/lib/commands/devops/{pull-request → review}/create.d.ts +1 -3
- package/lib/commands/devops/{pull-request → review}/create.js +11 -43
- package/lib/commands/devops/review/create.js.map +1 -0
- package/lib/commands/devops/stage/{add-branch.d.ts → branch/add.d.ts} +2 -2
- package/lib/commands/devops/stage/{add-branch.js → branch/add.js} +6 -6
- package/lib/commands/devops/stage/branch/add.js.map +1 -0
- package/lib/commands/devops/stage/{add-environment.d.ts → environment/add.d.ts} +2 -2
- package/lib/commands/devops/stage/{add-environment.js → environment/add.js} +13 -6
- package/lib/commands/devops/stage/environment/add.js.map +1 -0
- package/lib/commands/devops/stage/environment/delete.d.ts +15 -0
- package/lib/commands/devops/stage/environment/delete.js +75 -0
- package/lib/commands/devops/stage/environment/delete.js.map +1 -0
- package/lib/commands/devops/work-item/combine.d.ts +15 -0
- package/lib/commands/devops/work-item/combine.js +109 -0
- package/lib/commands/devops/work-item/combine.js.map +1 -0
- package/lib/commands/devops/work-item/prepare.d.ts +14 -0
- package/lib/commands/devops/work-item/prepare.js +98 -0
- package/lib/commands/devops/work-item/prepare.js.map +1 -0
- package/lib/commands/devops/work-item/{status/update.d.ts → update.d.ts} +6 -4
- package/lib/commands/devops/work-item/{status/update.js → update.js} +30 -9
- package/lib/commands/devops/work-item/update.js.map +1 -0
- package/lib/common/flags/promote/promoteFlags.d.ts +1 -0
- package/lib/common/flags/promote/promoteFlags.js +5 -0
- package/lib/common/flags/promote/promoteFlags.js.map +1 -1
- package/lib/common/outputService/aorOutputService.js +4 -4
- package/lib/common/outputService/aorOutputService.js.map +1 -1
- package/lib/common/outputService/outputUtils.js +1 -2
- package/lib/common/outputService/outputUtils.js.map +1 -1
- package/lib/common/selectors/asyncOperationResultsSelector.js +3 -1
- package/lib/common/selectors/asyncOperationResultsSelector.js.map +1 -1
- package/lib/common/selectors/deployComponentsSelector.js +5 -6
- package/lib/common/selectors/deployComponentsSelector.js.map +1 -1
- package/lib/common/selectors/deployProgressSummarySelector.js +3 -1
- package/lib/common/selectors/deployProgressSummarySelector.js.map +1 -1
- package/lib/common/selectors/deploymentResultsSelector.js +10 -6
- package/lib/common/selectors/deploymentResultsSelector.js.map +1 -1
- package/lib/common/selectors/environmentSelector.js +4 -2
- package/lib/common/selectors/environmentSelector.js.map +1 -1
- package/lib/common/selectors/namedCredentialSelector.js +2 -1
- package/lib/common/selectors/namedCredentialSelector.js.map +1 -1
- package/lib/common/selectors/pipelineStageSelector.js +5 -3
- package/lib/common/selectors/pipelineStageSelector.js.map +1 -1
- package/lib/common/selectors/validateDeploySelector.js +3 -1
- package/lib/common/selectors/validateDeploySelector.js.map +1 -1
- package/lib/common/selectors/workItemSelector.js +4 -1
- package/lib/common/selectors/workItemSelector.js.map +1 -1
- package/lib/utils/activatePipeline.d.ts +13 -4
- package/lib/utils/activatePipeline.js +7 -6
- package/lib/utils/activatePipeline.js.map +1 -1
- package/lib/utils/attachProject.js +2 -0
- package/lib/utils/attachProject.js.map +1 -1
- package/lib/utils/combineWorkItems.d.ts +20 -0
- package/lib/utils/combineWorkItems.js +42 -0
- package/lib/utils/combineWorkItems.js.map +1 -0
- package/lib/utils/createPipeline.d.ts +14 -1
- package/lib/utils/createPipeline.js +52 -6
- package/lib/utils/createPipeline.js.map +1 -1
- package/lib/utils/createProject.js +1 -0
- package/lib/utils/createProject.js.map +1 -1
- package/lib/utils/createPullRequest.d.ts +7 -19
- package/lib/utils/createPullRequest.js +51 -122
- package/lib/utils/createPullRequest.js.map +1 -1
- package/lib/utils/deletePipelineStage.d.ts +12 -0
- package/lib/utils/deletePipelineStage.js +41 -0
- package/lib/utils/deletePipelineStage.js.map +1 -0
- package/lib/utils/deleteStageEnvironment.d.ts +8 -0
- package/lib/utils/deleteStageEnvironment.js +33 -0
- package/lib/utils/deleteStageEnvironment.js.map +1 -0
- package/lib/utils/deployStage.d.ts +29 -0
- package/lib/utils/deployStage.js +68 -0
- package/lib/utils/deployStage.js.map +1 -0
- package/lib/utils/detachProject.d.ts +8 -0
- package/lib/utils/detachProject.js +37 -0
- package/lib/utils/detachProject.js.map +1 -0
- package/lib/utils/getPipeline.d.ts +27 -0
- package/lib/utils/getPipeline.js +66 -0
- package/lib/utils/getPipeline.js.map +1 -0
- package/lib/utils/getRequestStatus.d.ts +10 -0
- package/lib/utils/getRequestStatus.js +32 -0
- package/lib/utils/getRequestStatus.js.map +1 -0
- package/lib/utils/listPipelines.d.ts +11 -0
- package/lib/utils/listPipelines.js +20 -0
- package/lib/utils/listPipelines.js.map +1 -0
- package/lib/utils/pipelineUtils.js +3 -0
- package/lib/utils/pipelineUtils.js.map +1 -1
- package/lib/utils/prepareWorkItem.d.ts +25 -0
- package/lib/utils/prepareWorkItem.js +55 -0
- package/lib/utils/prepareWorkItem.js.map +1 -0
- package/lib/utils/promoteStage.d.ts +21 -0
- package/lib/utils/promoteStage.js +46 -0
- package/lib/utils/promoteStage.js.map +1 -0
- package/lib/utils/soqlUtils.d.ts +23 -0
- package/lib/utils/soqlUtils.js +63 -0
- package/lib/utils/soqlUtils.js.map +1 -0
- package/lib/utils/updateProject.d.ts +17 -0
- package/lib/utils/updateProject.js +41 -0
- package/lib/utils/updateProject.js.map +1 -0
- package/lib/utils/{updateWorkItemStatus.d.ts → updateWorkItem.d.ts} +12 -14
- package/lib/utils/{updateWorkItemStatus.js → updateWorkItem.js} +31 -27
- package/lib/utils/updateWorkItem.js.map +1 -0
- package/lib/utils/workItems.js +2 -0
- package/lib/utils/workItems.js.map +1 -1
- package/messages/devops.pipeline.create.md +26 -6
- package/messages/devops.pipeline.get.md +17 -0
- package/messages/devops.pipeline.list.md +13 -0
- package/messages/devops.pipeline.project.delete.md +25 -0
- package/messages/devops.pipeline.stage.delete.md +25 -0
- package/messages/devops.pipeline.update.md +47 -0
- package/messages/devops.project.update.md +45 -0
- package/messages/devops.promote.md +61 -0
- package/messages/devops.promotion.complete.md +47 -0
- package/messages/devops.request.status.md +21 -0
- package/messages/devops.review.create.md +33 -0
- package/messages/{devops.stage.add-environment.md → devops.stage.environment.add.md} +4 -0
- package/messages/devops.stage.environment.delete.md +29 -0
- package/messages/devops.work-item.combine.md +39 -0
- package/messages/devops.work-item.prepare.md +27 -0
- package/messages/devops.work-item.update.md +45 -0
- package/npm-shrinkwrap.json +37 -174
- package/oclif.lock +1 -1
- package/oclif.manifest.json +1167 -223
- package/package.json +20 -8
- package/schemas/devops-pipeline-get.json +98 -0
- package/schemas/devops-pipeline-list.json +38 -0
- package/schemas/devops-pipeline-project-delete.json +25 -0
- package/schemas/devops-pipeline-stage-delete.json +25 -0
- package/schemas/{devops-pipeline-activate.json → devops-pipeline-update.json} +5 -2
- package/schemas/devops-project-update.json +31 -0
- package/schemas/devops-promote.json +28 -0
- package/schemas/devops-promotion-complete.json +34 -0
- package/schemas/devops-request-status.json +31 -0
- package/schemas/{devops-pull__request-create.json → devops-review-create.json} +0 -3
- package/schemas/devops-stage-environment-delete.json +25 -0
- package/schemas/devops-work__item-combine.json +25 -0
- package/schemas/devops-work__item-prepare.json +25 -0
- package/schemas/{devops-work__item-status-update.json → devops-work__item-update.json} +8 -2
- package/lib/commands/devops/pipeline/activate.js.map +0 -1
- package/lib/commands/devops/pipeline/attach-project.js.map +0 -1
- package/lib/commands/devops/pull-request/create.js.map +0 -1
- package/lib/commands/devops/stage/add-branch.js.map +0 -1
- package/lib/commands/devops/stage/add-environment.js.map +0 -1
- package/lib/commands/devops/work-item/status/update.js.map +0 -1
- package/lib/utils/updateWorkItemStatus.js.map +0 -1
- package/messages/devops.pipeline.activate.md +0 -29
- package/messages/devops.pull-request.create.md +0 -57
- package/messages/devops.work-item.status.update.md +0 -29
- /package/messages/{devops.pipeline.attach-project.md → devops.pipeline.project.add.md} +0 -0
- /package/messages/{devops.stage.add-branch.md → devops.stage.branch.add.md} +0 -0
- /package/schemas/{devops-pipeline-attach__project.json → devops-pipeline-project-add.json} +0 -0
- /package/schemas/{devops-stage-add__branch.json → devops-stage-branch-add.json} +0 -0
- /package/schemas/{devops-stage-add__environment.json → devops-stage-environment-add.json} +0 -0
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { Connection } from '@salesforce/core';
|
|
2
|
-
export type
|
|
2
|
+
export type PipelineUpdateParams = {
|
|
3
3
|
connection: Connection;
|
|
4
4
|
pipelineId: string;
|
|
5
5
|
};
|
|
6
|
-
export type
|
|
6
|
+
export type PipelineUpdateResult = {
|
|
7
7
|
success: boolean;
|
|
8
8
|
pipelineId: string;
|
|
9
|
+
name?: string;
|
|
9
10
|
status?: string;
|
|
10
11
|
stageCount?: number;
|
|
11
12
|
error?: string;
|
|
12
13
|
};
|
|
14
|
+
export type ActivatePipelineParams = PipelineUpdateParams;
|
|
15
|
+
export type ActivatePipelineResult = PipelineUpdateResult;
|
|
13
16
|
/**
|
|
14
|
-
* Activates a DevOps Center pipeline via the Connect API.
|
|
15
17
|
* POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/activate
|
|
16
18
|
*/
|
|
17
|
-
export declare function activatePipeline(params:
|
|
19
|
+
export declare function activatePipeline(params: PipelineUpdateParams): Promise<PipelineUpdateResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Record API update — covers deactivate and/or rename since no Connect API exists for those.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updatePipelineRecord(connection: Connection, pipelineId: string, fields: {
|
|
24
|
+
IsActive?: boolean;
|
|
25
|
+
Name?: string;
|
|
26
|
+
}): Promise<void>;
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
/**
|
|
17
|
-
* Activates a DevOps Center pipeline via the Connect API.
|
|
18
17
|
* POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/activate
|
|
19
18
|
*/
|
|
20
19
|
export async function activatePipeline(params) {
|
|
@@ -26,10 +25,12 @@ export async function activatePipeline(params) {
|
|
|
26
25
|
body: '{}',
|
|
27
26
|
headers: { 'Content-Type': 'application/json' },
|
|
28
27
|
});
|
|
29
|
-
return {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
return { success: true, pipelineId, status: data.status ?? 'Active' };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Record API update — covers deactivate and/or rename since no Connect API exists for those.
|
|
32
|
+
*/
|
|
33
|
+
export async function updatePipelineRecord(connection, pipelineId, fields) {
|
|
34
|
+
await connection.sobject('DevopsPipeline').update({ Id: pipelineId, ...fields });
|
|
34
35
|
}
|
|
35
36
|
//# sourceMappingURL=activatePipeline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activatePipeline.js","sourceRoot":"","sources":["../../src/utils/activatePipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"activatePipeline.js","sourceRoot":"","sources":["../../src/utils/activatePipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAwBH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAA4B;IACjE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC1C,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,WAAW,CAAC;IAC7G,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAmB;QACtD,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAsB,EACtB,UAAkB,EAClB,MAA6C;IAE7C,MAAM,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { validateSalesforceId } from './soqlUtils.js';
|
|
16
17
|
/**
|
|
17
18
|
* Checks if a project is already attached to a pipeline.
|
|
18
19
|
* Returns the existing pipeline ID if found, undefined otherwise.
|
|
19
20
|
*/
|
|
20
21
|
export async function findExistingAttachment(connection, projectId) {
|
|
22
|
+
validateSalesforceId(projectId, 'project');
|
|
21
23
|
const result = await connection.query(`SELECT DevopsPipelineId FROM DevopsProjectPipeline WHERE DevopsProjectId = '${projectId}' LIMIT 1`);
|
|
22
24
|
return (result.records ?? [])[0]?.DevopsPipelineId;
|
|
23
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachProject.js","sourceRoot":"","sources":["../../src/utils/attachProject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"attachProject.js","sourceRoot":"","sources":["../../src/utils/attachProject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAetD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,UAAsB,EAAE,SAAiB;IACpF,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CACnC,+EAA+E,SAAS,WAAW,CACpG,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA2B;IAC7D,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC;QACtE,eAAe,EAAE,SAAS;QAC1B,gBAAgB,EAAE,UAAU;KAC7B,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5G,OAAO;QACL,OAAO,EAAE,KAAK;QACd,SAAS;QACT,UAAU;QACV,KAAK,EAAE,aAAa,IAAI,eAAe;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
export type CombineWorkItemsPrepareParams = {
|
|
3
|
+
connection: Connection;
|
|
4
|
+
pipelineId: string;
|
|
5
|
+
parentWorkItemId: string;
|
|
6
|
+
childWorkItemIds: string[];
|
|
7
|
+
sourceStageId: string;
|
|
8
|
+
targetStageId: string;
|
|
9
|
+
};
|
|
10
|
+
export type CombineWorkItemsPrepareResult = {
|
|
11
|
+
success: boolean;
|
|
12
|
+
requestToken: string | null;
|
|
13
|
+
errorCode: string | null;
|
|
14
|
+
errorMessage: string | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Prepares work items to be combined for custom promotion.
|
|
18
|
+
* POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote/combine/prepare
|
|
19
|
+
*/
|
|
20
|
+
export declare function combineWorkItemsPrepare(params: CombineWorkItemsPrepareParams): Promise<CombineWorkItemsPrepareResult>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Prepares work items to be combined for custom promotion.
|
|
18
|
+
* POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote/combine/prepare
|
|
19
|
+
*/
|
|
20
|
+
export async function combineWorkItemsPrepare(params) {
|
|
21
|
+
const { connection, pipelineId, parentWorkItemId, childWorkItemIds, sourceStageId, targetStageId } = params;
|
|
22
|
+
const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/promote/combine/prepare`;
|
|
23
|
+
const body = JSON.stringify({
|
|
24
|
+
parentWorkitemId: parentWorkItemId,
|
|
25
|
+
childWorkitemsId: childWorkItemIds,
|
|
26
|
+
sourceStageId,
|
|
27
|
+
targetStageId,
|
|
28
|
+
});
|
|
29
|
+
const data = await connection.request({
|
|
30
|
+
method: 'POST',
|
|
31
|
+
url: path,
|
|
32
|
+
body,
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
success: data.success ?? true,
|
|
37
|
+
requestToken: data.requestToken ?? null,
|
|
38
|
+
errorCode: data.errorCode ?? null,
|
|
39
|
+
errorMessage: data.errorMessage ?? null,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=combineWorkItems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combineWorkItems.js","sourceRoot":"","sources":["../../src/utils/combineWorkItems.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA2BH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAqC;IAErC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAE5G,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,0BAA0B,CAAC;IAC5H,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,gBAAgB,EAAE,gBAAgB;QAClC,gBAAgB,EAAE,gBAAgB;QAClC,aAAa;QACb,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAkC;QACrE,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI;QACJ,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;QACvC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -12,7 +12,8 @@ export type CreatePipelineParams = {
|
|
|
12
12
|
repoType: string;
|
|
13
13
|
createRepo?: boolean;
|
|
14
14
|
repoOwner?: string;
|
|
15
|
-
|
|
15
|
+
bitbucketWorkspace?: string;
|
|
16
|
+
bitbucketProjectKey?: string;
|
|
16
17
|
};
|
|
17
18
|
export type CreatePipelineResult = {
|
|
18
19
|
success: boolean;
|
|
@@ -27,6 +28,18 @@ export type CreatePipelineResult = {
|
|
|
27
28
|
* Detects repo type from a URL. Returns 'github' or 'bitbucket', or undefined.
|
|
28
29
|
*/
|
|
29
30
|
export declare function detectRepoType(repoUrl: string): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Validates that a GitHub owner (org or user) exists.
|
|
33
|
+
* Primary: uses `gh api` which handles keyring-based auth automatically.
|
|
34
|
+
* Fallback: direct GitHub API call with token (for environments without gh CLI).
|
|
35
|
+
* Skips validation silently when neither mechanism can authenticate, so we
|
|
36
|
+
* don't block the command when the check itself is unavailable.
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateGitHubOwner(owner: string, token?: string, fetchFn?: typeof fetch): Promise<void>;
|
|
39
|
+
export declare class GitHubOwnerNotFoundError extends Error {
|
|
40
|
+
readonly owner: string;
|
|
41
|
+
constructor(owner: string);
|
|
42
|
+
}
|
|
30
43
|
/**
|
|
31
44
|
* Creates a new DevOps Center pipeline via the Connect API.
|
|
32
45
|
* POST /services/data/v{version}/connect/devops/pipelines
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
16
17
|
const DEFAULT_STAGES = [{ name: 'Integration' }, { name: 'UAT' }, { name: 'Staging' }, { name: 'Production' }];
|
|
17
18
|
/**
|
|
18
19
|
* Detects repo type from a URL. Returns 'github' or 'bitbucket', or undefined.
|
|
@@ -25,12 +26,55 @@ export function detectRepoType(repoUrl) {
|
|
|
25
26
|
return 'bitbucket';
|
|
26
27
|
return undefined;
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Validates that a GitHub owner (org or user) exists.
|
|
31
|
+
* Primary: uses `gh api` which handles keyring-based auth automatically.
|
|
32
|
+
* Fallback: direct GitHub API call with token (for environments without gh CLI).
|
|
33
|
+
* Skips validation silently when neither mechanism can authenticate, so we
|
|
34
|
+
* don't block the command when the check itself is unavailable.
|
|
35
|
+
*/
|
|
36
|
+
export async function validateGitHubOwner(owner, token, fetchFn = fetch) {
|
|
37
|
+
try {
|
|
38
|
+
execSync(`gh api users/${encodeURIComponent(owner)}`, {
|
|
39
|
+
encoding: 'utf-8',
|
|
40
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
const stderr = String(e.stderr ?? '');
|
|
46
|
+
const stdout = String(e.stdout ?? '');
|
|
47
|
+
if (stderr.includes('404') || stdout.includes('"Not Found"')) {
|
|
48
|
+
throw new GitHubOwnerNotFoundError(owner);
|
|
49
|
+
}
|
|
50
|
+
// gh not available or not authenticated — fall through to token-based check
|
|
51
|
+
}
|
|
52
|
+
if (!token)
|
|
53
|
+
return;
|
|
54
|
+
const response = await fetchFn(`https://api.github.com/users/${encodeURIComponent(owner)}`, {
|
|
55
|
+
headers: {
|
|
56
|
+
Accept: 'application/vnd.github+json',
|
|
57
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
58
|
+
Authorization: `Bearer ${token}`,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
if (response.status === 404)
|
|
62
|
+
throw new GitHubOwnerNotFoundError(owner);
|
|
63
|
+
// 403 or other non-404: skip validation
|
|
64
|
+
}
|
|
65
|
+
export class GitHubOwnerNotFoundError extends Error {
|
|
66
|
+
owner;
|
|
67
|
+
constructor(owner) {
|
|
68
|
+
super(`GitHub owner "${owner}" does not exist`);
|
|
69
|
+
this.owner = owner;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
28
72
|
/**
|
|
29
73
|
* Creates a new DevOps Center pipeline via the Connect API.
|
|
30
74
|
* POST /services/data/v{version}/connect/devops/pipelines
|
|
31
75
|
*/
|
|
32
76
|
export async function createPipeline(params) {
|
|
33
|
-
const { connection, name, description, repo, repoType, createRepo, repoOwner,
|
|
77
|
+
const { connection, name, description, repo, repoType, createRepo, repoOwner, bitbucketWorkspace, bitbucketProjectKey, } = params;
|
|
34
78
|
const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines`;
|
|
35
79
|
const payload = {
|
|
36
80
|
name,
|
|
@@ -40,14 +84,16 @@ export async function createPipeline(params) {
|
|
|
40
84
|
if (createRepo) {
|
|
41
85
|
payload.createVcsRepo = true;
|
|
42
86
|
payload.vcsRepoName = repo;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
providerInfo.bitbucketProject = bitbucketProject;
|
|
87
|
+
if (repoType === 'bitbucket') {
|
|
88
|
+
const providerInfo = { bitbucketWorkspace: bitbucketWorkspace };
|
|
89
|
+
if (bitbucketProjectKey) {
|
|
90
|
+
providerInfo.bitbucketProjectKey = bitbucketProjectKey;
|
|
48
91
|
}
|
|
49
92
|
payload.repoProviderInfo = JSON.stringify(providerInfo);
|
|
50
93
|
}
|
|
94
|
+
else {
|
|
95
|
+
payload.vcsRepoOwner = repoOwner;
|
|
96
|
+
}
|
|
51
97
|
}
|
|
52
98
|
else {
|
|
53
99
|
payload.vcsRepoUrl = repo;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPipeline.js","sourceRoot":"","sources":["../../src/utils/createPipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"createPipeline.js","sourceRoot":"","sources":["../../src/utils/createPipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/utils/createProject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA2B;IAC7D,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;QAC9D,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,WAAW,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/utils/createProject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA2B;IAC7D,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;QAC9D,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,WAAW,IAAI,IAAI;QAChC,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,MAAM,CAAC,EAAE;YACpB,IAAI;YACJ,WAAW,EAAE,WAAW,IAAI,SAAS;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5G,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,aAAa,IAAI,eAAe;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -6,32 +6,18 @@ export type WorkItemDetail = {
|
|
|
6
6
|
branchName?: string;
|
|
7
7
|
targetBranch?: string;
|
|
8
8
|
projectId: string;
|
|
9
|
-
repoOwner?: string;
|
|
10
|
-
repoName?: string;
|
|
11
9
|
provider?: string;
|
|
12
10
|
};
|
|
13
|
-
export type CreatePullRequestParams = {
|
|
14
|
-
owner: string;
|
|
15
|
-
repo: string;
|
|
16
|
-
head: string;
|
|
17
|
-
base: string;
|
|
18
|
-
title: string;
|
|
19
|
-
body?: string;
|
|
20
|
-
provider: string;
|
|
21
|
-
token: string;
|
|
22
|
-
};
|
|
23
11
|
export type CreatePullRequestResult = {
|
|
24
12
|
success: boolean;
|
|
25
13
|
workItemName?: string;
|
|
26
|
-
title?: string;
|
|
27
14
|
url?: string;
|
|
28
15
|
sourceBranch?: string;
|
|
29
16
|
targetBranch?: string;
|
|
30
17
|
error?: string;
|
|
31
18
|
};
|
|
32
19
|
/**
|
|
33
|
-
* Queries a work item (by Name or Id) and resolves
|
|
34
|
-
* to create a pull request: branch, repo, owner, provider, and target branch.
|
|
20
|
+
* Queries a work item (by Name or Id) and resolves info needed to create a pull request.
|
|
35
21
|
*/
|
|
36
22
|
export declare function fetchWorkItemDetail(connection: Connection, filter: {
|
|
37
23
|
name: string;
|
|
@@ -39,11 +25,13 @@ export declare function fetchWorkItemDetail(connection: Connection, filter: {
|
|
|
39
25
|
id: string;
|
|
40
26
|
}): Promise<WorkItemDetail>;
|
|
41
27
|
/**
|
|
42
|
-
* Creates a pull request
|
|
28
|
+
* Creates a pull request via the Salesforce Connect API.
|
|
29
|
+
* POST /connect/devops/workItems/{workItemId}/review
|
|
30
|
+
* Salesforce handles VCS authentication and workspace resolution.
|
|
43
31
|
*/
|
|
44
|
-
export declare function createPullRequest(
|
|
32
|
+
export declare function createPullRequest(connection: Connection, workItemId: string): Promise<CreatePullRequestResult>;
|
|
45
33
|
/**
|
|
46
|
-
* Attempts to resolve a
|
|
47
|
-
*
|
|
34
|
+
* Attempts to resolve a GitHub authentication token from the environment or the gh CLI.
|
|
35
|
+
* Used by pipeline create for pre-flight owner validation.
|
|
48
36
|
*/
|
|
49
37
|
export declare function resolveGitHubToken(): Promise<string | undefined>;
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
16
17
|
import { getPipelineIdForProject, fetchPipelineStages, computeFirstStageId, findStageById, getBranchNameFromStage, resolveTargetStageId, } from './pipelineUtils.js';
|
|
18
|
+
import { escapeSOQL, validateSalesforceId } from './soqlUtils.js';
|
|
17
19
|
function normalizeProvider(provider) {
|
|
18
20
|
if (!provider)
|
|
19
21
|
return undefined;
|
|
@@ -22,52 +24,14 @@ function normalizeProvider(provider) {
|
|
|
22
24
|
return 'bitbucket';
|
|
23
25
|
return normalized;
|
|
24
26
|
}
|
|
25
|
-
function providerToVcsType(provider) {
|
|
26
|
-
const normalized = normalizeProvider(provider);
|
|
27
|
-
if (normalized === 'github')
|
|
28
|
-
return 'GITHUB';
|
|
29
|
-
if (normalized === 'bitbucket')
|
|
30
|
-
return 'BITBUCKET';
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
function extractOwnerFromVcsPayload(payload) {
|
|
34
|
-
if (!payload)
|
|
35
|
-
return undefined;
|
|
36
|
-
if (typeof payload === 'string')
|
|
37
|
-
return payload.trim() || undefined;
|
|
38
|
-
const obj = payload;
|
|
39
|
-
if (typeof obj.owner === 'string' && obj.owner.trim())
|
|
40
|
-
return obj.owner.trim();
|
|
41
|
-
const list = (obj.owners ?? obj.items ?? obj.records);
|
|
42
|
-
if (Array.isArray(list)) {
|
|
43
|
-
for (const candidate of list) {
|
|
44
|
-
if (typeof candidate === 'string' && candidate.trim())
|
|
45
|
-
return candidate.trim();
|
|
46
|
-
if (candidate && typeof candidate === 'object') {
|
|
47
|
-
const ownerVal = candidate.owner;
|
|
48
|
-
if (typeof ownerVal === 'string' && ownerVal.trim())
|
|
49
|
-
return ownerVal.trim();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
async function fetchOwnerByVcsType(connection, vcsType) {
|
|
56
|
-
const path = `/services/data/v${connection.getApiVersion()}/connect/devops/vcs/${vcsType}`;
|
|
57
|
-
const response = await connection.request({ method: 'GET', url: path });
|
|
58
|
-
return extractOwnerFromVcsPayload(response);
|
|
59
|
-
}
|
|
60
27
|
/**
|
|
61
|
-
* Queries a work item (by Name or Id) and resolves
|
|
62
|
-
* to create a pull request: branch, repo, owner, provider, and target branch.
|
|
28
|
+
* Queries a work item (by Name or Id) and resolves info needed to create a pull request.
|
|
63
29
|
*/
|
|
64
30
|
export async function fetchWorkItemDetail(connection, filter) {
|
|
65
|
-
const whereClause = 'name' in filter ? `Name = '${filter.name}'` : `Id = '${filter.id}'`;
|
|
31
|
+
const whereClause = 'name' in filter ? `Name = '${escapeSOQL(filter.name)}'` : `Id = '${validateSalesforceId(filter.id, 'work item')}'`;
|
|
66
32
|
const identifier = 'name' in filter ? filter.name : filter.id;
|
|
67
33
|
const result = await connection.query(`SELECT Id, Name, Subject, DevopsProjectId, DevopsPipelineStageId,
|
|
68
34
|
SourceCodeRepositoryBranch.Name,
|
|
69
|
-
SourceCodeRepositoryBranch.SourceCodeRepository.Name,
|
|
70
|
-
SourceCodeRepositoryBranch.SourceCodeRepository.RepositoryOwner,
|
|
71
35
|
SourceCodeRepositoryBranch.SourceCodeRepository.Provider
|
|
72
36
|
FROM WorkItem
|
|
73
37
|
WHERE ${whereClause}
|
|
@@ -77,24 +41,12 @@ export async function fetchWorkItemDetail(connection, filter) {
|
|
|
77
41
|
throw new Error(`Work item '${identifier}' not found.`);
|
|
78
42
|
}
|
|
79
43
|
const provider = normalizeProvider(record.SourceCodeRepositoryBranch?.SourceCodeRepository?.Provider);
|
|
80
|
-
let repoOwner = record.SourceCodeRepositoryBranch?.SourceCodeRepository?.RepositoryOwner ?? undefined;
|
|
81
|
-
const vcsType = providerToVcsType(provider);
|
|
82
|
-
if (vcsType && !repoOwner) {
|
|
83
|
-
try {
|
|
84
|
-
repoOwner = (await fetchOwnerByVcsType(connection, vcsType)) ?? undefined;
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// owner lookup is best-effort
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
44
|
const detail = {
|
|
91
45
|
workItemId: record.Id,
|
|
92
46
|
workItemName: record.Name,
|
|
93
47
|
subject: record.Subject ?? '',
|
|
94
48
|
branchName: record.SourceCodeRepositoryBranch?.Name ?? undefined,
|
|
95
49
|
projectId: record.DevopsProjectId,
|
|
96
|
-
repoOwner,
|
|
97
|
-
repoName: record.SourceCodeRepositoryBranch?.SourceCodeRepository?.Name ?? undefined,
|
|
98
50
|
provider,
|
|
99
51
|
};
|
|
100
52
|
const pipelineId = await getPipelineIdForProject(connection, record.DevopsProjectId);
|
|
@@ -110,95 +62,72 @@ export async function fetchWorkItemDetail(connection, filter) {
|
|
|
110
62
|
}
|
|
111
63
|
return detail;
|
|
112
64
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
65
|
+
function extractPrError(response) {
|
|
66
|
+
const raw = String(response.errorMessage ?? response.error ?? response.message ?? 'Pull request creation failed');
|
|
67
|
+
// Try to extract inner VCS error from "REVIEW_CREATION_FAILED:Failed to create pull request: ..."
|
|
68
|
+
const innerMatch = raw.match(/Failed to create pull request:\s*(.+)/s);
|
|
69
|
+
const inner = innerMatch ? innerMatch[1].trim() : raw;
|
|
70
|
+
// Try to parse JSON error body from named credential callout responses
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(inner);
|
|
73
|
+
const msg = parsed?.error?.message ?? parsed?.message;
|
|
74
|
+
if (msg)
|
|
75
|
+
return String(msg);
|
|
120
76
|
}
|
|
121
|
-
|
|
122
|
-
|
|
77
|
+
catch {
|
|
78
|
+
// not JSON, use as-is
|
|
123
79
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
async function createGitHubPullRequest(params) {
|
|
127
|
-
const { owner, repo, head, base, title, body, token } = params;
|
|
128
|
-
const url = `https://api.github.com/repos/${owner}/${repo}/pulls`;
|
|
129
|
-
const response = await fetch(url, {
|
|
130
|
-
method: 'POST',
|
|
131
|
-
headers: {
|
|
132
|
-
Authorization: `Bearer ${token}`,
|
|
133
|
-
Accept: 'application/vnd.github+json',
|
|
134
|
-
'Content-Type': 'application/json',
|
|
135
|
-
'X-GitHub-Api-Version': '2022-11-28',
|
|
136
|
-
},
|
|
137
|
-
body: JSON.stringify({ title, body: body ?? '', head, base }),
|
|
138
|
-
});
|
|
139
|
-
const data = (await response.json());
|
|
140
|
-
if (!response.ok) {
|
|
141
|
-
const errors = Array.isArray(data.errors)
|
|
142
|
-
? data.errors.map((e) => e.message ?? JSON.stringify(e)).join('; ')
|
|
143
|
-
: undefined;
|
|
144
|
-
const msg = data.message ?? `HTTP ${response.status}`;
|
|
145
|
-
throw new Error(errors ? `${msg}: ${errors}` : msg);
|
|
80
|
+
if (inner.includes('no changes')) {
|
|
81
|
+
return 'The branch has no commits ahead of the target branch. Push your changes and try again.';
|
|
146
82
|
}
|
|
147
|
-
return
|
|
148
|
-
success: true,
|
|
149
|
-
title: data.title,
|
|
150
|
-
url: data.html_url,
|
|
151
|
-
sourceBranch: head,
|
|
152
|
-
targetBranch: base,
|
|
153
|
-
};
|
|
83
|
+
return inner;
|
|
154
84
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
})
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Creates a pull request via the Salesforce Connect API.
|
|
87
|
+
* POST /connect/devops/workItems/{workItemId}/review
|
|
88
|
+
* Salesforce handles VCS authentication and workspace resolution.
|
|
89
|
+
*/
|
|
90
|
+
export async function createPullRequest(connection, workItemId) {
|
|
91
|
+
const path = `/services/data/v${connection.getApiVersion()}/connect/devops/workItems/${workItemId}/review`;
|
|
92
|
+
let response;
|
|
93
|
+
try {
|
|
94
|
+
response = await connection.request({
|
|
95
|
+
method: 'POST',
|
|
96
|
+
url: path,
|
|
97
|
+
body: JSON.stringify({}),
|
|
98
|
+
headers: { 'Content-Type': 'application/json' },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
const raw = e instanceof Error ? e.message : String(e);
|
|
103
|
+
throw new Error(extractPrError({ errorMessage: raw }));
|
|
104
|
+
}
|
|
105
|
+
const isError = response.status === 'Error' || response.success === false || !!response.errorMessage;
|
|
106
|
+
if (isError) {
|
|
107
|
+
throw new Error(extractPrError(response));
|
|
175
108
|
}
|
|
176
|
-
const links = data.links;
|
|
177
109
|
return {
|
|
178
110
|
success: true,
|
|
179
|
-
|
|
180
|
-
url: links?.html?.href ?? data.url ?? '',
|
|
181
|
-
sourceBranch: head,
|
|
182
|
-
targetBranch: base,
|
|
111
|
+
url: response.reviewUrl,
|
|
183
112
|
};
|
|
184
113
|
}
|
|
185
114
|
/**
|
|
186
|
-
* Attempts to resolve a
|
|
187
|
-
*
|
|
115
|
+
* Attempts to resolve a GitHub authentication token from the environment or the gh CLI.
|
|
116
|
+
* Used by pipeline create for pre-flight owner validation.
|
|
188
117
|
*/
|
|
189
|
-
export
|
|
118
|
+
export function resolveGitHubToken() {
|
|
190
119
|
const envToken = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
|
|
191
120
|
if (envToken)
|
|
192
|
-
return envToken;
|
|
121
|
+
return Promise.resolve(envToken);
|
|
193
122
|
try {
|
|
194
|
-
|
|
123
|
+
// execSync with a fixed string — no user input, no injection risk
|
|
195
124
|
const token = execSync('gh auth token', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
196
125
|
if (token)
|
|
197
|
-
return token;
|
|
126
|
+
return Promise.resolve(token);
|
|
198
127
|
}
|
|
199
128
|
catch {
|
|
200
129
|
// gh CLI not installed or not authenticated
|
|
201
130
|
}
|
|
202
|
-
return undefined;
|
|
131
|
+
return Promise.resolve(undefined);
|
|
203
132
|
}
|
|
204
133
|
//# sourceMappingURL=createPullRequest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPullRequest.js","sourceRoot":"","sources":["../../src/utils/createPullRequest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"createPullRequest.js","sourceRoot":"","sources":["../../src/utils/createPullRequest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
export type DeletePipelineStageResult = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
stageId?: string;
|
|
5
|
+
pipelineId?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Deletes a pipeline stage and re-links any predecessor stage so the chain stays intact.
|
|
10
|
+
* If stage B sits between A→B→C, deleting B updates A's NextStageId to C before the delete.
|
|
11
|
+
*/
|
|
12
|
+
export declare function deletePipelineStage(connection: Connection, pipelineId: string, stageId: string): Promise<DeletePipelineStageResult>;
|