go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/tools/urlHandling/links.ts (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { 16 ClusterId, 17 PresubmitRunId, 18 Variant, 19 } from '@/proto/go.chromium.org/luci/analysis/proto/v1/common.pb'; 20 import { Changelist, SourceRef } from '@/proto/go.chromium.org/luci/analysis/proto/v1/sources.pb'; 21 22 import { variantAsPairs } from '../variant_tools'; 23 24 export const linkToCluster = (project: string, c: ClusterId): string => { 25 if (c.algorithm.startsWith('rules-') || c.algorithm == 'rules') { 26 return linkToRule(project, c.id); 27 } else { 28 const projectEncoded = encodeURIComponent(project); 29 const algorithmEncoded = encodeURIComponent(c.algorithm); 30 const idEncoded = encodeURIComponent(c.id); 31 return `/p/${projectEncoded}/clusters/${algorithmEncoded}/${idEncoded}`; 32 } 33 }; 34 35 export const linkToRule = (project: string, ruleId: string): string => { 36 const projectEncoded = encodeURIComponent(project); 37 const ruleIdEncoded = encodeURIComponent(ruleId); 38 return `/p/${projectEncoded}/rules/${ruleIdEncoded}`; 39 }; 40 41 export const invocationName = (invocationId: string): string => { 42 if (invocationId.startsWith('build-')) { 43 return invocationId.slice('build-'.length); 44 } 45 return invocationId; 46 }; 47 48 export const failureLink = (invocationId: string, testId: string, variant?: Variant): string => { 49 const variantQuery = variantAsPairs(variant).map((vp) => { 50 return 'V:' + encodeURIComponent(vp.key || '') + '=' + encodeURIComponent(vp.value); 51 }).join(' '); 52 const query = `ID:${testId} ${variantQuery}`; 53 if (invocationId.startsWith('build-')) { 54 return `https://ci.chromium.org/ui/b/${invocationId.slice('build-'.length)}/test-results?q=${encodeURIComponent(query)}`; 55 } 56 return `https://ci.chromium.org/ui/inv/${invocationId}/test-results?q=${encodeURIComponent(query)}`; 57 }; 58 59 export const clLink = (cl: Changelist): string => { 60 return `https://${cl.host}/c/${cl.change}/${cl.patchset}`; 61 }; 62 63 export const clName = (cl: Changelist): string => { 64 const host = cl.host.replace('-review.googlesource.com', ''); 65 return `${host}/${cl.change}/${cl.patchset}`; 66 }; 67 68 export const presubmitRunLink = (runId: PresubmitRunId): string => { 69 return `https://luci-change-verifier.appspot.com/ui/run/${runId.id}`; 70 }; 71 72 export const testHistoryLink = (project: string, testId: string, partialVariant?: Variant): string => { 73 const query = variantAsPairs(partialVariant).map((vp) => { 74 return 'V:' + encodeURIComponent(vp.key || '') + '=' + encodeURIComponent(vp.value); 75 }).join(' '); 76 return `https://ci.chromium.org/ui/test/${encodeURIComponent(project)}/${encodeURIComponent(testId)}?q=${encodeURIComponent(query)}`; 77 }; 78 79 export const sourceRefLink = (sourceRef: SourceRef) : string => { 80 if (sourceRef.gitiles) { 81 return `https://${sourceRef.gitiles.host}/${sourceRef.gitiles.project}/+log/${sourceRef.gitiles.ref}`; 82 } 83 return ''; 84 }; 85 86 // loginLink constructs a URL to login to LUCI Analysis, with a redirect to 87 // the given absolute URL (which should start with "/"). 88 export const loginLink = (redirectTarget: string): string => { 89 return window.loginUrl + '?r=' + encodeURIComponent(redirectTarget); 90 }; 91 92 // logoutLink constructs a URL to logout from LUCI Analysis, with a redirect to 93 // the given absolute URL (which should start with "/"). 94 export const logoutLink = (redirectTarget: string): string => { 95 return window.logoutUrl + '?r=' + encodeURIComponent(redirectTarget); 96 };