From 09280aefd6156ee870e9d1001bdea41480b1dda9 Mon Sep 17 00:00:00 2001 From: hugocasa Date: Thu, 3 Sep 2026 17:35:35 +0200 Subject: [PATCH] fix: keep credential status out of exports and clear stale webhook warnings Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01C1xHmkxuxYb1GYvth1BS75 --- backend/ee-repo-ref.txt | 2 +- backend/src/monitor.rs | 5 ++++- backend/windmill-api/src/workspaces_export.rs | 16 ++++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index ef5cbb497f..e01fab6059 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -0dae6fb996c6bf0ffb2f60bfcf9bdda8baca2e85 +6ebc78675dc3510a8abc56a957b96160a4dc7f5f diff --git a/backend/src/monitor.rs b/backend/src/monitor.rs index 9d0910127f..a37d945335 100644 --- a/backend/src/monitor.rs +++ b/backend/src/monitor.rs @@ -4755,10 +4755,13 @@ async fn maintain_git_credentials_inner(db: &Pool) -> error::Result<() // state costs nothing, and only the repositories actually missing a // hook reach the host. use windmill_common::workspaces::AutoPullMode; + // Also when a hook exists but carries a warning: a save during a GitLab + // outage keeps the hook and records why it could not be confirmed, and + // that warning is only cleared by a reconcile that confirms it again. let needs_hook = repo.auto_pull.as_ref().is_some_and(|a| { a.enabled && matches!(a.mode, AutoPullMode::Auto | AutoPullMode::Webhook) - && a.webhook_id.is_none() + && (a.webhook_id.is_none() || a.webhook_error.is_some()) }); if needs_hook { let mut repo = repo.clone(); diff --git a/backend/windmill-api/src/workspaces_export.rs b/backend/windmill-api/src/workspaces_export.rs index 05cd354cd4..fcdf38ba31 100644 --- a/backend/windmill-api/src/workspaces_export.rs +++ b/backend/windmill-api/src/workspaces_export.rs @@ -1587,10 +1587,11 @@ pub(crate) async fn tarball_workspace( .await?; // Use v2 format only if explicitly requested, otherwise use v1 (legacy) for backward compatibility - // Server-owned auto-pull state (the HMAC webhook secret + hook id/error and - // the synced-sha / last-pull status) must never leave the server: keep it out - // of export archives and synced repos, and don't let a re-imported workspace - // inherit another install's hook/sync state. Mirrors the GET-settings redaction. + // Server-owned state (the HMAC webhook secret + hook id/error, the + // synced-sha / last-pull status, and what the credential check observed) + // must never leave the server: keep it out of export archives and synced + // repos, and don't let a re-imported workspace inherit another install's + // hook/sync state. Mirrors the GET-settings redaction. fn redact_git_sync_for_export(git_sync: Option) -> Option { let mut git_sync = git_sync?; if let Some(repos) = git_sync @@ -1611,6 +1612,13 @@ pub(crate) async fn tarball_workspace( auto_pull.remove(field); } } + // What this install observed about its own credential: a token + // id and fingerprint, and a `checked_at` that moves on its own. + // None of it describes the workspace, and in a git-synced + // `wmill.yaml` it would churn the file for no reason. + if let Some(repo) = repo.as_object_mut() { + repo.remove("credential"); + } } } Some(git_sync)