diff --git a/frontend/src/App.res b/frontend/src/App.res index 1dc1a446..f3df278b 100644 --- a/frontend/src/App.res +++ b/frontend/src/App.res @@ -14,6 +14,7 @@ query { let makeGetBenchmarksVariables = ( ~repoId, + ~branch=?, ~pullNumber=?, ~worker, ~benchmarkName=?, @@ -22,21 +23,24 @@ let makeGetBenchmarksVariables = ( ): GetBenchmarks.t_variables => { open BenchmarkDataHelpers let isMaster = Belt.Option.isNone(pullNumber) + let defaultBranch = Sidebar.defaultBranch let (worker, dockerImage) = switch worker { | None => (None, None) | Some((worker, dockerImage)) => (Some(worker), Some(dockerImage)) } let comparisonLimit = isMaster ? 0 : 50 { - repoId: repoId, - pullNumber: pullNumber, - isMaster: isMaster, - worker: worker, - dockerImage: dockerImage, + repoId, + branch, + defaultBranch, + pullNumber, + isMaster, + worker, + dockerImage, benchmarkName: Belt.Option.getWithDefault(benchmarkName, defaultBenchmarkName), - startDate: startDate, - endDate: endDate, - comparisonLimit: comparisonLimit, + startDate, + endDate, + comparisonLimit, } } @@ -189,7 +193,7 @@ module Benchmark = { module BenchmarkView = { @react.component - let make = (~repoId, ~pullNumber=?, ~worker, ~benchmarkName=?, ~startDate, ~endDate) => { + let make = (~repoId, ~branch=?, ~pullNumber=?, ~worker, ~benchmarkName=?, ~startDate, ~endDate) => { let ({ReScriptUrql.Hooks.response: response}, _) = { let startDate = Js.Date.toISOString(startDate)->Js.Json.string let endDate = Js.Date.toISOString(endDate)->Js.Json.string @@ -197,6 +201,7 @@ module BenchmarkView = { ~query=module(GetBenchmarks), makeGetBenchmarksVariables( ~repoId, + ~branch?, ~pullNumber?, ~worker, ~benchmarkName?, @@ -216,7 +221,7 @@ module BenchmarkView = { | Data(data) | PartialData(data, _) => - + } @@ -279,7 +284,7 @@ module ErrorView = { module RepoView = { @react.component - let make = (~repoId=?, ~pullNumber=?, ~benchmarkName=?, ~worker) => { + let make = (~repoId=?, ~branch=?, ~pullNumber=?, ~benchmarkName=?, ~worker) => { let ({ReScriptUrql.Hooks.response: response}, _) = { ReScriptUrql.Hooks.useQuery(~query=module(GetAllRepos), ()) } @@ -311,12 +316,12 @@ module RepoView = { | PartialData(data, _) => let repoIds = data.allRepoIds->Belt.Array.map(obj => obj.repo_id) let onSelectRepoId = makeOnSelectRepoId(worker) - let sidebar: React.element = { BeltHelpers.Array.contains(repoId)) => | Some(repoId) => + let branchBreadcrumb = branch->Belt.Option.getWithDefault(Sidebar.defaultBranch) let breadcrumbs = "/" { - let href = AppRouter.Repo({ + let href = AppRouter.RepoBranch({ repoId: repoId, + branch: branchBreadcrumb, benchmarkName: None, worker: worker, })->AppRouter.path - + } {pullNumber->Rx.onSome(pullNumber => { let href = AppRouter.RepoPull({ @@ -400,7 +407,7 @@ module RepoView = { {githubLink} - + }} @@ -419,5 +426,7 @@ let make = () => { | Ok(Repo({repoId, benchmarkName, worker})) => | Ok(RepoPull({repoId, pullNumber, benchmarkName, worker})) => + | Ok(RepoBranch({repoId, branch, benchmarkName, worker})) => + } } diff --git a/frontend/src/AppRouter.res b/frontend/src/AppRouter.res index 534c39b3..4a4d3a31 100644 --- a/frontend/src/AppRouter.res +++ b/frontend/src/AppRouter.res @@ -4,6 +4,7 @@ type route = | Main | Repo({repoId: string, benchmarkName: option, worker: worker}) | RepoPull({repoId: string, pullNumber: int, benchmarkName: option, worker: worker}) + | RepoBranch({repoId: string, branch: string, benchmarkName: option, worker: worker}) type error = { path: list, @@ -38,9 +39,31 @@ let route = (url: RescriptReactRouter.url) => { benchmarkName: None, worker})) | list{orgName, repoName, "benchmark", benchmarkName} => - Ok(Repo({repoId: orgName ++ "/" ++ repoName, - benchmarkName: Some(benchmarkName), - worker})) + Ok( + Repo({ + repoId: orgName ++ "/" ++ repoName, + benchmarkName: Some(benchmarkName), + worker, + }), + ) + | list{orgName, repoName, "branch", branchName} => + Ok( + RepoBranch({ + repoId: orgName ++ "/" ++ repoName, + branch: branchName, + benchmarkName: None, + worker, + }), + ) + | list{orgName, repoName, "branch", branchName, "benchmark", benchmarkName} => + Ok( + RepoBranch({ + repoId: orgName ++ "/" ++ repoName, + branch: branchName, + benchmarkName: Some(benchmarkName), + worker, + }), + ) | list{orgName, repoName, "pull", pullNumberStr} => switch Belt.Int.fromString(pullNumberStr) { | Some(pullNumber) => @@ -87,8 +110,17 @@ let path = route => | RepoPull({repoId, pullNumber, benchmarkName: None, worker}) => "/" ++ repoId ++ "/pull/" ++ Belt.Int.toString(pullNumber) ++ workerParams(worker) | RepoPull({repoId, pullNumber, benchmarkName: Some(benchmarkName), worker}) => - "/" ++ repoId ++ "/pull/" ++ Belt.Int.toString(pullNumber) ++ "/benchmark/" ++ benchmarkName - ++ workerParams(worker) + "/" ++ + repoId ++ + "/pull/" ++ + Belt.Int.toString(pullNumber) ++ + "/benchmark/" ++ + benchmarkName ++ + workerParams(worker) + | RepoBranch({repoId, branch, benchmarkName: None, worker}) => + "/" ++ repoId ++ "/branch/" ++ branch ++ workerParams(worker) + | RepoBranch({repoId, branch, benchmarkName: Some(benchmarkName), worker}) => + "/" ++ repoId ++ "/branch/" ++ branch ++ "/benchmark/" ++ benchmarkName ++ workerParams(worker) } let useRoute = () => RescriptReactRouter.useUrl()->route diff --git a/frontend/src/BenchmarkQueryHelpers.res b/frontend/src/BenchmarkQueryHelpers.res index 1adf1f09..741c60af 100644 --- a/frontend/src/BenchmarkQueryHelpers.res +++ b/frontend/src/BenchmarkQueryHelpers.res @@ -9,12 +9,15 @@ fragment BenchmarkMetrics on benchmarks { run_job_id worker docker_image + branch } `) module GetBenchmarks = %graphql(` query ($repoId: String!, $pullNumber: Int, + $branch: String, + $defaultBranch: String!, $isMaster: Boolean!, $worker: String, $dockerImage: String, @@ -25,6 +28,7 @@ query ($repoId: String!, benchmarks: benchmarks(where: {_and: [{pull_number: {_eq: $pullNumber}}, {pull_number: {_is_null: $isMaster}}, + {branch: {_eq: $branch}}, {repo_id: {_eq: $repoId}}, {worker: {_eq: $worker}}, {docker_image: {_eq: $dockerImage}}, @@ -36,6 +40,7 @@ query ($repoId: String!, } comparisonBenchmarks: benchmarks(where: {_and: [{pull_number: {_is_null: true}}, + {branch: {_eq: $defaultBranch}}, {repo_id: {_eq: $repoId}}, {worker: {_eq: $worker}}, {docker_image: {_eq: $dockerImage}}, diff --git a/frontend/src/CommitInfo.res b/frontend/src/CommitInfo.res index cff6121d..1910b4d4 100644 --- a/frontend/src/CommitInfo.res +++ b/frontend/src/CommitInfo.res @@ -4,6 +4,7 @@ open BenchmarkQueryHelpers module GetLastCommitInfo = %graphql(` query ($repoId: String!, + $branch: String, $pullNumber: Int, $isMaster: Boolean!, $worker: String, @@ -12,6 +13,7 @@ query ($repoId: String!, limit: 1, where: {_and: [{pull_number: {_eq: $pullNumber}}, {pull_number: {_is_null: $isMaster}}, + {branch: {_eq: $branch}}, {worker: {_eq: $worker}}, {docker_image: {_eq: $dockerImage}}, {repo_id: {_eq: $repoId}} @@ -38,6 +40,7 @@ query ($repoId: String!, let makeGetLastCommitInfoVariables = ( ~repoId, + ~branch=?, ~pullNumber=?, ~worker, ~dockerImage, @@ -45,11 +48,12 @@ let makeGetLastCommitInfoVariables = ( ): GetLastCommitInfo.t_variables => { let isMaster = Belt.Option.isNone(pullNumber) { - repoId: repoId, - pullNumber: pullNumber, - isMaster: isMaster, - worker: worker, - dockerImage: dockerImage, + repoId, + branch, + pullNumber, + isMaster, + worker, + dockerImage, } } @@ -98,7 +102,14 @@ let buildStatus = (lastCommitInfo: GetLastCommitInfo.t_lastCommitInfo) => { } @react.component -let make = (~repoId, ~pullNumber=?, ~benchmarks: GetBenchmarks.t, ~worker, ~setLastCommit) => { +let make = ( + ~repoId, + ~branch=?, + ~pullNumber=?, + ~benchmarks: GetBenchmarks.t, + ~worker, + ~setLastCommit, +) => { let benchmarks = benchmarks.benchmarks let (worker, dockerImage) = switch worker { | None => (None, None) @@ -107,7 +118,7 @@ let make = (~repoId, ~pullNumber=?, ~benchmarks: GetBenchmarks.t, ~worker, ~setL let ({ReScriptUrql.Hooks.response: response}, _) = { ReScriptUrql.Hooks.useQuery( ~query=module(GetLastCommitInfo), - makeGetLastCommitInfoVariables(~repoId, ~pullNumber?, ~worker, ~dockerImage, ()), + makeGetLastCommitInfoVariables(~repoId, ~branch?, ~pullNumber?, ~worker, ~dockerImage, ()), ) } diff --git a/frontend/src/Sidebar.res b/frontend/src/Sidebar.res index 884339fb..c33a3eda 100644 --- a/frontend/src/Sidebar.res +++ b/frontend/src/Sidebar.res @@ -18,6 +18,9 @@ query ($repoId: String!) { benchmarksMenuData: benchmarks(distinct_on: [benchmark_name], where: {repo_id: {_eq: $repoId}}, order_by: [{benchmark_name: asc_nulls_first}]) { benchmark_name } + branchesMenuData: benchmark_metadata(distinct_on: [branch], where: {_and: [{repo_id: {_eq: $repoId}}, {branch: {_is_null: false}}]}, order_by: [{branch: asc_nulls_first}]) { + branch + } } `) @@ -148,9 +151,81 @@ module BenchmarksMenu = { } } +let defaultBranch = "main" +let validDefaults = Belt.Set.String.fromArray(["main", "trunk", "master"]) + +module BranchesMenu = { + @react.component + let make = ( + ~repoId, + ~branchesMenuData: array, + ~selectedBranch=?, + ~selectedBenchmarkName=?, + ~selectedPull=?, + ~worker, + ) => { + let branchNames = branchesMenuData->Belt.Array.keepMap(obj => obj.branch) + + React.useEffect3(() => { + if ( + Belt.Option.isNone(selectedPull) && + branchNames->Belt.Array.getBy(name => Some(name) == selectedBranch) == None + ) { + switch branchNames->Belt.Array.getBy(name => Belt.Set.String.has(validDefaults, name)) { + | Some(branch) => + AppRouter.RepoBranch({ + repoId, + branch, + benchmarkName: selectedBenchmarkName, + worker, + })->AppRouter.go + | _ => () + } + } + None + }, (selectedBranch, branchesMenuData, selectedPull)) + + let branches = + branchesMenuData + ->Belt.Array.mapWithIndex((i, {branch}) => { + let branchRoute = switch branch { + | None => + AppRouter.Repo({ + repoId, + benchmarkName: selectedBenchmarkName, + worker, + }) + | Some(branch) => + AppRouter.RepoBranch({ + repoId, + branch, + benchmarkName: selectedBenchmarkName, + worker, + }) + } + AppRouter.path} + text={Belt.Option.getWithDefault(branch, defaultBranch)} + /> + }) + ->Rx.array(~empty="None"->Rx.string) + switch Belt.Array.length(branchesMenuData) { + | 0 | 1 => Rx.null + | _ => + + "Branches" + {branches} + + } + } +} + module SidebarMenu = { @react.component - let make = (~repoId, ~selectedPull=?, ~selectedBenchmarkName=?, ~worker) => { + let make = (~repoId, ~selectedBranch=?, ~selectedPull=?, ~selectedBenchmarkName=?, ~worker) => { let ({ReScriptUrql.Hooks.response: response}, _) = { ReScriptUrql.Hooks.useQuery( ~query=module(SidebarMenuData), @@ -165,8 +240,9 @@ module SidebarMenu = { | Error({networkError: Some(_)}) =>
{"Network Error"->Rx.text}
| Error({networkError: None}) =>
{"Unknown Error"->Rx.text}
| Fetching => Rx.text("Loading...") - | Data({benchmarksMenuData, pullsMenuData}) - | PartialData({benchmarksMenuData, pullsMenuData}, _) => <> + | Data({benchmarksMenuData, pullsMenuData, branchesMenuData}) + | PartialData({benchmarksMenuData, pullsMenuData, branchesMenuData}, _) => + <> {switch Belt.Array.some(benchmarksMenuData, bm => { bm.benchmark_name !== BenchmarkDataHelpers.defaultBenchmarkName }) { @@ -177,6 +253,9 @@ module SidebarMenu = { | false => Rx.null }} + } @@ -265,6 +344,7 @@ let make = ( ~repoIds, ~worker, ~setWorker, + ~selectedBranch=?, ~selectedRepoId=?, ~selectedPull=?, ~selectedBenchmarkName=?, @@ -272,9 +352,10 @@ let make = ( ): React.element => { let menu = switch selectedRepoId { | None => Rx.null - | Some(repoId) => <> + | Some(repoId) => + <> - + }