Skip to content

Deploy preview shows stale production URL after DEPLOY_PREVIEW_FAILURE #7755

@jonasbeck

Description

@jonasbeck

Describe the bug

When using the editorial workflow with GitLab (likely affects all backends), the "View Preview" button can show a stale production URL instead of the actual deploy preview URL — or instead of showing nothing at all.

Root cause

The DEPLOY_PREVIEW_FAILURE case in the deploys reducer only sets isFetching: false but does not clear the previous url and status:

case DEPLOY_PREVIEW_FAILURE: {
  const { collection, slug } = action.payload;
  state[`${collection}.${slug}`].isFetching = false;
  break;
}

This means the old state from a previous DEPLOY_PREVIEW_SUCCESS (or getDeploy for published entries) persists in the Redux store.

Reproduction flow

  1. Open an existing published entry in the CMS editor
  2. getDeploy runs → stores { url: "https://production-site.example.com/...", status: "SUCCESS" } in Redux
  3. User saves → creates a cms/* branch → CI pipeline starts building a preview
  4. componentDidUpdate triggers loadDeployPreview({ maxAttempts: 3 }) which polls for commit statuses
  5. If no commit status exists yet (CI hasn't posted one), getDeployPreview returns null
  6. DEPLOY_PREVIEW_FAILURE is dispatched → only sets isFetching: false
  7. Old { status: "SUCCESS", url: "https://production-site.example.com/..." } remains in Redux
  8. renderDeployPreviewControls sees status === 'SUCCESS' and renders the "View Preview" link pointing to the production URL, not the deploy preview

Expected behavior

When DEPLOY_PREVIEW_FAILURE fires, the stale url and status should be cleared so that no misleading "View Preview" link is shown:

case DEPLOY_PREVIEW_FAILURE: {
  const { collection, slug } = action.payload;
  const key = `${collection}.${slug}`;
  state[key].isFetching = false;
  state[key].url = undefined;
  state[key].status = undefined;
  break;
}

Workaround

We work around this by having our CI pipeline post a running commit status with target_url immediately when a cms/* branch is pushed. This ensures the first or second poll finds a status, causing DEPLOY_PREVIEW_SUCCESS with state: "OTHER" to overwrite the stale SUCCESS, which makes the toolbar show the "Check for Preview" refresh button instead of the misleading production link.

Applicable versions

  • decap-cms 3.10.0
  • GitLab backend
  • publish_mode: editorial_workflow
  • preview_context configured

Environment

  • Browser: Chrome
  • OS: macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions