Newer Version Available
deploy()
Uses file representations of components to create, update, or delete those components in an organization.
Syntax
1AsyncResult = metadatabinding.deploy(base64 zipFile, DeployOptions deployOptions)Usage
Use this call to take file representations of components and deploy them into an organization by creating, updating, or deleting the components they represent.
In API version 29.0, Salesforce improved the deployment status properties and removed the requirement to use checkStatus() after a deploy() call to get information about deployments. Salesforce continues to support the use of checkStatus() when using deploy() with API version 28.0 or earlier.
For API version 29.0 or later, deploy (create or update) packaged or unpackaged components using the following steps.
- Issue a deploy() call to start the asynchronous deployment. An AsyncResult object is returned. Note the value in the id field and use it for the next step.
- Issue a checkDeployStatus() call in a loop until the done field of the returned DeployResult contains true, which means that the call is completed. The DeployResult object contains information about an in-progress or completed deployment started using the deploy() call. When calling checkDeployStatus(), pass in the id value from the AsyncResult object from the first step.
For API version 28.0 or earlier, deploy (create or update) packaged or unpackaged components using the following steps.
- Issue a deploy() call to start the asynchronous deployment. An AsyncResult object is returned. If the call is completed, the done field contains true. Most often, the call is not completed quickly enough to be noted in the first result. If it is completed, note the value in the id field returned and skip the next step.
- If the call is not complete, issue a checkStatus() call in a loop using the value in the id field of the AsyncResult object returned by the deploy() call in the previous step. Check the AsyncResult object which is returned until the done field contains true. The time taken to complete a deploy() call depends on the size of the zip file being deployed, so a longer wait time between iterations should be used as the size of the zip file increases.
- Issue a checkDeployStatus() call to obtain the results of the deploy() call, using the id value returned in the first step.
To track the status of deployments that are in progress or completed in the last 30 days, from Setup, click or .
You can cancel a deployment while it’s in progress or in the queue by clicking Cancel next to the deployment. The deployment then has the status Cancel Requested until the deployment is completely canceled. A canceled deployment is listed in the Failed section.
The package.xml file is a project manifest that lists all the components that you want to retrieve or deploy. You can use package.xml to add components. To delete components, add another manifest file. See Deleting Components from an Organization.
Arguments
| Name | Type | Description |
|---|---|---|
| zipFile | base64 | Base 64-encoded binary data. Client applications must encode the binary data as base64. |
| deployOptions | DeployOptions | Encapsulates options for determining which packages or files are deployed. |
DeployOptions
The following deployment options can be selected for this call:
| Name | Type | Description |
|---|---|---|
| allowMissingFiles | boolean | Specifies whether a deploy succeeds even if files that are
specified in package.xml but are not in the
.zip file (true or not false). Do not set this argument for deployment to production organizations. |
| autoUpdatePackage | boolean | If a file is in the .zip
file but not specified in package.xml,
specifies whether the file should be automatically added to the
package (true or not false). A retrieve() is automatically issued with the updated
package.xml that includes the .zip file. Do not set this argument for deployment to production organizations. |
| checkOnly | boolean | Indicates whether Apex classes and triggers are saved to the organization as part of the deployment (false) or not (true). Defaults to false. Any errors or messages that would have been issued are still generated. This parameter is similar to the Salesforce Ant tool’s checkOnly parameter. |
| ignoreWarnings | boolean |
Indicates whether a warning
should allow a deployment to complete successfully (true) or not (false). Defaults to false. The DeployMessage object for a warning contains the following values:
If a warning occurs and ignoreWarnings is set to true, the success field in DeployMessage is true. If ignoreWarnings is set to false, success is set to false and the warning is treated like an error. This field is available in API version 18.0 and later. Prior to version 18.0, there was no distinction between warnings and errors. All problems were treated as errors and prevented a successful deployment. |
| performRetrieve | boolean | Indicates whether a retrieve() call is performed immediately after the deployment (true) or not (false). Set to true in order to retrieve whatever was just deployed. |
| purgeOnDelete | boolean |
If true, the deleted components in the
destructiveChanges.xml manifest file
aren't stored in the Recycle Bin. Instead, they become immediately eligible for
deletion. This field is available in API version 22.0 and later. This option only works in Developer Edition or sandbox organizations; it doesn't work in production organizations. |
| rollbackOnError | boolean | Indicates whether any failure causes a complete rollback (true) or not (false). If false, whatever set of actions can be performed without errors are performed, and errors are returned for the remaining actions. This parameter must be set to true if you are deploying to a production organization. The default is false. |
| runAllTests | boolean | (Deprecated and only available in API version 33.0 and earlier.) This field defaults to false. Set to true to run all Apex tests after deployment, including tests that originate from installed managed packages. |
| runTests | string[] | A list of Apex tests to run during deployment. Specify the class name, one name
per instance. The class name can also specify a namespace with a dot
notation. For more information, see Running a Subset of Tests in a Deployment. To use this option, set testLevel to RunSpecifiedTests. |
| singlePackage | boolean | Indicates whether the specified .zip file points to a directory structure with a single package (true) or a set of packages (false). |
| testLevel | TestLevel (enumeration of type string) |
Optional. Specifies which tests are run as part of a deployment.
The test level is enforced regardless of the types of components that are present in the
deployment package. Valid values are:
If you don’t specify a test level, the default test execution behavior is used. See Running Tests in a Deployment. This field is available in API version 34.0 and later. |
Response
Sample Code—Java
This sample shows how to deploy components in a zip file. See the retrieve() sample code for details on how to retrieve a zip file.
1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package com.doc.samples;
18
19import java.io.*;
20
21import java.rmi.RemoteException;
22
23import com.sforce.soap.metadata.AsyncResult;
24import com.sforce.soap.metadata.DeployDetails;
25import com.sforce.soap.metadata.MetadataConnection;
26import com.sforce.soap.metadata.DeployOptions;
27import com.sforce.soap.metadata.DeployResult;
28import com.sforce.soap.metadata.DeployMessage;
29import com.sforce.soap.metadata.RunTestsResult;
30import com.sforce.soap.metadata.RunTestFailure;
31import com.sforce.soap.metadata.CodeCoverageWarning;
32import com.sforce.soap.enterprise.LoginResult;
33import com.sforce.soap.enterprise.EnterpriseConnection;
34import com.sforce.ws.ConnectionException;
35import com.sforce.ws.ConnectorConfig;
36
37/**
38 * Deploy a zip file of metadata components.
39 * Prerequisite: Have a deploy.zip file that includes a package.xml manifest file that
40 * details the contents of the zip file.
41 */
42public class DeploySample {
43 // binding for the metadata WSDL used for making metadata API calls
44 private MetadataConnection metadataConnection;
45
46 static BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
47
48 private static final String ZIP_FILE = "deploy.zip";
49
50 // one second in milliseconds
51 private static final long ONE_SECOND = 1000;
52 // maximum number of attempts to deploy the zip file
53 private static final int MAX_NUM_POLL_REQUESTS = 50;
54
55 public static void main(String[] args) throws Exception {
56 final String USERNAME = "user@company.com";
57 // This is only a sample. Hard coding passwords in source files is a bad practice.
58 final String PASSWORD = "password";
59 final String URL = "https://login.salesforce.com/services/Soap/c/29.0";
60
61 DeploySample sample = new DeploySample(USERNAME, PASSWORD, URL);
62 sample.deployZip();
63 }
64
65 public DeploySample(String username, String password, String loginUrl)
66 throws ConnectionException {
67 createMetadataConnection(username, password, loginUrl);
68 }
69
70 public void deployZip()
71 throws RemoteException, Exception
72 {
73 byte zipBytes[] = readZipFile();
74 DeployOptions deployOptions = new DeployOptions();
75 deployOptions.setPerformRetrieve(false);
76 deployOptions.setRollbackOnError(true);
77 AsyncResult asyncResult = metadataConnection.deploy(zipBytes, deployOptions);
78 String asyncResultId = asyncResult.getId();
79
80 // Wait for the deploy to complete
81 int poll = 0;
82 long waitTimeMilliSecs = ONE_SECOND;
83 DeployResult deployResult = null;
84 boolean fetchDetails;
85 do {
86 Thread.sleep(waitTimeMilliSecs);
87 // double the wait time for the next iteration
88 waitTimeMilliSecs *= 2;
89 if (poll++ > MAX_NUM_POLL_REQUESTS) {
90 throw new Exception("Request timed out. If this is a large set " +
91 "of metadata components, check that the time allowed by " +
92 "MAX_NUM_POLL_REQUESTS is sufficient.");
93 }
94
95 // Fetch in-progress details once for every 3 polls
96 fetchDetails = (poll % 3 == 0);
97 deployResult = metadataConnection.checkDeployStatus(asyncResultId, fetchDetails);
98 System.out.println("Status is: " + deployResult.getStatus());
99 if (!deployResult.isDone() && fetchDetails) {
100 printErrors(deployResult, "Failures for deployment in progress:\n");
101 }
102 }
103 while (!deployResult.isDone());
104
105 if (!deployResult.isSuccess() && deployResult.getErrorStatusCode() != null) {
106 throw new Exception(deployResult.getErrorStatusCode() + " msg: " +
107 deployResult.getErrorMessage());
108 }
109
110 if (!fetchDetails) {
111 // Get the final result with details if we didn't do it in the last attempt.
112 deployResult = metadataConnection.checkDeployStatus(asyncResultId, true);
113 }
114
115 if (!deployResult.isSuccess()) {
116 printErrors(deployResult, "Final list of failures:\n");
117 throw new Exception("The files were not successfully deployed");
118 }
119
120 System.out.println("The file " + ZIP_FILE + " was successfully deployed");
121 }
122
123 /**
124 * Read the zip file contents into a byte array.
125 * @return byte[]
126 * @throws Exception - if cannot find the zip file to deploy
127 */
128 private byte[] readZipFile()
129 throws Exception
130 {
131 // We assume here that you have a deploy.zip file.
132 // See the retrieve sample for how to retrieve a zip file.
133 File deployZip = new File(ZIP_FILE);
134 if (!deployZip.exists() || !deployZip.isFile())
135 throw new Exception("Cannot find the zip file to deploy. Looking for " +
136 deployZip.getAbsolutePath());
137
138 FileInputStream fos = new FileInputStream(deployZip);
139 ByteArrayOutputStream bos = new ByteArrayOutputStream();
140 int readbyte = -1;
141 while ((readbyte = fos.read()) != -1) {
142 bos.write(readbyte);
143 }
144 fos.close();
145 bos.close();
146 return bos.toByteArray();
147 }
148
149
150 /**
151 * Print out any errors, if any, related to the deploy.
152 * @param result - DeployResult
153 */
154 private void printErrors(DeployResult result, String messageHeader)
155 {
156 DeployDetails deployDetails = result.getDetails();
157
158 StringBuilder errorMessageBuilder = new StringBuilder();
159 if (deployDetails != null) {
160 DeployMessage[] componentFailures = deployDetails.getComponentFailures();
161 for (DeployMessage message : componentFailures) {
162 String loc = (message.getLineNumber() == 0 ? "" :
163 ("(" + message.getLineNumber() + "," +
164 message.getColumnNumber() + ")"));
165 if (loc.length() == 0
166 && !message.getFileName().equals(message.getFullName())) {
167 loc = "(" + message.getFullName() + ")";
168 }
169 errorMessageBuilder.append(message.getFileName() + loc + ":" +
170 message.getProblem()).append('\n');
171 }
172 RunTestsResult rtr = deployDetails.getRunTestResult();
173 if (rtr.getFailures() != null) {
174 for (RunTestFailure failure : rtr.getFailures()) {
175 String n = (failure.getNamespace() == null ? "" :
176 (failure.getNamespace() + ".")) + failure.getName();
177 errorMessageBuilder.append("Test failure, method: " + n + "." +
178 failure.getMethodName() + " -- " +
179 failure.getMessage() + " stack " +
180 failure.getStackTrace() + "\n\n");
181 }
182 }
183 if (rtr.getCodeCoverageWarnings() != null) {
184 for (CodeCoverageWarning ccw : rtr.getCodeCoverageWarnings()) {
185 errorMessageBuilder.append("Code coverage issue");
186 if (ccw.getName() != null) {
187 String n = (ccw.getNamespace() == null ? "" :
188 (ccw.getNamespace() + ".")) + ccw.getName();
189 errorMessageBuilder.append(", class: " + n);
190 }
191 errorMessageBuilder.append(" -- " + ccw.getMessage() + "\n");
192 }
193 }
194 }
195
196 if (errorMessageBuilder.length() > 0) {
197 errorMessageBuilder.insert(0, messageHeader);
198 System.out.println(errorMessageBuilder.toString());
199 }
200 }
201
202 private void createMetadataConnection(
203 final String username,
204 final String password,
205 final String loginUrl) throws ConnectionException {
206
207 final ConnectorConfig loginConfig = new ConnectorConfig();
208 loginConfig.setAuthEndpoint(loginUrl);
209 loginConfig.setServiceEndpoint(loginUrl);
210 loginConfig.setManualLogin(true);
211 LoginResult loginResult = (new EnterpriseConnection(loginConfig)).login(
212 username, password);
213
214 final ConnectorConfig metadataConfig = new ConnectorConfig();
215 metadataConfig.setServiceEndpoint(loginResult.getMetadataServerUrl());
216 metadataConfig.setSessionId(loginResult.getSessionId());
217 this.metadataConnection = new MetadataConnection(metadataConfig);
218 }
219
220}