@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.
Files changed (67) hide show
  1. package/package.json +1 -1
  2. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +239 -0
  3. package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +21 -0
  4. package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +90 -0
  5. package/skills/automation-sandbox-post-copy-config-generate/examples/sample_sop_excerpt.md +31 -0
  6. package/skills/automation-sandbox-post-copy-config-generate/examples/sample_sop_to_config.json +50 -0
  7. package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +76 -0
  8. package/skills/automation-sandbox-post-copy-config-generate/references/sop_parsing_patterns.md +157 -0
  9. package/skills/automation-sandbox-post-copy-config-generate/references/source_format_handling.md +230 -0
  10. package/skills/dx-apexguru-scan/SKILL.md +403 -0
  11. package/skills/dx-apexguru-scan/examples/README.md +54 -0
  12. package/skills/dx-apexguru-scan/examples/sample-decoded-summary.json +176 -0
  13. package/skills/dx-apexguru-scan/examples/sample-full-no-runtime-response.json +26 -0
  14. package/skills/dx-apexguru-scan/examples/sample-succeeded-response.json +15 -0
  15. package/skills/dx-apexguru-scan/references/api-reference.md +81 -0
  16. package/skills/dx-apexguru-scan/references/authentication.md +134 -0
  17. package/skills/dx-apexguru-scan/references/error-handling.md +56 -0
  18. package/skills/dx-apexguru-scan/references/violation-catalog.md +28 -0
  19. package/skills/dx-apexguru-scan/scripts/build-zip.sh +87 -0
  20. package/skills/dx-apexguru-scan/scripts/decode-report.js +389 -0
  21. package/skills/dx-apexguru-scan/scripts/resolve-token.sh +151 -0
  22. package/skills/dx-apexguru-scan/scripts/run-scan.sh +153 -0
  23. package/skills/dx-apexguru-scan/scripts/scan.sh +96 -0
  24. package/skills/dx-apexguru-scan/scripts/validate-token.js +121 -0
  25. package/skills/dx-devops-pipeline-manage/SKILL.md +263 -0
  26. package/skills/dx-devops-pipeline-manage/examples/common-workflows.md +177 -0
  27. package/skills/dx-devops-pipeline-manage/references/cli-commands.md +298 -0
  28. package/skills/dx-devops-pipeline-manage/references/parsing-patterns.md +134 -0
  29. package/skills/dx-devops-pipeline-manage/scripts/check-activation-ready.sh +34 -0
  30. package/skills/dx-devops-pipeline-manage/scripts/validate-org-type.sh +17 -0
  31. package/skills/dx-devops-pipeline-manage/scripts/verify-operation.sh +82 -0
  32. package/skills/dx-devops-promote/SKILL.md +214 -0
  33. package/skills/dx-devops-promote/examples/promotion-workflows.md +212 -0
  34. package/skills/dx-devops-promote/references/cli-commands.md +303 -0
  35. package/skills/experience-lwc-base-components-integrate/SKILL.md +176 -0
  36. package/skills/experience-lwc-base-components-integrate/references/lbc-expert-guidance.md +127 -0
  37. package/skills/experience-lwc-base-components-integrate/references/lightning-component-index.md +179 -0
  38. package/skills/experience-lwc-base-components-integrate/references/lightning-components.md +5429 -0
  39. package/skills/experience-lwc-base-components-integrate/scripts/extract-component-docs.sh +61 -0
  40. package/skills/experience-lwc-rtl-validate/SKILL.md +149 -0
  41. package/skills/experience-lwc-rtl-validate/references/rtl-expert.md +892 -0
  42. package/skills/experience-lwc-rtl-validate/scripts/scan-rtl-css.sh +206 -0
  43. package/skills/experience-lwc-typescript-migrate/SKILL.md +207 -0
  44. package/skills/experience-lwc-typescript-migrate/assets/dts-template.ts +15 -0
  45. package/skills/experience-lwc-typescript-migrate/assets/type-patterns.ts +44 -0
  46. package/skills/experience-lwc-typescript-migrate/scripts/find-consumers.sh +128 -0
  47. package/skills/experience-ui-bundle-localize/SKILL.md +323 -0
  48. package/skills/experience-ui-bundle-localize/references/gotchas.md +249 -0
  49. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +169 -0
  50. package/skills/experience-ui-bundle-localize/references/interpolation.md +311 -0
  51. package/skills/experience-ui-bundle-localize/references/label-xml.md +282 -0
  52. package/skills/experience-ui-bundle-localize/references/verifying.md +219 -0
  53. package/skills/experience-ui-bundle-localize/scripts/check-i18n-wired.sh +195 -0
  54. package/skills/experience-ui-bundle-localize/scripts/check-manifest-registered.sh +100 -0
  55. package/skills/experience-ui-bundle-localize/scripts/check-org-api-version.sh +40 -0
  56. package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +57 -0
  57. package/skills/platform-custom-lightning-type-generate/SKILL.md +3 -0
  58. package/skills/platform-custom-lightning-type-generate/assets/primitive-types-and-constraints.md +1 -1
  59. package/skills/platform-mcp-tool-widget-coordinate/SKILL.md +250 -0
  60. package/skills/platform-mcp-tool-widget-coordinate/examples/action-name-source-prompt.md +74 -0
  61. package/skills/platform-mcp-tool-widget-coordinate/examples/apex-invocable-source-prompt.md +90 -0
  62. package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-source-prompt.md +191 -0
  63. package/skills/platform-mcp-tool-widget-coordinate/examples/pasted-tool-output-prompt.md +85 -0
  64. package/skills/platform-mcp-tool-widget-coordinate/references/build-plan-format.md +74 -0
  65. package/skills/platform-mcp-tool-widget-coordinate/references/mcp-tool-output-discovery.md +184 -0
  66. package/skills/platform-mcp-tool-widget-coordinate/references/two-clt-modeling.md +128 -0
  67. 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