Skip to content
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

Worker Versioning #2576

Merged
merged 22 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c5e3ff8
Bump api version, add new page for deployments. WIP
Alex-Tideman Feb 10, 2025
777098c
More setup, add individual deployment page. WIP
Alex-Tideman Feb 10, 2025
1a11e9c
Finish deployment and deployment version pages
Alex-Tideman Feb 11, 2025
bc5cc4f
Add trending icon
Alex-Tideman Feb 11, 2025
6d07932
Fix merge conflicts
Alex-Tideman Feb 24, 2025
c2acddd
Return real data
Alex-Tideman Feb 24, 2025
e4925ae
Merge branch 'main' into safe-deploys
Alex-Tideman Feb 24, 2025
d125428
Add Deployment columns to workflow list, add drained/inactive icons, …
Alex-Tideman Feb 24, 2025
10023a2
Remove search for now, better colors, add deployment column
Alex-Tideman Feb 24, 2025
67114b0
Remove deployment details
Alex-Tideman Feb 24, 2025
85fcee2
Update snapshots
Alex-Tideman Feb 24, 2025
3cf8bfb
Update src/lib/pages/deployments.svelte
Alex-Tideman Feb 25, 2025
e8e406f
Update src/lib/pages/deployments.svelte
Alex-Tideman Feb 25, 2025
d87b320
Update src/lib/components/deployments/version-table-row.svelte
Alex-Tideman Feb 25, 2025
3d7e514
Update src/lib/utilities/route-for.ts
Alex-Tideman Feb 25, 2025
37fb68c
Update src/lib/components/deployments/version-table-row.svelte
Alex-Tideman Feb 25, 2025
acae1cf
Fix route
Alex-Tideman Feb 25, 2025
a9a0199
Add back versioning tab for v2 versioning
Alex-Tideman Feb 25, 2025
1bfd8c5
Add link for versioning docs
Alex-Tideman Feb 25, 2025
5a3dc6e
Change link url
Alex-Tideman Feb 25, 2025
c9c0537
Remove description text
Alex-Tideman Feb 25, 2025
6d910e1
Change text
Alex-Tideman Feb 25, 2025
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
45 changes: 45 additions & 0 deletions src/lib/components/deployments/deployment-status.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts">
import { cva } from 'class-variance-authority';

import type { IconName } from '$lib/holocene/icon';
import Icon from '$lib/holocene/icon/icon.svelte';
import type { DeploymentStatus } from '$lib/types/deployments';

export let status: DeploymentStatus;
export let version: string;
export let label: string;

const icon: Record<DeploymentStatus, IconName> = {
Current: 'heartbeat',
Ramping: 'trending-up',
Draining: 'trending-down',
Drained: 'drained',
Inactive: 'inactive',
};

const deploymentStatus = cva(
[
'flex items-center gap-1 rounded-sm border border-subtle px-1 transition-colors',
],
{
variants: {
status: {
Ramping: 'text-cyan-600 dark:text-cyan-400',
Current: 'text-blue-600 dark:text-blue-400',
Draining: 'text-yellow-600 dark:text-yellow-200',
Drained: 'text-secondary',
Inactive: 'text-secondary',
},
},
},
);
</script>

<p class="flex items-center gap-2">
<span class="rounded-sm border border-subtle px-1">
{version}
</span>
<span class={deploymentStatus({ status })}>
<Icon name={icon[status]} />{label}</span
>
</p>
86 changes: 86 additions & 0 deletions src/lib/components/deployments/deployment-table-row.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<script lang="ts">
import { page } from '$app/stores';

import Link from '$lib/holocene/link.svelte';
import { translate } from '$lib/i18n/translate';
import type { ConfigurableTableHeader } from '$lib/stores/configurable-table-columns';
import { relativeTime, timeFormat } from '$lib/stores/time-format';
import type { WorkerDeploymentSummary } from '$lib/types/deployments';
import { formatDate } from '$lib/utilities/format-date';
import {
routeForWorkerDeployment,
routeForWorkflowsWithQuery,
} from '$lib/utilities/route-for';

import DeploymentStatus from './deployment-status.svelte';

export let deployment: WorkerDeploymentSummary;
export let columns: ConfigurableTableHeader[];
</script>

<tr>
{#each columns as { label } (label)}
{#if label === translate('deployments.name')}
<td class="p-2 text-left"
><Link
href={routeForWorkerDeployment({
namespace: $page.params.namespace,
deployment: deployment.name,
})}>{deployment.name}</Link
></td
>
{:else if label === translate('deployments.deployment-version')}
<td class="whitespace-pre-line break-words p-2 text-left">
<div class="flex flex-col gap-1">
{#if deployment.routingConfig.rampingVersion}
<DeploymentStatus
status="Ramping"
version={deployment.routingConfig.rampingVersion}
label={translate('deployments.ramping-percentage', {
percentage: deployment.routingConfig.rampingVersionPercentage,
})}
/>
{/if}
<DeploymentStatus
status="Current"
version={deployment.routingConfig.currentVersion}
label={translate('deployments.current')}
/>
</div>
</td>
{:else if label === translate('deployments.deployed')}
<td class="truncate p-2 text-left">
<div class="flex flex-col gap-1">
{#if deployment.routingConfig.rampingVersionChangedTime}
<p>
{formatDate(
deployment.routingConfig.rampingVersionChangedTime,
$timeFormat,
{
relative: $relativeTime,
},
)}
</p>
{/if}
<p>
{formatDate(deployment.createTime, $timeFormat, {
relative: $relativeTime,
})}
</p>
</div>
</td>
{:else if label === translate('deployments.workflows')}
<td class="truncate p-2 text-center"
><p>
<Link
icon="external-link"
href={routeForWorkflowsWithQuery({
namespace: $page.params.namespace,
query: `TemporalWorkerDeployment="${deployment.name}"`,
})}
/>
</p></td
>
{/if}
{/each}
</tr>
29 changes: 29 additions & 0 deletions src/lib/components/deployments/version-details.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
import { translate } from '$lib/i18n/translate';
import { relativeTime, timeFormat } from '$lib/stores/time-format';
import type { WorkerDeploymentVersionInfo } from '$lib/types/deployments';
import { formatDate } from '$lib/utilities/format-date';

import WorkflowDetail from '../lines-and-dots/workflow-detail.svelte';

export let version: WorkerDeploymentVersionInfo;
</script>

<div class="flex w-full flex-col gap-2 lg:flex-row lg:gap-8 xl:gap-16">
<div class="flex w-full flex-col gap-2 lg:w-1/3 xl:w-1/4">
<WorkflowDetail
title={translate('common.status')}
content={version.drainageInfo.status}
/>
<WorkflowDetail
title={translate('deployments.rollout-started')}
content={formatDate(version.createTime, $timeFormat, {
relative: $relativeTime,
})}
/>
</div>
<div class="flex w-full flex-col gap-2 lg:w-1/3 xl:w-1/4">
<WorkflowDetail title={translate('deployments.rollout-id')} content="-" />
<WorkflowDetail title={translate('deployments.rollout-url')} content="-" />
</div>
</div>
75 changes: 75 additions & 0 deletions src/lib/components/deployments/version-table-row.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script lang="ts">
import { page } from '$app/stores';

import Link from '$lib/holocene/link.svelte';
import { translate } from '$lib/i18n/translate';
import type { ConfigurableTableHeader } from '$lib/stores/configurable-table-columns';
import { relativeTime, timeFormat } from '$lib/stores/time-format';
import type { RoutingConfig, VersionSummary } from '$lib/types/deployments';
import type { DeploymentStatus as Status } from '$lib/types/deployments';
import { formatDate } from '$lib/utilities/format-date';
import { routeForWorkflowsWithQuery } from '$lib/utilities/route-for';
import { fromScreamingEnum } from '$lib/utilities/screaming-enums';

import DeploymentStatus from './deployment-status.svelte';

export let routingConfig: RoutingConfig;
export let version: VersionSummary;
export let columns: ConfigurableTableHeader[];

$: isCurrent = version.version === routingConfig.currentVersion;
$: isRamping = version.version === routingConfig.rampingVersion;
$: drainageStatus = version.drainageStatus;

$: status = (
isCurrent
? translate('deployments.current')
: isRamping
? translate('deployments.ramping')
: drainageStatus
? fromScreamingEnum(drainageStatus, 'VersionDrainageStatus')
: 'Inactive'
) as Status;

$: statusLabel = isCurrent
? translate('deployments.current')
: isRamping
? translate('deployments.ramping', {
percentage: routingConfig.rampingVersionPercentage,
})
: drainageStatus
? fromScreamingEnum(drainageStatus, 'VersionDrainageStatus')
: 'Inactive';
</script>

<tr>
{#each columns as { label } (label)}
{#if label === translate('deployments.version')}
<td class="p-2 text-left">
<DeploymentStatus
{status}
version={version.version}
label={statusLabel}
/>
</td>
{:else if label === translate('deployments.deployed')}
<td class="whitespace-pre-line break-words p-2 text-left"
>{formatDate(version?.createTime, $timeFormat, {
relative: $relativeTime,
})}</td
>
{:else if label === translate('deployments.workflows')}
<td class="whitespace-pre-line break-words p-2 text-center"
><p>
<Link
icon="external-link"
href={routeForWorkflowsWithQuery({
namespace: $page.params.namespace,
query: `TemporalWorkerDeploymentVersion="${version.version}"`,
})}
/>
</p></td
>
{/if}
{/each}
</tr>
55 changes: 51 additions & 4 deletions src/lib/components/lines-and-dots/workflow-details.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { formatDate } from '$lib/utilities/format-date';
import { formatDistanceAbbreviated } from '$lib/utilities/format-time';
import {
routeForWorkerDeployment,
routeForWorkers,
routeForWorkflow,
routeForWorkflowsWithQuery,
Expand All @@ -23,10 +24,26 @@
end: workflow?.endTime || Date.now(),
includeMilliseconds: true,
});
$: deployment =
workflow?.searchAttributes?.indexedFields?.['TemporalWorkerDeployment'];
$: deploymentVersion =
workflow?.searchAttributes?.indexedFields?.[
'TemporalWorkerDeploymentVersion'
];
$: deploymentBehavior =
workflow?.searchAttributes?.indexedFields?.[
'TemporalWorkflowVersioningBehavior'
];
</script>

<div class="flex w-full flex-col gap-2 xl:flex-row xl:gap-16">
<div class="flex w-full flex-col gap-2 xl:w-1/3">
<div
class="flex w-full flex-col gap-2 {deployment
? '2xl:flex-row 2xl:gap-8'
: 'xl:flex-row xl:gap-8'}"
>
<div
class="flex w-full flex-col gap-2 {deployment ? '2xl:w-1/4' : 'xl:w-1/3'}"
>
<WorkflowDetail
title={translate('common.start')}
tooltip={$relativeTime
Expand Down Expand Up @@ -57,7 +74,9 @@
/>
<WorkflowDetail content={elapsedTime} icon="clock" />
</div>
<div class="flex w-full flex-col gap-2 xl:w-1/3">
<div
class="flex w-full flex-col gap-2 {deployment ? '2xl:w-1/4' : 'xl:w-1/3'}"
>
<WorkflowDetail
title={translate('common.run-id')}
content={workflow?.runId}
Expand All @@ -83,7 +102,35 @@
})}
/>
</div>
<div class="flex w-full flex-col gap-2 xl:w-1/3">
{#if deployment}
<div class="flex w-full flex-col gap-2 2xl:w-1/4">
<WorkflowDetail
title={translate('deployments.deployment')}
content={deployment}
href={routeForWorkerDeployment({
namespace,
deployment,
})}
/>
{#if deploymentVersion}
<WorkflowDetail
title={translate('deployments.deployment-version')}
content={workflow.searchAttributes.indexedFields[
'TemporalWorkerDeploymentVersion'
]}
/>
{/if}
{#if deploymentBehavior}
<WorkflowDetail
title={translate('deployments.deployment-behavior')}
content={deploymentBehavior}
/>
{/if}
</div>
{/if}
<div
class="flex w-full flex-col gap-2 {deployment ? '2xl:w-1/4' : 'xl:w-1/3'}"
>
{#if workflow?.parent}
<WorkflowDetail
title={translate('workflows.parent-workflow')}
Expand Down
17 changes: 17 additions & 0 deletions src/lib/components/worker-table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
import Table from '$lib/holocene/table/table.svelte';
import { translate } from '$lib/i18n/translate';
import { type GetPollersResponse } from '$lib/services/pollers-service';
import { isCloud } from '$lib/stores/advanced-visibility';
import { relativeTime, timeFormat } from '$lib/stores/time-format';
import { formatDate } from '$lib/utilities/format-date';

import PollerIcon from './poller-icon.svelte';

export let workers: GetPollersResponse;

const getDeploymentName = (poller) => {
const deployment = poller?.workerVersionCapabilities?.deploymentSeriesName;
return deployment ?? '';
};
</script>

<h2 class="flex items-center gap-2" data-testid="workers">
Expand All @@ -25,6 +31,9 @@
<TableHeaderRow slot="headers">
<th class={'w-4/12'}>{translate('common.id')}</th>
<th class={'w-3/12'}>{translate('workers.buildId')}</th>
{#if !$isCloud}
<th class={'w-3/12'}>{translate('deployments.deployment')}</th>
{/if}
<th class="w-2/12">{translate('workflows.last-accessed')}</th>
<th class="w-2/12">
<p class="text-center">
Expand All @@ -45,6 +54,14 @@
{poller?.workerVersionCapabilities?.buildId ?? ''}
</p>
</td>
{#if !$isCloud}
{@const deployment = getDeploymentName(poller)}
<td class="text-left" data-testid="worker-build-id">
<p class="select-all break-all">
{deployment ?? ''}
</p>
</td>
{/if}
<td class="text-left" data-testid="worker-last-access-time">
<p class="select-all">
{formatDate(poller.lastAccessTime, $timeFormat, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@
{content && typeof content === 'string'
? formatDate(content, $timeFormat, { relative: $relativeTime })
: ''}
{:else if label === 'Deployment'}
{@const content =
workflow.searchAttributes?.indexedFields?.TemporalWorkerDeployment}
{content && typeof content === 'string' ? content : ''}
{:else if label === 'Deployment Version'}
{@const content =
workflow.searchAttributes?.indexedFields
?.TemporalWorkerDeploymentVersion}
{content && typeof content === 'string' ? content : ''}
{:else if label === 'Versioning Behavior'}
{@const content =
workflow.searchAttributes?.indexedFields
?.TemporalWorkflowVersioningBehavior}
{content && typeof content === 'string' ? content : ''}
{:else if isCustomSearchAttribute(label) && workflowIncludesSearchAttribute(workflow, label)}
{@const content = workflow.searchAttributes.indexedFields[label]}
{#if $customSearchAttributes[label] === SEARCH_ATTRIBUTE_TYPE.DATETIME && typeof content === 'string'}
Expand Down
Loading
Loading