Skip to content

06.d ~ Git based deployments and CICD

JΓΆrn Berkefeld edited this page Mar 24, 2025 · 5 revisions

While you can use mcdev completely without Git and any task automation, it is strongly encouraged to use both in your daily flow. For these situations, we build a wrapper around the above methods to execute everything except deploy with a single command:

createDeltaPkg

Command: mcdev createDeltaPkg [range] [--filter]

Alias: mcdev cdp

This command is rather versatile and hence can be used in multiple ways. The most potent option presents itself when you configure options.deployment.sourceTargetMapping to point to a source marketList (usually for DEV-BU with a DEV market) and a target marketList (e.g. to a QA BU-market combo and a Production BU-market combo). Given this is configured, it can create all deployable files using Accenture SFMC DevTools's templating engine on the fly for you.

The minimum configuration you need to have in your config could look something like the following:

Note: the following example does not show all necessary parts of the config, just those that are needed for createDeltaPkg.

The example tells createDeltaPkg that the source BU is called MyProject/DEV and that there are two targets for deployment, MyProject/QA and MyProject/PROD. Furthermore, it associates the markets dev, qa, and prod to these BUs to ensure templating is applied - however, the markets in this example are empty, which means no actual string replacement will occur. This is normal for most basic cases in which you would expect 1:1 copies on DEV, QA, and PROD.

When MC Connect is used, one would expect to see the External Keys of the Synchronized DataExtensions be mentioned in the markets for easy auto-replacement.

{
  "credentials": {
    "MyProject": {
      "businessUnits": {
        "DEV": "1235",
        "QA": "1236",
        "PROD": "1237"
      }
    }
  },
  "options": {
    "deployment": {
      "commitHistory": 10,
      "sourceTargetMapping": {
        "deployment-source": "deployment-target"
      }
    }
  },
  "directories": {
    "deltaPackage": "docs/deltaPackage/",
    "deploy": "deploy/",
    "retrieve": "retrieve/",
    "template": "template/",
    "templateBuilds": ["retrieve/", "deploy/"]
  },
  "markets": {
    "dev": {},
    "qa": {},
    "prod": {}
  },
  "marketList": {
    "deployment-source": {
      "description": "Define one 1:1 BU-Market combo here to as source for automated creation of deployment packages; you can create more than one source market list",
      "MyProject/DEV": "dev"
    },
    "deployment-target": {
      "description": "Define n BU-Market combo here to as target for automated creation of deployment packages; you can create more than one target market list and they can be as complex as you like",
      "MyProject/QA": "qa",
      "MyProject/PROD": "prod"
    }
  }
}

Detailed Background infos: createDeltaPkg internally first compares the 2 commits in Git to find the differences, then executes buildTemplate for all of these found differences, which creates files in your template/ directory. Finally, it runs buildDefinitionBulk for everything, updating your retrieve/ directory as well as, optionally, your deploy/ directory, depending on your Accenture SFMC DevTools config's directories.templateBuilds value. The update to the first folder enables you to update you branch, while the second folder gives you the right files to immediately deploy to your BUs afterwards (not part of `createDeltaPkg).

Interactive commit selection:

This allows you to compare your latest commit (not what's still only unstaged/staged) with previous commits. This approach is especially useful if you are in charge of the deployment and simply want to compare the latest commits to your master / release branch with the commit that was last deployed.

Important: Make sure you are on the branch corresponding to the environment you want to deploy to, e.g. the master branch.

mcdev createDeltaPkg

The output will look something like this:

interactive commit selection

Note: The amount of displayed past commits depends on your Accenture SFMC DevTools configs settings in options.deployment.commitHistory. The default value is 10.

Manual commit selection:

This is what you would do when you work on a feature branch and want to include the proposed changes for the target BUs already in the branch.

# Option 1 - RECOMMENDED
# compare based on what you last committed
# you just committed all your changes and want to create the deployment package for master/Production;
# Recommendation: run this before creating a pull request to include the changes in your PR.

mcdev createDeltaPkg master # resolves to master..HEAD

Alternatives:

# the same example with another branch name:
mcdev createDeltaPkg "release/sprint-14" # resolves to release/sprint-14..HEAD

# or even use a commit ID instead of a branch name
mcdev createDeltaPkg d21b4221  # resolves to d21b4221..HEAD


# Option 2 - full git range
mcdev createDeltaPkg master..develop

Manual commit selection without templating:

If you don't want to use templating, you may instead provide the optional filter parameter. If the filter option is used, then no markets/marketLists are used - and it does not use buildTemplate nor buildDefinition internally. Therefore, you should only expect changes in your deploy/ folder, not the template/ folder. Instead, it creates a 1:1 copy of relevant files in the deploy folder. This is particularly useful for people that make a lot of changes with search & replace and then need to know which files have to be deployed.

mcdev createDeltaPkg d21b4221..HEAD --filter 'MyProject/BU1'

Range and multiple filters (without templating):

mcdev createDeltaPkg d21b4221..HEAD --filter 'MyProject/BU1,MyProject/BU3'

No Range and filter that includes metadata type (without templating):

mcdev createDeltaPkg --filter 'MyProject/BU1/asset/template'

Note to CLI experts:

If you provide a range you can run this command without the interactive wizard asking questions using the --skipInteraction (or short--yes/--y) flag. This will automatically empty your deploy folder before adding new files. Your command will look like this:

mcdev createDeltaPkg <range> [--filter] --y

Components that require pre- or post-deployment steps

Generic: Deleted components

mcdev cdp (createDeltaPkg) generates a ready-to-copy mcdev delete command with everything it THINKS needs to be deleted. DO check that because renamed components might be in this list. Do NOT assume this list is always correct!

πŸ‘ˆπŸ‘‰ Do this as a pre- or post-step.

Generic: Changing the key (renamed components)

mcdev has no way of knowing that you changed a key and with it the filename. If you component is used by other metadata, the link might be broken if you simply delete + re-deploy this. Be VERY careful in this situation and ideally do the key-change as part of a hotfix during which you actively change the keys rather than follow the normal deployment process!

πŸ‘ˆ Do this as a pre-step.

DataExtensions

Changing Retention settings

This can be achieved via Contact Builder, but currently not via Email Studio nor via mcdev.

πŸ‘ˆπŸ‘‰ Do this as a pre- or post-step. Pre is faster.

Synchronized DataExtensions

You have to create/update them manually via UI, but the change does show up on your Parent BU alongside updates to changed attribute groups & attribute sets on the child BU. Therefore, to track these changes, make sure you have your team commit them to your git repository.

πŸ‘ˆ Do this as a pre-step.

Shared DataExtensions

You can deploy them via mcdecv but be aware that they will only show in your Parent BU's folder. Making changes to them can affect your child BUs attribute groups and attribute sets. Actual sharing is handled via their folders and can only be done in the UI. It is recommended to have mcdev handle folder creation during deployment and then take care of sharing afterwards manually. Be aware that shared DE folders initially grant access to all BUs.

πŸ‘‰ Do this as a post-step.

DataExtension fields

Renamed DataExtension fields

Similar to changing the key of things, this should be done as part of a hotfix. If you choose to deploy this through the automated pipeline, it will simply add a new field instead. Either change the field name in the UI or follow this guide to change a field name via mcdev: https://github.com/Accenture/sfmc-devtools/wiki/08.-Metadata-specific-settings-&-options#renaming-fields-of-a-data-extensions

πŸ‘ˆ Do this as a pre-step.

Deleted DataExtension fields

As of now, mcdev will not automatically remove fields that are no longer in your deployment package. Instead it will simply not touch them. If you want fields deleted, you need to do so via UI or via mcdev delete MyProject/ParentBU -m dataExtensionField:MyUserTable.MyFieldName

πŸ‘ˆπŸ‘‰ Do this as a pre- or post-step. Pre is faster.

Adding a new Primary Key field

You cannot add a new primary key field to an existing table that has data. Therefore, if you that's what you need to do, export the data first, empty the DataExtension, run the update and then import the data again.

πŸ‘ˆ+πŸ‘‰ Do this as a pre- AND post-step.

Changing the field type

You cannot change the field type but you can delete and recreate a field with the same name. Therefore, if you that's what you need to do, export the data first, empty the DataExtension, run the update and then import the data again.

πŸ‘ˆ+πŸ‘‰ Do this as a pre- AND post-step.

File Locations

It’s not supported by mcdev but required by import file activities

πŸ‘ˆ Do this as a pre-step.

Domain Verifications / From Name Management

SAP / Registered Domain / Private Domain need to be set up manually via UI or else actual emails that can get created wont be automatically verified.

πŸ‘ˆ Do this as a pre-step.

Cloudpages (asset-asset)

As of today, there is still no API for creating Cloudpages and hence you need to manually create them via the SFMC UI. Afterwards, you will then find a new asset under asset/asset folder with a UUID key. In the JSON, you will notice it reads assetType.name: "webpage" and the name will equal the name of the Cloudpage you created.

πŸ‘ˆ Do this as a pre-step.

To enable easy deployments of changes to the cloudpage, it is recommended to keep your actual cloudpage code in a code snippet and then reference that code snippet in the cloudpage. This way, you can easily update the code snippet and the cloudpage will automatically reflect the changes without a need to re-publish it:

Your Cloudpage code:

%%=ContentBlockByKey("myCloudpage_codesnippet")=%%

Your Cloudpage code snippet (key:"myCloudpage_codesnippet"):

<!--insert whatever HTML, Ampscript/SSJS or other code you need here-->

This way, whenever you want to update this cloudpage, simply update the code snippet ("myCloudpage_codesnippet" in the above sample) and the cloudpage will automatically reflect the changes.

Clone this wiki locally