diff --git a/torchci/clickhouse_queries/commit_jobs_query/query.sql b/torchci/clickhouse_queries/commit_jobs_query/query.sql index fbb5389235..71182dc009 100644 --- a/torchci/clickhouse_queries/commit_jobs_query/query.sql +++ b/torchci/clickhouse_queries/commit_jobs_query/query.sql @@ -11,7 +11,14 @@ WITH job AS ( job.id, workflow.id AS workflow_id, workflow.artifacts_url AS github_artifact_url, - job.conclusion, + multiIf( + job.conclusion = '' + and status = 'queued' , + 'queued', + job.conclusion = '', + 'pending', + job.conclusion + ) as conclusion, job.html_url, IF( {repo: String } = 'pytorch/pytorch', diff --git a/torchci/clickhouse_queries/hud_query/query.sql b/torchci/clickhouse_queries/hud_query/query.sql index e72b608bcc..869a439fdc 100644 --- a/torchci/clickhouse_queries/hud_query/query.sql +++ b/torchci/clickhouse_queries/hud_query/query.sql @@ -4,6 +4,7 @@ WITH job AS ( job.name as job_name, workflow.name as workflow_name, job.id as id, + job.status as status, job.conclusion as conclusion, job.html_url as html_url, IF( @@ -47,11 +48,15 @@ SELECT sha, CONCAT(workflow_name, ' / ', job_name) as name, id, - if( - conclusion = '', - 'pending', - conclusion - ) as conclusion, + multiIf( + conclusion = '' + and status = 'queued' , + 'queued', + conclusion = '', + 'pending', + conclusion + ) as conclusion, + status as status, html_url as htmlUrl, log_url as logUrl, duration_s as durationS, diff --git a/torchci/components/CommitStatus.tsx b/torchci/components/CommitStatus.tsx index 272b0503aa..00e5902c61 100644 --- a/torchci/components/CommitStatus.tsx +++ b/torchci/components/CommitStatus.tsx @@ -11,6 +11,7 @@ import { useState } from "react"; import { linkIt, UrlComponent, urlRegex } from "react-linkify-it"; import { getConclusionSeverityForSorting } from "../lib/JobClassifierUtil"; import FilteredJobList from "./FilteredJobList"; +import { JobStatus } from "./GroupJobConclusion"; import VersionControlLinks from "./VersionControlLinks"; import WorkflowBox from "./WorkflowBox"; import WorkflowDispatcher from "./WorkflowDispatcher"; @@ -162,7 +163,13 @@ export default function CommitStatus({ job.conclusion === "pending"} + pred={(job) => job.conclusion === JobStatus.Pending} + unstableIssues={unstableIssues} + /> + job.conclusion === JobStatus.Queued} unstableIssues={unstableIssues} /> @@ -127,6 +135,7 @@ function GroupTooltip({ groupName, erroredJobs, pendingJobs, + queuedJobs, failedPreviousRunJobs, sha, }: { @@ -134,6 +143,7 @@ function GroupTooltip({ groupName: string; erroredJobs: JobData[]; pendingJobs: JobData[]; + queuedJobs: JobData[]; failedPreviousRunJobs: JobData[]; sha?: string; }) { @@ -146,6 +156,15 @@ function GroupTooltip({ message={"The following jobs errored out:"} /> ); + } else if (conclusion === GroupedJobStatus.Queued) { + return ( + + ); } else if (conclusion === GroupedJobStatus.Pending) { return ( Raw logs diff --git a/torchci/components/ReproductionCommand.tsx b/torchci/components/ReproductionCommand.tsx index 2bd585347e..6cc7806893 100644 --- a/torchci/components/ReproductionCommand.tsx +++ b/torchci/components/ReproductionCommand.tsx @@ -1,3 +1,4 @@ +import { IsJobInProgress } from "lib/JobClassifierUtil"; import { useEffect, useState } from "react"; import { JobData } from "../lib/types"; import CopyLink from "./CopyLink"; @@ -11,7 +12,7 @@ export default function ReproductionCommand({ job }: { job: JobData }) { if ( job === null || - job.conclusion === "pending" || + IsJobInProgress(job.conclusion) || !job.jobName?.includes("test") || reproComamnd === null ) { diff --git a/torchci/components/TestInsights.tsx b/torchci/components/TestInsights.tsx index 7ae2e15a14..ae1a65ec8e 100644 --- a/torchci/components/TestInsights.tsx +++ b/torchci/components/TestInsights.tsx @@ -1,3 +1,4 @@ +import { IsJobInProgress } from "lib/JobClassifierUtil"; import { JobData } from "../lib/types"; // The following jobs are not supported at the moment because neither the monitoring @@ -15,8 +16,8 @@ export default function TestInsightsLink({ return null; } - if (job.conclusion === "pending") { - // If the job is pending, there is no test insights available yet + if (IsJobInProgress(job.conclusion)) { + // If the job is still in progress, there is no test insights available yet return null; } diff --git a/torchci/components/additionalTestInfo/TestInfo.tsx b/torchci/components/additionalTestInfo/TestInfo.tsx index 99bb4208f1..3bb56d4013 100644 --- a/torchci/components/additionalTestInfo/TestInfo.tsx +++ b/torchci/components/additionalTestInfo/TestInfo.tsx @@ -1,5 +1,6 @@ import { fetcher } from "lib/GeneralUtils"; import { runWorkflow } from "lib/githubFunctions"; +import { IsJobInProgress } from "lib/JobClassifierUtil"; import { JobData } from "lib/types"; import { useSession } from "next-auth/react"; import { useState } from "react"; @@ -31,7 +32,7 @@ export function genMessage({ } export function isPending(jobs: JobData[]) { - return jobs.some((job) => job.conclusion === "pending"); + return jobs.some((job) => IsJobInProgress(job.conclusion)); } export function RecursiveDetailsSummary({ diff --git a/torchci/lib/JobClassifierUtil.ts b/torchci/lib/JobClassifierUtil.ts index 0e60fc1a9a..8ccb499a32 100644 --- a/torchci/lib/JobClassifierUtil.ts +++ b/torchci/lib/JobClassifierUtil.ts @@ -215,6 +215,8 @@ export function getGroupConclusionChar(conclusion?: GroupedJobStatus): string { return "O"; case GroupedJobStatus.Failure: return "X"; + case GroupedJobStatus.Queued: + return "Q"; case GroupedJobStatus.Pending: return "?"; case GroupedJobStatus.AllNull: @@ -239,12 +241,31 @@ export function isFailure(conclusion?: string): boolean { case JobStatus.Success: case JobStatus.Neutral: case JobStatus.Skipped: + case JobStatus.Queued: case JobStatus.Pending: case undefined: default: return false; } } + +export function IsJobInProgress(conclusion?: string): boolean { + switch (conclusion) { + case JobStatus.Queued: + case JobStatus.Pending: + return true; + case JobStatus.Success: + case JobStatus.Neutral: + case JobStatus.Skipped: + case JobStatus.Failure: + case JobStatus.Cancelled: + case JobStatus.Timed_out: + case undefined: + default: + return false; + } +} + export function getConclusionChar( conclusion?: string, failedPreviousRun?: boolean @@ -265,6 +286,8 @@ export function getConclusionChar( return "T"; case JobStatus.Skipped: return "S"; + case JobStatus.Queued: + return "Q"; case JobStatus.Pending: return "?"; case undefined: @@ -286,14 +309,16 @@ export function getConclusionSeverityForSorting(conclusion?: string): number { return 2; case JobStatus.Cancelled: return 3; - case JobStatus.Pending: + case JobStatus.Queued: return 4; - case undefined: + case JobStatus.Pending: return 5; - case JobStatus.Failure: + case undefined: return 6; - default: + case JobStatus.Failure: return 7; + default: + return 8; } } diff --git a/torchci/lib/searchLogs.ts b/torchci/lib/searchLogs.ts index c8880a13a2..76b583d51a 100644 --- a/torchci/lib/searchLogs.ts +++ b/torchci/lib/searchLogs.ts @@ -1,3 +1,4 @@ +import { IsJobInProgress } from "./JobClassifierUtil"; import { JobData } from "./types"; export interface LogSearchResult { @@ -52,10 +53,10 @@ async function searchLog( ): Promise { // Search individual log try { - if (job.conclusion == "pending") { + if (IsJobInProgress(job.conclusion)) { return { results: [], - info: "Job is still running", + info: "Job is still in progress", }; } diff --git a/torchci/lib/types.ts b/torchci/lib/types.ts index 0f197dd2eb..0f74c9564c 100644 --- a/torchci/lib/types.ts +++ b/torchci/lib/types.ts @@ -5,6 +5,7 @@ export interface BasicJobData { name?: string; time?: string; conclusion?: string; + status?: string; runnerName?: string; authorEmail?: string; } diff --git a/torchci/pages/[repoOwner]/[repoName]/commit/[sha].tsx b/torchci/pages/[repoOwner]/[repoName]/commit/[sha].tsx index 583198d21f..81fb1e81b3 100644 --- a/torchci/pages/[repoOwner]/[repoName]/commit/[sha].tsx +++ b/torchci/pages/[repoOwner]/[repoName]/commit/[sha].tsx @@ -41,6 +41,7 @@ export function CommitInfo({ } const { commit, jobs } = commitData; + return (

{commit.commitTitle}

diff --git a/torchci/pages/minihud/[repoOwner]/[repoName]/[branch]/[[...page]].tsx b/torchci/pages/minihud/[repoOwner]/[repoName]/[branch]/[[...page]].tsx index b9260dd9ce..ab055a7ad0 100644 --- a/torchci/pages/minihud/[repoOwner]/[repoName]/[branch]/[[...page]].tsx +++ b/torchci/pages/minihud/[repoOwner]/[repoName]/[branch]/[[...page]].tsx @@ -1,4 +1,5 @@ import CopyLink from "components/CopyLink"; +import { JobStatus } from "components/GroupJobConclusion"; import JobAnnotationToggle from "components/JobAnnotationToggle"; import JobConclusion from "components/JobConclusion"; import JobFilterInput from "components/JobFilterInput"; @@ -201,11 +202,13 @@ function CommitLinks({ row }: { row: RowData }) { function CommitSummaryLine({ row, + numQueued, numPending, showRevert, ttsAlert, }: { row: RowData; + numQueued: number; numPending: number; showRevert: boolean; ttsAlert: boolean; @@ -231,7 +234,11 @@ function CommitSummaryLine({ textToCopy={`${location.href.replace(location.hash, "")}#${row.sha}`} /> - + {numQueued > 0 && ( + + {numQueued} queued + + )} {numPending > 0 && ( {numPending} pending @@ -441,7 +448,10 @@ function CommitSummary({ const failedJobs = jobs.filter(isFailedJob); const classifiedJobs = jobs.filter((job) => job.failureAnnotation != null); - const pendingJobs = jobs.filter((job) => job.conclusion === "pending"); + const pendingJobs = jobs.filter( + (job) => job.conclusion === JobStatus.Pending + ); + const queuedJobs = jobs.filter((job) => job.conclusion === JobStatus.Queued); let className; if (jobs.length === 0) { @@ -497,6 +507,7 @@ function CommitSummary({ > 0}