@salesforce/afv-skills 1.34.0 → 1.35.0
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/package.json +1 -1
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +239 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +21 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +90 -0
- package/skills/automation-sandbox-post-copy-config-generate/examples/sample_sop_excerpt.md +31 -0
- package/skills/automation-sandbox-post-copy-config-generate/examples/sample_sop_to_config.json +50 -0
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +76 -0
- package/skills/automation-sandbox-post-copy-config-generate/references/sop_parsing_patterns.md +157 -0
- package/skills/automation-sandbox-post-copy-config-generate/references/source_format_handling.md +230 -0
- package/skills/dx-apexguru-scan/SKILL.md +403 -0
- package/skills/dx-apexguru-scan/examples/README.md +54 -0
- package/skills/dx-apexguru-scan/examples/sample-decoded-summary.json +176 -0
- package/skills/dx-apexguru-scan/examples/sample-full-no-runtime-response.json +26 -0
- package/skills/dx-apexguru-scan/examples/sample-succeeded-response.json +15 -0
- package/skills/dx-apexguru-scan/references/api-reference.md +81 -0
- package/skills/dx-apexguru-scan/references/authentication.md +134 -0
- package/skills/dx-apexguru-scan/references/error-handling.md +56 -0
- package/skills/dx-apexguru-scan/references/violation-catalog.md +28 -0
- package/skills/dx-apexguru-scan/scripts/build-zip.sh +87 -0
- package/skills/dx-apexguru-scan/scripts/decode-report.js +389 -0
- package/skills/dx-apexguru-scan/scripts/resolve-token.sh +151 -0
- package/skills/dx-apexguru-scan/scripts/run-scan.sh +153 -0
- package/skills/dx-apexguru-scan/scripts/scan.sh +96 -0
- package/skills/dx-apexguru-scan/scripts/validate-token.js +121 -0
- package/skills/dx-devops-pipeline-manage/SKILL.md +263 -0
- package/skills/dx-devops-pipeline-manage/examples/common-workflows.md +177 -0
- package/skills/dx-devops-pipeline-manage/references/cli-commands.md +298 -0
- package/skills/dx-devops-pipeline-manage/references/parsing-patterns.md +134 -0
- package/skills/dx-devops-pipeline-manage/scripts/check-activation-ready.sh +34 -0
- package/skills/dx-devops-pipeline-manage/scripts/validate-org-type.sh +17 -0
- package/skills/dx-devops-pipeline-manage/scripts/verify-operation.sh +82 -0
- package/skills/dx-devops-promote/SKILL.md +214 -0
- package/skills/dx-devops-promote/examples/promotion-workflows.md +212 -0
- package/skills/dx-devops-promote/references/cli-commands.md +303 -0
- package/skills/experience-lwc-base-components-integrate/SKILL.md +176 -0
- package/skills/experience-lwc-base-components-integrate/references/lbc-expert-guidance.md +127 -0
- package/skills/experience-lwc-base-components-integrate/references/lightning-component-index.md +179 -0
- package/skills/experience-lwc-base-components-integrate/references/lightning-components.md +5429 -0
- package/skills/experience-lwc-base-components-integrate/scripts/extract-component-docs.sh +61 -0
- package/skills/experience-lwc-rtl-validate/SKILL.md +149 -0
- package/skills/experience-lwc-rtl-validate/references/rtl-expert.md +892 -0
- package/skills/experience-lwc-rtl-validate/scripts/scan-rtl-css.sh +206 -0
- package/skills/experience-lwc-typescript-migrate/SKILL.md +207 -0
- package/skills/experience-lwc-typescript-migrate/assets/dts-template.ts +15 -0
- package/skills/experience-lwc-typescript-migrate/assets/type-patterns.ts +44 -0
- package/skills/experience-lwc-typescript-migrate/scripts/find-consumers.sh +128 -0
- package/skills/experience-ui-bundle-localize/SKILL.md +323 -0
- package/skills/experience-ui-bundle-localize/references/gotchas.md +249 -0
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +169 -0
- package/skills/experience-ui-bundle-localize/references/interpolation.md +311 -0
- package/skills/experience-ui-bundle-localize/references/label-xml.md +282 -0
- package/skills/experience-ui-bundle-localize/references/verifying.md +219 -0
- package/skills/experience-ui-bundle-localize/scripts/check-i18n-wired.sh +195 -0
- package/skills/experience-ui-bundle-localize/scripts/check-manifest-registered.sh +100 -0
- package/skills/experience-ui-bundle-localize/scripts/check-org-api-version.sh +40 -0
- package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +57 -0
- package/skills/platform-custom-lightning-type-generate/SKILL.md +3 -0
- package/skills/platform-custom-lightning-type-generate/assets/primitive-types-and-constraints.md +1 -1
- package/skills/platform-mcp-tool-widget-coordinate/SKILL.md +250 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/action-name-source-prompt.md +74 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/apex-invocable-source-prompt.md +90 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-source-prompt.md +191 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/pasted-tool-output-prompt.md +85 -0
- package/skills/platform-mcp-tool-widget-coordinate/references/build-plan-format.md +74 -0
- package/skills/platform-mcp-tool-widget-coordinate/references/mcp-tool-output-discovery.md +184 -0
- package/skills/platform-mcp-tool-widget-coordinate/references/two-clt-modeling.md +128 -0
- package/skills/platform-mcp-tool-widget-coordinate/references/validation-gates.md +181 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Common Pipeline Management Workflows
|
|
2
|
+
|
|
3
|
+
Real-world examples of typical pipeline operations in DevOps Center autonomous release scenarios. All commands use `--json`; add `--target-org <alias>` when not relying on the default org.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Workflow 1: End-to-End Pipeline Setup — Create, Stage, Bind Environments, Activate
|
|
8
|
+
|
|
9
|
+
**User request:** "Set up a release pipeline on repo myorg/myrepo with Integration → UAT → Production and activate it"
|
|
10
|
+
|
|
11
|
+
**Steps:**
|
|
12
|
+
|
|
13
|
+
1. **Create the pipeline** against the existing repo, then resolve its ID from the list:
|
|
14
|
+
```bash
|
|
15
|
+
sf devops pipeline create \
|
|
16
|
+
--name "Release Pipeline" \
|
|
17
|
+
--repo https://github.com/myorg/myrepo \
|
|
18
|
+
--json
|
|
19
|
+
PIPELINE_ID=$(sf devops pipeline list --json | \
|
|
20
|
+
jq -r '.result.pipelines[] | select(.Name == "Release Pipeline") | .Id' | head -n1)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. **Inspect the initial stages** (a new pipeline always starts with at least one seeded stage):
|
|
24
|
+
```bash
|
|
25
|
+
sf devops pipeline get --pipeline-id "$PIPELINE_ID" --json | \
|
|
26
|
+
jq -r '.result.stages[] | "\(.name) (\(.id)) -> next: \(.nextStageId)"'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **Add stages in promotion order.** `stage add` inserts a stage *before* `--next-stage-id`, so anchor each new stage to the one that should follow it. To build Integration → UAT → Production, add Production first (or anchor to the terminal stage), then insert UAT before Production, then Integration before UAT:
|
|
30
|
+
```bash
|
|
31
|
+
# Assume Production stage id is 0Xc...PROD (from step 2 or a prior add)
|
|
32
|
+
sf devops pipeline stage add --pipeline-id "$PIPELINE_ID" \
|
|
33
|
+
--name "UAT" --next-stage-id 0XcPROD --json
|
|
34
|
+
sf devops pipeline stage add --pipeline-id "$PIPELINE_ID" \
|
|
35
|
+
--name "Integration" --next-stage-id 0XcUAT --json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
4. **Bind an environment to each stage** (re-fetch stage IDs with `pipeline get`). In CI, add `--no-browser`:
|
|
39
|
+
```bash
|
|
40
|
+
sf devops stage environment add --pipeline-id "$PIPELINE_ID" \
|
|
41
|
+
--stage-id 0XcINT --environment-name integration-org --org-type Sandbox --no-browser --json
|
|
42
|
+
sf devops stage environment add --pipeline-id "$PIPELINE_ID" \
|
|
43
|
+
--stage-id 0XcUAT --environment-name uat-org --org-type Sandbox --no-browser --json
|
|
44
|
+
sf devops stage environment add --pipeline-id "$PIPELINE_ID" \
|
|
45
|
+
--stage-id 0XcPROD --environment-name prod-org --org-type Production --no-browser --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
5. **Activate** once every stage has an environment:
|
|
49
|
+
```bash
|
|
50
|
+
sf devops pipeline update --pipeline-id "$PIPELINE_ID" --activate --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
6. **Verify** the final shape:
|
|
54
|
+
```bash
|
|
55
|
+
sf devops pipeline get --pipeline-id "$PIPELINE_ID" --json | \
|
|
56
|
+
jq -r '.result | "\(.name) [\(.isActive)]: \([.stages[].name] | join(", "))"'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Report:** "Release Pipeline created and activated: Integration → UAT → Production, environments bound."
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Workflow 2: Insert a Staging Stage Before Production
|
|
64
|
+
|
|
65
|
+
**User request:** "Add a Staging stage between UAT and Production on the Release Pipeline"
|
|
66
|
+
|
|
67
|
+
**Steps:**
|
|
68
|
+
|
|
69
|
+
1. **Find the pipeline and stage IDs**:
|
|
70
|
+
```bash
|
|
71
|
+
PIPELINE_ID=$(sf devops pipeline list --json | \
|
|
72
|
+
jq -r '.result.pipelines[] | select(.Name == "Release Pipeline") | .Id' | head -n1)
|
|
73
|
+
sf devops pipeline get --pipeline-id "$PIPELINE_ID" --json | \
|
|
74
|
+
jq -r '.result.stages[] | "\(.name) (\(.id)) -> next: \(.nextStageId)"'
|
|
75
|
+
# Integration (0XcINT) -> next: 0XcUAT
|
|
76
|
+
# UAT (0XcUAT) -> next: 0XcPROD
|
|
77
|
+
# Production (0XcPROD) -> next: null
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
2. **Insert Staging before Production**:
|
|
81
|
+
```bash
|
|
82
|
+
sf devops pipeline stage add --pipeline-id "$PIPELINE_ID" \
|
|
83
|
+
--name "Staging" --next-stage-id 0XcPROD --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
3. **Bind the staging environment** (get the new stage ID from `pipeline get`):
|
|
87
|
+
```bash
|
|
88
|
+
sf devops stage environment add --pipeline-id "$PIPELINE_ID" \
|
|
89
|
+
--stage-id 0XcSTG --environment-name staging-org --org-type Sandbox --no-browser --json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
4. **Verify** Staging now sits between UAT and Production.
|
|
93
|
+
|
|
94
|
+
> **Constraint:** This works only if the pipeline is not yet locked. Stages can't be modified after the pipeline is activated and changes have been promoted through it.
|
|
95
|
+
|
|
96
|
+
**Report:** "Staging stage inserted before Production, bound to staging-org."
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Workflow 3: Attach a Project to a Pipeline
|
|
101
|
+
|
|
102
|
+
**User request:** "Connect Project Alpha to the Release Pipeline"
|
|
103
|
+
|
|
104
|
+
**Steps:**
|
|
105
|
+
|
|
106
|
+
1. **Resolve IDs**:
|
|
107
|
+
```bash
|
|
108
|
+
PIPELINE_ID=$(sf devops pipeline list --json | \
|
|
109
|
+
jq -r '.result.pipelines[] | select(.Name == "Release Pipeline") | .Id' | head -n1)
|
|
110
|
+
PROJECT_ID=$(sf devops project list --json | \
|
|
111
|
+
jq -r '.result.projects[] | select(.Name == "Project Alpha") | .Id' | head -n1)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
2. **Attach**:
|
|
115
|
+
```bash
|
|
116
|
+
sf devops pipeline project add --pipeline-id "$PIPELINE_ID" --project-id "$PROJECT_ID" --json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
3. **Verify** via `pipeline get` that Project Alpha appears in `.result.connectedProjects[]`.
|
|
120
|
+
|
|
121
|
+
> **Constraint:** A project attaches to only one pipeline. If attach fails with "already attached," detach it from the other pipeline first: `sf devops pipeline project delete --pipeline-id <other> --project-id "$PROJECT_ID" --json`.
|
|
122
|
+
|
|
123
|
+
**Report:** "Project Alpha attached to Release Pipeline."
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Workflow 4: Rename and Deactivate a Pipeline
|
|
128
|
+
|
|
129
|
+
**User request:** "Deactivate the Release Pipeline and rename it to Legacy Pipeline"
|
|
130
|
+
|
|
131
|
+
**Steps:**
|
|
132
|
+
|
|
133
|
+
1. **Combine deactivate + rename** in one command:
|
|
134
|
+
```bash
|
|
135
|
+
sf devops pipeline update --pipeline-id 0XB000000000001 \
|
|
136
|
+
--deactivate --name "Legacy Pipeline" --json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
2. **Verify** via `pipeline get` that `.result.isActive` is false and the name updated.
|
|
140
|
+
|
|
141
|
+
**Report:** "Pipeline deactivated and renamed to 'Legacy Pipeline'."
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Workflow 5: Idempotent Pipeline Setup (Safe Re-Run in CI)
|
|
146
|
+
|
|
147
|
+
**User request:** "Ensure the Release Pipeline exists — runs on every CI job"
|
|
148
|
+
|
|
149
|
+
**Steps:**
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
PIPELINE_NAME="Release Pipeline"
|
|
153
|
+
|
|
154
|
+
EXISTING_ID=$(sf devops pipeline list --json | \
|
|
155
|
+
jq -r ".result.pipelines[] | select(.Name == \"$PIPELINE_NAME\") | .Id" | head -n1)
|
|
156
|
+
|
|
157
|
+
if [ -n "$EXISTING_ID" ]; then
|
|
158
|
+
echo "Pipeline already exists: $EXISTING_ID"
|
|
159
|
+
else
|
|
160
|
+
sf devops pipeline create --name "$PIPELINE_NAME" \
|
|
161
|
+
--repo https://github.com/myorg/myrepo --json
|
|
162
|
+
fi
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Report:** either the existing pipeline ID or the newly created one — no duplicate created.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Notes for Autonomous Runs
|
|
170
|
+
|
|
171
|
+
- Confirm org auth with `sf org display --json` before the first command.
|
|
172
|
+
- **Stage IDs come from `sf devops pipeline get`** — always fetch them before `stage add` / `stage update` / `stage delete` / `stage environment add`.
|
|
173
|
+
- `stage add` inserts *before* `--next-stage-id`; plan the anchor stage to get the order you want.
|
|
174
|
+
- `stage environment add` opens a browser OAuth flow — always pass `--no-browser` in CI and complete auth via the printed redirect URL.
|
|
175
|
+
- Finish all stage/environment configuration **before** activating; an active, promoted pipeline locks its stage structure.
|
|
176
|
+
- Deactivate before deleting an environment; the pipeline must be inactive.
|
|
177
|
+
- Treat a same-name create as idempotent — check-before-create and report the existing pipeline.
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# DevOps Center Pipeline CLI Commands Reference
|
|
2
|
+
|
|
3
|
+
Command reference for `sf devops pipeline` and `sf devops stage` — flags and JSON output schemas. For jq parsing snippets, error handling, the idempotent check-before-create pattern, and auth setup, see `references/parsing-patterns.md`.
|
|
4
|
+
|
|
5
|
+
## Command Summary
|
|
6
|
+
|
|
7
|
+
| Command | Purpose | Required Flags |
|
|
8
|
+
|---------|---------|---------------|
|
|
9
|
+
| `sf devops pipeline list` | List all pipelines in the org | `--target-org` |
|
|
10
|
+
| `sf devops pipeline get` | Get one pipeline's stages, repos, and connected projects | `--target-org`, `--pipeline-id` |
|
|
11
|
+
| `sf devops pipeline create` | Create a pipeline linked to a Git repo | `--target-org`, `--name`, `--repo` |
|
|
12
|
+
| `sf devops pipeline update` | Activate / deactivate / rename a pipeline | `--target-org`, `--pipeline-id` |
|
|
13
|
+
| `sf devops pipeline stage add` | Insert an empty stage before another stage | `--target-org`, `--pipeline-id`, `--name`, `--next-stage-id` |
|
|
14
|
+
| `sf devops pipeline stage update` | Rename a stage | `--target-org`, `--pipeline-id`, `--stage-id`, `--name` |
|
|
15
|
+
| `sf devops pipeline stage delete` | Delete a stage (auto-relinks neighbors) | `--target-org`, `--pipeline-id`, `--stage-id` |
|
|
16
|
+
| `sf devops pipeline project add` | Attach a project to a pipeline | `--target-org`, `--pipeline-id`, `--project-id` |
|
|
17
|
+
| `sf devops pipeline project delete` | Detach a project from a pipeline | `--target-org`, `--pipeline-id`, `--project-id` |
|
|
18
|
+
| `sf devops stage environment add` | Add a Salesforce environment to a stage | `--target-org`, `--pipeline-id`, `--stage-id`, `--environment-name`, `--org-type` |
|
|
19
|
+
| `sf devops stage environment delete` | Remove an environment (inactive pipeline only) | `--target-org`, `--pipeline-id`, `--environment-id` |
|
|
20
|
+
|
|
21
|
+
All commands support `--json` for structured output and `--api-version <value>` to override the API version. `--target-org` is not required if the `target-org` config variable is already set.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## List Pipelines
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
sf devops pipeline list --target-org my-devops-org --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Returns all pipelines in the org as **SObject records** under `.result.pipelines[]`, with capitalized fields (`Id`, `Name`, `Description`, `IsActive`). This summary view does **not** include stages or connected projects — use `pipeline get` for those.
|
|
32
|
+
|
|
33
|
+
### JSON Output Schema
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"status": 0,
|
|
38
|
+
"result": {
|
|
39
|
+
"pipelines": [
|
|
40
|
+
{
|
|
41
|
+
"attributes": { "type": "DevopsPipeline", "url": "/services/data/v67.0/sobjects/DevopsPipeline/1PJWt0000007NsjOAE" },
|
|
42
|
+
"Id": "1PJWt0000007NsjOAE",
|
|
43
|
+
"Name": "Release Pipeline",
|
|
44
|
+
"Description": null,
|
|
45
|
+
"IsActive": false
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use `.Id` with `--pipeline-id` in follow-on commands.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Get Pipeline Details
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
sf devops pipeline get --target-org my-devops-org --pipeline-id 0XB000000000001 --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Returns a single pipeline's full detail — its stages, the repo/branch per stage, and connected projects. **This is how you discover stage IDs** needed by `stage add` (`--next-stage-id`), `stage update`/`stage delete` (`--stage-id`), and `stage environment add` (`--stage-id`). Unlike `pipeline list`, `get` uses lowercase camelCase fields (`id`, `name`, `stages`, `connectedProjects`).
|
|
63
|
+
|
|
64
|
+
### JSON Output Schema
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"status": 0,
|
|
69
|
+
"result": {
|
|
70
|
+
"id": "1PJWt000000HLUfOAO",
|
|
71
|
+
"name": "Release Pipeline",
|
|
72
|
+
"description": null,
|
|
73
|
+
"isActive": true,
|
|
74
|
+
"stages": [
|
|
75
|
+
{
|
|
76
|
+
"id": "1QVWt000000G3huOAC",
|
|
77
|
+
"name": "Staging",
|
|
78
|
+
"nextStageId": "1QVWt000000G3htOAC",
|
|
79
|
+
"branchName": "staging",
|
|
80
|
+
"repositoryName": "my-new-rep",
|
|
81
|
+
"repositoryOwner": "ad-shreya",
|
|
82
|
+
"environment": { "id": "1QeWt0000000i13KAA", "name": "cli-stage" }
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "1QVWt000000G3htOAC",
|
|
86
|
+
"name": "Production",
|
|
87
|
+
"nextStageId": null,
|
|
88
|
+
"branchName": "main",
|
|
89
|
+
"repositoryName": "my-new-rep",
|
|
90
|
+
"repositoryOwner": "ad-shreya",
|
|
91
|
+
"environment": { "id": "1QeWt0000000jDFKAY", "name": "Prod 2" }
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"connectedProjects": [ { "id": "1QgWt0000000rabKAA", "name": "Release Project 1" } ],
|
|
95
|
+
"warnings": []
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Stage Ordering — Linked List, Not an Array Index
|
|
101
|
+
|
|
102
|
+
Stages form a **linked list** via `nextStageId`, not a numeric `order` field:
|
|
103
|
+
- Each stage's `nextStageId` points to the stage that follows it in the promotion chain.
|
|
104
|
+
- The **terminal stage** (last, typically Production) has `nextStageId: null`.
|
|
105
|
+
- To insert before a given stage with `stage add`, pass that stage's `id` as `--next-stage-id`.
|
|
106
|
+
|
|
107
|
+
See `references/parsing-patterns.md` for jq snippets that list stage names/IDs, find the terminal stage, and resolve a stage ID by name.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Create Pipeline
|
|
112
|
+
|
|
113
|
+
A pipeline must be linked to a Git repository at creation.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Existing repo — pass the full URL, nothing else
|
|
117
|
+
sf devops pipeline create --target-org my-devops-org --name "Release Pipeline" \
|
|
118
|
+
--repo https://github.com/myorg/myrepo --json
|
|
119
|
+
|
|
120
|
+
# New GitHub repo — requires --repo-owner
|
|
121
|
+
sf devops pipeline create --target-org my-devops-org --name "Release Pipeline" \
|
|
122
|
+
--repo my-new-repo --create-repo --repo-type github --repo-owner myorg --json
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
For a **new Bitbucket repo**, swap the provider flags: `--repo-type bitbucket --bitbucket-workspace myworkspace` (plus optional `--bitbucket-project-key PROJ`) in place of `--repo-type github --repo-owner`. Add `--description "<text>"` to any scenario for a pipeline description.
|
|
126
|
+
|
|
127
|
+
### Required Flags by Scenario
|
|
128
|
+
|
|
129
|
+
The correct flag set depends on whether the repo already exists and, for new repos, on the provider. Always required: `--name` and `--repo`. `--description` is optional in every scenario.
|
|
130
|
+
|
|
131
|
+
| Scenario | Required flags | Must NOT include |
|
|
132
|
+
|----------|---------------|------------------|
|
|
133
|
+
| **Existing repo** (GitHub or Bitbucket) | `--name`, `--repo <url>` | `--create-repo`, `--repo-type`, `--repo-owner`, `--bitbucket-*` |
|
|
134
|
+
| **New GitHub repo** | `--name`, `--repo <name>`, `--create-repo`, `--repo-type github`, `--repo-owner <org-or-user>` | `--bitbucket-workspace`, `--bitbucket-project-key` |
|
|
135
|
+
| **New Bitbucket repo** | `--name`, `--repo <name>`, `--create-repo`, `--repo-type bitbucket`, `--bitbucket-workspace <workspace>` | `--repo-owner` |
|
|
136
|
+
|
|
137
|
+
Per-flag detail:
|
|
138
|
+
|
|
139
|
+
| Flag | Applies to | Notes |
|
|
140
|
+
|------|-----------|-------|
|
|
141
|
+
| `--name` / `-n` | all | Pipeline name (required) |
|
|
142
|
+
| `--repo` / `-r` | all | Existing repo URL, or a repo name when used with `--create-repo` (required) |
|
|
143
|
+
| `--description` / `-d` | all | Pipeline description (optional) |
|
|
144
|
+
| `--create-repo` | new repo only | Create the repo if it doesn't exist |
|
|
145
|
+
| `--repo-type` | new repo only | `github` or `bitbucket` (required when creating a repo) |
|
|
146
|
+
| `--repo-owner` | **GitHub** new repo | Organization or user that owns the repo (required for GitHub create) |
|
|
147
|
+
| `--bitbucket-workspace` | **Bitbucket** new repo | Workspace that owns the repo (required for Bitbucket create) |
|
|
148
|
+
| `--bitbucket-project-key` | Bitbucket new repo | Optional Bitbucket project key |
|
|
149
|
+
| `--stage` / `-s` | all | Name of a pipeline stage, in promotion order. Repeat once per stage. Defaults to Integration, UAT, Staging, Production |
|
|
150
|
+
|
|
151
|
+
> **Provider mismatch fails:** pairing `--repo-owner` with `--repo-type bitbucket`, or `--bitbucket-workspace` with `--repo-type github`, is rejected. Match the provider flag to `--repo-type`.
|
|
152
|
+
|
|
153
|
+
### Custom Stage Names at Create Time
|
|
154
|
+
|
|
155
|
+
By default a new pipeline seeds the stage chain **Integration → UAT → Staging → Production**. To seed a different chain, repeat `--stage` once per stage in promotion order:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
sf devops pipeline create \
|
|
159
|
+
--target-org my-devops-org \
|
|
160
|
+
--name "Release Pipeline" \
|
|
161
|
+
--repo https://github.com/myorg/myrepo \
|
|
162
|
+
--stage Dev --stage QA --stage Prod \
|
|
163
|
+
--json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Seeding stages at create time avoids a separate round of `stage add` / `stage update` calls afterward.
|
|
167
|
+
|
|
168
|
+
After creating, resolve the new pipeline's ID by name from `sf devops pipeline list --json` (see `references/parsing-patterns.md`) — this avoids depending on the exact shape of the create response. A new pipeline always starts with at least one stage (the default chain, or your `--stage` list) — run `sf devops pipeline get` to see the seeded stages, then add or rename stages if you need to adjust the chain.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Update Pipeline (Activate / Deactivate / Rename)
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Activate — requires at least one stage
|
|
176
|
+
sf devops pipeline update --pipeline-id 0XB000000000001 --activate --json
|
|
177
|
+
|
|
178
|
+
# Deactivate
|
|
179
|
+
sf devops pipeline update --pipeline-id 0XB000000000001 --deactivate --json
|
|
180
|
+
|
|
181
|
+
# Rename
|
|
182
|
+
sf devops pipeline update --pipeline-id 0XB000000000001 --name "My Pipeline" --json
|
|
183
|
+
|
|
184
|
+
# Deactivate and rename in one step
|
|
185
|
+
sf devops pipeline update --pipeline-id 0XB000000000001 --deactivate --name "My Pipeline" --json
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
| Flag | Notes |
|
|
189
|
+
|------|-------|
|
|
190
|
+
| `--pipeline-id` | Required — ID of the pipeline to update |
|
|
191
|
+
| `--activate` | Activate the pipeline. Mutually exclusive with `--deactivate` |
|
|
192
|
+
| `--deactivate` | Deactivate the pipeline. Mutually exclusive with `--activate` |
|
|
193
|
+
| `--name` / `-n` | New name for the pipeline. Can be combined with `--deactivate` |
|
|
194
|
+
|
|
195
|
+
- A pipeline must have **at least one stage** before it can be activated.
|
|
196
|
+
- `--activate` and `--deactivate` cannot be used together; `--deactivate` and `--name` may be combined in one command.
|
|
197
|
+
- **You can't modify pipeline stages after you activate and promote changes through it.** Finish all stage/environment configuration before activating.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Add a Stage
|
|
202
|
+
|
|
203
|
+
Inserts an **empty** stage (no branch or environment) immediately before `--next-stage-id`. Configure its environment separately afterward.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Add a Development stage before Integration
|
|
207
|
+
sf devops pipeline stage add \
|
|
208
|
+
--target-org my-devops-org \
|
|
209
|
+
--pipeline-id 0XB000000000001 \
|
|
210
|
+
--name "Development" \
|
|
211
|
+
--next-stage-id 0Xc000000000001 \
|
|
212
|
+
--json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Get the `--next-stage-id` from `sf devops pipeline get`. The new stage is always inserted **immediately before** the anchor stage you pass as `--next-stage-id` — there is no append-to-end flag. To place a stage at a given point in the chain, choose the anchor that should follow it (e.g. anchor to the terminal stage to insert the new stage just before it).
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Rename / Delete a Stage
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# Rename a stage
|
|
223
|
+
sf devops pipeline stage update \
|
|
224
|
+
--pipeline-id 0XB000000000001 \
|
|
225
|
+
--stage-id 0Xc000000000002 \
|
|
226
|
+
--name "QA" \
|
|
227
|
+
--json
|
|
228
|
+
|
|
229
|
+
# Delete a stage — the predecessor auto-relinks to the successor so the chain stays intact
|
|
230
|
+
sf devops pipeline stage delete \
|
|
231
|
+
--pipeline-id 0XB000000000001 \
|
|
232
|
+
--stage-id 0Xc000000000002 \
|
|
233
|
+
--json
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Add an Environment to a Stage
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
sf devops stage environment add \
|
|
242
|
+
--target-org my-devops-org \
|
|
243
|
+
--pipeline-id 0XB000000000001 \
|
|
244
|
+
--stage-id 0Xp000000000001 \
|
|
245
|
+
--environment-name Production_Org \
|
|
246
|
+
--org-type Production \
|
|
247
|
+
--json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
| Flag | Required | Notes |
|
|
251
|
+
|------|----------|-------|
|
|
252
|
+
| `--pipeline-id` | Required | Pipeline containing the stage |
|
|
253
|
+
| `--stage-id` | Required | Target stage (from `pipeline get`) |
|
|
254
|
+
| `--environment-name` / `-e` | Required | Environment name |
|
|
255
|
+
| `--org-type` | Required | Exactly `Production` or `Sandbox` |
|
|
256
|
+
| `--no-browser` | Optional | Don't auto-open a browser for OAuth; prints the redirect URL instead |
|
|
257
|
+
|
|
258
|
+
> **Headless caveat:** This command triggers an OAuth flow and opens a browser by default. In CI or headless runs, pass `--no-browser` and complete authentication via the printed redirect URL.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Delete an Environment from a Stage
|
|
263
|
+
|
|
264
|
+
The pipeline must be **inactive** before you can delete an environment.
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
sf devops stage environment delete \
|
|
268
|
+
--target-org my-devops-org \
|
|
269
|
+
--pipeline-id 0XB000000000001 \
|
|
270
|
+
--environment-id 0Xe000000000001 \
|
|
271
|
+
--json
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
`--pipeline-id` is used to verify the pipeline is inactive before deleting.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Attach / Detach a Project
|
|
279
|
+
|
|
280
|
+
A project can be attached to **only one pipeline**.
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# Attach
|
|
284
|
+
sf devops pipeline project add \
|
|
285
|
+
--target-org my-devops-org \
|
|
286
|
+
--pipeline-id 0XB000000000001 \
|
|
287
|
+
--project-id 0Hn000000000001 \
|
|
288
|
+
--json
|
|
289
|
+
|
|
290
|
+
# Detach — deletes only the junction record; the project itself is not deleted
|
|
291
|
+
sf devops pipeline project delete \
|
|
292
|
+
--target-org my-devops-org \
|
|
293
|
+
--pipeline-id 0XB000000000001 \
|
|
294
|
+
--project-id 0Hn000000000001 \
|
|
295
|
+
--json
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Resolve a project ID from its name via `sf devops project list --json` — see `references/parsing-patterns.md` for the jq snippet.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# DevOps Center Pipeline — Parsing, Errors & Auth
|
|
2
|
+
|
|
3
|
+
jq snippets for parsing `sf devops` JSON output, error-handling reference, the idempotent check-before-create pattern, and authentication requirements. For command flags and JSON schemas, see `references/cli-commands.md`.
|
|
4
|
+
|
|
5
|
+
## Parsing Stage Chains
|
|
6
|
+
|
|
7
|
+
Stages form a linked list via `nextStageId` (see the schema in `references/cli-commands.md`). Use these snippets against `pipeline get`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# List stage names and IDs with their next pointer
|
|
11
|
+
sf devops pipeline get --pipeline-id 1PJWt000000HLUfOAO --json | \
|
|
12
|
+
jq -r '.result.stages[] | "\(.name) (\(.id)) -> next: \(.nextStageId)"'
|
|
13
|
+
|
|
14
|
+
# Find the terminal stage ID (nextStageId is null)
|
|
15
|
+
sf devops pipeline get --pipeline-id 1PJWt000000HLUfOAO --json | \
|
|
16
|
+
jq -r '.result.stages[] | select(.nextStageId == null) | .id'
|
|
17
|
+
|
|
18
|
+
# Find a stage ID by name (e.g. to anchor an insert before "Production")
|
|
19
|
+
sf devops pipeline get --pipeline-id 1PJWt000000HLUfOAO --json | \
|
|
20
|
+
jq -r '.result.stages[] | select(.name == "Production") | .id'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Resolve a Pipeline ID by Name
|
|
26
|
+
|
|
27
|
+
`pipeline list` is the reliable way to turn a pipeline name into an ID (note the `.pipelines[]` wrapper and capitalized `Name`/`Id`):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
PIPELINE_ID=$(sf devops pipeline list --json | \
|
|
31
|
+
jq -r '.result.pipelines[] | select(.Name == "Release Pipeline") | .Id' | head -n1)
|
|
32
|
+
echo "Pipeline: $PIPELINE_ID"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### List Pipelines (name, ID, active state)
|
|
36
|
+
|
|
37
|
+
`pipeline list` does not carry stages — to show the stage chain, feed each ID into `pipeline get`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sf devops pipeline list --json | \
|
|
41
|
+
jq -r '.result.pipelines[] | "\(.Name) [\(.IsActive)] (\(.Id))"'
|
|
42
|
+
# Release Pipeline [true] (1PJWt000000HLUfOAO)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Resolve a Project ID by Name
|
|
48
|
+
|
|
49
|
+
`project list` returns SObject records under `.result.projects[]` with capitalized fields (`Id`, `Name`):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
sf devops project list --json | jq -r '.result.projects[] | "\(.Id): \(.Name)"'
|
|
53
|
+
|
|
54
|
+
# Extract a specific project ID by name
|
|
55
|
+
sf devops project list --json | \
|
|
56
|
+
jq -r '.result.projects[] | select(.Name == "Release Project 1") | .Id'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Idempotent Create (Check-Before-Create)
|
|
62
|
+
|
|
63
|
+
The CLI does not dedupe pipelines. Check for an existing pipeline before creating:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
PIPELINE_NAME="Release Pipeline"
|
|
67
|
+
|
|
68
|
+
EXISTING_ID=$(sf devops pipeline list --json | \
|
|
69
|
+
jq -r ".result.pipelines[] | select(.Name == \"$PIPELINE_NAME\") | .Id" | head -n1)
|
|
70
|
+
|
|
71
|
+
if [ -n "$EXISTING_ID" ]; then
|
|
72
|
+
echo "Pipeline already exists: $EXISTING_ID"
|
|
73
|
+
else
|
|
74
|
+
sf devops pipeline create \
|
|
75
|
+
--name "$PIPELINE_NAME" \
|
|
76
|
+
--repo https://github.com/myorg/myrepo \
|
|
77
|
+
--json
|
|
78
|
+
NEW_ID=$(sf devops pipeline list --json | \
|
|
79
|
+
jq -r ".result.pipelines[] | select(.Name == \"$PIPELINE_NAME\") | .Id" | head -n1)
|
|
80
|
+
echo "Created new pipeline: $NEW_ID"
|
|
81
|
+
fi
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Error Handling
|
|
87
|
+
|
|
88
|
+
**Missing required repo (create):**
|
|
89
|
+
```json
|
|
90
|
+
{ "status": 1, "name": "RequiredFlagsError", "message": "Missing required flag --repo", "exitCode": 1 }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Pipeline not found:**
|
|
94
|
+
```json
|
|
95
|
+
{ "status": 1, "name": "NOT_FOUND", "message": "Pipeline 0XB000000000999 does not exist or is not accessible", "exitCode": 1 }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Activation without a stage:**
|
|
99
|
+
```json
|
|
100
|
+
{ "status": 1, "name": "NO_STAGES", "message": "A pipeline must have at least one stage before you can activate it", "exitCode": 1 }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Environment delete on active pipeline:**
|
|
104
|
+
```json
|
|
105
|
+
{ "status": 1, "name": "PIPELINE_ACTIVE", "message": "The environment must belong to an inactive pipeline", "exitCode": 1 }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Project already attached:**
|
|
109
|
+
```json
|
|
110
|
+
{ "status": 1, "name": "PROJECT_ALREADY_ATTACHED", "message": "You can attach a project to only one pipeline", "exitCode": 1 }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Authentication failure:**
|
|
114
|
+
```json
|
|
115
|
+
{ "status": 1, "name": "NoOrgFound", "message": "No org configuration found for target-org. Run 'sf org login web' to authenticate.", "exitCode": 1 }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> **Note:** Error `name`/`message` strings are representative — match on the non-zero `status` and the substring of `message`, not exact strings.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Authentication Requirements
|
|
123
|
+
|
|
124
|
+
All `sf devops pipeline` / `sf devops stage` commands require:
|
|
125
|
+
|
|
126
|
+
1. **Authenticated org**: `sf org login web` or JWT auth
|
|
127
|
+
2. **DevOps Center enabled**: org must have DOCe provisioned
|
|
128
|
+
3. **Appropriate permissions**: access to the pipeline, its stages, and connected environments
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
sf org display --target-org <alias> --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If auth fails: `sf org login web --set-default --alias <alias>`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Check the deterministic activation prerequisite: a pipeline must have >=1 stage
|
|
3
|
+
# before `sf devops pipeline update --activate` will succeed.
|
|
4
|
+
# Usage: scripts/check-activation-ready.sh <pipeline-id> [target-org-alias]
|
|
5
|
+
# Exits 0 if the pipeline has at least one stage; otherwise prints an actionable
|
|
6
|
+
# error and exits 1. Exits 2 if the pipeline can't be read.
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
PIPELINE_ID="${1:?Usage: check-activation-ready.sh <pipeline-id> [target-org-alias]}"
|
|
11
|
+
TARGET_ORG="${2:-}"
|
|
12
|
+
|
|
13
|
+
ORG_FLAG=()
|
|
14
|
+
[ -n "$TARGET_ORG" ] && ORG_FLAG=(--target-org "$TARGET_ORG")
|
|
15
|
+
|
|
16
|
+
GET_JSON=$(sf devops pipeline get --pipeline-id "$PIPELINE_ID" "${ORG_FLAG[@]+"${ORG_FLAG[@]}"}" --json 2>/dev/null) || {
|
|
17
|
+
echo "ERROR: could not read pipeline '$PIPELINE_ID'. Verify the ID with 'sf devops pipeline list --json' and that the org has DevOps Center enabled." >&2
|
|
18
|
+
exit 2
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
STATUS=$(echo "$GET_JSON" | jq -r '.status // 1')
|
|
22
|
+
if [ "$STATUS" != "0" ]; then
|
|
23
|
+
echo "ERROR: 'pipeline get' returned status $STATUS for '$PIPELINE_ID'." >&2
|
|
24
|
+
exit 2
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
STAGE_COUNT=$(echo "$GET_JSON" | jq -r '(.result.stages // []) | length')
|
|
28
|
+
if [ "$STAGE_COUNT" -ge 1 ]; then
|
|
29
|
+
echo "OK: pipeline '$PIPELINE_ID' has $STAGE_COUNT stage(s) — ready to activate"
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo "ERROR: pipeline '$PIPELINE_ID' has no stages. Add at least one stage (sf devops pipeline stage add ...) before --activate." >&2
|
|
34
|
+
exit 1
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Validate a stage-environment --org-type value against the fixed CLI enum.
|
|
3
|
+
# Usage: scripts/validate-org-type.sh <org-type>
|
|
4
|
+
# Exits 0 if the value is exactly "Production" or "Sandbox"; otherwise prints
|
|
5
|
+
# an actionable error and exits 1.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
ORG_TYPE="${1:-}"
|
|
10
|
+
|
|
11
|
+
if [ "$ORG_TYPE" = "Production" ] || [ "$ORG_TYPE" = "Sandbox" ]; then
|
|
12
|
+
echo "OK: --org-type '$ORG_TYPE' is valid"
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
echo "ERROR: --org-type must be exactly 'Production' or 'Sandbox' (case-sensitive). Got: '${ORG_TYPE}'" >&2
|
|
17
|
+
exit 1
|