mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-09 08:53:18 +08:00
304 lines
11 KiB
Markdown
304 lines
11 KiB
Markdown
# DevOps Center Promotion CLI Commands Reference
|
|
|
|
Complete reference for the `sf devops` promotion commands with JSON output schemas and error handling. All commands support `--json` and `--target-org <alias>`. Every command is keyed on **record IDs**, not work item names.
|
|
|
|
## Command Summary
|
|
|
|
| Command | Purpose | Required Flags | Async? |
|
|
|---------|---------|---------------|--------|
|
|
| `sf devops promotion validate` | Validate work item promotion to a target stage | `--work-item-id`, `--target-stage-id` | No |
|
|
| `sf devops work-item prepare` | Prepare one work item for promotion | `--work-item-id`, `--target-stage-id` | No |
|
|
| `sf devops work-item combine` | Combine child work items into a parent | `--parent-work-item-id`, `--child-work-item-id`, `--target-stage-id` | No |
|
|
| `sf devops promote` | Promote work item(s) or a stage to a target stage | (`--work-item-id` XOR `--stage-id`), `--target-stage-id`; add `--skip-validation` only if Phase 1 validate passed this session | Yes |
|
|
| `sf devops promotion complete` | Finalize the promotion in the target stage | `--target-stage-id` | No |
|
|
|
|
**Org authentication** — verify before any command:
|
|
```bash
|
|
sf org display --json
|
|
```
|
|
|
|
---
|
|
|
|
## Validate (Mandatory First Step)
|
|
|
|
Validates whether the specified work item(s) can be promoted to the target stage — checks for VCS and object-permission errors before a promotion is attempted. Requires `--target-stage-id`; repeat `--work-item-id` to validate multiple work items in one call.
|
|
|
|
```bash
|
|
sf devops promotion validate \
|
|
--work-item-id 1fkxx0000000001AAA \
|
|
--target-stage-id 1QVxx0000000001AAA \
|
|
--target-org myorg \
|
|
--json
|
|
```
|
|
|
|
### Key Flags
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-i, --work-item-id` | Work item to validate for promotion (required, repeatable) |
|
|
| `-t, --target-stage-id` | Target pipeline stage to validate promotion to (required) |
|
|
| `-o, --target-org` | Target org alias |
|
|
|
|
### JSON Output Schema (success)
|
|
|
|
```json
|
|
{
|
|
"status": 0,
|
|
"result": {
|
|
"success": true,
|
|
"errorType": null,
|
|
"errorDetails": null,
|
|
"combineDetails": null,
|
|
"suggestions": []
|
|
},
|
|
"warnings": []
|
|
}
|
|
```
|
|
|
|
### JSON Output Schema (success, work items share components)
|
|
|
|
When multiple work items share metadata, validation still succeeds (`success: true`) but returns `combineDetails` and `suggestions` describing whether to combine before promoting:
|
|
|
|
```json
|
|
{
|
|
"status": 0,
|
|
"result": {
|
|
"success": true,
|
|
"errorType": null,
|
|
"errorDetails": null,
|
|
"combineDetails": {
|
|
"parentWorkitemId": "1fk000000000001",
|
|
"childWorkitemsId": ["1fk000000000002"],
|
|
"sharedComponentsList": {
|
|
"1fk000000000001": ["MyApexClass", "MyTrigger"],
|
|
"1fk000000000002": ["MyApexClass"]
|
|
}
|
|
},
|
|
"suggestions": [
|
|
"The selected work items share one or more components. Choose one of these approaches:",
|
|
"Option 1 - Combine the work items and promote them as a single unit: ...",
|
|
"Option 2 - Promote the work items as they are, without combining: ..."
|
|
]
|
|
},
|
|
"warnings": []
|
|
}
|
|
```
|
|
|
|
### Interpreting the result
|
|
|
|
- **Success:** `status == 0` and `.result.success == true`. Proceed.
|
|
- **Shared components:** if `.result.combineDetails` is non-null, the work items share metadata. Use `.result.combineDetails.parentWorkitemId` / `.childWorkitemsId` to drive the combine decision in Phase 2 (see Combine), then promote the parent. This is the authoritative signal for whether to combine — don't guess.
|
|
- **Failure:** a non-zero exit code. The command surfaces an error such as `Validation failed (VCS_ERROR): No pull request exists for the work item on the source branch.`, with `.result.errorType` / `.result.errorDetails` populated in `--json`. STOP — do not prepare/combine/promote. The `VCS_ERROR` case confirms the associated-PR requirement is enforced here.
|
|
|
|
---
|
|
|
|
## Prepare
|
|
|
|
`--target-stage-id` is required (the pipeline stage the work item is being prepared to promote to).
|
|
|
|
```bash
|
|
sf devops work-item prepare --work-item-id 1fkxx0000000001AAA --target-stage-id 1QVxx0000000001AAA --target-org myorg --json
|
|
```
|
|
|
|
### JSON Output Schema
|
|
|
|
```json
|
|
{
|
|
"status": 0,
|
|
"result": {
|
|
"workItemId": "1fkxx0000000001AAA",
|
|
"prepared": true
|
|
}
|
|
}
|
|
```
|
|
|
|
Idempotent — re-running a prepared work item is a safe no-op.
|
|
|
|
---
|
|
|
|
## Combine
|
|
|
|
Combine one or more child work items into a parent work item so they promote as a single unit. Repeat `--child-work-item-id` once per child.
|
|
|
|
```bash
|
|
sf devops work-item combine \
|
|
--parent-work-item-id 1fkxx0000000001AAA \
|
|
--child-work-item-id 1fkxx0000000002AAA \
|
|
--child-work-item-id 1fkxx0000000003AAA \
|
|
--target-stage-id 1QVxx0000000001AAA \
|
|
--target-org myorg \
|
|
--json
|
|
```
|
|
|
|
### Key Flags
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `--parent-work-item-id` | The primary work item that continues through the pipeline |
|
|
| `--child-work-item-id` | A work item to merge into the parent (repeatable) |
|
|
| `--target-stage-id` | The pipeline stage to promote the combined unit to (required) |
|
|
| `-o, --target-org` | Target org alias |
|
|
|
|
After combining, promote the **parent** work item ID via `sf devops promote`.
|
|
|
|
---
|
|
|
|
## Promote (Async)
|
|
|
|
Exactly one of `--work-item-id` or `--stage-id` must be provided; they are mutually exclusive. `--target-stage-id` is always required. **Pass `--skip-validation` ONLY when the Phase 1 validate step completed successfully this session for every work item being promoted** — `promote`'s built-in pre-promote validation runs the *same* checks (including the associated-PR requirement) as `sf devops promotion validate`. When that validation already ran this session, skipping avoids a redundant re-run; but if the agent resumed mid-workflow or promotion was invoked without a preceding validate, OMIT the flag so the CLI validates.
|
|
|
|
### Promote one or more work items
|
|
|
|
```bash
|
|
sf devops promote \
|
|
--work-item-id 1fkxx0000000001AAA \
|
|
--target-stage-id 1QVxx0000000001AAA \
|
|
--skip-validation \
|
|
--target-org myorg \
|
|
--json
|
|
```
|
|
|
|
Repeat `--work-item-id` per item. For a combined promotion, pass the **parent** work item ID.
|
|
|
|
### Promote an entire source stage
|
|
|
|
```bash
|
|
sf devops promote \
|
|
--stage-id 1QVxx0000000000AAA \
|
|
--target-stage-id 1QVxx0000000001AAA \
|
|
--skip-validation \
|
|
--target-org myorg \
|
|
--json
|
|
```
|
|
|
|
### Key Flags
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-i, --work-item-id` | Work item to promote (repeatable, mutually exclusive with `--stage-id`) |
|
|
| `-s, --stage-id` | Source stage whose approved work items are promoted (mutually exclusive with `--work-item-id`) |
|
|
| `-t, --target-stage-id` | Destination pipeline stage (required) |
|
|
| `-a, --deploy-all` | Deploy all metadata in the branch, not just changes not yet in the target stage |
|
|
| `-l, --test-level` | Apex test level: `NoTestRun`, `RunSpecifiedTests`, `RunLocalTests`, `RunAllTestsInOrg` |
|
|
| `--tests` | Specific tests to run when `--test-level RunSpecifiedTests` |
|
|
| `--skip-validation` | Skip `promote`'s built-in pre-promote validation. It runs the same checks (including the associated-PR requirement) as `promotion validate`. Pass this ONLY when Phase 1 validate already ran successfully this session; omit it if promotion was invoked without a preceding validate (e.g. mid-workflow resume) so the CLI validates |
|
|
| `-o, --target-org` | Target org alias |
|
|
|
|
### JSON Output Schema
|
|
|
|
```json
|
|
{
|
|
"status": 0,
|
|
"result": {
|
|
"promotionId": "0Af000000000001AAA",
|
|
"sourceStageId": "1QVxx0000000000AAA",
|
|
"targetStageId": "1QVxx0000000001AAA",
|
|
"status": "InProgress"
|
|
}
|
|
}
|
|
```
|
|
|
|
- Async operation. Capture `.result.promotionId` (some CLI versions use `.result.asyncOperationId`).
|
|
- Poll the returned identifier separately to confirm completion — do NOT busy-wait here.
|
|
- After the deploy completes, run `sf devops promotion complete` to finalize.
|
|
|
|
---
|
|
|
|
## Promotion Complete
|
|
|
|
Finalize the promotion — advances the promoted work items in the target stage. Run after the promote deploy succeeds. `--target-stage-id` is required (the same target stage the work items were promoted to).
|
|
|
|
```bash
|
|
sf devops promotion complete --target-stage-id 1QVxx0000000001AAA --target-org myorg --json
|
|
```
|
|
|
|
### JSON Output Schema
|
|
|
|
```json
|
|
{
|
|
"status": 0,
|
|
"result": {
|
|
"completed": true,
|
|
"targetStageId": "1QVxx0000000001AAA"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
**Work item not found:**
|
|
```json
|
|
{ "status": 1, "name": "NOT_FOUND", "message": "Work item does not exist or is not accessible", "exitCode": 1 }
|
|
```
|
|
|
|
**Not prepared before promote:**
|
|
```json
|
|
{ "status": 1, "name": "NOT_PREPARED", "message": "Work item has not been prepared for promotion", "exitCode": 1 }
|
|
```
|
|
|
|
**Missing target stage:**
|
|
```json
|
|
{ "status": 1, "name": "MissingRequiredFlag", "message": "Missing required flag --target-stage-id", "exitCode": 1 }
|
|
```
|
|
|
|
**Conflict on deploy:**
|
|
```json
|
|
{ "status": 1, "name": "DEPLOY_CONFLICT", "message": "Metadata conflict detected during deployment", "exitCode": 1 }
|
|
```
|
|
|
|
**Authentication failure:**
|
|
```json
|
|
{ "status": 1, "name": "NoOrgFound", "message": "No org configuration found for target-org. Run 'sf org login web' to authenticate.", "exitCode": 1 }
|
|
```
|
|
|
|
---
|
|
|
|
## Parsing Async Promotion IDs
|
|
|
|
```bash
|
|
# Promote and capture the promotion ID for status polling.
|
|
# --skip-validation is shown here because this snippet assumes Phase 1 validate
|
|
# already passed this session; OMIT it if promotion is invoked without a
|
|
# preceding validate (e.g. a mid-workflow resume).
|
|
PROMOTION_ID=$(sf devops promote \
|
|
--work-item-id 1fkxx0000000001AAA \
|
|
--target-stage-id 1QVxx0000000001AAA \
|
|
--skip-validation \
|
|
--target-org myorg \
|
|
--json | jq -r '.result.promotionId // .result.asyncOperationId')
|
|
|
|
echo "Promotion initiated. Promotion ID: $PROMOTION_ID"
|
|
# Poll this ID separately, then run: sf devops promotion complete --target-stage-id 1QVxx0000000001AAA --target-org myorg --json
|
|
```
|
|
|
|
---
|
|
|
|
## Resolving Names to IDs
|
|
|
|
Promotion commands need record IDs. Resolve a project name and work item subject/name to IDs first:
|
|
|
|
```bash
|
|
# List projects to resolve a project name to an ID
|
|
# (project list returns .result.projects[] with capitalized .Id / .Name)
|
|
sf devops project list --json | jq -r '.result.projects[] | "\(.Id): \(.Name)"'
|
|
|
|
# Resolve a work item subject to its ID
|
|
# (work-item list returns .result.workItems[] with .id / .subject)
|
|
sf devops work-item list --project-id <project-id> --json | \
|
|
jq -r '.result.workItems[] | select(.subject == "<subject>") | .id'
|
|
```
|
|
|
|
---
|
|
|
|
## Authentication Requirements
|
|
|
|
All promotion commands require:
|
|
|
|
1. **Authenticated org**: `sf org login web` or JWT auth (for CI)
|
|
2. **DevOps Center enabled**: org must have DOCe provisioned
|
|
3. **Promotion permissions**: user/service account must be able to promote in the target pipeline
|
|
|
|
Auth is the caller's responsibility — these skills contain no auth logic. In CI, use a JWT-authenticated service-account alias with least-privilege scopes.
|