Skip to content

Commit 4298e30

Browse files
authored
feat(perforce): Add frontend support for Perforce integration (#103172)
This commit adds frontend support for Perforce version control integration: - New Perforce icon component and assets - Integration icon and plugin support - Updated repository project path config form to support Perforce - Type definitions for Perforce integration The frontend changes enable: - Visual representation of Perforce integration in the UI - Configuration UI for repository and code mappings - Integration with existing VCS provider infrastructure
1 parent cc07c9c commit 4298e30

File tree

8 files changed

+48
-8
lines changed

8 files changed

+48
-8
lines changed
Lines changed: 5 additions & 0 deletions
Loading

static/app/icons/iconPerforce.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type {SVGIconProps} from './svgIcon';
2+
import {SvgIcon} from './svgIcon';
3+
4+
export function IconPerforce(props: SVGIconProps) {
5+
return (
6+
<SvgIcon {...props}>
7+
<path d="M1.28125 1.8457C2.08337 1.38511 3.0417 1.38512 3.84473 1.8457L6.44434 3.33789L4.8877 4.23145L3.06738 3.18555C2.61281 2.92531 2.21222 3.09894 2.06055 3.18555C1.9092 3.27207 1.55673 3.53097 1.55664 4.05273V11.9482C1.55676 12.47 1.90921 12.7289 2.06055 12.8154C2.21223 12.902 2.61372 13.0757 3.06738 12.8154L9.94141 8.86816C10.3951 8.6077 10.4443 8.17496 10.4443 8.00098C10.4443 7.82703 10.3952 7.39429 9.94141 7.13379L9.55664 6.91309L11.0762 6.04004C11.6607 6.51866 12 7.22487 12 8C12 8.92108 11.5207 9.7464 10.7188 10.207L3.84473 14.1543C3.4433 14.3841 3.00387 14.4999 2.56348 14.5C2.12299 14.5 1.68277 14.385 1.28125 14.1543C0.479393 13.6937 5.80635e-05 12.8683 0 11.9473V4.05273C6.83815e-05 3.13175 0.479391 2.30721 1.28125 1.8457ZM13.4365 1.5C13.877 1.5 14.3172 1.61497 14.7188 1.8457C15.5206 2.30632 15.9999 3.13177 16 4.05273V11.9473C15.9999 12.8682 15.5206 13.6937 14.7188 14.1543C13.9166 14.6149 12.9574 14.6149 12.1553 14.1543L9.55566 12.6621L11.1123 11.7686L12.9326 12.8145C13.3872 13.0747 13.7878 12.9011 13.9395 12.8145C14.0908 12.7279 14.4423 12.469 14.4424 11.9473V4.05273C14.4423 3.53097 14.0908 3.27207 13.9395 3.18555C13.7878 3.09894 13.3863 2.92531 12.9326 3.18555L6.05859 7.13281C5.60478 7.39332 5.55567 7.82606 5.55566 8C5.55566 8.17393 5.60478 8.60667 6.05859 8.86719L6.44336 9.08789L4.92383 9.96094V9.95996C4.33928 9.48134 4 8.77514 4 8C4.00001 7.07891 4.47928 6.25359 5.28125 5.79297L12.1553 1.8457C12.5567 1.61592 12.9961 1.50005 13.4365 1.5Z" />
8+
</SvgIcon>
9+
);
10+
}

static/app/icons/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export {IconNumber} from './iconNumber';
8585
export {IconOpen} from './iconOpen';
8686
export {IconPanel} from './iconPanel';
8787
export {IconPause} from './iconPause';
88+
export {IconPerforce} from './iconPerforce';
8889
export {IconPin} from './iconPin';
8990
export {IconPlay} from './iconPlay';
9091
export {IconPrevent} from './iconPrevent';

static/app/plugins/components/pluginIcon.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import jumpcloud from 'sentry-logos/logo-jumpcloud.svg';
1717
import msteams from 'sentry-logos/logo-msteams.svg';
1818
import opsgenie from 'sentry-logos/logo-opsgenie.svg';
1919
import pagerduty from 'sentry-logos/logo-pagerduty.svg';
20+
import perforce from 'sentry-logos/logo-perforce.svg';
2021
import pivotal from 'sentry-logos/logo-pivotaltracker.svg';
2122
import pushover from 'sentry-logos/logo-pushover.svg';
2223
import redmine from 'sentry-logos/logo-redmine.svg';
@@ -59,6 +60,7 @@ const PLUGIN_ICONS = {
5960
msteams,
6061
opsgenie,
6162
pagerduty,
63+
perforce,
6264
pivotal,
6365
pushover,
6466
redmine,

static/app/types/integrations.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ export type CodeOwner = {
577577
users_without_access: string[];
578578
};
579579
id: string;
580-
provider: 'github' | 'gitlab';
580+
provider: 'github' | 'gitlab' | 'perforce';
581581
raw: string;
582582
codeMapping?: RepositoryProjectPathConfig;
583583
ownershipSyntax?: string;

static/app/utils/integrationUtil.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
IconGithub,
1010
IconGitlab,
1111
IconJira,
12+
IconPerforce,
1213
IconSentry,
1314
IconVsts,
1415
} from 'sentry/icons';
@@ -206,6 +207,8 @@ export const getIntegrationIcon = (
206207
case 'jira':
207208
case 'jira_server':
208209
return <IconJira size={iconSize} />;
210+
case 'perforce':
211+
return <IconPerforce size={iconSize} />;
209212
case 'vsts':
210213
return <IconVsts size={iconSize} />;
211214
case 'codecov':
@@ -230,6 +233,8 @@ export const getIntegrationDisplayName = (integrationType?: string) => {
230233
case 'jira':
231234
case 'jira_server':
232235
return 'Jira';
236+
case 'perforce':
237+
return 'Perforce';
233238
case 'vsts':
234239
return 'Azure DevOps';
235240
case 'codecov':
@@ -279,6 +284,8 @@ export function getCodeOwnerIcon(
279284
return <IconGithub size={iconSize} />;
280285
case 'gitlab':
281286
return <IconGitlab size={iconSize} />;
287+
case 'perforce':
288+
return <IconPerforce size={iconSize} />;
282289
default:
283290
return <IconSentry size={iconSize} />;
284291
}

static/app/views/settings/organizationIntegrations/repositoryProjectPathConfigForm.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ function RepositoryProjectPathConfigForm({
5858
}
5959
);
6060

61+
// Stream-based VCS (like Perforce) use streams/codelines instead of branches
62+
// and don't require a default branch to be specified
63+
const isStreamBased = integration.provider.key === 'perforce';
64+
6165
// Effect to handle the case when integration repos data becomes available
6266
useEffect(() => {
6367
if (integrationReposData?.repos && selectedRepo) {
@@ -93,13 +97,19 @@ function RepositoryProjectPathConfigForm({
9397
{
9498
name: 'defaultBranch',
9599
type: 'string',
96-
required: true,
97-
label: t('Branch'),
98-
placeholder: t('Type your branch'),
100+
required: !isStreamBased,
101+
label: isStreamBased ? t('Stream') : t('Branch'),
102+
placeholder: isStreamBased
103+
? t('Type your stream (optional, e.g., main)')
104+
: t('Type your branch'),
99105
showHelpInTooltip: true,
100-
help: t(
101-
'If an event does not have a release tied to a commit, we will use this branch when linking to your source code.'
102-
),
106+
help: isStreamBased
107+
? t(
108+
'Optional: Specify a stream/codeline (e.g., "main"). If not specified, the depot root will be used. Streams are part of the depot path in Perforce.'
109+
)
110+
: t(
111+
'If an event does not have a release tied to a commit, we will use this branch when linking to your source code.'
112+
),
103113
},
104114
{
105115
name: 'stackRoot',
@@ -135,7 +145,7 @@ function RepositoryProjectPathConfigForm({
135145
}
136146

137147
const initialData = {
138-
defaultBranch: 'main',
148+
defaultBranch: isStreamBased ? '' : 'main',
139149
stackRoot: '',
140150
sourceRoot: '',
141151
repositoryId: existingConfig?.repoId,
Lines changed: 5 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)