mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-07 16:03:21 +00:00
* feat: add dev workspaces paired with a lockable prod workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: gate dev-workspace prod-lock on admin and prevent attach cycles Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: redirect locked-prod edits into the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make dev-workspace settings tab available on CE (was EE-gated) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: lock prod against forking too and funnel edits to the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: open dev item page on edit and tailor dev-workspace lock messages Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: prevent nested dev workspaces and hide dev option when one exists Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: drop the redundant already-has-dev hint on the fork form Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: badge dev workspaces and sort them ahead of forks in the tree/switcher Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: label dev workspaces as 'Dev workspace of X' instead of 'Fork of X' Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: label edit as 'Edit in <dev>', cover editor headers, auto-expand dev in tree Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: split prod lock into separate block-deploy and prevent-forking toggles Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: make resources/variables workspace-specific from compare page Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: steer AI-chat sessions to the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: refine session fork options and lock guidance for dev/prod Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: session picker reads prod's real rules, default to current ws Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: copy members into forks and clarify dev-workspace root labeling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: place the workspace id field under the fork name Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address dev-workspace review findings and harden fork detection Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: regenerate sqlx offline cache Restores entries dropped during the origin/main merge and adds the dev-workspace queries (is_dev_workspace, ws_specific, has_parent). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address second-round dev-workspace review findings Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address Pi and Codex review findings on dev-workspace endpoints Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: gate locked-dev git-branch fork on admin and validate ws_specific path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: clear prod dev-lock when deleting an attached dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: consolidate dev-workspace migration and scope all-group join to attach Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: restore dev-workspace CHECK into consolidated migration and scope all-group join Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: drop copy_members from the dev-workspace attach path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: dev-workspace lifecycle/auth fixes from Codex review round Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: explicit create-in-other for workspace-specific items Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make create-in-other strictly create-only (never overwrite target) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: return 403 (not 401) for dev-workspace permission denials Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: allow attaching a same-family fork as a dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: emphasize the go-to-dev action in the no-direct-deploy alert Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: seed a resource's linked variables when creating it in the other workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: judge workspace deploy/fork locks against the user's identity in that workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: clarify create-in help text in workspace-specific panel Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: admin-gate dev-workspace creation and harden lock/seed edges Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: preserve a staged fork's source on picker create-mode re-entry Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: clear dev flag on archive and check dev existence server-side Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make create-in-other atomically create-only via direct create Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: create-only resource insert, ws-specific list scopes, archive lock guard Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: reserve the dev_workspace_lock protection-rule name from the public API Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: reattach create_protection_rule doc comment to its function Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: make dev-archive pairing teardown atomic with the archive Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: follow deploy_to on root rename; show dev pairing to non-member prod admins Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: copy creator metadata on fork; invalidate fork routing cache on rename Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: accept g/ paths in set_ws_specific; gate copy_members to dev workspaces Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
3.1 KiB
Svelte
91 lines
3.1 KiB
Svelte
<script lang="ts">
|
|
import type { ProtectionRuleset } from '$lib/gen'
|
|
import { userStore, type UserExt } from '$lib/stores'
|
|
import { getUserExt } from '$lib/user'
|
|
import {
|
|
fetchProtectionRulesForWorkspace,
|
|
isRuleActiveInRulesets,
|
|
canUserBypassRuleKindInRulesets,
|
|
getActiveRulesetsForKindInRulesets
|
|
} from '$lib/workspaceProtectionRules.svelte'
|
|
import { Alert } from './common'
|
|
import { resource } from 'runed'
|
|
|
|
let {
|
|
parentWorkspaceId,
|
|
onUpdateCanDeploy = (value) => {}
|
|
}: {
|
|
parentWorkspaceId: string
|
|
onUpdateCanDeploy?: (value: boolean) => void
|
|
} = $props()
|
|
|
|
let overrideChecked = $state(false)
|
|
|
|
// Fetch the parent's rules and the user's identity in the parent together. Both must come from the
|
|
// parent: bypass is judged with is_admin/groups in the PARENT (per-workspace), not the active/fork
|
|
// workspace's `$userStore`; getUserExt returns undefined for a non-member, treated as no bypass.
|
|
const parentDataResource = resource(
|
|
() => parentWorkspaceId,
|
|
async (wsId) => {
|
|
if (!wsId) return { rules: [] as ProtectionRuleset[], user: undefined as UserExt | undefined }
|
|
const [rules, user] = await Promise.all([
|
|
fetchProtectionRulesForWorkspace(wsId),
|
|
getUserExt(wsId)
|
|
])
|
|
return { rules, user }
|
|
}
|
|
)
|
|
let parentRulesets = $derived(parentDataResource.current?.rules ?? [])
|
|
let parentUserInfo = $derived(parentDataResource.current?.user)
|
|
|
|
let activeDeployRulesets = $derived(
|
|
getActiveRulesetsForKindInRulesets(parentRulesets, 'DisableDirectDeployment')
|
|
)
|
|
|
|
let canBypass = $derived(
|
|
canUserBypassRuleKindInRulesets(parentRulesets, 'DisableDirectDeployment', parentUserInfo)
|
|
)
|
|
|
|
// Block deploy until the parent's rules/identity have loaded: while loading `parentRulesets` is
|
|
// empty, which would otherwise read as "no lock" and briefly enable deploy before the real
|
|
// lock/bypass check resolves.
|
|
let canDeploy = $derived(
|
|
!parentDataResource.loading &&
|
|
(!isRuleActiveInRulesets(parentRulesets, 'DisableDirectDeployment') ||
|
|
(canBypass && overrideChecked))
|
|
)
|
|
|
|
// Reset override when parent workspace changes
|
|
$effect(() => {
|
|
parentWorkspaceId
|
|
overrideChecked = false
|
|
})
|
|
|
|
// Communicate deployment status to parent
|
|
$effect(() => {
|
|
onUpdateCanDeploy(canDeploy)
|
|
})
|
|
</script>
|
|
|
|
{#if !$userStore?.operator && activeDeployRulesets.length > 0}
|
|
<Alert type="info" title="Parent workspace protection active" class="my-2">
|
|
<div class="flex flex-col gap-2">
|
|
<p>
|
|
The workspace {parentWorkspaceId} has a protection rule{activeDeployRulesets.length > 1
|
|
? 's'
|
|
: ''}
|
|
<b>{activeDeployRulesets.map((r) => r.name).join(', ')}</b>
|
|
that restrict{activeDeployRulesets.length > 1 ? '' : 's'} direct deployments. You need to merge
|
|
changes through the synced git repo with Git Sync, or by asking a user with the rights to bypass
|
|
this rule.
|
|
</p>
|
|
{#if canBypass}
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input class="rounded max-w-4" type="checkbox" bind:checked={overrideChecked} />
|
|
<span class="text-xs">Bypass restriction and deploy anyway</span>
|
|
</label>
|
|
{/if}
|
|
</div>
|
|
</Alert>
|
|
{/if}
|