Skip to content

feat: add support for skipping hibernated apps in bulk deploy #2613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/ApplicationGroup/AppGroup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export interface BulkCDTriggerType extends BulkRuntimeParamsType {
appList: BulkCDDetailType[]
closePopup: (e) => void
updateBulkInputMaterial: (materialList: Record<string, any>) => void
onClickTriggerBulkCD: (appsToRetry?: Record<string, boolean>) => void
onClickTriggerBulkCD: (skipIfHibernated: boolean, appsToRetry?: Record<string, boolean>) => void
changeTab?: (
materrialId: string | number,
artifactId: number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
CDMaterialResponseType,
DeploymentNodeType,
Drawer,
Progressing,
ReleaseTag,
ImageComment,
showError,
Expand Down Expand Up @@ -48,9 +47,12 @@
Button,
ComponentSizeType,
AnimatedDeployButton,
ButtonVariantType,
Icon,
ButtonStyleType,
useMainContext,
} from '@devtron-labs/devtron-fe-common-lib'
import { useHistory, useLocation } from 'react-router-dom'
import { ReactComponent as Close } from '@Icons/ic-cross.svg'
import { ReactComponent as DeployIcon } from '@Icons/ic-nav-rocket.svg'
import { ReactComponent as PlayIcon } from '@Icons/ic-play-outline.svg'
import { ReactComponent as Error } from '@Icons/ic-warning.svg'
Expand Down Expand Up @@ -89,6 +91,7 @@
() => ({ isValid: true, cellError: {} }),
'function',
)
const SkipHibernatedCheckbox = importComponentFromFELibrary('SkipHibernatedCheckbox', null, 'function')

// TODO: Fix release tags selection
export default function BulkCDTrigger({
Expand All @@ -109,6 +112,7 @@
runtimeParamsErrorState,
setRuntimeParamsErrorState,
}: BulkCDTriggerType) {
const { deployUnhibernatedAppOnly } = useMainContext()

Check failure on line 115 in src/components/ApplicationGroup/Details/TriggerView/BulkCDTrigger.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'MainContext'.

Check failure on line 115 in src/components/ApplicationGroup/Details/TriggerView/BulkCDTrigger.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'MainContext'.
const [selectedApp, setSelectedApp] = useState<BulkCDDetailType>(
appList.find((app) => !app.warningMessage) || appList[0],
)
Expand All @@ -125,6 +129,7 @@
const [isPartialActionAllowed, setIsPartialActionAllowed] = useState(false)
const [showResistanceBox, setShowResistanceBox] = useState(false)
const [currentSidebarTab, setCurrentSidebarTab] = useState<CDMaterialSidebarType>(CDMaterialSidebarType.IMAGE)
const [skipHibernated, setSkipHibernated] = useState<boolean>(false)

const location = useLocation()
const history = useHistory()
Expand Down Expand Up @@ -351,15 +356,18 @@
const renderHeaderSection = (): JSX.Element => {
return (
<div className="flex flex-align-center flex-justify dc__border-bottom bg__primary pt-16 pr-20 pb-16 pl-20">
<h2 className="fs-16 fw-6 lh-1-43 m-0">Deploy to {appList[0].envName}</h2>
<button
type="button"
className="dc__transparent flex icon-dim-24"
<h2 className="fs-16 fw-6 lh-1-5 m-0">Deploy to {appList[0].envName}</h2>
<Button
dataTestId="bulk-cd-modal-close"
disabled={isLoading}
onClick={closeBulkCDModal}
>
<Close className="icon-dim-24" />
</button>
size={ComponentSizeType.xs}
icon={<Icon name="ic-close-small" size={null} color={null} />}
ariaLabel="close bulk cd trigger modal"
showAriaLabelInTippy={false}
style={ButtonStyleType.negativeGrey}
variant={ButtonVariantType.borderLess}
/>
</div>
)
}
Expand Down Expand Up @@ -829,13 +837,15 @@
setShowResistanceBox(false)
}

const triggerBulkCD = () => onClickTriggerBulkCD(skipHibernated)

const onClickStartDeploy = (e): void => {
if (isPartialActionAllowed && BulkDeployResistanceTippy && !showResistanceBox) {
setShowResistanceBox(true)
} else {
isBulkDeploymentTriggered.current = true
stopPropagation(e)
onClickTriggerBulkCD()
triggerBulkCD()
setShowResistanceBox(false)
}
}
Expand All @@ -848,8 +858,21 @@

const renderFooterSection = (): JSX.Element => {
const isDeployButtonDisabled: boolean = isDeployDisabled()
const showSkipHibernatedCheckbox = stage === DeploymentNodeType.CD && !!SkipHibernatedCheckbox && deployUnhibernatedAppOnly
return (
<div className="dc__border-top flex right bg__primary px-20 py-16">
<div
className={`dc__border-top flex ${showSkipHibernatedCheckbox ? 'dc__content-space' : 'right'} bg__primary px-20 py-16`}
>
{showSkipHibernatedCheckbox && (
<SkipHibernatedCheckbox
isDeploymentLoading={isLoading}
envId={appList[0].envId}
envName={appList[0].envName}
appIds={appList.map((app) => app.appId)}
skipHibernated={skipHibernated}
setSkipHibernated={setSkipHibernated}
/>
)}
<div className="dc__position-rel tippy-over">
{!isDeployButtonDisabled && stage === DeploymentNodeType.CD && !isLoading ? (
<AnimatedDeployButton onButtonClick={onClickStartDeploy} isVirtualEnvironment={false} />
Expand All @@ -874,7 +897,7 @@
return (
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
<div className="bg__primary bulk-ci-trigger-container">
<div className='flexbox-col flex-grow-1 dc__overflow-hidden'>
<div className="flexbox-col flex-grow-1 dc__overflow-hidden">
{renderHeaderSection()}
{responseListLength ? (
<TriggerResponseModalBody
Expand All @@ -892,7 +915,7 @@
closePopup={closeBulkCDModal}
responseList={responseList}
isLoading={isLoading}
onClickRetryBuild={onClickTriggerBulkCD}
onClickRetryBuild={triggerBulkCD}
/>
) : (
renderFooterSection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,7 @@
return true
}

const onClickTriggerBulkCD = (appsToRetry?: Record<string, boolean>) => {
const onClickTriggerBulkCD = (skipIfHibernated: boolean, appsToRetry?: Record<string, boolean>) => {
if (isCDLoading || !validateBulkRuntimeParams()) {
return
}
Expand Down Expand Up @@ -1482,6 +1482,7 @@
...(getRuntimeParamsPayload
? { runtimeParamsPayload: getRuntimeParamsPayload(runtimeParams[currentAppId] ?? []) }
: {}),
skipIfHibernated: skipIfHibernated,

Check failure on line 1485 in src/components/ApplicationGroup/Details/TriggerView/EnvTriggerView.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'skipIfHibernated' does not exist in type 'TriggerCDNodeServiceProps'.

Check failure on line 1485 in src/components/ApplicationGroup/Details/TriggerView/EnvTriggerView.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'skipIfHibernated' does not exist in type 'TriggerCDNodeServiceProps'.
}),
)
} else {
Expand Down Expand Up @@ -1941,7 +1942,7 @@
}
if (!filteredWorkflows.length) {
return (
<div className='flex-grow-1'>
<div className="flex-grow-1">
<AppNotConfigured />
</div>
)
Expand Down Expand Up @@ -2099,7 +2100,7 @@
)
}

const renderBulkSourchChange = (): JSX.Element | null => {
const renderBulkSourceChange = (): JSX.Element | null => {
if (!showBulkSourceChangeModal) {
return null
}
Expand Down Expand Up @@ -2452,12 +2453,12 @@
{renderBulkCDMaterial()}
{renderBulkCIMaterial()}
{renderApprovalMaterial()}
{renderBulkSourchChange()}
{renderBulkSourceChange()}
</TriggerViewContext.Provider>
<div />
</div>
{!!selectedAppList.length && (
<div className="flexbox dc__gap-8 dc__content-space dc__border-top w-100 bg__primary pt-12 pr-20 pb-12 pl-20">
<div className="flexbox dc__gap-8 dc__content-space dc__border-top w-100 bg__primary px-20 py-12">
{renderSelectedApps()}
{renderBulkTriggerActionButtons()}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/app/details/triggerView/cdMaterial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@
...(getRuntimeParamsPayload
? { runtimeParamsPayload: getRuntimeParamsPayload(runtimeParamsList ?? []) }
: {}),
skipIfHibernated: false,

Check failure on line 897 in src/components/app/details/triggerView/cdMaterial.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'skipIfHibernated' does not exist in type 'TriggerCDNodeServiceProps'.

Check failure on line 897 in src/components/app/details/triggerView/cdMaterial.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'skipIfHibernated' does not exist in type 'TriggerCDNodeServiceProps'.
})
.then((response: any) => {
if (response.result) {
Expand Down
5 changes: 5 additions & 0 deletions src/components/common/navigation/NavigationRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
isManifestScanningEnabled: false,
canOnlyViewPermittedEnvOrgLevel: false,
featureGitOpsFlags: structuredClone(DEFAULT_GIT_OPS_FEATURE_FLAGS),
deployUnhibernatedAppOnly: false,

Check failure on line 160 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataStateType | (() => EnvironmentDataStateType)'.

Check failure on line 160 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataStateType | (() => EnvironmentDataStateType)'.
devtronManagedLicensingEnabled: false,
})
const [userPreferences, setUserPreferences] = useState<UserPreferencesType>(null)
Expand Down Expand Up @@ -339,10 +340,11 @@
isManifestScanningEnabled: false,
canOnlyViewPermittedEnvOrgLevel: false,
featureGitOpsFlags: structuredClone(DEFAULT_GIT_OPS_FEATURE_FLAGS),
deployUnhibernatedAppOnly: false,

Check failure on line 343 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataValuesDTO'.
devtronManagedLicensingEnabled: false,
}

if (!getEnvironmentData) {

Check failure on line 347 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataValuesDTO'.
return fallbackResponse
}

Expand All @@ -359,10 +361,11 @@
isManifestScanningEnabled: result.isManifestScanningEnabled,
canOnlyViewPermittedEnvOrgLevel: result.canOnlyViewPermittedEnvOrgLevel,
featureGitOpsFlags: parsedFeatureGitOpsFlags,
deployUnhibernatedAppOnly: result.deployUnhibernatedAppOnly ?? false,

Check failure on line 364 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataValuesDTO'.

Check failure on line 364 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'EnvironmentDataValuesDTO'.
devtronManagedLicensingEnabled: result.devtronManagedLicensingEnabled || false,
}
} catch {
return fallbackResponse

Check failure on line 368 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'EnvironmentDataValuesDTO'.

Check failure on line 368 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'EnvironmentDataValuesDTO'.
}
}

Expand All @@ -386,7 +389,7 @@
} else {
handleInitializeUserPreferencesFromResponse(userPreferencesResponse)
}
} catch (error) {

Check failure on line 392 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'SetStateAction<EnvironmentDataStateType>'.

Check failure on line 392 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'EnvironmentDataValuesDTO'.
setUserPreferencesError(error)
}
}
Expand All @@ -407,6 +410,7 @@
isManifestScanningEnabled: environmentDataResponse.isManifestScanningEnabled,
canOnlyViewPermittedEnvOrgLevel: environmentDataResponse.canOnlyViewPermittedEnvOrgLevel,
featureGitOpsFlags: environmentDataResponse.featureGitOpsFlags,
deployUnhibernatedAppOnly: environmentDataResponse.deployUnhibernatedAppOnly,

Check failure on line 413 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'SetStateAction<EnvironmentDataStateType>'.

Check failure on line 413 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Property 'deployUnhibernatedAppOnly' does not exist on type 'EnvironmentDataValuesDTO'.
devtronManagedLicensingEnabled: environmentDataResponse.devtronManagedLicensingEnabled,
})

Expand Down Expand Up @@ -492,7 +496,7 @@

const showStackManager = !devtronManagedLicensingEnabled

return (

Check failure on line 499 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'MainContext'.
<MainContextProvider
value={{
serverMode,
Expand Down Expand Up @@ -528,6 +532,7 @@
handleOpenLicenseInfoDialog,
licenseData,
setLicenseData,
deployUnhibernatedAppOnly: environmentDataState.deployUnhibernatedAppOnly,

Check failure on line 535 in src/components/common/navigation/NavigationRoutes.tsx

View workflow job for this annotation

GitHub Actions / ci

Object literal may only specify known properties, and 'deployUnhibernatedAppOnly' does not exist in type 'MainContext'.
}}
>
<main className={_isOnboardingPage ? 'no-nav' : ''} id={DEVTRON_BASE_MAIN_ID}>
Expand Down
Loading