Skip to content

ci(api-docs): read package versions from MSBuild, not a .csproj scrape - #106

Merged
WomB0ComB0 merged 1 commit into
mainfrom
ci/api-docs-version-from-msbuild
Sep 22, 2026
Merged

WomB0ComB0 merged 1 commit into
mainfrom
ci/api-docs-version-from-msbuild

Conversation

@WomB0ComB0

@WomB0ComB0 WomB0ComB0 commented Sep 22, 2026

Copy link
Copy Markdown
Member

Every package in this repo's generated API reference is currently labelled vunknown.

Why

The version lookup scrapes <Version> / <VersionPrefix> out of each .csproj and returns "unknown" when neither is found. Since this repo adopted MinVer (#104), no project carries a literal version string by design — that was the whole point, since a literal in the tree is something an inbound sync can revert. So the scrape misses on every package.

This is not a hypothetical. Measured against this tree at e727403, with full history and tags, after restore:

Project today with this PR
ResQ.Storage unknown 0.6.1-alpha.0.42
ResQ.Core unknown 0.6.1-alpha.0.42

The fix

Ask MSBuild instead of parsing XML:

dotnet msbuild <csproj> -t:GetAssemblyVersion -getProperty:Version

-getProperty alone only evaluates the project, which returns the SDK default before MinVer has run. GetAssemblyVersion is a stock SDK target, so invoking it forces MinVer to execute and report the tag-derived version. The .csproj scrape is retained as a fallback for SDKs older than 8.0.200, which have no -getProperty.

This was already fixed upstream in resq-software/docs#133. The file here is taken verbatim from that template, so the next template sync is a no-op against this repo rather than a revert.

One thing worth knowing

This repo contains two ResQ.Core.csproj files:

  • ResQ.Core/ResQ.Core.csproj — the real one, referenced by ResQ.Sdk.sln
  • resq-core/ResQ.Core.csproj — an orphan, not in the solution, whose Protobuf Include points at ../../protocols/core.proto, a path outside the repo

The orphan is never restored, so MinVer's targets are never imported for it and MSBuild reports the SDK default 1.0.0. That is a plausible-looking wrong answer, so it matters which candidate wins.

The upstream logic already handles it: read_version sorts candidates, skips any whose value equals the SDK default, and only falls back to that value if nothing better exists. I replayed the selection across both candidates to confirm the real 0.6.1-alpha.0.42 wins and the orphan's 1.0.0 is discarded.

The orphan itself arrived via an inbound sync from the internal monorepo and looks like debris rather than anything live. Cleaning it up is out of scope here — flagging it as a separate item.

Verification

  • Ran both the old and new logic against a full-history clone of this repo; the table above is measured, not inferred.
  • actionlint clean.
  • Confirmed the template restores and builds the solution before the version query, so MinVer's targets are imported when it runs — without that ordering the query would silently return 1.0.0 for everything.

Summary by CodeRabbit

  • Bug Fixes
    • API documentation now displays accurate package versions derived from repository tags.
    • Improved version detection provides more reliable results when project metadata is incomplete or unavailable.
    • Documentation output is now stable and consistent across different build environments.

Every package in the generated reference is currently labelled
`vunknown`. The version lookup scrapes `<Version>`/`<VersionPrefix>`
out of the .csproj and returns "unknown" when neither is present --
and since this repo moved to MinVer, no project carries a literal
version by design. The scrape therefore misses on all of them.

This replaces that step with the version already fixed upstream in
resq-software/docs#133: ask MSBuild via
`-t:GetAssemblyVersion -getProperty:Version`. GetAssemblyVersion is
a stock SDK target, so MinVer runs and reports the tag-derived
value; the .csproj scrape is kept as a fallback for SDKs older than
8.0.200, which have no -getProperty.

The file is taken verbatim from the upstream template, so the next
template sync is a no-op here instead of a revert.

Verified locally against this tree at e727403 (full history, tags
present, after restore):

  ResQ.Storage   unknown -> 0.6.1-alpha.0.42
  ResQ.Core      unknown -> 0.6.1-alpha.0.42

Note the repo contains two ResQ.Core.csproj files -- the real
`ResQ.Core/` in the solution, and an orphaned `resq-core/` copy that
is not. The orphan is never restored, so MSBuild reports the SDK
default 1.0.0 for it. The upstream logic already handles this: it
skips any candidate whose value equals the SDK default and only
falls back to it last, so the real 0.6.1-alpha.0.42 wins. Confirmed
by replaying the selection over both candidates.
@github-actions github-actions Bot added size/M A-DevOps DevOps: CI/CD, workflows, actions, scripts, and git hooks labels Sep 22, 2026
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 721b4602-1059-4701-9a2a-82d503c7641a

📥 Commits

Reviewing files that changed from the base of the PR and between e727403 and f80f17d.

📒 Files selected for processing (1)
  • .github/workflows/api-docs.yml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The API documentation workflow now fetches full Git history and tags. Its index-generation step resolves project versions through MSBuild, literal project-file values, and SDK defaults in a stable order.

Changes

API documentation versioning

Layer / File(s) Summary
Full-history checkout
.github/workflows/api-docs.yml
The source checkout now uses fetch-depth: 0 to include Git history and tags.
MSBuild version resolution
.github/workflows/api-docs.yml
Version lookup now queries MSBuild first, falls back to literal <Version> or <VersionPrefix> values, and then uses the observed SDK default or "unknown". Candidate project files are sorted for stable results.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to f80f1

The workflow improves generated API documentation version labels through full-history and MSBuild-based resolution; no merge-blocking risk remains identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: API documentation CI now reads package versions from MSBuild instead of relying on .csproj scraping.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the C-Chore Chore: deps, tooling, or config with no public API change label Sep 22, 2026
@github-actions

Copy link
Copy Markdown

Audit Passed

The audit of the changes in this pull request found no security vulnerabilities, logic bugs, or performance issues.

Key Observations:

  • Correctness: The transition from manual .csproj scraping to querying MSBuild via -t:GetAssemblyVersion -getProperty:Version is a robust solution for retrieving versions derived from git tags (via MinVer).
  • Edge Case Handling: The logic for selecting project version candidates effectively handles the presence of orphaned or duplicate project files by filtering out the SDK default version (1.0.0) and prioritizing active projects.
  • Security: The workflow continues to use best practices, including pinned action hashes and environment variable indirection to prevent shell injection from user-controlled data (e.g., ref names).
  • Performance: The impact of running MSBuild for version retrieval is minimal and well-contained within the documentation generation process.

The audit is complete and the changes are approved from a security and logic perspective.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

Generated by ai-auditor for issue #106 ·

@WomB0ComB0
WomB0ComB0 merged commit d2dffb1 into main Sep 22, 2026
48 checks passed
@WomB0ComB0
WomB0ComB0 deleted the ci/api-docs-version-from-msbuild branch September 22, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-DevOps DevOps: CI/CD, workflows, actions, scripts, and git hooks C-Chore Chore: deps, tooling, or config with no public API change size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant