fix tarring the entire cache back to s3 + UX nits

This commit is contained in:
Ruben Fiszel
2022-11-21 09:25:22 +01:00
parent bc7afad1d9
commit 8835659796
11 changed files with 102 additions and 286 deletions
+2 -1
View File
@@ -147,8 +147,9 @@ async fn copy_cache_to_bucket_as_tar(bucket: &str) {
}
match Command::new("rclone")
.current_dir(ROOT_CACHE_DIR)
.arg("copyto")
.arg(ROOT_CACHE_DIR)
.arg(TAR_CACHE_FILENAME)
.arg(format!(":s3,env_auth=true:{bucket}/{TAR_CACHE_FILENAME}"))
.arg("--size-only")
.arg("--fast-list")
+1 -1
View File
@@ -409,8 +409,8 @@
timeoutModel && clearTimeout(timeoutModel)
timeoutModel = setTimeout(() => {
code = getCode()
dispatch('change')
}, 500)
dispatch('change')
})
editor.onDidFocusEditorText(() => {
+10 -13
View File
@@ -23,7 +23,7 @@
import Button from './common/button/Button.svelte'
import HighlightCode from './HighlightCode.svelte'
import DrawerContent from './common/drawer/DrawerContent.svelte'
import { Drawer } from './common'
import { Badge, Drawer } from './common'
export let lang: 'python3' | 'deno' | 'go' | 'bash'
export let editor: Editor
@@ -213,17 +213,14 @@
<ResourceEditor bind:this={resourceEditor} on:refresh={resourcePicker.openDrawer} />
<VariableEditor bind:this={variableEditor} on:create={variablePicker.openDrawer} />
<div class="flex flex-row justify-between items-center overflow-hidden w-full">
<div class="flex flex-row justify-between items-center overflow-hidden w-full px-1">
<div class="flex flex-row divide-x items-center">
<div class="mx-2">
<span
title={validCode
? 'last signature parsing was sucessful'
: 'last signature parsing was NOT succesful'}
class="relative inline-flex rounded-full h-2 w-2 {validCode
? 'bg-green-500/80'
: 'bg-red-500'}"
/>
{#if validCode}
<Badge color="green">Inputs</Badge>
{:else}
<Badge color="red">Inputs</Badge>
{/if}
</div>
<div>
<Button
@@ -293,9 +290,9 @@
</Button>
</div>
</div>
<div>
<div class="py-1">
<Button
btnClasses="ml-1 !font-medium"
btnClasses="!font-medium"
size="xs"
spacingSize="md"
color="light"
@@ -305,7 +302,7 @@
{#if !iconOnly}
Reload assistants
{/if}
<span class="ml-1">
<span class="ml-1 -my-1">
{#if lang == 'deno'}
(<span class={websocketAlive.deno ? 'green' : 'text-red-700'}>Deno</span>)
{:else if lang == 'go'}
@@ -1,197 +0,0 @@
<script lang="ts">
import { scriptPathToHref } from '$lib/utils'
import { slide } from 'svelte/transition'
import InputTransformsViewer from './InputTransformsViewer.svelte'
import IconedPath from './IconedPath.svelte'
import type { FlowModule } from '$lib/gen'
import HighlightCode from './HighlightCode.svelte'
import { faBug } from '@fortawesome/free-solid-svg-icons'
import Icon from 'svelte-awesome'
export let modules: FlowModule[]
export let failureModule: FlowModule | undefined
let open: { [id: number]: boolean } = {}
</script>
<p class="font-black text-lg my-6 w-full">
<span>{modules?.length} Step{modules?.length > 1 ? 's' : ''} </span>
<span class="mt-4" />
</p>
<ul class="-mb-8 w-full">
{#each modules ?? [] as mod, i}
<li class="w-full">
<div class="relative pb-8 w-full">
{#if i < (modules ?? []).length - 1 || failureModule}
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true" />
{/if}
<div class="relative flex space-x-3">
<div>
<span
class="h-8 w-8 rounded-full bg-blue-600 flex items-center justify-center ring-8 ring-white text-white"
>
{i + 1}
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
<div class="w-full">
<span class="text-black">{mod?.summary ?? ''}</span>
<p class="text-sm text-gray-500">
{#if mod?.value?.type == 'script'}
<a
target="_blank"
href={scriptPathToHref(mod?.value?.path ?? '')}
class="font-medium text-gray-900"
>
<IconedPath path={mod?.value?.path ?? ''} />
</a>
{#if mod?.value?.path?.startsWith('hub/')}
<div>
<button
on:click={async () => {
open[i] = !open[i]
}}
class="mb-2 underline text-black"
>
View code and inputs {open[i] ? '(-)' : '(+)'}</button
>
{#if open[i]}
<div class="border border-black p-2 bg-gray-50 divide-y">
<InputTransformsViewer
inputTransforms={mod?.value?.input_transforms ??
mod?.input_transforms ??
{}}
/>
<div class="w-full h-full mt-6">
<iframe
style="height: 400px;"
class="w-full h-full text-sm"
title="embedded script from hub"
frameborder="0"
src="https://hub.windmill.dev/embed/script/{mod?.value?.path?.substring(
4
)}"
/>
</div>
</div>
{/if}
</div>
{/if}
{:else if mod?.value?.type == 'rawscript'}
<button on:click={() => (open[i] = !open[i])} class="mb-2 underline text-black">
Raw {mod?.value?.language} script {open[i] ? '(-)' : '(+)'}</button
>
{#if open[i]}
<div transition:slide class="border border-black p-2 bg-gray-50 w-full">
<InputTransformsViewer
inputTransforms={mod?.value?.input_transforms ??
mod?.input_transforms ??
{}}
/>
<HighlightCode
language={mod?.value?.language ?? 'deno'}
code={mod?.value?.content}
/>
</div>
{/if}
{:else if mod?.value?.type == 'forloopflow'}
For loop over all the elements of the list returned as a result of step {i}:
<svelte:self modules={mod.value.modules} />
{/if}
</p>
</div>
</div>
</div>
</div>
</li>
{/each}
{#if failureModule}
<li class="w-full">
<div class="relative pb-8 w-full">
<div class="relative flex space-x-3">
<div>
<span
class="h-8 w-8 rounded-full bg-red-600 flex items-center justify-center ring-8 ring-white text-white"
>
<Icon data={faBug} />
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
<div class="w-full">
<span class="text-black">{failureModule?.summary ?? ''}</span>
<p class="text-sm text-gray-500">
{#if failureModule?.value?.type == 'script'}
<a
target="_blank"
href={scriptPathToHref(failureModule?.value?.path ?? '')}
class="font-medium text-gray-900"
>
<IconedPath path={failureModule?.value?.path ?? ''} />
</a>
{#if failureModule?.value?.path?.startsWith('hub/')}
<div>
<button
on:click={async () => {
open[modules.length] = !open[modules.length]
}}
class="mb-2 underline text-black"
>
View code and inputs {open[modules.length] ? '(-)' : '(+)'}</button
>
{#if open[modules.length]}
<div class="border border-black p-2 bg-gray-50 divide-y">
<InputTransformsViewer
inputTransforms={failureModule?.value?.input_transforms ??
failureModule?.input_transforms ??
{}}
/>
<div class="w-full h-full mt-6">
<iframe
style="height: 400px;"
class="w-full h-full text-sm"
title="embedded script from hub"
frameborder="0"
src="https://hub.windmill.dev/embed/script/{failureModule?.value?.path?.substring(
4
)}"
/>
</div>
</div>
{/if}
</div>
{/if}
{:else if failureModule?.value?.type == 'rawscript'}
<button
on:click={() => (open[modules.length] = !open[modules.length])}
class="mb-2 underline text-black"
>
Error handler: Raw {failureModule?.value?.language} script {open[modules.length]
? '(-)'
: '(+)'}</button
>
{#if open[modules.length]}
<div transition:slide class="border border-black p-2 bg-gray-50 w-full">
<InputTransformsViewer
inputTransforms={failureModule?.value?.input_transforms ??
failureModule?.input_transforms ??
{}}
/>
<HighlightCode
language={failureModule?.value?.language ?? 'deno'}
code={failureModule?.value?.content}
/>
</div>
{/if}
{/if}
</p>
</div>
</div>
</div>
</div>
</li>
{/if}
</ul>
+33 -29
View File
@@ -2,6 +2,7 @@
import type { Schema } from '$lib/common'
import type { InputTransform } from '$lib/gen'
import { allTrue } from '$lib/utils'
import { slide } from 'svelte/transition'
import ArgInput from './ArgInput.svelte'
import InputTransformForm from './InputTransformForm.svelte'
@@ -15,6 +16,7 @@
export let extraLib: string = 'missing extraLib'
export let importPath: string | undefined = undefined
export let autofocus = false
export let animateNew = false
let clazz: string = ''
export { clazz as class }
@@ -41,35 +43,37 @@
<div class="w-full {clazz}">
{#if Object.keys(schema?.properties ?? {}).length > 0}
{#each Object.keys(schema?.properties ?? {}) as argName, i (argName)}
{#if inputTransform}
<InputTransformForm
bind:arg={args[argName]}
bind:schema
bind:argName
bind:inputCheck={inputCheck[argName]}
bind:extraLib
bind:importPath
/>
{:else}
<ArgInput
autofocus={i == 0 && autofocus}
label={argName}
bind:description={schema.properties[argName].description}
bind:value={args[argName]}
type={schema.properties[argName].type}
required={schema.required.includes(argName)}
bind:pattern={schema.properties[argName].pattern}
bind:valid={inputCheck[argName]}
defaultValue={schema.properties[argName].default}
bind:enum_={schema.properties[argName].enum}
bind:format={schema.properties[argName].format}
contentEncoding={schema.properties[argName].contentEncoding}
properties={schema.properties[argName].properties}
bind:itemsType={schema.properties[argName].items}
disabled={disabledArgs.includes(argName)}
{editableSchema}
/>
{/if}
<div transition:slide|local>
{#if inputTransform}
<InputTransformForm
bind:arg={args[argName]}
bind:schema
bind:argName
bind:inputCheck={inputCheck[argName]}
bind:extraLib
bind:importPath
/>
{:else}
<ArgInput
autofocus={i == 0 && autofocus}
label={argName}
bind:description={schema.properties[argName].description}
bind:value={args[argName]}
type={schema.properties[argName].type}
required={schema.required.includes(argName)}
bind:pattern={schema.properties[argName].pattern}
bind:valid={inputCheck[argName]}
defaultValue={schema.properties[argName].default}
bind:enum_={schema.properties[argName].enum}
bind:format={schema.properties[argName].format}
contentEncoding={schema.properties[argName].contentEncoding}
properties={schema.properties[argName].properties}
bind:itemsType={schema.properties[argName].items}
disabled={disabledArgs.includes(argName)}
{editableSchema}
/>
{/if}
</div>
{/each}
{:else}
<p class="italic text-sm">No inputs</p>
@@ -16,7 +16,7 @@
import UnsavedConfirmationModal from './common/confirmationModal/UnsavedConfirmationModal.svelte'
import { dirtyStore } from './common/confirmationModal/dirtyStore'
import { Button } from './common'
import { faChevronDown, faChevronUp, faPen } from '@fortawesome/free-solid-svg-icons'
import { faChevronDown, faChevronUp, faPen, faSave } from '@fortawesome/free-solid-svg-icons'
import Breadcrumb from './common/breadcrumb/Breadcrumb.svelte'
import Toggle from './Toggle.svelte'
@@ -86,11 +86,13 @@
<UnsavedConfirmationModal />
<div class="flex flex-col h-screen">
<!-- Nav between steps-->
<div class="flex flex-col w-full px-4 py-2 border-b shadow-sm">
<div class="justify-between flex flex-row w-full items-center overflow-x-auto scrollbar-hidden">
<div class="flex flex-row">
<div class="flex flex-col w-full px-2 py-1 border-b shadow-sm">
<div
class="justify-between flex flex-row w-full items-center overflow-x-auto scrollbar-hidden px-2"
>
<div class="flex flex-row py-1">
<Breadcrumb
items={['Metadata', 'Code', 'UI Customisation']}
items={['Metadata', 'Code', 'Advanced']}
selectedIndex={step}
on:select={(e) => changeStep(e.detail.index + 1)}
disabled={pathError != ''}
@@ -130,13 +132,6 @@
</Button>
</div>
<div class="flex flex-row gap-x-2">
<Button
size="sm"
variant={step == 1 ? 'border' : 'contained'}
disabled={step === 1 && pathError !== ''}
btnClasses={step == 1 && initialPath == '' ? 'hidden sm:invisible' : ''}
on:click={editScript}>Save (commit)</Button
>
<Button
variant="border"
size="sm"
@@ -145,18 +140,22 @@
>
Back
</Button>
{#if step < 3}
<Button
size="sm"
btnClasses={step == 3 ? 'hidden sm:invisible' : ''}
disabled={step === 1 && pathError !== ''}
on:click={() => changeStep(step + 1)}
>
Next
</Button>
{:else}
<Button size="sm" on:click={editScript}>Save</Button>
{/if}
<Button
size="sm"
variant={step == 1 ? 'contained' : 'border'}
btnClasses={step == 3 ? 'invisible' : ''}
disabled={step === 1 && pathError !== ''}
on:click={() => changeStep(step + 1)}
>
Next
</Button>
<Button
size="sm"
variant={step == 1 ? 'border' : 'contained'}
disabled={step === 1 && pathError !== ''}
btnClasses={step == 1 && initialPath == '' ? 'invisible' : ''}
on:click={editScript}>Save</Button
>
</div>
</div>
</div>
@@ -146,6 +146,7 @@
bind:code
bind:websocketAlive
bind:this={editor}
on:change={() => inferSchema()}
cmdEnterAction={async () => {
await inferSchema()
runTest()
@@ -21,7 +21,7 @@
</script>
<div class="w-full">
<h1 class="my-4">UI customisation</h1>
<h1 class="my-4">Advanced</h1>
<Tabs selected="ui">
<Tab value="ui">UI</Tab>
@@ -61,7 +61,7 @@
variant === 'border' ? 'border' : '',
ButtonType.FontSizeClasses[size],
ButtonType.SpacingClasses[spacingSize],
'focus:ring-4 font-semibold',
'focus:ring-2 font-semibold',
'rounded-md',
'justify-center items-center text-center whitespace-nowrap inline-flex',
btnClasses,
@@ -176,9 +176,15 @@
automaticLayout={true}
cmdEnterAction={async () => {
selected = 'test'
if (flowModule.value.type === 'rawscript') {
flowModule.value.content = editor.getCode()
}
await reload(flowModule)
modulePreview?.runTestWithStepArgs()
}}
on:change={async (event) => {
await reload(flowModule)
}}
formatAction={() => reload(flowModule)}
/>
</div>
@@ -5,10 +5,10 @@
import CenteredModal from '$lib/components/CenteredModal.svelte'
import { sendUserToast } from '$lib/utils'
import FlowMetadata from '$lib/components/FlowMetadata.svelte'
import FlowModulesViewer from '$lib/components/FlowModulesViewer.svelte'
import JobArgs from '$lib/components/JobArgs.svelte'
import { onDestroy, onMount } from 'svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import FlowGraph from '$lib/components/graph/FlowGraph.svelte'
let job: Job | undefined = undefined
let currentApprovers: { resume_id: number; approver: string }[] = []
@@ -21,6 +21,7 @@
.includes(new Number($page.params.resume).valueOf())
let timeout: NodeJS.Timer | undefined = undefined
let error: string | undefined = undefined
getJob()
@@ -28,14 +29,16 @@
timeout = setInterval(getJob, 1000)
window.onunhandledrejection = (event: PromiseRejectionEvent) => {
event.preventDefault()
timeout && clearInterval(timeout)
if (event.reason?.message) {
const { message, body, status } = event.reason
if (body) {
sendUserToast(`${body}`, true)
error = body.toString()
} else {
sendUserToast(`${message}`, true)
error = message.toString()
}
} else {
console.log('Caught unhandled promise rejection without message', event)
@@ -48,19 +51,15 @@
})
async function getJob() {
try {
const suspendedJobFlow = await JobService.getSuspendedJobFlow({
workspace: $page.params.workspace,
id: $page.params.job,
resumeId: new Number($page.params.resume).valueOf(),
signature: $page.params.hmac,
approver
})
job = suspendedJobFlow.job
currentApprovers = suspendedJobFlow.approvers
} catch (e) {
sendUserToast(e.message, true)
}
const suspendedJobFlow = await JobService.getSuspendedJobFlow({
workspace: $page.params.workspace,
id: $page.params.job,
resumeId: new Number($page.params.resume).valueOf(),
signature: $page.params.hmac,
approver
})
job = suspendedJobFlow.job
currentApprovers = suspendedJobFlow.approvers
}
async function resume() {
@@ -92,6 +91,9 @@
<div class="min-h-screen antialiased text-gray-900">
<CenteredModal title="Approve resuming of flow?">
{#if error}
<h1 class="text-red-400">{error}</h1>
{/if}
<div class="flex flex-row justify-between flex-wrap sm:flex-nowrap gap-x-4">
<div class="w-full">
<h2 class="mt-4">Current approvers</h2>
@@ -167,10 +169,13 @@
</div>
{#if job && job.raw_flow}
<h2 class="mt-10">Flow details</h2>
<FlowModulesViewer
modules={job.raw_flow?.modules}
failureModule={job.raw_flow?.failure_module}
/>
<div class="border border-gray-700">
<FlowGraph
modules={job.raw_flow?.modules}
failureModule={job.raw_flow?.failure_module}
notSelectable
/>
</div>
{/if}
</CenteredModal>
</div>