mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
c57c769dea
* feat: add CI test scripts with auto-trigger on deploy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: fix annotation parser early return and handle renames correctly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: move CI test results to top of script/flow detail pages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: improve CI test results spacing, icon, and remove pass label Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: support one-line annotation and use script/path format Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: move CI test trigger logic to EE Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: move CI badge next to New badge and add deduplicated CI summary Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add CI test e2e tests and fix nullable column annotations Add integration tests for CI test annotation parsing (creates/removes ci_test_reference rows) and the CI test results API (single + batch endpoints). Add backend test for auto-trigger on deploy (private+python). Fix sqlx LEFT JOIN LATERAL nullable column annotations in get_ci_test_results and get_ci_test_results_batch queries — sqlx cannot infer nullability from LATERAL subqueries, causing runtime decode errors when no matching job exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix build/sqlx * fix * feat: CI test improvements and templates - Fix windmill-dep-map/private feature propagation in worker, api-scripts, and api-flows Cargo.toml so CI test triggers actually fire in EE mode - Clone ci_test_reference rows during workspace fork - Add polling to CiTestResults component (refetch every 3s while running) - Add running state and auto-refresh to ForkWorkspaceBanner CI summary - Add yellow "CI test" badge on script list rows and detail page - Fix Library badge border color (remove indigo border override) - Add CI Test TypeScript and CI Test Python templates in ScriptBuilder - Update sqlx offline cache - Add debug tracing for CI test trigger in worker_lockfiles Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add missing children prop to WorkspaceDeployLayout Fixes svelte-fast-check type error when passing named snippets as children content inside the component tag. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review feedback - Remove empty wrapper divs around CiTestResults, move mb-4 into component - Add batch endpoint size cap (max 200 items) - Add ON DELETE CASCADE to ci_test_reference workspace FK (new migration) - Downgrade CI test trigger logs from info to debug - Fix false-positive polling: only treat status='running' as running, not null status (CiTestResults, CompareWorkspaces, ForkWorkspaceBanner) - Fix test numbering in integration tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to latest EE commit Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to d9d68c2406df0b59f413ea0b2cb24780a9817d04 This commit updates the EE repository reference after PR #516 was merged in windmill-ee-private. Previous ee-repo-ref: d7ccd9b86da99ec056a0e8708e3637d64290387a New ee-repo-ref: d9d68c2406df0b59f413ea0b2cb24780a9817d04 Automated by sync-ee-ref workflow. * fix: treat queued jobs (job_id set, null status) as running Jobs that have been pushed but not yet picked up by a worker have a job_id but null status. Treat these as 'running' to avoid showing misleading 'pass' badges or '0 passing'. Tests that were never triggered (no job_id, null status) remain neutral/hidden. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: hugocasa <hugo@casademont.ch> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
158 lines
3.9 KiB
Svelte
158 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import { Loader2 } from 'lucide-svelte'
|
|
import { Badge } from './common'
|
|
import Row from './common/table/Row.svelte'
|
|
import Tooltip from './Tooltip.svelte'
|
|
import type { Snippet } from 'svelte'
|
|
import type { Kind } from '$lib/utils_deployable'
|
|
|
|
interface DeployableItem {
|
|
key: string
|
|
path: string
|
|
kind: Kind
|
|
triggerKind?: string
|
|
[key: string]: unknown
|
|
}
|
|
|
|
interface Props {
|
|
items: DeployableItem[]
|
|
selectedItems: string[]
|
|
selectablePredicate?: (item: DeployableItem) => boolean
|
|
deploymentStatus: Record<string, { status: 'loading' | 'deployed' | 'failed'; error?: string }>
|
|
allSelected?: boolean
|
|
emptyMessage?: string
|
|
children?: Snippet
|
|
|
|
// Snippets for customization
|
|
header?: Snippet
|
|
alerts?: Snippet
|
|
itemSummary?: Snippet<[DeployableItem]>
|
|
itemActions?: Snippet<[DeployableItem]>
|
|
footer?: Snippet
|
|
|
|
// Callbacks
|
|
onToggleItem?: (item: DeployableItem) => void
|
|
onSelectAll?: () => void
|
|
onDeselectAll?: () => void
|
|
}
|
|
|
|
let {
|
|
items,
|
|
selectedItems,
|
|
selectablePredicate = () => true,
|
|
deploymentStatus,
|
|
allSelected = false,
|
|
emptyMessage = 'No items to deploy',
|
|
header,
|
|
alerts,
|
|
itemSummary,
|
|
itemActions,
|
|
footer,
|
|
onToggleItem,
|
|
onSelectAll,
|
|
onDeselectAll
|
|
}: Props = $props()
|
|
|
|
let selectableItems = $derived(items.filter(selectablePredicate))
|
|
let hasSelectableItems = $derived(selectableItems.length > 0)
|
|
</script>
|
|
|
|
<div class="flex flex-col h-full">
|
|
<!-- Header section -->
|
|
{#if header}
|
|
<div class="bg-surface">
|
|
{@render header()}
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Alerts section -->
|
|
{#if alerts}
|
|
{@render alerts()}
|
|
{/if}
|
|
|
|
{#if items.length > 0}
|
|
<!-- Select all row -->
|
|
<div class="px-4 py-2 flex items-center justify-between">
|
|
<div
|
|
class="flex items-center gap-2 text-secondary text-xs"
|
|
class:opacity-50={!hasSelectableItems}
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
disabled={!hasSelectableItems}
|
|
checked={allSelected}
|
|
onchange={allSelected ? onDeselectAll : onSelectAll}
|
|
class="rounded max-w-4 w-full"
|
|
/> Select all
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Items list -->
|
|
<div class="overflow-y-auto">
|
|
<div class="border rounded-md bg-surface-tertiary">
|
|
{#each items as item (item.key)}
|
|
{@const isSelectable = selectablePredicate(item)}
|
|
{@const isSelected = selectedItems.includes(item.key)}
|
|
{@const status = deploymentStatus[item.key]}
|
|
{@const isDeployed = status?.status === 'deployed'}
|
|
|
|
<Row
|
|
isSelectable={isSelectable && !isDeployed}
|
|
alignWithSelectable={true}
|
|
disabled={!isSelectable}
|
|
selected={isSelected && !isDeployed}
|
|
onSelect={() => onToggleItem?.(item)}
|
|
path={item.kind !== 'resource' &&
|
|
item.kind !== 'variable' &&
|
|
item.kind !== 'resource_type'
|
|
? item.path
|
|
: ''}
|
|
marked={undefined}
|
|
kind={item.kind}
|
|
triggerKind={item.triggerKind}
|
|
canFavorite={false}
|
|
workspaceId=""
|
|
>
|
|
{#snippet customSummary()}
|
|
{#if itemSummary}
|
|
{@render itemSummary(item)}
|
|
{:else}
|
|
{item.path}
|
|
{/if}
|
|
{/snippet}
|
|
{#snippet actions()}
|
|
{#if itemActions}
|
|
{@render itemActions(item)}
|
|
{/if}
|
|
<!-- Deployment status always shown -->
|
|
{#if status}
|
|
{#if status.status === 'loading'}
|
|
<Loader2 class="animate-spin" />
|
|
{:else if status.status === 'deployed'}
|
|
<Badge color="green">Deployed</Badge>
|
|
{:else if status.status === 'failed'}
|
|
<div class="inline-flex gap-1">
|
|
<Badge color="red">Failed</Badge>
|
|
<Tooltip>{status.error}</Tooltip>
|
|
</div>
|
|
{/if}
|
|
{/if}
|
|
{/snippet}
|
|
</Row>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{:else}
|
|
<div class="flex items-center justify-center h-full">
|
|
<div class="text-hint text-xs">{emptyMessage}</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Footer -->
|
|
{#if footer}
|
|
<div class="pt-4">
|
|
{@render footer()}
|
|
</div>
|
|
{/if}
|
|
</div>
|