Change Set Downloader
- abhyash
- Nov 2, 2022
- 2 min read
Updated: Nov 5, 2022
V1 Prepared By: Abhyash Timsina – 2 November 2022
Motivation: This is providing ability to download change set metadata as a single zip for a specific change set with a single click from a flow. Note - This is a personal project and not intended for financial gain.
My Technical Components

Open Source Technical Components

The Flow

Images



Source Code for ChangeSetDownloader Apex Class (with annotation starting with //)
/**
* Created by Abhyash Timsina on 2/11/22.
*/
public with sharing class ChangeSetDownloader {
// Flow inputs - the change set name (passed by the user from screen flow) and the api version( this gets passed when flow queries itself and gets the current api version)
public class flowInput {
@InvocableVariable(Required=true)
public String changeSetName;
@InvocableVariable(Required=true)
public Integer apiVersion;
}
// Invocable method that is accessible by flow
@InvocableMethod(Label='Change Set Downloader Invocable' Description='Download Change Sets')
public static void changeSetToDownload(flowInput[] requests) {
for (flowInput request : requests) {
// Call workbench future method with parameters
workbenchCallout(request.changeSetName, request.apiVersion);
}
}
// The future method
@Future(Callout = true)
public static void workbenchCallout(String changeSetName, Integer apiVersion){
List<String> changeSetNames = new List<String>();
changeSetNames.add(changeSetName);
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
// Set Session Headers so Workbench knows to communicate with logged in users id
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();
// Do a retrieve request and pass variables to Workbench, specifically the change set name from screen
MetadataService.RetrieveRequest retrieveRequest = new MetadataService.RetrieveRequest();
Decimal apiVersionDecimal = apiVersion;
retrieveRequest.apiVersion = apiVersionDecimal;
retrieveRequest.packageNames = changeSetNames;
retrieveRequest.singlePackage = true;
retrieveRequest.specificFiles = null;
retrieveRequest.unpackaged = null;
// Async the retrieval
MetadataService.AsyncResult ar = service.retrieve(retrieveRequest);
// Wait 4 seconds - this is required because the zip file has a delay
wait(4000);
// Make request to check status of the retrieval
MetadataService.RetrieveResult retrieveResult = service.checkRetrieveStatus
(ar.id, true);
// Create a File and pass the decoded base 64 version of the zip file that was retrieved
ContentVersion cv = new ContentVersion(
Title = 'Change Set: ' + changeSetName,
VersionData = EncodingUtil.base64Decode(retrieveResult.zipFile),
PathOnClient = 'Change Set: ' + changeSetName + '.zip'
);
insert cv;
// Create a Content Distribution record so the file can have a publicly accessible link
ContentDistribution cd = new ContentDistribution();
cd.Name = 'Change Set: ' + changeSetName;
cd.ContentVersionId = cv.Id;
cd.PreferencesAllowViewInBrowser = true;
insert cd;
}
// Method for waiting using milliseconds as parameters
w
public static void wait(Long millisec)
{
if(millisec == null || millisec < 0) {
millisec = 0;
}
Long startTime = Datetime.now().getTime();
Long finishTime = Datetime.now().getTime();
while ((finishTime - startTime) < millisec) {
finishTime = Datetime.now().getTime();
}
}
}
Package Link:
If you need help in installing and getting this working – please contact me on LinkedIn
Comments