## Documentation CI is red — `deploydocs` SSH push fails with `Permission denied (publickey)` (stale/missing `DOCUMENTER_KEY` deploy key) The `Documentation` check on `main` (HEAD `648fa86`, run [27516101302](https://github.com/SciML/CatalystNetworkAnalysis.jl/actions/runs/27516101302)) fails. **The docs build itself is completely green** — the failure is purely in the `deploydocs` push step. ### Evidence (from the failing job log) The build pipeline ran cleanly to completion: ``` [ Info: SetupBuildDirectory ... ExpandTemplates ... CrossReferences ... [ Info: CheckDocument: running document checks. ┌ Warning: 203 docstrings not included in the manual: <-- benign, allowed by warnonly = [:missing_docs] [ Info: Populate / RenderDocument ┌ Info: Deployment criteria for deploying devbranch build from GitHub Actions: │ - ✔ ENV["DOCUMENTER_KEY"] exists and is non-empty └ Deploying: ✔ ``` It then fails only at the git push: ``` git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. ┌ Error: Git failed to fetch git@github.com:SciML/CatalystNetworkAnalysis.jl.git │ This can be caused by a DOCUMENTER_KEY variable that is not correctly set up. └ @ Documenter .../deploydocs.jl:395 ERROR: LoadError: failed process: Process(... `git fetch upstream` ...) ProcessExited(128) ``` ### Root cause `Documenter.authentication_method(::GitHubActions)` returns `SSH` whenever `DOCUMENTER_KEY` is non-empty (`deployconfig.jl:453`). The org-inherited `DOCUMENTER_KEY` IS present (the log shows `ENV["DOCUMENTER_KEY"] exists and is non-empty → Deploying: ✔`), so Documenter takes the SSH path — but the corresponding **public deploy key is not registered (or is stale) on this repo**, so the SSH push is rejected with `Permission denied (publickey)`. This is repo-specific, not a problem with the shared CI: - This repo's `gh-pages` branch has not updated since **2025-02-10** ("build based on 45e9df0"); every docs deploy since has failed with this same SSH error. - Sibling repos using the identical centralized workflow (`SciML/.github/.github/workflows/documentation.yml@v1`) and the same org `DOCUMENTER_KEY` deploy green — e.g. DataInterpolations.jl run [27525214743](https://github.com/SciML/DataInterpolations.jl/actions/runs/27525214743) shows `ENV["DOCUMENTER_KEY"] exists and is non-empty → Deploying: ✔` followed by a successful push. So the org secret + SSH mechanism works; only this repo's registered deploy key is wrong/missing. ### Fix (requires repo-admin — cannot be done in repo code) Regenerate and re-register the deploy keypair, then the push will succeed unchanged: ```julia using DocumenterTools DocumenterTools.genkeys(user="SciML", repo="CatalystNetworkAnalysis.jl") ``` Then: 1. Add the printed **public** key as a repo **Deploy key** (Settings → Deploy keys) with **write access** titled `documenter`. 2. Set the printed **private** key (Base64) as the repo Actions **secret** `DOCUMENTER_KEY` (or confirm the repo isn't shadowing the org `DOCUMENTER_KEY` with a stale repo-level secret). No source/workflow change in this repo is needed. (Forcing the HTTPS `GITHUB_TOKEN` deploy path by blanking `DOCUMENTER_KEY` would also work, but it diverges from the SciML SSH-deploy-key convention used fleet-wide and its viability depends on the repo's Actions `GITHUB_TOKEN` write-permission policy, so the deploy-key rotation above is the correct fix.) --- Reported by automated CI triage. cc @ChrisRackauckas