[SalesForce] How to Make Metadata.Operation deploy work

Did anyone tried to new Salesforce Summer 17 feature to deploy metadata records and layouts by Apex Code?

I tried to use this feature to update custom metadata record and it fails for me.
I just copied the examples from official documentation:

I have DeployCallback class implementation like it is provided in the documentation but it doesn't seem that this callback is even called

public class MyDeployCallback implements Metadata.DeployCallback {
    public void handleResult(Metadata.DeployResult result,
                             Metadata.DeployCallbackContext context) {
        System.debug(LoggingLevel.ERROR, '@@@ result: ' + result );
        System.debug(LoggingLevel.ERROR, '@@@ context: ' + context );
        if (result.status == Metadata.DeployStatus.Succeeded) {
            // Deployment was successful
        } else {
            // Deployment was not successful
        }
    }
}

Also I copied Deploy Metadata example from the documentation

public class CreateMetadata{
  public void updateAndDeployMetadata() {
    // Setup custom metadata to be created in the subscriber org.
    Metadata.CustomMetadata customMetadata =  new Metadata.CustomMetadata();
    customMetadata.fullName = 'MetadataTypeName.MetadataRecordName';

    Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();
    customField.field = 'customField__c';
    customField.value = 'New value';

    customMetadata.values.add(customField);

    Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();
    mdContainer.addMetadata(customMetadata);

    // Setup deploy callback, MyDeployCallback implements
    // the Metadata.DeployCallback interface (code for
    // this class not shown in this example)
    MyDeployCallback callback = new MyDeployCallback();

    // Enqueue custom metadata deployment
    Id jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);
      System.debug(LoggingLevel.ERROR, '@@@ jobId: ' + jobId );
  }
}

new CreateMetadata().updateAndDeployMetadata();

However, it doesn't seem to work.

I don't find the corresponding debug log for the Metadata Deploy Callback.

Also when I look at the deployment tab I see the following Fatal Error
Fatal Error
Fatal Error
UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you contact support: 1021353307-20718 (1846919495)

Below I see Component Errors message

Component Errors

Column
Error Message
MetadataTypeName.MetadataRecordName Custom Metadata Record 0 0 Required fields are missing: [MasterLabel]

I have even tried to modify my code and include the following line

customMetadata.MasterLabel = 'MetadataRecordName';

However, such code doesn't compile and throws error

Variable does not exist: masterLabel

When I try to modify this line to

customMetadata.label = 'MetadataRecordName';

It compiles but still gives error
Fatal Error

Strange, but the record gets updated or created in this case.

Does anyone know how to make Deploy Callback work?

Best Answer

Looks like we can't have DeployCallback defined in Anonymous Execution Window code.

If we define DeployCallback as separate class or an inner class of some class saved in the organization (not defined in Anonymous Execution Window) or if we pass second parameter as null then deployment succeeds Success

Also looks like we don't have any option yet to have some action poller to poll async status.

Metadata.Operations.enqueueDeployment method returns Id starting with 0Af prefix.

if we run this code to find out which SObject is related to this prefix

static string getTypeByPrefix(String prefix) {
Id some = prefix + '000000000000';
return some.getSObjectType().getDescribe().getName();
}
System.debug(LoggingLevel.ERROR, '@@@ v: ' + getTypeByPrefix('0Af'));

then it will return us DeployRequest.

However, if we try to run this SOQL Query

select id from DeployRequest

this would return an error saying

sObject type 'DeployRequest' is not supported.

even if we use Tooling API Checkbox. So DeployRequest class is not available and it is not exposed.

DeployCallbackContext variable has jobId property with value 7074D000005dvGOQAY, which should be of type AsyncApexJob. However, if we try to query this record, no records will be returned

select id from AsyncApexJob where Id = '7074D000005dvGOQAY'
Related Topic