mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 08:02:38 +00:00
fix: an app deploy pins only a version it wrote as the next draft's base
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a149ba9231
commit
03ec3fde2f
@@ -63,7 +63,7 @@
|
||||
import LazyModePanel from './contextPanel/LazyModePanel.svelte'
|
||||
import type { DiffDrawerI } from '$lib/components/diff_drawer'
|
||||
import AppEditorHeaderDeploy from './AppEditorHeaderDeploy.svelte'
|
||||
import { computeSecretUrl } from './appDeploy.svelte'
|
||||
import { computeSecretUrl, versionThisDeployWrote } from './appDeploy.svelte'
|
||||
import { updatePolicy } from './appPolicy'
|
||||
import { editInForkAllowed, editInForkLabel, openEditInFork } from '$lib/utils/editInFork'
|
||||
import { isCloudHosted } from '$lib/cloud'
|
||||
@@ -392,7 +392,7 @@
|
||||
workspace: $workspaceStore!,
|
||||
path: npath
|
||||
})
|
||||
version = appHistory[0]?.version
|
||||
version = versionThisDeployWrote(appHistory, $userStore?.username)
|
||||
// Re-pin the fork base to the just-deployed head: the editor stays open, so a
|
||||
// follow-up deploy (or a new edit) would otherwise compare against the now-
|
||||
// superseded base and falsely warn. parent_version is in
|
||||
|
||||
@@ -1,7 +1,28 @@
|
||||
import { base } from "$lib/base"
|
||||
import { workspaceStore } from "$lib/stores"
|
||||
import { get } from "svelte/store"
|
||||
import { base } from '$lib/base'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { get } from 'svelte/store'
|
||||
|
||||
export function computeSecretUrl(secretUrl: string) {
|
||||
return `${window.location.origin}${base}/public/${get(workspaceStore)}/${secretUrl}`
|
||||
return `${window.location.origin}${base}/public/${get(workspaceStore)}/${secretUrl}`
|
||||
}
|
||||
|
||||
/**
|
||||
* The version a just-finished deploy wrote, read back from the history it lands in.
|
||||
* The deploy and this read are two requests, so someone else's deploy in between is the
|
||||
* newest entry too; taking it would make their version the fork base of content it never
|
||||
* contained, and the next deploy would find base === head and overwrite them with no
|
||||
* warning. A head this caller did not write therefore yields `undefined`: an unknown
|
||||
* base, which the timestamps still cover, rather than a wrong one.
|
||||
*
|
||||
* Author is all the history can be matched on (`deployment_msg` is written later, by the
|
||||
* dependency job), so a second deploy by the same user inside that window still reads as
|
||||
* this one's.
|
||||
*/
|
||||
export function versionThisDeployWrote(
|
||||
history: { version: number; created_by?: string }[] | undefined,
|
||||
deployedBy: string | undefined
|
||||
): number | undefined {
|
||||
const head = history?.[0]
|
||||
if (!head || !deployedBy || head.created_by !== deployedBy) return undefined
|
||||
return head.version
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { versionThisDeployWrote } from './appDeploy.svelte'
|
||||
|
||||
describe('versionThisDeployWrote', () => {
|
||||
it('takes the head this deploy wrote', () => {
|
||||
expect(versionThisDeployWrote([{ version: 7, created_by: 'alice' }], 'alice')).toBe(7)
|
||||
})
|
||||
|
||||
it('claims nothing when another deploy landed on top', () => {
|
||||
// The base would otherwise be a version this content never contained, and the
|
||||
// next deploy would find base === head and overwrite it unwarned.
|
||||
expect(versionThisDeployWrote([{ version: 8, created_by: 'bob' }], 'alice')).toBe(undefined)
|
||||
expect(versionThisDeployWrote([], 'alice')).toBe(undefined)
|
||||
expect(versionThisDeployWrote([{ version: 7, created_by: 'alice' }], undefined)).toBe(undefined)
|
||||
})
|
||||
})
|
||||
@@ -70,6 +70,7 @@
|
||||
// `runtime.syncPreviewWithDeployed`, which discards the fork draft + reloads
|
||||
// the preview to the deployed version.
|
||||
import { AIBtnClasses } from '../copilot/chat/AIButtonStyle'
|
||||
import { versionThisDeployWrote } from '../apps/editor/appDeploy.svelte'
|
||||
import { stripRawAppDiffNoise } from './utils'
|
||||
import type { RawAppData } from './dataTableRefUtils'
|
||||
import { editInForkAllowed, editInForkLabel, openEditInFork } from '$lib/utils/editInFork'
|
||||
@@ -544,7 +545,8 @@
|
||||
workspace: opWorkspace!,
|
||||
path: npath
|
||||
})
|
||||
version = appHistory[0]?.version
|
||||
// Only a version this deploy can claim becomes the draft's base below.
|
||||
version = versionThisDeployWrote(appHistory, $userStore?.username)
|
||||
|
||||
closeSaveDrawer()
|
||||
sendUserToast('App deployed successfully')
|
||||
|
||||
Reference in New Issue
Block a user