deployRecentValidation()
構文
1string = metadatabinding.deployRecentValidation(ID validationID)使用方法
deployRecentValidation() を使用して、Apex テストの実行を省略し、より短い時間でコンポーネントを本番組織にリリースできます。最近の検証をリリースする前に次の要件が満たされていることを確認します。
- コンポーネントが対象の環境で過去 10 日以内に正常に検証されている。
- 検証の一部として、対象組織での Apex テストに合格している。
- コードカバー率要件を満たしている。
- 組織のすべてのテストまたはすべてのローカルテストが実行された場合、全体のコードカバー率は 75% 以上で、Apex トリガーについてもある程度のコードカバー率が必要である。
- 特定のテストが RunSpecifiedTests テストレベルで実行された場合、リリースされる各クラスおよびトリガーの個々のカバー率が 75% 以上である。
このコールは、Salesforce ユーザーインターフェースの [リリース状況] ページで最近の検証のクイックリリースを実行するのと同じです。
deployRecentValidation() をコールするには、組織に最近実行された検証がある必要があります。コンポーネントのセットに対して検証を実行するには、deployOptions パラメーターの checkOnly プロパティを true に設定して deploy() をコールします。deploy() コールで取得した ID をメモします。この ID は、次のステップで deployRecentValidation() コールに使用します。
検証の実行が成功したら、この手順を使用して、同じリリース先環境に検証をクイックリリースします。
- 非同期クイックリリースを開始するには、deployRecentValidation() をコールして最近の検証の ID を渡します。この ID は、前の deploy() コールで取得したものです。deployRecentValidation() コールはクイックリリースの ID を返します。この値をメモします。次のステップでこれを使用します。
- コールが完了したかどうかを確認します。このプロセスは deploy() のプロセスと似ています。checkDeployStatus() コールの発行をループします。このループは、返される DeployResult の done 項目がコールの完了を示す true になるまで続けられます。DeployResult オブジェクトには、deployRecentValidation() コールを使用して開始された進行中または完了済みのリリースに関する情報が含まれます。checkDeployStatus() をコールするときに、最初のステップで取得した ID 値を渡します。
バージョン
API バージョン 33.0 以降で利用できます。
引数
| 名前 | 型 | 説明 |
|---|---|---|
| validationID | string | 最近の検証の ID。 |
応答
型: string
クイックリリースの ID。
サンプルコード — Java
1package com.salesforce.test.metadata;
2
3import java.rmi.RemoteException;
4
5import com.sforce.soap.metadata.CodeCoverageWarning;
6import com.sforce.soap.metadata.DeployDetails;
7import com.sforce.soap.metadata.DeployMessage;
8import com.sforce.soap.metadata.DeployResult;
9import com.sforce.soap.metadata.MetadataConnection;
10import com.sforce.soap.metadata.RunTestFailure;
11import com.sforce.soap.metadata.RunTestsResult;
12import com.sforce.soap.partner.Connector;
13import com.sforce.ws.ConnectionException;
14import com.sforce.ws.ConnectorConfig;
15
16/**
17 * Quick-deploy a recent validation.
18 * Prerequisite: A successful validation (check-only deploy) has been done in the org recently.
19 */
20public class DeployRecentValidationSample {
21 // binding for the metadata WSDL used for making metadata API calls
22 private MetadataConnection metadataConnection;
23
24 // one second in milliseconds
25 private static final long ONE_SECOND = 1000;
26 // maximum number of attempts to deploy the zip file
27 private static final int MAX_NUM_POLL_REQUESTS = 50;
28
29 public static void main(String[] args) throws Exception {
30 final String USERNAME = args[0];
31 final String PASSWORD = args[1];
32 final String URL = args[2];
33
34 final String recentValidationId = args[3];
35
36 DeployRecentValidationSample sample = new DeployRecentValidationSample(
37 USERNAME, PASSWORD, URL);
38 sample.deployRecentValidation(recentValidationId);
39 }
40
41 public DeployRecentValidationSample(String username, String password, String loginUrl)
42 throws ConnectionException {
43 createMetadataConnection(username, password, loginUrl);
44 }
45
46 public void deployRecentValidation(String recentValidationId)
47 throws RemoteException, Exception
48 {
49 String asyncResultId = metadataConnection.deployRecentValidation(recentValidationId);
50
51 // Wait for the deploy to complete
52 int poll = 0;
53 long waitTimeMilliSecs = ONE_SECOND;
54 DeployResult deployResult = null;
55 boolean fetchDetails;
56 do {
57 Thread.sleep(waitTimeMilliSecs);
58 // double the wait time for the next iteration
59 waitTimeMilliSecs *= 2;
60 if (poll++ > MAX_NUM_POLL_REQUESTS) {
61 throw new Exception("Request timed out. If this is a large set " +
62 "of metadata components, check that the time allowed by " +
63 "MAX_NUM_POLL_REQUESTS is sufficient.");
64 }
65
66 // Fetch in-progress details once for every 3 polls
67 fetchDetails = (poll % 3 == 0);
68 deployResult = metadataConnection.checkDeployStatus(asyncResultId, fetchDetails);
69 System.out.println("Status is: " + deployResult.getStatus());
70 if (!deployResult.isDone() && fetchDetails) {
71 printErrors(deployResult, "Failures for deployment in progress:\n");
72 }
73 }
74 while (!deployResult.isDone());
75
76 if (!deployResult.isSuccess() && deployResult.getErrorStatusCode() != null) {
77 throw new Exception(deployResult.getErrorStatusCode() + " msg: " +
78 deployResult.getErrorMessage());
79 }
80
81 if (!fetchDetails) {
82 // Get the final result with details if we didn't do it in the last attempt.
83 deployResult = metadataConnection.checkDeployStatus(asyncResultId, true);
84 }
85
86 if (!deployResult.isSuccess()) {
87 printErrors(deployResult, "Final list of failures:\n");
88 throw new Exception("The files were not successfully deployed");
89 }
90
91 System.out.println("The recent validation " + recentValidationId +
92 " was successfully deployed");
93 }
94
95 /**
96 * Print out any errors, if any, related to the deploy.
97 * @param result - DeployResult
98 */
99 private void printErrors(DeployResult result, String messageHeader)
100 {
101 DeployDetails deployDetails = result.getDetails();
102
103 StringBuilder errorMessageBuilder = new StringBuilder();
104 if (deployDetails != null) {
105 DeployMessage[] componentFailures = deployDetails.getComponentFailures();
106 for (DeployMessage message : componentFailures) {
107 String loc = (message.getLineNumber() == 0 ? "" :
108 ("(" + message.getLineNumber() + "," +
109 message.getColumnNumber() + ")"));
110 if (loc.length() == 0
111 && !message.getFileName().equals(message.getFullName())) {
112 loc = "(" + message.getFullName() + ")";
113 }
114 errorMessageBuilder.append(message.getFileName() + loc + ":" +
115 message.getProblem()).append('\n');
116 }
117 RunTestsResult rtr = deployDetails.getRunTestResult();
118 if (rtr.getFailures() != null) {
119 for (RunTestFailure failure : rtr.getFailures()) {
120 String n = (failure.getNamespace() == null ? "" :
121 (failure.getNamespace() + ".")) + failure.getName();
122 errorMessageBuilder.append("Test failure, method: " + n + "." +
123 failure.getMethodName() + " -- " +
124 failure.getMessage() + " stack " +
125 failure.getStackTrace() + "\n\n");
126 }
127 }
128 if (rtr.getCodeCoverageWarnings() != null) {
129 for (CodeCoverageWarning ccw : rtr.getCodeCoverageWarnings()) {
130 errorMessageBuilder.append("Code coverage issue");
131 if (ccw.getName() != null) {
132 String n = (ccw.getNamespace() == null ? "" :
133 (ccw.getNamespace() + ".")) + ccw.getName();
134 errorMessageBuilder.append(", class: " + n);
135 }
136 errorMessageBuilder.append(" -- " + ccw.getMessage() + "\n");
137 }
138 }
139 }
140
141 if (errorMessageBuilder.length() > 0) {
142 errorMessageBuilder.insert(0, messageHeader);
143 System.out.println(errorMessageBuilder.toString());
144 }
145 }
146
147 private void createMetadataConnection(
148 final String username,
149 final String password,
150 final String loginUrl) throws ConnectionException {
151
152 final ConnectorConfig loginConfig = new ConnectorConfig();
153 loginConfig.setUsername(username);
154 loginConfig.setPassword(password);
155 loginConfig.setAuthEndpoint(loginUrl);
156
157 Connector.newConnection(loginConfig);
158
159
160 final ConnectorConfig metadataConfig = new ConnectorConfig();
161 metadataConfig.setServiceEndpoint(
162 loginConfig.getServiceEndpoint().replace("/u/", "/m/"));
163 metadataConfig.setSessionId(loginConfig.getSessionId());
164 this.metadataConnection = com.sforce.soap.metadata.Connector.
165 newConnection(metadataConfig);
166 }
167
168}