The documentation site at psmodule.io/docs has not been republished since 2026-07-18, even though the Docs workflow reports success on every push to main and every scheduled run. Merged documentation changes never reach readers, and the reported green check makes the failure invisible.
Observed behavior
Every Docs run on push and schedule completes with conclusion success while its Publish job is skipped, so no GitHub Pages deployment is created.
gh run view 30748531321 --repo PSModule/docs --json jobs --jq '.jobs[] | "\(.name) \(.conclusion)"'
# Build success
# Lint skipped
# Publish skipped
The most recent github-pages deployment is from 2026-07-18:
gh api "repos/PSModule/docs/deployments?environment=github-pages&per_page=1" --jq '.[] | "\(.created_at) \(.sha[0:8])"'
# 2026-07-18T15:31:48Z 88c92d87
The user-visible symptom is that Modules/Repository-Standard/ returns 404 while the superseded Modules/Repository-Defaults/ still serves, although #96 renamed that page and merged to main on 2026-08-02.
Expected behavior
A push to main that touches the documentation sources deploys the built site, and a scheduled run redeploys it so the generated module catalog stays current. A failed build never deploys, and a pull_request event never deploys.
Reproduction
- Merge any change under
src/** to main.
- Wait for the
Docs workflow run to finish, and observe it reports success.
- Inspect its jobs and observe
Publish is skipped.
- Request the newly published page and observe a 404.
Environment
PSModule/docs on main, .github/workflows/Docs.yml, GitHub-hosted ubuntu-24.04 runners, GitHub Pages via actions/deploy-pages.
Regression
Introduced by #74, merged 2026-07-19, which added the schedule trigger and restricted the lint job to pull_request events. The last successful deployment is from the day before, which matches. The Publish job has been unreachable on push and schedule ever since.
Workaround
None automatic. A deployment can only be produced by running the workflow on a pull_request-shaped event, which the publish condition also excludes, so today the site cannot be republished at all without editing the workflow.
Acceptance criteria
- A push to
main that touches the documentation sources deploys the site.
- A scheduled run deploys the site.
- A run whose
build job fails or is cancelled never deploys.
- A
pull_request event never deploys.
Modules/Repository-Standard/ resolves after the fix reaches main.
References
Technical decisions
Verified root cause. In GitHub Actions a job whose needs list contains a skipped job is itself skipped, unless its own if uses a status function such as always(), !cancelled(), or an explicit needs.<job>.result check. A plain if: expression is implicitly wrapped in success(), and success() is false when an upstream job was skipped. publish declares needs: [build, lint] with a plain if: github.event_name != 'pull_request', while lint declares if: github.event_name == 'pull_request'. On every event that can reach publish, lint is skipped, so publish is skipped too.
Bounding. The two jobs are mutually exclusive by construction: lint runs only on pull_request, and publish runs only when the event is not pull_request. The dependency edge from publish to lint can therefore never carry a signal, in either direction. The correction is to remove that edge rather than to keep it and neutralize it with a status function, because a status function would preserve a dependency that reads as a lint gate while gating nothing.
Failure handling. needs: [build] with a plain if: keeps the implicit success() over build, so a failed or cancelled build still blocks deployment without any explicit result comparison. Adding !cancelled() would weaken that guarantee and has to be paired with needs.build.result == 'success' to restore it.
Not in scope. Whether lint should also run on push, and whether the every-five-minutes schedule should deploy unconditionally rather than only when the built site changed. Both are separate design questions; record them as follow-ups if they matter.
Verification. The failure is a workflow-graph condition, not testable in this repository's build. The equivalent repeatable verification is: after merge, confirm a new github-pages deployment exists whose sha matches the merge commit, and that the renamed page resolves.
Implementation plan
The documentation site at psmodule.io/docs has not been republished since 2026-07-18, even though the
Docsworkflow reports success on every push tomainand every scheduled run. Merged documentation changes never reach readers, and the reported green check makes the failure invisible.Observed behavior
Every
Docsrun onpushandschedulecompletes with conclusionsuccesswhile itsPublishjob is skipped, so no GitHub Pages deployment is created.The most recent
github-pagesdeployment is from 2026-07-18:The user-visible symptom is that
Modules/Repository-Standard/returns 404 while the supersededModules/Repository-Defaults/still serves, although #96 renamed that page and merged tomainon 2026-08-02.Expected behavior
A push to
mainthat touches the documentation sources deploys the built site, and a scheduled run redeploys it so the generated module catalog stays current. A failed build never deploys, and apull_requestevent never deploys.Reproduction
src/**tomain.Docsworkflow run to finish, and observe it reports success.Publishis skipped.Environment
PSModule/docsonmain,.github/workflows/Docs.yml, GitHub-hostedubuntu-24.04runners, GitHub Pages viaactions/deploy-pages.Regression
Introduced by #74, merged 2026-07-19, which added the
scheduletrigger and restricted thelintjob topull_requestevents. The last successful deployment is from the day before, which matches. ThePublishjob has been unreachable onpushandscheduleever since.Workaround
None automatic. A deployment can only be produced by running the workflow on a
pull_request-shaped event, which thepublishcondition also excludes, so today the site cannot be republished at all without editing the workflow.Acceptance criteria
mainthat touches the documentation sources deploys the site.buildjob fails or is cancelled never deploys.pull_requestevent never deploys.Modules/Repository-Standard/resolves after the fix reachesmain.References
Technical decisions
Verified root cause. In GitHub Actions a job whose
needslist contains a skipped job is itself skipped, unless its ownifuses a status function such asalways(),!cancelled(), or an explicitneeds.<job>.resultcheck. A plainif:expression is implicitly wrapped insuccess(), andsuccess()is false when an upstream job was skipped.publishdeclaresneeds: [build, lint]with a plainif: github.event_name != 'pull_request', whilelintdeclaresif: github.event_name == 'pull_request'. On every event that can reachpublish,lintis skipped, sopublishis skipped too.Bounding. The two jobs are mutually exclusive by construction:
lintruns only onpull_request, andpublishruns only when the event is notpull_request. The dependency edge frompublishtolintcan therefore never carry a signal, in either direction. The correction is to remove that edge rather than to keep it and neutralize it with a status function, because a status function would preserve a dependency that reads as a lint gate while gating nothing.Failure handling.
needs: [build]with a plainif:keeps the implicitsuccess()overbuild, so a failed or cancelled build still blocks deployment without any explicit result comparison. Adding!cancelled()would weaken that guarantee and has to be paired withneeds.build.result == 'success'to restore it.Not in scope. Whether
lintshould also run onpush, and whether the every-five-minutesscheduleshould deploy unconditionally rather than only when the built site changed. Both are separate design questions; record them as follow-ups if they matter.Verification. The failure is a workflow-graph condition, not testable in this repository's build. The equivalent repeatable verification is: after merge, confirm a new
github-pagesdeployment exists whoseshamatches the merge commit, and that the renamed page resolves.Implementation plan
pushandscheduleruns showPublish skipped, and the newest deployment predates the regression.lintfrom thepublishjob'sneeds, keepingbuild, and explain in the workflow why the edge is absent so it is not reinstated.github-pagesdeployment for the merge commit and thatModules/Repository-Standard/resolves.