Skip to content

Commit

Permalink
feat(core/managed): add pre-deployment events for builds (#8768)
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Munson committed Dec 4, 2020
1 parent 8038dd8 commit cb68308
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 28 deletions.
4 changes: 2 additions & 2 deletions app/scripts/modules/core/src/domain/IManagedEntity.ts
Expand Up @@ -108,9 +108,9 @@ export interface IManagedArtifactVersion {
lifecycleSteps?: Array<{
// likely more scopes + types later, but hard-coding to avoid premature abstraction for now
scope: 'PRE_DEPLOYMENT';
type: 'BAKE';
type: 'BUILD' | 'BAKE';
id: string;
status: 'NOT_STARTED' | 'RUNNING' | 'SUCCEEDED' | 'FAILED';
status: 'NOT_STARTED' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'ABORTED' | 'UNKNOWN';
startedAt?: string;
completedAt?: string;
link?: string;
Expand Down
8 changes: 5 additions & 3 deletions app/scripts/modules/core/src/managed/ArtifactDetail.tsx
Expand Up @@ -244,7 +244,9 @@ export const ArtifactDetail = ({
const isPinnedEverywhere = environments.every(({ pinned }) => pinned);
const isBadEverywhere = environments.every(({ state }) => state === 'vetoed');
const createdAtTimestamp = useMemo(() => createdAt && DateTime.fromISO(createdAt), [createdAt]);
const preDeploymentSteps = lifecycleSteps?.filter(({ scope }) => scope === 'PRE_DEPLOYMENT');

// These steps come in with chronological ordering, but we need reverse-chronological orddering for display
const preDeploymentSteps = lifecycleSteps?.filter(({ scope }) => scope === 'PRE_DEPLOYMENT').reverse();

return (
<>
Expand Down Expand Up @@ -350,7 +352,7 @@ export const ArtifactDetail = ({
name={environmentName}
resources={resourcesByEnvironment[environmentName]}
>
<div className="sp-margin-l-right">
<div>
<EnvironmentCards
application={application}
environment={environment}
Expand Down Expand Up @@ -389,7 +391,7 @@ export const ArtifactDetail = ({
})}
{preDeploymentSteps && preDeploymentSteps.length > 0 && (
<PreDeploymentRow>
{lifecycleSteps.map((step) => (
{preDeploymentSteps.map((step) => (
<PreDeploymentStepCard key={step.id} step={step} application={application} reference={reference} />
))}
</PreDeploymentRow>
Expand Down
14 changes: 10 additions & 4 deletions app/scripts/modules/core/src/managed/ArtifactsList.tsx
Expand Up @@ -167,13 +167,19 @@ function getArtifactStatuses({ environments, lifecycleSteps }: IManagedArtifactV
// NOTE: The order in which entries are added to `statuses` is important. The highest priority
// item must be inserted first.

const bakeStep = lifecycleSteps?.find(
const preDeploymentSteps = lifecycleSteps?.filter(
({ scope, type, status }) =>
scope === 'PRE_DEPLOYMENT' && type === 'BAKE' && ['RUNNING', 'FAILED'].includes(status),
scope === 'PRE_DEPLOYMENT' && ['BUILD', 'BAKE'].includes(type) && ['RUNNING', 'FAILED'].includes(status),
);

if (bakeStep) {
statuses.push({ iconName: 'bake', appearance: bakeStep.status === 'RUNNING' ? 'progress' : 'error' });
if (preDeploymentSteps?.length > 0) {
// These steps come in with chronological ordering, but we need reverse-chronological orddering for display
preDeploymentSteps.reverse().forEach(({ type, status }) => {
statuses.push({
iconName: type === 'BUILD' ? 'build' : 'bake',
appearance: status === 'RUNNING' ? 'progress' : 'error',
});
});
}

const pendingConstraintIcons = new Set<IconNames>();
Expand Down
59 changes: 44 additions & 15 deletions app/scripts/modules/core/src/managed/PreDeploymentStepCard.tsx
Expand Up @@ -9,17 +9,42 @@ import { Application } from '../application';
import { StatusCard } from './StatusCard';
import { Button } from './Button';

const SUPPORTED_TYPES = ['BAKE'];
const SUPPORTED_TYPES = ['BUILD', 'BAKE'];

const cardAppearanceByStatus = {
NOT_STARTED: 'future',
RUNNING: 'info',
SUCCEEDED: 'neutral',
FAILED: 'error',
ABORTED: 'neutral',
UNKNOWN: 'warning',
} as const;

const cardConfigurationByType = {
BUILD: {
iconName: 'build',
title: ({ status, startedAt, completedAt }: IManagedArtifactVersionLifecycleStep) => {
const startedAtDate = startedAt ? DateTime.fromISO(startedAt).toJSDate() : null;
const completedAtDate = completedAt ? DateTime.fromISO(completedAt).toJSDate() : null;

switch (status) {
case 'NOT_STARTED':
return 'A build will run before deployment';
case 'RUNNING':
return 'Building';
case 'SUCCEEDED':
return `Built in ${distanceInWords(startedAtDate, completedAtDate)}`;
case 'FAILED':
return `Build failed after ${distanceInWords(startedAtDate, completedAtDate)}`;
case 'ABORTED':
return `Build aborted after ${distanceInWords(startedAtDate, completedAtDate)}`;
case 'UNKNOWN':
return 'Unable to find the status of this build';
}
},
},
BAKE: {
iconName: 'bake',
appearance: {
NOT_STARTED: 'future',
RUNNING: 'info',
SUCCEEDED: 'neutral',
FAILED: 'error',
},
title: ({ status, startedAt, completedAt }: IManagedArtifactVersionLifecycleStep) => {
const startedAtDate = startedAt ? DateTime.fromISO(startedAt).toJSDate() : null;
const completedAtDate = completedAt ? DateTime.fromISO(completedAt).toJSDate() : null;
Expand All @@ -33,8 +58,10 @@ const cardConfigurationByType = {
return `Baked in ${distanceInWords(startedAtDate, completedAtDate)}`;
case 'FAILED':
return `Baking failed after ${distanceInWords(startedAtDate, completedAtDate)}`;
default:
return null;
case 'ABORTED':
return `Baking aborted after ${distanceInWords(startedAtDate, completedAtDate)}`;
case 'UNKNOWN':
return 'Unable to find the status of this bake';
}
},
},
Expand Down Expand Up @@ -70,25 +97,27 @@ export const PreDeploymentStepCard = memo(({ step, application, reference }: Pre
return null;
}

const { iconName, appearance, title } = cardConfigurationByType[type];
const { iconName, title } = cardConfigurationByType[type];

return (
<StatusCard
appearance={appearance[status]}
appearance={cardAppearanceByStatus[status]}
active={status !== 'NOT_STARTED'}
iconName={iconName}
timestamp={getTimestamp(startedAt, completedAt)}
title={title(step)}
actions={
link && (
<Button
<a
className="nostyle"
href={link}
rel="noopener noreferrer"
onClick={() => {
window.open(link, '_blank', 'noopener noreferrer');
logEvent('Pre-deployment details link clicked', application.name, reference, type, status);
}}
>
See {status === 'RUNNING' ? 'progress' : 'details'}
</Button>
<Button>See {status === 'RUNNING' ? 'progress' : 'details'}</Button>
</a>
)
}
/>
Expand Down
11 changes: 7 additions & 4 deletions app/scripts/modules/core/src/managed/VersionStateCard.tsx
Expand Up @@ -138,14 +138,17 @@ export const VersionStateCard = memo(
description={cardAppearanceByState[state].description?.(cardMetadata)}
actions={
compareLink && (
<Button
<a
className="nostyle"
href={compareLink}
target="_blank"
rel="noopener noreferrer"
onClick={() => {
window.open(compareLink, '_blank', 'noopener noreferrer');
logClick('See changes clicked');
}}
>
See changes
</Button>
<Button>See changes</Button>
</a>
)
}
/>
Expand Down

0 comments on commit cb68308

Please sign in to comment.