Allow publishing retry (#204758)

* Allow publishing retry

* Update build/azure-pipelines/common/publish.ts

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>

* Update build/azure-pipelines/common/publish.ts

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>

* Compile

---------

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
This commit is contained in:
Logan Ramos 2024-02-08 12:00:44 -07:00 committed by GitHub
parent f1f5d07d14
commit 2033eae5af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 2 deletions

View file

@ -41,6 +41,9 @@ class Temp {
}
}
}
function isCreateProvisionedFilesErrorResponse(response) {
return response?.ErrorDetails !== undefined;
}
class ProvisionService {
log;
accessToken;
@ -63,6 +66,10 @@ class ProvisionService {
});
this.log(`Provisioning ${fileName} (releaseId: ${releaseId}, fileId: ${fileId})...`);
const res = await (0, retry_1.retry)(() => this.request('POST', '/api/v2/ProvisionedFiles/CreateProvisionedFiles', { body }));
if (isCreateProvisionedFilesErrorResponse(res) && res.ErrorDetails.Code === 'FriendlyFileNameAlreadyProvisioned') {
this.log(`File already provisioned (most likley due to a re-run), skipping: ${fileName}`);
return;
}
if (!res.IsSuccess) {
throw new Error(`Failed to submit provisioning request: ${JSON.stringify(res.ErrorDetails)}`);
}
@ -78,7 +85,9 @@ class ProvisionService {
}
};
const res = await fetch(`https://dsprovisionapi.microsoft.com${url}`, opts);
if (!res.ok || res.status < 200 || res.status >= 500) {
// 400 normally means the request is bad or something is already provisioned, so we will return as retries are useless
// Otherwise log the text body and headers. We do text because some responses are not JSON.
if ((!res.ok || res.status < 200 || res.status >= 500) && res.status !== 400) {
throw new Error(`Unexpected status code: ${res.status}\nResponse Headers: ${JSON.stringify(res.headers)}\nBody Text: ${await res.text()}`);
}
return await res.json();

View file

@ -69,6 +69,10 @@ interface CreateProvisionedFilesErrorResponse {
type CreateProvisionedFilesResponse = CreateProvisionedFilesSuccessResponse | CreateProvisionedFilesErrorResponse;
function isCreateProvisionedFilesErrorResponse(response: unknown): response is CreateProvisionedFilesErrorResponse {
return (response as CreateProvisionedFilesErrorResponse)?.ErrorDetails !== undefined;
}
class ProvisionService {
constructor(
@ -93,6 +97,11 @@ class ProvisionService {
this.log(`Provisioning ${fileName} (releaseId: ${releaseId}, fileId: ${fileId})...`);
const res = await retry(() => this.request<CreateProvisionedFilesResponse>('POST', '/api/v2/ProvisionedFiles/CreateProvisionedFiles', { body }));
if (isCreateProvisionedFilesErrorResponse(res) && res.ErrorDetails.Code === 'FriendlyFileNameAlreadyProvisioned') {
this.log(`File already provisioned (most likley due to a re-run), skipping: ${fileName}`);
return;
}
if (!res.IsSuccess) {
throw new Error(`Failed to submit provisioning request: ${JSON.stringify(res.ErrorDetails)}`);
}
@ -112,7 +121,10 @@ class ProvisionService {
const res = await fetch(`https://dsprovisionapi.microsoft.com${url}`, opts);
if (!res.ok || res.status < 200 || res.status >= 500) {
// 400 normally means the request is bad or something is already provisioned, so we will return as retries are useless
// Otherwise log the text body and headers. We do text because some responses are not JSON.
if ((!res.ok || res.status < 200 || res.status >= 500) && res.status !== 400) {
throw new Error(`Unexpected status code: ${res.status}\nResponse Headers: ${JSON.stringify(res.headers)}\nBody Text: ${await res.text()}`);
}