Add offline codegen drift check + fleet --pull=always lint tasks#264
Merged
Conversation
Closes #259. Codegen drift check (offline, deterministic): - LanguageTagsCreate gains a --skip-download (-s) option that regenerates the embedded data from the already-committed LanguageData/ directory with no network access. DownloadDataAsync is split so path resolution is shared; UseExistingData resolves the same paths and verifies each source file exists. - validate-task.yml gains a codegen-drift job: regenerate offline, run the same CSharpier the codegen workflow uses, then git diff --exit-code. It fails when an emitter or committed source-data change was not accompanied by a regeneration in the same PR, and is strictly offline so upstream registry drift can never trip it (refreshing from upstream stays the scheduled codegen workflow's job). Because test-pull-request reuses validate-task, this runs on every push and produces no dependency on upstream availability. - AGENTS.md documents the contributor workflow: change an emitter or the committed source data, regenerate offline, and commit both in the same PR. Fleet lint change: - .vscode/tasks.json: add --pull=always after --rm to each Docker Lint task so local runs always pull the :latest linter image. Verified: dotnet build clean (warnings-as-errors), dotnet test 310 passed, offline regen + csharpier reproduces the committed *DataGen.cs / *.json exactly (git diff clean), csharpier/format-style/actionlint/markdownlint all clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #264 +/- ##
========================================
Coverage 87.43% 87.43%
========================================
Files 11 11
Lines 1973 1973
Branches 243 243
========================================
Hits 1725 1725
Misses 166 166
Partials 82 82 🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an offline (“no upstream registry download”) codegen path to the LanguageTagsCreate tool and wires a deterministic drift check into PR validation so emitter/source-data changes must regenerate and commit outputs in the same PR. Also updates local VS Code Docker lint tasks to always pull the latest linter images.
Changes:
- Add
--skip-download(-s) to regenerate from committedLanguageData/without network fetches. - Add a
codegen-driftjob tovalidate-task.ymlthat runs offline regen + CSharpier format and then checks for diffs. - Document the offline-regeneration workflow in
AGENTS.mdand update VS Code lint tasks to usedocker run --pull=always.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| LanguageTagsCreate/Program.cs | Branches execution between online download and offline “use existing data” mode. |
| LanguageTagsCreate/CreateTagData.cs | Refactors path resolution and adds UseExistingData() validation for offline regeneration. |
| LanguageTagsCreate/CommandLine.cs | Introduces the --skip-download CLI option and plumbs it into options parsing. |
| .github/workflows/validate-task.yml | Adds the codegen-drift PR job (offline regen + format + drift detection). |
| AGENTS.md | Documents the contributor workflow for offline regeneration when emitters/data change. |
| .vscode/tasks.json | Forces local Docker-based lint tasks to always pull :latest images. |
git diff --exit-code ignores untracked files, so a brand-new emitted output file would slip through. Add a git status --porcelain check to catch it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iner CSharpier is a local dotnet tool, so a fresh clone needs 'dotnet tool restore' first. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch git diff --exit-code prints the full patch, which for generated data files (multi-MB *DataGen.cs) floods the Actions log. A git status --porcelain check covers both tracked modifications and untracked files; print it plus a diffstat instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #259.
Offline codegen drift check
Adds a deterministic, offline codegen drift guard that runs on every PR, so a regression in the code-emitting tooling (
SaveCodeAsync/SaveJsonAsync/GetCodeGenString) is caught on the PR that introduces it rather than deferred to the next upstream-triggered codegen run.LanguageTagsCreate. New--skip-download(-s) option regenerates from the already-committedLanguageData/directory with no network access.DownloadDataAsyncis refactored so path resolution is shared (ResolveDataFilePaths);UseExistingDataresolves the same paths and verifies each source file is present.Program.ExecuteAsyncbranches on the flag.codegen-driftjob invalidate-task.yml: regenerate offline (--skip-download), run the samedotnet csharpier formatthe codegen workflow uses, thengit diff --exit-code. It fails when regenerated output drifts from the committed*DataGen.cs/*.json(i.e. an emitter or committed source-data change was not regenerated in the same PR) and passes when they match. It is strictly offline, so upstream registry drift can never trip it — refreshing from upstream stays the scheduledrun-codegen-pull-request-task.ymljob. Becausetest-pull-requestreusesvalidate-task, this runs on every push with no dependency on upstream availability. Actions SHA-pinned consistent with the existing workflows.Acceptance criteria
--skip-download).git diff --exit-codeafter offline regen + format; failure path verified locally).Fleet
--pull=always.vscode/tasks.json:--pull=alwaysinserted after--rmin each Docker Lint task (editorconfig-checker, actionlint, markdownlint-cli2, cspell) so local runs always pull the:latestlinter image. JSONC valid, CRLF preserved.Validation
dotnet buildclean (warnings-as-errors),dotnet test310 passed / 0 failed.dotnet csharpier format .reproduces the committedLanguageTags/*DataGen.csandLanguageData/*.jsonexactly (git diffshows only the intended source edits).git diff --exit-codeexit non-zero.csharpier check,dotnet format style --verify-no-changes,actionlint, andmarkdownlintall clean.LanguageData/data file hand-edited; EOL preserved throughout.