Skip to content

fix(workspace): topological sort and incremental dep propagation - #34

Merged
ElectricCookie merged 2 commits into
mainfrom
fix/workspace-versioning-order-and-cascade
Jun 28, 2026
Merged

ElectricCookie merged 2 commits into
mainfrom
fix/workspace-versioning-order-and-cascade

Conversation

@ElectricCookie

Copy link
Copy Markdown
Collaborator

Problem

Two bugs in workspace versioning caused unreliable version bumps across multiple runs:

Bug 1 — Ordering: updateWorkspaceDependencies ran as a single pass after all packages were versioned. Packages were processed in workspace declaration order, so a consumer package could be versioned before its dependency's pubspec was updated. The dep-constraint bump would then land in a later commit, outside the new tag's range, causing another spurious bump on the next CI run.

Bug 2 — Cascade: Because the dep bump ended up in a post-tag commit, the next run would see pubspec.yaml changes since the last tag and re-version the consumer again indefinitely.

Fix

  • workspace_utils.dart: Add sortPackagesTopologically() (Kahn's algorithm). Builds the intra-workspace dependency graph from each package's pubspec.yaml and returns packages in an order where every dependency appears before its consumers. Falls back to the original order on detected cycles (with a warning).

  • workspace_version.dart: Use sortPackagesTopologically before the versioning loop. After each package is versioned, immediately call updateWorkspaceDependencies for just that package so that downstream consumers see the updated constraint within the same run. The dep bump is then captured inside the new tag's range, and subsequent runs start from the new tag with no spurious changes.

Tests

6 new unit tests in test/version/workspace_utils_test.dart:

  • No-dependency packages keep their original stable order
  • Single dependency: dep comes before dependent
  • Diamond dependency graph: correct ordering at all levels
  • Real-world scenario: liquid_flutter before test_utils and reactive_forms
  • External (non-workspace) dependencies are ignored
  • Cycle detection: falls back to original order without throwing

- Add sortPackagesTopologically() to workspace_utils.dart using Kahn's
  algorithm so dependency packages are always versioned before their
  consumers.
- Replace the single end-of-loop updateWorkspaceDependencies() call in
  versionWorkspace() with an incremental call immediately after each
  package is versioned, so downstream packages see the updated constraint
  during the same run and the dep bump is captured inside the new tag's
  range (preventing cascade bumps on subsequent runs).
- Add workspace_utils_test.dart covering: stable order, single dep,
  diamond graph, liquid_flutter scenario, external deps ignored, cycle
  fallback.
@github-actions

Copy link
Copy Markdown

Version Analysis

Next Version: 8.1.2

Changelog: 📄 View detailed changelog in job summary

Badge:
Version Badge

@github-actions

Copy link
Copy Markdown

Version Analysis

Next Version: 8.1.2

Changelog: 📄 View detailed changelog in job summary

Badge:
Version Badge

@ElectricCookie
ElectricCookie merged commit 05e46e0 into main Jun 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant