-
Notifications
You must be signed in to change notification settings - Fork 0
Description
This issue tracks the implementation of the azdo pipelines variable-group update command.
Command Description
Update a variable group’s metadata (name, description, provider data, project sharing), and optionally manage “grant access permission to all pipelines” for the variable group resource. The
Azure CLI fetches the group, mutates changed fields, persists it with update_variable_group, and optionally toggles authorization via set_authorize_resource (source (https://github.com/
Azure/azure-devops-cli-extension/blob/master/azure-devops/azext_devops/dev/pipelines/variable_group.py#L114-L160)). azdo should replicate this flow with explicit validation and clearer
output while covering the Azure DevOps REST 7.1 surface.
Important REST constraints:
- Azure DevOps REST never returns secret variable values. If this command touches variables in any way, it must never attempt to print secret values and must not rely on reading them back
from responses. - Cross-project sharing is expressed via variableGroupProjectReferences. The isShared field is an output/derived property and must not be treated as an update input field.
azdo Command Signature
azdo pipelines variable-group update [ORGANIZATION/]PROJECT/VARIABLE_GROUP_ID_OR_NAME [flags]
Flags (metadata / group shape):
- --name string: New display name.
- --description string: New description (empty string clears it).
- --type string: Update the variable group type (e.g., Vsts, AzureKeyVault). Validate against supported values.
- --provider-data-json string: Raw JSON payload for providerData (advanced).
- --clear-provider-data: Clear providerData. Mutually exclusive with --provider-data-json.
Flags (cross-project sharing):
- --project-reference <PROJECT_ID_OR_NAME> (repeatable): Add project references for sharing.
- --clear-project-references: Overwrite existing variableGroupProjectReferences with exactly the provided --project-reference set. If provided without any --project-reference, this removes
all project references (unshare everywhere except the owning project).
Flags (pipeline permissions / “authorize for all pipelines”):
- --authorize bool: Tri-state toggle. Only apply if explicitly set (use Flags().Changed("authorize")).
- true means “grant access permission to all pipelines”
- false means “do not grant access permission to all pipelines”
JSON export flags:
- Support --json, --jq, --template via util.AddJSONFlags (see JSON contract below).
At least one mutating flag must be supplied; otherwise return a validation error.
Behavior
- Parse [ORGANIZATION/]PROJECT/VARIABLE_GROUP_ID_OR_NAME using util.ParseProjectTargetWithDefaultOrganization; wrap parse errors with util.FlagErrorWrap.
- Start progress indicator immediately after IOStreams() and stop before printing.
- Resolve the variable group ID-or-name using the shared helper shared.ResolveVariableGroup (do not re-implement ID/name resolution). If missing, return an error.
- Apply changes in-memory to the fetched group/model:
- Only mutate fields that correspond to explicitly provided flags.
- Validate mutual exclusivity: --provider-data-json vs --clear-provider-data.
- Update sharing by writing variableGroupProjectReferences (do not try to set an isShared input field).
- Authorization (“pipeline permissions”):
- If --authorize was explicitly set, update pipeline permissions for resource type variablegroup using the pipeline permissions API.
- If --authorize was not set, do not change pipeline permissions.
- Key Vault groups:
- This command must reject attempts to mutate variables/secret values for AzureKeyVault groups (values are managed via Key Vault). Metadata updates (name/description/sharing/permissions/
providerData JSON) may still be allowed depending on the REST surface; if a requested change is not supported, return a descriptive error.
- This command must reject attempts to mutate variables/secret values for AzureKeyVault groups (values are managed via Key Vault). Metadata updates (name/description/sharing/permissions/
- Persist changes:
- Call TaskAgent.UpdateVariableGroup when any variable-group fields changed (name/description/type/providerData/variableGroupProjectReferences/variables).
- If only --authorize changed, do not call UpdateVariableGroup; update pipeline permissions only.
- Output (single-object command):
- Default output is a Go text template (consistent with azdo pipelines variable-group show style).
- Never print secret variable values (use *** for secret values if any variable list is shown).
- JSON output:
- Emit the complete SDK model you are working with (the updated taskagent.VariableGroup).
- Exception: if you include pipeline permissions in JSON, use an augmented struct that embeds *taskagent.VariableGroup and adds pipelinePermissions (mirroring the existing show command).
- util.AddJSONFlags list must match the JSON tags exposed by the output type (field-level contract). For parity with show, register:
- id, name, type, description, isShared, variables, variableGroupProjectReferences, providerData, createdBy, createdOn, modifiedBy, modifiedOn, pipelinePermissions (only if the
output includes pipelinePermissions).
- id, name, type, description, isShared, variables, variableGroupProjectReferences, providerData, createdBy, createdOn, modifiedBy, modifiedOn, pipelinePermissions (only if the
Wiring / Scope (no persistent flags)
- No group-level “persistent” --organization/--project flags are added. Project/organization scope is provided by the positional argument [ORGANIZATION/]PROJECT/....
- Wiring chain must be explicit and complete: root -> pipelines -> variable-group -> update.
Implementation Notes (filled checklist)
- Implement command: internal/cmd/pipelines/variablegroup/update/update.go (type opts struct, NewCmd(ctx), run(ctx, opts)).
- Wire command: internal/cmd/pipelines/variablegroup/variablegroup.go must AddCommand(update.NewCmd(ctx)) and be reachable from azdo pipelines variable-group.
- Parse scope: util.ParseProjectTargetWithDefaultOrganization(ctx, targetArg); wrap parse errors with util.FlagErrorWrap.
- Clients:
- Task Agent: ctx.ClientFactory().TaskAgent(ctx.Context(), scope.Organization) for variable group read/update.
- Pipeline Permissions: ctx.ClientFactory().PipelinePermissions(ctx.Context(), scope.Organization) for --authorize (resource type variablegroup).
- Core client only if needed to resolve project IDs for --project-reference inputs.
- Resolve group: shared.ResolveVariableGroup(ctx, taskClient, scope.Project, scope.Target) where ctx is the injected util.CmdContext passed into NewCmd/run.
- Progress: ios.StartProgressIndicator(); defer ios.StopProgressIndicator() and stop before printing.
- Update algorithm:
- Fetch group.
- Apply explicit flag changes (name/description/type/providerData/project references).
- If --authorize changed: update pipeline permissions for the variablegroup resource.
- Call TaskAgent.UpdateVariableGroup only when group fields changed.
- Output:
- Template: render a single-object template output (consistent with internal/cmd/pipelines/variablegroup/show/show.go).
- JSON: emit SDK model; only use an augmented wrapper if including pipelinePermissions; ensure util.AddJSONFlags list matches the output’s JSON tags.
- Secret rule: never print secret values; JSON must never contain secret values.
- Tests:
- Add unit tests at internal/cmd/pipelines/variablegroup/update/update_test.go.
- Hermetic mocks: Task Agent client + PipelinePermissions client (+ Core client if project reference resolution is implemented).
- Table-driven cases: name/description update, authorize-only (no UpdateVariableGroup call), project reference overwrite/clear semantics, provider-data json vs clear exclusivity, missing
mutating flags validation error, AzureKeyVault restrictions.
Definition of Done (short)
- Command is wired into the CLI (root -> pipelines -> variable-group -> update).
- Behavior matches the checklist (parsing, resolution, update flow, authorization flow).
- Hermetic unit tests exist at internal/cmd/pipelines/variablegroup/update/update_test.go with mocks.
References
- Azure CLI implementation: variable_group_update (https://github.com/Azure/azure-devops-cli-extension/blob/master/azure-devops/azext_devops/dev/pipelines/variable_group.py#L114-L160)
- Azure DevOps REST API 7.1: Update variable group (https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/variablegroups/update?view=azure-devops-rest-7.1)
- Azure DevOps docs: Manage variable groups (https://learn.microsoft.com/azure/devops/pipelines/library/variable-groups)