For the Blog agent on proxmox and the VPS agent, to retest together. Raised because #30 changes the live deploy path and the change has only been reasoned about and tested locally, never run end to end against the real host.
This is not a contradiction of the earlier joint testing. That testing stands, and two independent measurements on #30 confirmed it rather than challenged it:
- The pointer flip is atomic.
strace on rsync -a --no-recursive src/current dst/ shows symlink("releases/new", ".current.0") then rename(".current.0", "current"), with no unlink of current at any point. rename(2) is atomic, so a request in flight resolves the old target or the new one, never nothing.
- A first deploy into a fresh environment needs no special case.
rsync -az --mkpath --link-dest=<missing dir> prints --link-dest arg does not exist and exits 0, transferring in full without hard-linking.
Both were challenged during review and both held. Nothing below disputes them.
What is new and untested
#30 adds three options to the rsync transport, which previously carried only -i and IdentitiesOnly:
-o StrictHostKeyChecking=yes
-o UserKnownHostsFile=~/.ssh/known_hosts
-o BatchMode=yes
Rationale is in the PR: the workflow writes known_hosts from a per-environment variable and its own comments call host key integrity load-bearing, then handed the actual verification to the runner's OpenSSH defaults. The care and the enforcement were in different places.
What was verified, and its limit. ssh -G with the options single-quoted, so no shell touches them:
$ ssh -G -o 'UserKnownHostsFile=~/.ssh/known_hosts' -o 'IdentityFile=~/.ssh/deploy' example.invalid
identityfile ~/.ssh/deploy
userknownhostsfile /home/pieter/.ssh/known_hosts
So OpenSSH performs the tilde expansion itself and the no-shell case resolves correctly. That was measured on a workstation, against no host. It does not exercise the runner's OpenSSH build, rsync's own splitting of the -e string, or the rrsync -wo forced command at the far end.
What to retest
- A staging deploy end to end. The transport now fails closed rather than open, so a mismatch that previously proceeded will now stop the deploy. That is the intended behavior and the reason to prove it on staging first.
- The known-hosts value actually verifies. With
StrictHostKeyChecking=yes, a DEPLOY_SSH_KNOWN_HOSTS variable that is stale, wrong-format, or missing the host's current key now fails the deploy instead of being tolerated. Worth confirming the stored value matches what the VPS presents today, on both environments.
- The forced command is unaffected.
BatchMode=yes suppresses prompts; confirm it does not interact badly with rrsync -wo on the far side.
- Production only after staging passes, since a broken transport blocks the rollback path as well as the deploy.
The rest of #30 is off the deploy path: the composite action for the generator pin, the theme provenance record, the markdown glob, permissions: {}, and the workflow outputs.
One more, lower stakes
The production ref gate moved from github.ref_name != "main" to github.ref != "refs/heads/main", because tags and branches are separate namespaces sharing a short name and workflow_dispatch accepts a tag. Worth one dispatch from a non-default branch to confirm it still refuses, since the gate failing open would be silent.
Reference leaf and contract: ptr727/ProjectTemplate#560.
For the Blog agent on proxmox and the VPS agent, to retest together. Raised because #30 changes the live deploy path and the change has only been reasoned about and tested locally, never run end to end against the real host.
This is not a contradiction of the earlier joint testing. That testing stands, and two independent measurements on #30 confirmed it rather than challenged it:
straceonrsync -a --no-recursive src/current dst/showssymlink("releases/new", ".current.0")thenrename(".current.0", "current"), with nounlinkofcurrentat any point.rename(2)is atomic, so a request in flight resolves the old target or the new one, never nothing.rsync -az --mkpath --link-dest=<missing dir>prints--link-dest arg does not existand exits 0, transferring in full without hard-linking.Both were challenged during review and both held. Nothing below disputes them.
What is new and untested
#30 adds three options to the rsync transport, which previously carried only
-iandIdentitiesOnly:Rationale is in the PR: the workflow writes
known_hostsfrom a per-environment variable and its own comments call host key integrity load-bearing, then handed the actual verification to the runner's OpenSSH defaults. The care and the enforcement were in different places.What was verified, and its limit.
ssh -Gwith the options single-quoted, so no shell touches them:So OpenSSH performs the tilde expansion itself and the no-shell case resolves correctly. That was measured on a workstation, against no host. It does not exercise the runner's OpenSSH build, rsync's own splitting of the
-estring, or therrsync -woforced command at the far end.What to retest
StrictHostKeyChecking=yes, aDEPLOY_SSH_KNOWN_HOSTSvariable that is stale, wrong-format, or missing the host's current key now fails the deploy instead of being tolerated. Worth confirming the stored value matches what the VPS presents today, on both environments.BatchMode=yessuppresses prompts; confirm it does not interact badly withrrsync -woon the far side.The rest of #30 is off the deploy path: the composite action for the generator pin, the theme provenance record, the markdown glob,
permissions: {}, and the workflow outputs.One more, lower stakes
The production ref gate moved from
github.ref_name != "main"togithub.ref != "refs/heads/main", because tags and branches are separate namespaces sharing a short name andworkflow_dispatchaccepts a tag. Worth one dispatch from a non-default branch to confirm it still refuses, since the gate failing open would be silent.Reference leaf and contract: ptr727/ProjectTemplate#560.