Search code examples
salesforceapexapex-code

How to package a Custom Metadata Type in a Salesforce 2GMP (Second Generation Managed Package)?


I am tasked with the creation of a Salesforce 2GMP (Second Generation Managed Package) and I wonder how I can include a Custom Metadata Type in my package.

A simple creation of the Custom Metadata type including a custom field in my Salesforce Developer Org and then retrieving it with sf project retrieve start --metadata CustomMetadata wasn't enough since when I want to create a new package version I am retrieving errors that the Custom Metadata Type does not exist in my Apex Code:

Warning: (1) <REDACTED>TriggerHandler: Variable does not exist: realWebhookTokens
(2) <REDACTED>TriggerHandler: Invalid type: <REDACTEDNAMESPACE>__<REDACTED>_Webhook_Token__mdt
(3) <REDACTED>TriggerHandlerTest: Dependent class is invalid and needs recompilation:
 Class <REDACTEDNAMESPACE>.<REDACTED>TriggerHandler : Invalid type: <REDACTEDNAMESPACE>__<REDACTED>_Webhook_Token__mdt
(4) <REDACTEDCONNECTEDAPP>: Ausnahme bei Änderung von Patch für verwaltetes Paket: An der Patch-Version wurde eine Änderung vorgenommen, die das sichtbare Verhalten der Anwendung ändert.: Konnektivitäts-Entwicklerkonfiguration: <REDACTEDCONNECTEDAPP>_oauth_devConfig: Komponente hinzugefügt
(5) <REDACTED>TriggerHandler: Variable does not exist: realWebhookTokens

To provide a little bit of context: I am hiding a webhook token in Custom Metadata Type that is only accessible by objects in the same namespace. I am dynamically serializing Apex Triggers which call this TriggerHandler after creating a Custom Metadata Record which contains the actual webhook token and pass the ID to the serialized Apex Trigger which passes it to the TriggerHandler which then queries the real webhook token with this ID to send an HTTP request.

So how am I supposed to package the Custom Metadata Type?


Solution

  • So after having spoken to the Salesforce support, the retrieval of the actual Custom Metadata Type is actually the same as retrieving Custom Objects.

    Therefore you need to create a package.xml at the root level of your project and declare the type in it:

    <?xml version="1.0" encoding="UTF-8"?>
    <Package xmlns="http://soap.sforce.com/2006/04/metadata">
        <types>
            <members><REDACTEDNAMESPACE>__<REDACTED>_Webhook_Token__mdt</members>
            <name>CustomObject</name>
        </types>
        <version>59.0</version>
    </Package>
    

    After that you can retrieve it with the following command:

    sf project retrieve start --manifest package.xml -o <ORGANISATION-ALIAS-OR-ID>

    The Custom Metadata Type including its custom fields will then appear at force-app/main/default/objects:

    Picture of folder structure after retrieving Custom Metadata Type