Context and request
Three repositories now check Markdown links, and each has its own copy of the logic:
| Repository |
File |
Slug dialect |
| MSXOrg/docs |
.github/scripts/Test-DocumentationLink.ps1 |
python-markdown, for the published site |
| MSXOrg/docs |
.github/scripts/Test-CrossRepositoryLink.ps1 |
github-slugger, for links into other repositories |
| Storhaug-ting/Kilden |
scripts/Test-MarkdownLink.ps1 |
github-slugger, adapted from the first |
Storhaug-ting/S62#10 needs the same thing and has no .github directory at all, so it is about to be a fourth.
MSXOrg/docs#142 asked whether this ships as a managed file through Custo rather than being copied again. The answer given there was repository-local for now, because Custo has no managed-file mechanism — it contains LICENSE and README.md and nothing else. That is an accurate description of today, not a decision that copying is right. This issue carries the other half.
Acceptance criteria
- A repository that adopts the check receives it from here rather than copying it by hand.
- An improvement made once reaches every adopter without a human remembering which repositories have a copy.
- An adopter can decline or pin, so distribution is not a way to break someone else's pull request without warning.
Technical decisions
The two slug dialects are a real difference, not duplication to collapse. Test-DocumentationLink.ps1 mirrors python-markdown because it checks a link that resolves on the published site; the other two mirror github-slugger because they check a link that resolves on github.com. Merging them into one function with a mode flag would be the obvious move and the wrong one — the flag would be set wrong somewhere and the check would agree with itself. Whatever ships, the dialect stays a property of the question, not a parameter someone chooses.
The candidate is Test-CrossRepositoryLink.ps1 as it stands. It was written for this: single file, no repository-specific constants, everything that varies is a parameter — -Path, -Owner, -ApiBaseUri, -SelfRepository — and the repository it runs in comes from GITHUB_REPOSITORY or the git remote, so a copy needs no edit. Its Pester suite runs fully offline against an in-process HTTP stub, which is what makes it safe to distribute: an adopter can prove it works without network access or credentials.
Distribution needs a contract before it needs a mechanism. What a managed file promises — how an adopter pins, how a breaking change is announced, whether the workflow that calls it is managed too or only the script — is the part worth getting right. Copying it into three repositories is cheap; the cost is the fourth year, not the fourth repository.
Implementation plan
Context and request
Three repositories now check Markdown links, and each has its own copy of the logic:
.github/scripts/Test-DocumentationLink.ps1.github/scripts/Test-CrossRepositoryLink.ps1scripts/Test-MarkdownLink.ps1Storhaug-ting/S62#10 needs the same thing and has no
.githubdirectory at all, so it is about to be a fourth.MSXOrg/docs#142 asked whether this ships as a managed file through Custo rather than being copied again. The answer given there was repository-local for now, because Custo has no managed-file mechanism — it contains
LICENSEandREADME.mdand nothing else. That is an accurate description of today, not a decision that copying is right. This issue carries the other half.Acceptance criteria
Technical decisions
The two slug dialects are a real difference, not duplication to collapse.
Test-DocumentationLink.ps1mirrors python-markdown because it checks a link that resolves on the published site; the other two mirror github-slugger because they check a link that resolves on github.com. Merging them into one function with a mode flag would be the obvious move and the wrong one — the flag would be set wrong somewhere and the check would agree with itself. Whatever ships, the dialect stays a property of the question, not a parameter someone chooses.The candidate is
Test-CrossRepositoryLink.ps1as it stands. It was written for this: single file, no repository-specific constants, everything that varies is a parameter —-Path,-Owner,-ApiBaseUri,-SelfRepository— and the repository it runs in comes fromGITHUB_REPOSITORYor the git remote, so a copy needs no edit. Its Pester suite runs fully offline against an in-process HTTP stub, which is what makes it safe to distribute: an adopter can prove it works without network access or credentials.Distribution needs a contract before it needs a mechanism. What a managed file promises — how an adopter pins, how a breaking change is announced, whether the workflow that calls it is managed too or only the script — is the part worth getting right. Copying it into three repositories is cheap; the cost is the fourth year, not the fourth repository.
Implementation plan
Test-CrossRepositoryLink.ps1from MSXOrg/docs as the first managed file