#1456

ci: use easySFTP for the emscripten deploy

Openeiservwants to merge intofrom

Disclosure up front: I maintain easySFTP, so this is me proposing my own action. Close it without ceremony if you would rather not switch. I kept the diff to the deploy step and touched nothing else.

What changes

The deploy job of emscripten.yml uses eiserv/easySFTP@v3 instead of wlixcc/SFTP-Deploy-Action@v1.2.4.

Secret names are unchanged (USERNAME, SERVER, PORT, PRIVATE_KEY, REMOTE_PATH), so there is nothing to add or rename in repo settings before this can be merged.

Input mapping:

beforeafternote
serverhost
ssh_private_keyprivate-keysame PEM content, same secret
local_path: './emscripten/*'source: emscriptencontents land in target, same result as put -r ./emscripten/*
remote_pathtarget
sftp_only: truedropped
allow-any-host-key: truesee below

sftp_only: true was there to stop the old action from opening a second SSH session just to run mkdir -p. easySFTP creates missing remote directories over the SFTP channel it already has, so there is no exec session to suppress and no flag to set.

About that allow-any-host-key

easySFTP refuses to connect unless you either pin the server's host key or state explicitly that you do not want to. The old action hardcoded -o StrictHostKeyChecking=no, so allow-any-host-key: true is what keeps today's behaviour exactly as it is. Merging this changes your trust model in neither direction.

If you want the upgrade later it is a one line swap. Run

ssh-keyscan -p <port> <host>

put the output into a KNOWN_HOSTS secret, and replace allow-any-host-key: true with known-hosts: ${{ secrets.KNOWN_HOSTS }}. Multiple lines are accepted, so you can paste every key the server offers and not worry about which algorithm gets negotiated.

Why bother

Three things that are relevant to this specific job.

Uploads are atomic per file. sftp -b with put -r writes straight into the destination path. If the connection drops partway through tracy-profiler.wasm.zst, the file being served is now a truncated one, and it stays truncated until the next successful run. easySFTP streams each file to a temporary sibling and renames it over the target only once the transfer completed, so a broken connection leaves the previous version live.

It retries. Right now a dropped connection is a failed job and a half deployed site. easySFTP redials on connection level errors within a run wide retry budget and picks up where it stopped. It also has a stall watchdog for the less obvious case where the server accepts the connection and then goes quiet.

Less fixed cost per run. wlixcc/SFTP-Deploy-Action is a Docker action, so every run builds an Alpine image and apk adds rsync, sshpass, openssh and expect before the first byte moves. easySFTP is a composite action that pulls one static Go binary and checks it against the release checksums. On seven files that setup cost is most of the wall clock.

Throughput matters less here because the payload is small, but for the record: the old action pushes files one after another through a single sftp channel, easySFTP transfers files in parallel (4 by default) and keeps multiple write requests in flight per file (16 by default), which is what actually fills a high latency link.

Smaller things you may or may not care about: a dry-run input, files-uploaded / bytes-uploaded / duration-ms step outputs, a job summary table, and gitignore syntax exclude patterns.

Docs: https://github.com/eiserv/easySFTP. Benchmark method and stored results live in benchmarks/ in that repo.

I have not been able to test this against your actual server for obvious reasons, so the sanity check I can offer is that the input mapping above is mechanical and the deploy job is unchanged otherwise. Happy to adjust anything.

Activity

2
copilot-pull-request-reviewer[bot]reviewed2mo ago
copilot-pull-request-reviewer[bot]2mo ago

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.