Product Preview · AlphaCommands, flags and behavior may change without notice. Expect the occasional plot twist — and tell us about it.
    Copado Agentia
    ← Back to Training
    Use case 7a · Developer

    Develop a metadata change

    The basic flow to build a Salesforce change, test it, commit it, and submit it to the pipeline so it can be promoted later to other environments.

    The flow

    work set → Salesforce CLI / Git → work test → work publish → work submit → work environment-sync (if needed) → work submit

    Video coming soon

    Before you start

    Git stays Git. Salesforce CLI stays the way you retrieve and deploy to your development org. Agentia is how you work with Copado CI/CD from the same project.

    Run every agentia command from your Salesforce DX project (the Git repository Copado manages), not from some other clone.

    Stay on this local path. agentia cicd cloud commit and agentia cicd cloud promote retrieve and commit from the org in Copado. They do not read your local branch and will interfere with local and remote branches, causing push rejections and conflicts. Pick one model per story. This page covers the local model only.

    Example used on this page

    A Copado User Story with three metadata changes:

    1. Add Account field Tag__c, Text (255), default new.
    2. Add validation rule TagValidation: Tag__c must contain one of new, checked or scheduled.
    3. Grant the Sales Team permission set access to the Account object and to the Phone and Tag__c fields.

    If the story also includes Apex, add a class and its test (for example HelloWorld / HelloWorldTest) so local Apex gates have something to run. Commands below use US-XXXXXXX as a stand-in for your story name.

    Your story needs a pipeline and a source credential. If work set warns that those are missing, fix the story in Copado before you publish or submit.

    1. Work set (story-based)

    Select the story and make it your current work. Agentia creates or checks out its feature branch from the pipeline, release or user story base branch fetched from the remote, so you start from up-to-date changes.

    Your Git working tree must be clean (no uncommitted tracked changes), or Agentia warns you and stops, so unintended changes from another branch aren't dragged in.

    agentia cicd work list --assigned-to-me --json
    agentia cicd work get US-XXXXXXX --json
    
    agentia cicd work set US-XXXXXXX

    After a successful set:

    • You are on feature/US-XXXXXXX.
    • Later work test, work publish and work submit use this story; you do not pass the ID again.
    • Stay on that branch for every implementation commit.

    Branches in this flow

    BranchWhat it is
    Base branch (often main)The branch the pipeline compares your story against. work set starts from here when the feature branch is new.
    feature/US-XXXXXXXYour working branch. All Git commits for this story belong here.
    Dev org branchYour personal / development-org branch. work publish updates it so Copado and the org stay aligned with the story.

    To start from a different base (release or hotfix):

    agentia cicd work set US-XXXXXXX --base-branch develop
    If the story has no pipeline or credential, work set warns and does not prepare Git. Publish and submit won't work until you fix the story and run work set again. To recover, create the feature branch manually and commit your changes there, making sure you edited the metadata from the right source branch.

    2. Typical Salesforce development

    This step is not an Agentia command. Retrieve, edit and deploy with Salesforce CLI, your IDE or an agent, the way you already do, targeting the development org on the story.

    sf project retrieve start --metadata CustomField:Account.Tag__c
    sf project retrieve start --metadata ValidationRule:Account.TagValidation
    sf project retrieve start --metadata PermissionSet:Sales_Team
    
    sf project deploy start \
      --metadata CustomField:Account.Tag__c \
      --metadata ValidationRule:Account.TagValidation \
      --metadata PermissionSet:Sales_Team

    With Apex on the story:

    sf project deploy start \
      --metadata ApexClass:HelloWorld \
      --metadata ApexClass:HelloWorldTest

    Files in this example:

    • force-app/main/default/objects/Account/fields/Tag__c.field-meta.xml
    • force-app/main/default/objects/Account/validationRules/TagValidation.validationRule-meta.xml
    • force-app/main/default/permissionsets/Sales_Team.permissionset-meta.xml

    The field and validation rule are nested under Account. The permission set carries object and field access, including the new field. work publish detects that; you don't need a special commit command for it.

    3. Local testing and quality gates

    Local quality gates are a script your Git project owns. Agentia runs .agentia_quality_gates.sh (macOS/Linux) or .agentia_quality_gates.cmd (Windows) from the repository root. A non-zero exit fails the command.

    They give you or your AI agent fast feedback on a change long before it is committed, pushed or submitted. You could keep them as untracked files, but then it's very hard to know which gates each team member runs, so this isn't recommended.

    • agentia cicd work test runs the gates on their own.
    • agentia cicd work submit runs the same project script first (when it exists), then continues to pipeline validation.
    To record the run on the User Story in Copado, the org needs an Extension Configuration named Local Quality Gate (Copado Phase Test, Extension Tool None, Test Type Unit Test). Without it the gates still run on your machine, but the command fails and Copado warns that it could not store the result.

    Repo and local setup

    In the Salesforce project, run setup and accept the local quality gates prompt:

    agentia setup

    Commit both generated files so the team shares the same gates:

    git add .agentia_quality_gates.sh .agentia_quality_gates.cmd
    git commit -m "US-XXXXXXX add shared local quality gates"

    If those files are missing, work test still runs a stock sample (it doesn't add files to the repo). work submit does not use that fallback: without a project script, submit skips local gates. You must be on feature/US-XXXXXXX (after work set) for the result to attach to the story.

    Typical quality-gate script

    agentia setup writes a sample you are expected to edit. Keep set -euo pipefail (and the matching if errorlevel 1 checks on Windows) so a failed gate stops the script. Put the cheapest checks first.

    • Salesforce Code Analyzer: the sample runs sf code-analyzer run first. You need Salesforce CLI and a project Code Analyzer can scan. A failure stops the rest of the script.
    • Apex tests: the sample calls agentia cicd work test apex instead of sf apex run test. Pass the classes for this story with agentia cicd work test --apex-test-classes=HelloWorldTest. If you leave out --apex-test-classes, the Apex step skips and exits successfully; other gates still run.
    • Apex on its own: agentia cicd work test apex -t HelloWorldTest runs Apex without Code Analyzer or Jest. --rerun-failed reruns classes that failed last time on this story; run a full Apex pass once first so there is something to rerun.
    • Jest (LWC): the sample runs npx sfdx-lwc-jest --passWithNoTests. With no Lightning tests in the project, the gate still passes. Replace that line if your team requires a real Jest suite.
    • Copado Test record: when the script finishes, Agentia records success, failure or skipped on the User Story, with the script output as logs. work submit --skip-local-tests records skipped rather than hiding the step.

    Edit the script to add other checks (lint, formatting, metadata validation). Agentia only cares that the process exits non-zero on failure.

    4. Git add / commit

    Agentia does not commit files for you. work publish and work submit need a clean tracked tree and only see committed work on feature/US-XXXXXXX. This prevents accidental changes from being mirrored in Copado.

    git add \
      force-app/main/default/objects/Account/fields/Tag__c.field-meta.xml \
      force-app/main/default/objects/Account/validationRules/TagValidation.validationRule-meta.xml \
      force-app/main/default/permissionsets/Sales_Team.permissionset-meta.xml
    
    git commit -m "US-XXXXXXX: Account Tag__c, TagValidation, Sales Team permissions"
    git status

    Include the story name in the message. Don't git push yet: a plain push doesn't register a Copado Commit — that's what work publish does. If you already pushed, that's fine, but you still need to run work publish, and an empty Commit may be added to complete it.

    5. Work publish

    work publish is the Copado Commit for local Git work. It:

    • Detects metadata changes on the feature branch (including nested components and permission sets).
    • Applies Copado environment-variable and YAML replacements when the story has them.
    • Pushes the feature branch, registers the commits on the User Story and updates the dev org branch.

    A plain git push does none of that. You must still be on feature/US-XXXXXXX with a clean tree.

    agentia cicd work publish

    Metadata detection usually covers this example without extra flags. For the Account Tag / Sales Team story, the nested-detection step looks like this:

    Detecting nested metadata changes... done
    
    Permission parents (kept in the change list):
      PermissionSet:Sales_Team
    
    Nested metadata: CustomField:Account.Phone,
      CustomField:Account.Tag__c, CustomObject:Account
    
    Retrieve only (nested Profile and PermissionSet metadata):
      CustomField:Account.Phone
      CustomField:Account.Tag__c
      CustomObject:Account

    Read those three lists before you submit:

    ListIn this exampleMeaning
    Permission parents (kept in the change list)PermissionSet:Sales_TeamThe permission set (or profile) file stays on the commit. Copado needs that parent to apply the access changes.
    Nested metadataCustomField:Account.Phone, CustomField:Account.Tag__c, CustomObject:AccountMembers that actually changed inside a parent file — here, object and field access on Sales Team.
    Retrieve onlyThe same three namesNot deployed as their own components. Copado retrieves them from the org and applies only the permission set (or profile) access. Phone is not redeployed; Tag still deploys from its own field file if you committed it.

    Other lines appear when they apply: Nested parents (a non-permission parent whose file changed only inside nested blocks) and Nested metadata deleted (a nested member removed from a parent). Each line is left out when its list is empty.

    Nested metadata and permissions

    Salesforce often stores several Copado components in one file (a permission set, a profile, a custom object, a workflow). If Copado took the whole file, the promotion would carry members another story owns. Publish diffs the branch and registers what actually changed:

    What you changedWhat Copado receives
    New nested files such as Account.Tag__c or TagValidationThose components (not the entire Account object, unless you changed object-level fields)
    A new permission set, or you ask for the whole fileFull metadata — the complete permission set deploys
    Only access inside an existing permission set or profile (for example Phone or Tag__c FLS)The parent file is committed; the named permissions are Retrieve Only, so Copado applies access without redeploying those fields or classes
    A nested member removed from a parent file (not a permission revoke)A delete of that member
    A field permission removed from a permission setStill Retrieve Only — revoking FLS does not delete the field

    If auto-detection gets it wrong, override it with flags on that publish only. This is like picking nested items, permissions or full metadata by hand in the Copado Commit experience.

    agentia cicd work publish --permissions CustomField:Account.Tag__c
    agentia cicd work publish --full-metadata PermissionSet:Sales_Team
    agentia cicd work publish --skip-nested-metadata-detection

    Environment-variable and YAML replacements

    If the User Story has Copado replacement rules, publish applies them to the files this branch added or changed, then commits the result (the message ends with copado replacements) before registering. You don't run the replacement tools yourself. Delete-only commits have nothing to rewrite, so replacements are skipped.

    Deletes

    To remove nested metadata, delete the file in Git, commit and publish:

    git rm force-app/main/default/objects/Account/validationRules/TagValidation.validationRule-meta.xml
    git commit -m "US-XXXXXXX: remove TagValidation"
    agentia cicd work publish
    Publish registers the member as deleted, but side effects — like a deleted field affecting all the layouts of its object — are not added to the commit automatically. Retrieve the related metadata of the object and commit it too. That's the usual way to work with Salesforce and Git; Copado cloud commits can detect these cascade deletions, which would be too intrusive to do locally.

    6. Work submit (validate, deploy, pull request)

    work submit hands the story to the pipeline. By default it validates against the next environment but doesn't deploy or merge yet. The cloud promotion and validation keep running in the background.

    It runs local quality gates first (when the project script exists), publishes any unpushed commits, waits if a Commit job is still running, warns if your environment is behind, validates, and opens the merge request / compare URL.

    agentia cicd work submit
    • Skip opening the browser: agentia cicd work submit --skip-pull-request
    • Pass Apex classes to the local gates: agentia cicd work submit --apex-test-classes=HelloWorldTest
    • Skip local gates (recorded as skipped on the story): agentia cicd work submit --skip-local-tests
    • Promote and deploy to the next environment (--done and --deploy are the same): agentia cicd work submit --done

    agentia cicd work done is a compatibility alias of submit --done. Prefer submit --done.

    CommandEffect
    work submitValidate + open the pull request
    work submit --done or --deployPromote and deploy to the next environment

    Validations and promotions are asynchronous. Check them with:

    agentia cicd work status
    If submit warns that user stories are behind, don't promote yet. Use environment-sync (next step).

    7. Work environment-sync

    You are behind when other stories already reached the next pipeline environment and your development org doesn't have them.

    work submit warns you. work environment-sync back-promotes every story that is behind onto your destination (dev) environment. It doesn't take a user story ID; it uses your current work from work set.

    Detect that you are behind

    agentia cicd work get --user-stories-ahead-behind --json

    Back-promote

    agentia cicd work environment-sync
    
    # or name the destination
    agentia cicd work environment-sync --destination-environment <dev-environment>

    If nothing is behind, the command says so and stops. Copado's behind count can lag behind Git; wait and retry if you just promoted another story.

    Resolve conflicts

    If the same metadata changed in both places, Git merge conflicts stop the run and Copado marks the back-promotion as Merge Conflict.

    git status
    # edit the unmerged files, then:
    git add <resolved-files>
    
    agentia cicd work environment-sync --promotion <promotion-name> --continue
    
    # or discard the in-progress merge:
    agentia cicd work environment-sync --promotion <promotion-name> --abort
    • --continue: finishes after you resolve (or after you have already committed the merge).
    • --abort: cancels the merge and returns the back-promotion to Draft.

    When the sync succeeds, continue with work publish / work submit --done as needed.

    Why it's easier than a back-promotion

    • One round of conflicts: environment-sync needs only one round, instead of up to one stop per user story, so it's much easier for a developer or AI to integrate and move on.
    • Your feature branch gets the change: after merging, deploying to the dev org and checking everything, both the feature branch and the environment branch are up to date. Copado CI/CD cloud only updates the environment branch.
    • On the environment branch: when your current branch is the environment branch, environment-sync updates only that one.