deploy()
ファイル表現のコンポーネントを使用して、組織のファイル表現のコンポーネントを作成、更新、または削除します。
構文
1AsyncResult = metadatabinding.deploy(base64 zipFile, DeployOptions deployOptions)使用方法
このコールを使用して、ファイル表現のコンポーネントを取得し、ファイル表現のコンポーネントが表すコンポーネントを作成、更新、または削除することにより、組織にファイル表現のコンポーネントをリリースします。
API バージョン 29.0 では、Salesforce は、リリース状況プロパティを改善し、deploy() コール後にリリースに関する情報を取得するために checkStatus() を使用する要件を削除しました。Salesforce では、API バージョン 28.0 以前で deploy() を使用する場合の checkStatus() の使用を引き続きサポートします。
API バージョン 29.0 以降の場合、次の手順に従って、パッケージ化されたコンポーネントまたはパッケージ化されていないコンポーネントをリリース (作成または更新) します。
- deploy() コールを発行して、非同期リリースを開始すると、AsyncResult オブジェクトが返されます。id 項目の値をメモし、次のステップで使用します。
- checkDeployStatus() コールの発行を、返される DeployResult の done 項目がコールの完了を示す true になるまでループします。DeployResult オブジェクトには、deploy() コールを使用して開始された進行中または完了済みのリリースに関する情報が含まれます。checkDeployStatus() をコールするとき、最初のステップの AsyncResult オブジェクトから id 値を渡します。
API バージョン 28.0 以前の場合、次の手順に従って、パッケージ化されたコンポーネントまたはパッケージ化されていないコンポーネントをリリース (作成または更新) します。
- deploy() コールを発行して、非同期リリースを開始すると、AsyncResult オブジェクトが返されます。コールが完了すると、done 項目に true が含まれます。ほとんどの場合、コールはすぐに完了しないため最初の結果に記述されません。完了している場合、返された id 項目の値を書き留め、次のステップを省略します。
- コールが完了していない場合、前のステップで deploy() コールから返された AsyncResult オブジェクトの id 項目の値を使用して、ループで checkStatus() コールを発行します。done 項目に true が含まれるまで、返される AsyncResult オブジェクトを確認します。deploy() コールを完了するまでにかかる時間は、リリースされる zip ファイルのサイズによって異なるため、zip ファイルのサイズが大きくなるほど、反復間の待機時間をより長くする必要があります。
- 最初のステップで返された id 値を使用して、checkDeployStatus() コールを発行し、deploy() コールの結果を取得します。
処理中または過去 30 日間で完了したリリースの状況を追跡するには、[設定] で または をクリックします。
進行中またはキュー内のリリースは、リリースの横にある [キャンセル] をクリックしてキャンセルできます。リリースが完全にキャンセルされるまで、リリースの状況は Cancel Requested になります。キャンセルされたリリースは、[失敗] セクションにリストされます。
package.xml ファイルは、取得またはリリースするすべてのコンポーネントをリストするプロジェクトマニフェストです。package.xml を使用して、コンポーネントを追加できます。コンポーネントを削除するには、別のマニフェストファイルを追加します。「組織からのコンポーネントの削除」を参照してください。
引数
| 名前 | 型 | 説明 |
|---|---|---|
| zipFile | base64 | Base 64 で符号化されたバイナリデータ クライアントアプリケーションは、バイナリデータを base64 に符号化する必要があります。 |
| deployOptions | DeployOptions | リリースするパッケージまたはファイルを特定するためのオプションをカプセル化します。 |
DeployOptions
このコールでは次のリリースオプションを選択できます。
| 名前 | 型 | 説明 |
|---|---|---|
| allowMissingFiles | boolean | ファイルが package.xml では指定されているが、.zip ファイルにはない場合でもリリースを継続するか (true)、否か (false) を指定します。 |
| autoUpdatePackage | boolean | ファイルが .zip ファイルにはあるが、package.xml で指定されていない場合、ファイルを自動的にパッケージに追加するか (true)、否か (false) を指定します。.zip ファイルを含む package.xml が更新された場合は、retrieve() が自動的に発行されます。 本番組織へのリリースでは、この引数を設定することはできません。 |
| checkOnly | boolean | Apex クラスおよびトリガをリリースの一部として組織に保存するか (false)、否か (true) を示します。デフォルトは false です。発行済みのエラーまたはメッセージもすべて生成されます。このパラメータは、Salesforce Ant ツールの checkOnly パラメータと似ています。 |
| ignoreWarnings | boolean |
警告を無視してリリースの正常な完了を許可するか (true)、否か (false) を示します。デフォルトは false です。 警告の DeployMessage オブジェクトには次の値が含まれます。
警告が発生し、ignoreWarnings が true に設定されている場合は、DeployMessage の success 項目は true です。ignoreWarnings が false に設定されている場合、success は false に設定され、警告はエラーとして処理されます。 この項目は API バージョン 18.0 以降で使用できます。バージョン 18.0 より前では、警告とエラーは区別されていませんでした。すべての問題はエラーとして処理され、リリースの成功を妨げていました。 |
| performRetrieve | boolean | retrieve() コールをリリース直後に実行するか (true)、否か (false) を示します。リリース直後のものをすべて取得するには true に設定します。 |
| purgeOnDelete | boolean |
true の場合、destructiveChanges.xml マニフェストファイルの削除されたコンポーネントはごみ箱に保存されません。代わりに、即座に削除の対象となります。 この項目は API バージョン 22.0 以降で使用できます。 このオプションは Developer Edition 組織または Sandbox 組織でのみ機能しますが、本番組織では機能しません。 |
| rollbackOnError | boolean | エラーが発生した場合、ロールバックを完了するか (true)、否か (false) を示します。false の場合、エラーなしで実行できるアクションのセットはすべて実行され、残りのアクションではエラーが返されます。本番組織にリリースする場合は、このパラメータは true に設定されている必要があります。デフォルトは、false です。 |
| runAllTests | boolean | (廃止。API バージョン 33.0 以前でのみ使用可能) この項目のデフォルトは false です。インストール済みの管理パッケージから作成されたテストを含むすべての Apex テストをリリース後に実行するには、true に設定します。 |
| runTests | string[] | リリース時に実行される Apex テストのリスト。クラス名 (1 インスタンスあたり 1 つの名前) を指定します。また、クラス名にはドット表記で名前空間を指定することもできます。詳細は、「リリースでのテストのサブセットの実行」 を参照してください。 このオプションを使用するには、testLevel を RunSpecifiedTests に設定します。 |
| singlePackage | boolean | 指定された .zip ファイルが指し示すディレクトリ構造が 1 つのパッケージを持つか (true)、パッケージのセットを持つか (false)) を示します。 |
| testLevel | TestLevel (string 型の列挙) |
省略可能。リリースの一環として実行するテストを指定します。テストレベルは、リリースパッケージに存在するコンポーネントの種類に関係なく強制適用されます。有効な値は、次のとおりです。
テストレベルを指定しないと、デフォルトのテスト実行動作が使用されます。「リリースでのテストの実行」を参照してください。 この項目は、API バージョン 34.0 以降で使用できます。 |
応答
サンプルコード —Java
このサンプルでは、zip ファイルでコンポーネントをリリースする方法を示します。zip ファイルの取得方法についての詳細は、retrieve() のサンプルコードを参照してください。
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}