Skip to content

Commit 7ef8b55

Browse files
authored
Merge pull request #2774 from devtron-labs/feat/combined-ci-cd-pipeline
feat: Build and Deploy Combined Pipeline Creation
2 parents d7057fe + 2414b8a commit 7ef8b55

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2208
-763
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ src/components/ciPipeline/ConfigureWebhook.tsx
189189
src/components/ciPipeline/ExternalCIPipeline.tsx
190190
src/components/ciPipeline/LinkedCIPipelineEdit.tsx
191191
src/components/ciPipeline/LinkedCIPipelineView.tsx
192-
src/components/ciPipeline/SourceMaterials.tsx
193192
src/components/ciPipeline/Webhook/WebhookDetailsModal.tsx
194193
src/components/ciPipeline/Webhook/webhook.service.ts
195194
src/components/ciPipeline/Webhook/webhook.utils.ts

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.16.0-pre-0",
7+
"@devtron-labs/devtron-fe-common-lib": "1.16.0-pre-1",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/App.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ const App = () => {
170170
</Switch>
171171
<div id="visible-modal" />
172172
<div id="visible-modal-2" />
173-
<div id="animated-dialog-backdrop" />
174173
</BreadcrumbStore>
175174
</ErrorBoundary>
176175
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { DeploymentAppTypes } from '@devtron-labs/devtron-fe-common-lib'
2+
3+
import { DeploymentAppRadioGroup } from '@Components/v2/values/chartValuesDiff/ChartValuesView.component'
4+
5+
import { CDPipelineDeploymentAppTypeProps } from './types'
6+
7+
export const CDPipelineDeploymentAppType = ({
8+
isVirtualEnvironment,
9+
allowedDeploymentTypes,
10+
noGitOpsModuleInstalledAndConfigured,
11+
isGitOpsInstalledButNotConfigured,
12+
deploymentAppType,
13+
rootClassName,
14+
isDisabled,
15+
handleChange,
16+
isGitOpsRepoNotConfigured,
17+
gitOpsRepoConfigInfoBar,
18+
}: CDPipelineDeploymentAppTypeProps) =>
19+
!window._env_.HIDE_GITOPS_OR_HELM_OPTION &&
20+
!isVirtualEnvironment &&
21+
allowedDeploymentTypes?.length > 0 &&
22+
// Want to show this when gitops module is installed, does not matter if it is configured or not
23+
(!noGitOpsModuleInstalledAndConfigured || isGitOpsInstalledButNotConfigured) && (
24+
<div className="mt-16">
25+
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
26+
<label className="form__label form__label--sentence">How do you want to deploy?</label>
27+
<DeploymentAppRadioGroup
28+
deploymentAppType={deploymentAppType ?? DeploymentAppTypes.HELM}
29+
handleOnChange={handleChange}
30+
allowedDeploymentTypes={allowedDeploymentTypes}
31+
rootClassName={rootClassName}
32+
isDisabled={isDisabled}
33+
isFromCDPipeline
34+
isGitOpsRepoNotConfigured={isGitOpsRepoNotConfigured}
35+
gitOpsRepoConfigInfoBar={gitOpsRepoConfigInfoBar}
36+
areGitopsCredentialsConfigured={!isGitOpsInstalledButNotConfigured}
37+
/>
38+
</div>
39+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './CDPipelineDeploymentAppType'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { DeploymentAppRadioGroupType } from '@Components/v2/values/chartValuesDiff/ChartValuesView.type'
2+
3+
export interface CDPipelineDeploymentAppTypeProps
4+
extends Omit<DeploymentAppRadioGroupType, 'isFromCDPipeline' | 'handleOnChange'> {
5+
isVirtualEnvironment: boolean
6+
noGitOpsModuleInstalledAndConfigured: boolean
7+
isGitOpsInstalledButNotConfigured: boolean
8+
handleChange: DeploymentAppRadioGroupType['handleOnChange']
9+
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import { ChangeEvent, useState } from 'react'
2+
import { useHistory } from 'react-router-dom'
3+
4+
import {
5+
API_STATUS_CODES,
6+
ButtonVariantType,
7+
ComponentSizeType,
8+
DeploymentAppTypes,
9+
Icon,
10+
InfoBlock,
11+
noop,
12+
showError,
13+
} from '@devtron-labs/devtron-fe-common-lib'
14+
15+
import { GeneratedHelmPush } from '@Components/cdPipeline/cdPipeline.types'
16+
import { ValidationRules } from '@Components/ciPipeline/validationRules'
17+
import { EnvironmentWithSelectPickerType } from '@Components/CIPipelineN/types'
18+
import { GITOPS_REPO_REQUIRED } from '@Components/v2/values/chartValuesDiff/constant'
19+
import { ENV_ALREADY_EXIST_ERROR } from '@Config/constants'
20+
import { URLS } from '@Config/routes'
21+
import { getGitOpsRepoConfig } from '@Services/service'
22+
23+
import { CDPipelineDeploymentAppType } from '../CDPipelineDeploymentAppType'
24+
import { SourceMaterialsSelector } from '../SourceMaterialsSelector'
25+
import { CDStepperContentProps } from './types'
26+
import { getEnvironmentOptions } from './utils'
27+
28+
const validationRules = new ValidationRules()
29+
30+
export const CDStepperContent = ({
31+
appId,
32+
isCreatingWorkflow,
33+
cdNodeCreateError,
34+
onRetry,
35+
ciCdPipeline,
36+
ciCdPipelineFormError,
37+
noGitOpsModuleInstalledAndConfigured,
38+
isGitOpsInstalledButNotConfigured,
39+
isGitOpsRepoNotConfigured,
40+
envIds,
41+
setCiCdPipeline,
42+
setCiCdPipelineFormError,
43+
setReloadNoGitOpsRepoConfiguredModal,
44+
}: CDStepperContentProps) => {
45+
// STATES
46+
const [gitopsConflictLoading, setGitopsConflictLoading] = useState(false)
47+
48+
// HOOKS
49+
const { push } = useHistory()
50+
51+
// CONSTANTS
52+
const { environments, selectedEnvironment, deploymentAppType } = ciCdPipeline.cd
53+
const isFormDisabled = isCreatingWorkflow
54+
const isHelmEnforced =
55+
selectedEnvironment &&
56+
selectedEnvironment.allowedDeploymentTypes.length === 1 &&
57+
selectedEnvironment.allowedDeploymentTypes[0] === DeploymentAppTypes.HELM
58+
const gitOpsRepoNotConfiguredAndOptionsHidden =
59+
window._env_.HIDE_GITOPS_OR_HELM_OPTION &&
60+
!noGitOpsModuleInstalledAndConfigured &&
61+
!isHelmEnforced &&
62+
isGitOpsRepoNotConfigured
63+
64+
// HANDLERS
65+
const handleEnvironmentChange = (selection: EnvironmentWithSelectPickerType) => {
66+
const { ci, cd } = structuredClone(ciCdPipeline)
67+
cd.selectedEnvironment = selection
68+
cd.generatedHelmPushAction = selection.isVirtualEnvironment
69+
? GeneratedHelmPush.DO_NOT_PUSH
70+
: GeneratedHelmPush.PUSH
71+
72+
setCiCdPipeline({ ci, cd })
73+
74+
const updatedCiCdPipelineFormError = structuredClone(ciCdPipelineFormError)
75+
updatedCiCdPipelineFormError.cd.environment = envIds.includes(selection.id)
76+
? ENV_ALREADY_EXIST_ERROR
77+
: validationRules.environment(selection.id).message
78+
79+
setCiCdPipelineFormError(updatedCiCdPipelineFormError)
80+
}
81+
82+
const handleDeploymentAppTypeChange = (event: ChangeEvent<HTMLInputElement>) => {
83+
const { ci, cd } = structuredClone(ciCdPipeline)
84+
cd.deploymentAppType = event.target.value
85+
setCiCdPipeline({ ci, cd })
86+
}
87+
88+
const checkGitOpsRepoConflict = async () => {
89+
setGitopsConflictLoading(true)
90+
91+
try {
92+
await getGitOpsRepoConfig(+appId)
93+
94+
setGitopsConflictLoading(false)
95+
push(`/app/${appId}/edit/${URLS.APP_GITOPS_CONFIG}`)
96+
} catch (err) {
97+
setGitopsConflictLoading(false)
98+
if (err.code === API_STATUS_CODES.CONFLICT) {
99+
setReloadNoGitOpsRepoConfiguredModal(true)
100+
} else {
101+
showError(err)
102+
}
103+
}
104+
}
105+
106+
// RENDERERS
107+
const gitOpsRepoConfigInfoBar = (content: string) => (
108+
<InfoBlock
109+
description={content}
110+
variant="warning"
111+
buttonProps={{
112+
dataTestId: 'configure-gitops-repo-button',
113+
variant: ButtonVariantType.text,
114+
text: 'Configure',
115+
endIcon: <Icon name="ic-arrow-right" color={null} />,
116+
onClick: checkGitOpsRepoConflict,
117+
isLoading: gitopsConflictLoading,
118+
}}
119+
/>
120+
)
121+
122+
return (
123+
<div className="flexbox-col dc__gap-20">
124+
{!!cdNodeCreateError && (
125+
<InfoBlock
126+
variant="error"
127+
heading="Failed to create deployment pipeline"
128+
description={cdNodeCreateError.errors?.[0]?.userMessage ?? 'failed'}
129+
size={ComponentSizeType.medium}
130+
buttonProps={{
131+
dataTestId: 'retry-cd-node-creation',
132+
startIcon: <Icon name="ic-arrow-clockwise" color={null} />,
133+
variant: ButtonVariantType.text,
134+
text: 'Retry',
135+
onClick: onRetry,
136+
}}
137+
/>
138+
)}
139+
<div>
140+
<SourceMaterialsSelector
141+
branchInputProps={{
142+
name: 'cd-pipeline-namespace',
143+
onChange: noop,
144+
placeholder:
145+
selectedEnvironment?.isVirtualEnvironment && !selectedEnvironment?.namespace
146+
? 'Not available'
147+
: 'Will be auto-populated based on environment',
148+
label: 'Namespace',
149+
value: selectedEnvironment?.namespace,
150+
disabled: true,
151+
}}
152+
sourceTypePickerProps={{
153+
inputId: 'cd-pipeline-environment',
154+
classNamePrefix: 'cd-pipeline-environment',
155+
label: 'Environment',
156+
placeholder: 'Select environment',
157+
isDisabled: isFormDisabled,
158+
menuPosition: 'fixed',
159+
options: getEnvironmentOptions(environments),
160+
value: selectedEnvironment,
161+
getOptionValue: (option) => option.value as string,
162+
helperText: selectedEnvironment?.isVirtualEnvironment ? 'Isolated environment' : null,
163+
error: ciCdPipelineFormError.cd.environment ?? null,
164+
onChange: handleEnvironmentChange,
165+
}}
166+
/>
167+
<div className="mt-16">
168+
{gitOpsRepoNotConfiguredAndOptionsHidden && gitOpsRepoConfigInfoBar(GITOPS_REPO_REQUIRED)}
169+
</div>
170+
<CDPipelineDeploymentAppType
171+
isVirtualEnvironment={selectedEnvironment?.isVirtualEnvironment}
172+
isGitOpsInstalledButNotConfigured={isGitOpsInstalledButNotConfigured}
173+
noGitOpsModuleInstalledAndConfigured={noGitOpsModuleInstalledAndConfigured}
174+
deploymentAppType={deploymentAppType ?? DeploymentAppTypes.HELM}
175+
handleChange={handleDeploymentAppTypeChange}
176+
allowedDeploymentTypes={selectedEnvironment?.allowedDeploymentTypes}
177+
rootClassName="chartrepo-type__radio-group"
178+
isDisabled={isFormDisabled}
179+
isGitOpsRepoNotConfigured={isGitOpsRepoNotConfigured}
180+
gitOpsRepoConfigInfoBar={gitOpsRepoConfigInfoBar}
181+
areGitopsCredentialsConfigured={!isGitOpsInstalledButNotConfigured}
182+
/>
183+
</div>
184+
</div>
185+
)
186+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Icon } from '@devtron-labs/devtron-fe-common-lib'
2+
3+
import { CICDStepperProps } from './types'
4+
5+
export const CICDStepper = ({ config }: CICDStepperProps) => (
6+
<div className="ci-cd-pipeline__stepper-container flexbox-col flex-grow-1 dc__align-self-start">
7+
{config.map(({ id, icon, title, content }) => (
8+
<div key={id} className="ci-cd-pipeline__stepper flex left top dc__gap-8">
9+
<div className="dc__position-rel flex p-7 br-6 border__secondary bg__modal--primary">
10+
<Icon name={icon} color={null} size={20} />
11+
</div>
12+
<div className="flexbox-col flex-grow-1 br-6 border__secondary dc__overflow-hidden">
13+
<div className="px-11 pt-8 pb-7 border__secondary--bottom bg__modal--primary">
14+
<p className="m-0 fs-13 lh-20 fw-6 cn-9">{title}</p>
15+
</div>
16+
<div className="flex-grow-1 p-16 bg__primary">{content}</div>
17+
</div>
18+
</div>
19+
))}
20+
</div>
21+
)

0 commit comments

Comments
 (0)