Skip to content

Make Generate deterministic and add CI verification step#89

Merged
jaredpar merged 5 commits into
mainfrom
jaredpar/deterministic-file-enumeration
Jun 15, 2026
Merged

Make Generate deterministic and add CI verification step#89
jaredpar merged 5 commits into
mainfrom
jaredpar/deterministic-file-enumeration

Conversation

@jaredpar

Copy link
Copy Markdown
Owner

The Generate tool's output was non-deterministic because Directory.GetFiles does not guarantee enumeration order, and different OSes return files in different orders. This meant running the generator on Linux vs Windows could produce different Generated.cs/targets files even with identical inputs.

Approach

  • In FindDlls, collect results into a list instead of yielding immediately, normalize path separators to /, and sort by relative path using StringComparison.Ordinal. This ensures identical output regardless of OS or filesystem behavior.
  • Rebaselined all 53 generated files with the new deterministic ordering.
  • Added a CI workflow step that runs the generator after restore and fails if there is any diff, ensuring PRs always ship freshly generated output.

jaredpar and others added 5 commits June 12, 2026 09:44
The file system enumeration in FindDlls was non-deterministic because
Directory.GetFiles does not guarantee ordering, and the ordering varies
across operating systems. Fix by:

1. Collecting all results into a list instead of yielding immediately
2. Normalizing path separators to forward slash for consistent sorting
3. Sorting by relative path using ordinal comparison

This ensures the generated output is identical regardless of OS or
file system enumeration order.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Runs the generator after restore and fails the build if there are any
uncommitted diffs, ensuring PRs always include freshly generated output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Path.Join uses the OS-specific separator between the prefix and the
relative path, producing different output on Windows vs Linux. Replace
with string interpolation using a consistent forward slash separator
since MSBuild handles both styles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On Linux, Substring(packagePrefix.Length) produces a leading / in the
relative path. Combined with the interpolated /, this caused // in the
output. TrimStart('/') after normalization ensures no leading separator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add .gitattributes to enforce LF line endings and normalize the
generator output with ReplaceLineEndings to always produce LF.
This ensures the generator produces identical output on Windows
and Linux, making the CI verification step pass on both platforms.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jaredpar jaredpar merged commit 6762518 into main Jun 15, 2026
1 check passed
@jaredpar jaredpar deleted the jaredpar/deterministic-file-enumeration branch June 15, 2026 14:11
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