Skip to content

feat: README expertise banner rule and remediation - #208

Merged
davidnmbond merged 4 commits into
mainfrom
feat/expertise-banner
Nov 13, 2026
Merged

davidnmbond merged 4 commits into
mainfrom
feat/expertise-banner

Conversation

@davidnmbond

Copy link
Copy Markdown
Contributor

Adds the expertise banner rule (README must open with the expertise statement), its remediation, the ReadmeExpertiseBanner renderer and the configurable ExpertiseBannerTemplate setting. Also refreshes nuget-floors.json and nuget-versions.json.

Includes merges of origin/main: the DOC-02 rule conflict was resolved in favour of main's version, which carries the Codacy S131 default-arm fix from #206.

Local check: build clean; SupportedDotNetVersions and ExpertiseBanner tests 37/37 pass.

- Introduced ExpertiseBannerTemplate in AppSettings and RepoOptions for customizable README banners.
- Implemented ExpertiseBannerRule to ensure the expertise statement appears at the top of README.md.
- Created ReadmeExpertiseBanner service for rendering and inserting the expertise statement.
- Added ExpertiseBannerRemediation to automate the insertion of the banner when missing.
- Developed tests for expertise banner compliance (ExpertiseBannerTests) and supported .NET versions documentation (SupportedDotNetVersionsDocumentedTests).
- Updated secrets.schema.json to include ExpertiseBannerTemplate.
- Enhanced documentation and README.md to reflect the new features and .NET 11.0 support.
- Updated nuget-floors.json and nuget-versions.json for dependency updates.
….NugetManagement

# Conflicts:
#	PanoramicData.NugetManagement/Rules/Documentation/SupportedDotNetVersionsDocumentedRule.cs
@codacy-production

codacy-production Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 51 complexity · 1 duplication

Metric Results
Complexity 51
Duplication 1

View in Codacy

🟢 Coverage 90.57% diff coverage · +0.12% coverage variation

Metric Results
Coverage variation ✅ +0.12% coverage variation (-1.00%)
Diff coverage ✅ 90.57% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (4241718) 22938 14670 63.96%
Head commit (dd9c0b8) 23044 (+106) 14766 (+96) 64.08% (+0.12%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#208) 106 96 90.57%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

⚠️ Resolve issues before merging

The README handling has correctness gaps around front matter, multiline HTML containers, and fenced code blocks; these can cause metadata loss, incorrect banner placement, or unrelated documentation content to be modified. These should be addressed before merging.

The non-packable repository behavior appears unaddressed, and the remediation file is a higher-risk area because it has uncovered branches and only partial coverage.

About this PR

  • The non-packable repository path appears unaddressed and should be implemented and covered by an automated test before merging.

Test suggestions

  • Default banner renders the required expertise wording and links
  • A correctly positioned banner passes the rule
  • A missing or incorrectly positioned banner fails with remediation data
  • A configured banner template is honored
  • A missing README is not applicable
  • Insertion preserves LF and CRLF endings and is idempotent
  • Remediation fixes a README and the rule passes afterward
  • Non-packable repositories skip the rule
  • Remediation safely handles a missing target file
  • Remediation safely handles an unsupported remediation type or an already-correct README
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Non-packable repositories skip the rule
2. Remediation safely handles a missing target file
3. Remediation safely handles an unsupported remediation type or an already-correct README

TIP Add a Jira or Linear ticket key to the branch or title so the reviewer can check the PR against it. Using another tracker? Tell us.
TIP How was this review? Give us feedback

public static string Insert(string readme, string banner)
{
var newLine = readme.Contains("\r\n", StringComparison.Ordinal) ? "\r\n" : "\n";
var lines = SplitLines(readme).Where(line => Normalise(line) != Normalise(banner)).ToList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Restrict banner removal to actual banner blocks outside fenced code blocks so matching text in documentation examples is preserved.

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

|| trimmed.StartsWith("[![", StringComparison.Ordinal)
|| trimmed.StartsWith("![", StringComparison.Ordinal)
|| trimmed.StartsWith("<img", StringComparison.OrdinalIgnoreCase)
|| trimmed.StartsWith("<p", StringComparison.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Treat multiline HTML logo or badge containers as complete blocks before placing or validating the banner, and add a regression test.

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

var lines = SplitLines(readme).Where(line => Normalise(line) != Normalise(banner)).ToList();

var at = 0;
while (at < lines.Count && IsHeaderLine(lines[at]))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Preserve leading YAML front matter and insert the banner only after the front matter and title; add a regression test for README files containing front matter.

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

Comment on lines +32 to +41
{
return;
}

var file = ReadStrings(data, "file")[0];
var banner = ReadStrings(data, "banner")[0];
var path = Path.Combine(localPath, file);
if (!File.Exists(path))
{
onOutput?.Invoke($"⏭️ [{result.RuleId}] {file} does not exist — cannot add the statement.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Suggestion: Add tests for unsupported remediation data and a missing README, verifying that remediation does not throw, does not report a file as applied, and emits the expected skip result.

See Coverage in Codacy

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

/// The default expertise statement README-05 puts at the top of every package README, as one
/// Markdown line. <c>{PackageName}</c> is replaced with the repository name.
/// </summary>
public const string ExpertiseBannerTemplate =

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Suggestion: Expose the banner template as a runtime-read property instead of a public constant to avoid consumers retaining stale inlined values.

See Issue in Codacy

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

@davidnmbond
davidnmbond merged commit 725c434 into main Nov 13, 2026
8 checks passed
@davidnmbond
davidnmbond deleted the feat/expertise-banner branch November 13, 2026 16:56
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