Move result-index availability check to monitorQuery
This commit is contained in:
@@ -10,6 +10,8 @@ import { RemoteQuery } from './remote-query';
|
|||||||
import { RemoteQueryFailureIndexItem, RemoteQueryResultIndex, RemoteQuerySuccessIndexItem } from './remote-query-result-index';
|
import { RemoteQueryFailureIndexItem, RemoteQueryResultIndex, RemoteQuerySuccessIndexItem } from './remote-query-result-index';
|
||||||
import { getErrorMessage } from '../pure/helpers-pure';
|
import { getErrorMessage } from '../pure/helpers-pure';
|
||||||
|
|
||||||
|
export const RESULT_INDEX_ARTIFACT_NAME = 'result-index';
|
||||||
|
|
||||||
interface ApiSuccessIndexItem {
|
interface ApiSuccessIndexItem {
|
||||||
nwo: string;
|
nwo: string;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -43,7 +45,8 @@ export async function getRemoteQueryIndex(
|
|||||||
const workflowUri = `https://github.com/${owner}/${repoName}/actions/runs/${workflowRunId}`;
|
const workflowUri = `https://github.com/${owner}/${repoName}/actions/runs/${workflowRunId}`;
|
||||||
const artifactsUrlPath = `/repos/${owner}/${repoName}/actions/artifacts`;
|
const artifactsUrlPath = `/repos/${owner}/${repoName}/actions/artifacts`;
|
||||||
|
|
||||||
const [artifactList, resultIndexArtifactId] = await waitForArtifact(credentials, owner, repoName, workflowRunId, 'result-indx');
|
const artifactList = await listWorkflowRunArtifacts(credentials, owner, repoName, workflowRunId);
|
||||||
|
const resultIndexArtifactId = tryGetArtifactIDfromName(RESULT_INDEX_ARTIFACT_NAME, artifactList);
|
||||||
if (!resultIndexArtifactId) {
|
if (!resultIndexArtifactId) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -115,6 +118,27 @@ export async function downloadArtifactFromLink(
|
|||||||
return path.join(extractedPath, downloadLink.innerFilePath || '');
|
return path.join(extractedPath, downloadLink.innerFilePath || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a specific artifact is present in the list of artifacts of a workflow run.
|
||||||
|
* @param credentials Credentials for authenticating to the GitHub API.
|
||||||
|
* @param owner
|
||||||
|
* @param repo
|
||||||
|
* @param workflowRunId The ID of the workflow run to get the artifact for.
|
||||||
|
* @param artifactName The artifact name, as a string.
|
||||||
|
* @returns A boolean indicating if the artifact is available.
|
||||||
|
*/
|
||||||
|
export async function isArtifactAvailable(
|
||||||
|
credentials: Credentials,
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
workflowRunId: number,
|
||||||
|
artifactName: string,
|
||||||
|
): Promise<boolean> {
|
||||||
|
const artifactList = await listWorkflowRunArtifacts(credentials, owner, repo, workflowRunId);
|
||||||
|
|
||||||
|
return tryGetArtifactIDfromName(artifactName, artifactList) !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads the result index artifact and extracts the result index items.
|
* Downloads the result index artifact and extracts the result index items.
|
||||||
* @param credentials Credentials for authenticating to the GitHub API.
|
* @param credentials Credentials for authenticating to the GitHub API.
|
||||||
@@ -254,44 +278,6 @@ function tryGetArtifactIDfromName(
|
|||||||
return artifact?.id;
|
return artifact?.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for an artifact to be available in a workflow run.
|
|
||||||
* @param credentials Credentials for authenticating to the GitHub API.
|
|
||||||
* @param owner
|
|
||||||
* @param repo
|
|
||||||
* @param workflowRunId The ID of the workflow run to get the artifact for.
|
|
||||||
* @param artifactName The artifact name, as a string.
|
|
||||||
* @param maxAttempts The maximum number of attempts to download the artifact.
|
|
||||||
* @returns An array containing the full list of artifacts and the ID of the artifact with the given name.
|
|
||||||
*/
|
|
||||||
async function waitForArtifact(
|
|
||||||
credentials: Credentials,
|
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
workflowRunId: number,
|
|
||||||
artifactName: string,
|
|
||||||
maxAttempts = 10,
|
|
||||||
intervalBetweenAttempts = 1000
|
|
||||||
): Promise<[Awaited<ReturnType<typeof listWorkflowRunArtifacts>>, number | undefined]> {
|
|
||||||
let attemptCount = 0;
|
|
||||||
let artifactList: Awaited<ReturnType<typeof listWorkflowRunArtifacts>> = [];
|
|
||||||
|
|
||||||
while (attemptCount < maxAttempts) {
|
|
||||||
artifactList = await listWorkflowRunArtifacts(credentials, owner, repo, workflowRunId);
|
|
||||||
|
|
||||||
const resultIndexArtifactId = tryGetArtifactIDfromName(artifactName, artifactList);
|
|
||||||
if (resultIndexArtifactId) {
|
|
||||||
return [artifactList, resultIndexArtifactId];
|
|
||||||
}
|
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, intervalBetweenAttempts));
|
|
||||||
|
|
||||||
attemptCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [artifactList, undefined];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads an artifact from a workflow run.
|
* Downloads an artifact from a workflow run.
|
||||||
* @param credentials Credentials for authenticating to the GitHub API.
|
* @param credentials Credentials for authenticating to the GitHub API.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { Credentials } from '../authentication';
|
import { Credentials } from '../authentication';
|
||||||
import { Logger } from '../logging';
|
import { Logger } from '../logging';
|
||||||
import { getWorkflowStatus } from './gh-actions-api-client';
|
import { getWorkflowStatus, isArtifactAvailable, RESULT_INDEX_ARTIFACT_NAME } from './gh-actions-api-client';
|
||||||
import { RemoteQuery } from './remote-query';
|
import { RemoteQuery } from './remote-query';
|
||||||
import { RemoteQueryWorkflowResult } from './remote-query-workflow-result';
|
import { RemoteQueryWorkflowResult } from './remote-query-workflow-result';
|
||||||
|
|
||||||
@@ -42,7 +42,25 @@ export class RemoteQueriesMonitor {
|
|||||||
remoteQuery.controllerRepository.name,
|
remoteQuery.controllerRepository.name,
|
||||||
remoteQuery.actionsWorkflowRunId);
|
remoteQuery.actionsWorkflowRunId);
|
||||||
|
|
||||||
if (workflowStatus.status !== 'InProgress') {
|
// Even if the workflow indicates it has completed, artifacts
|
||||||
|
// might still take a while to become available. So we need to
|
||||||
|
// check for the artifact before we can declare the workflow
|
||||||
|
// as having completed.
|
||||||
|
if (workflowStatus.status === 'CompletedSuccessfully') {
|
||||||
|
const resultIndexAvailable = await isArtifactAvailable(
|
||||||
|
credentials,
|
||||||
|
remoteQuery.controllerRepository.owner,
|
||||||
|
remoteQuery.controllerRepository.name,
|
||||||
|
remoteQuery.actionsWorkflowRunId,
|
||||||
|
RESULT_INDEX_ARTIFACT_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resultIndexAvailable) {
|
||||||
|
return workflowStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't have a result-index yet, so we'll keep monitoring.
|
||||||
|
} else if (workflowStatus.status !== 'InProgress') {
|
||||||
return workflowStatus;
|
return workflowStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user