Forgejo Action: deploy a folder to a YunoHost my_webapp over SFTP
  • Python 70.3%
  • Shell 19.1%
  • Makefile 10.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ralph Mayer ab7469c069
All checks were successful
Test / test (push) Successful in 24s
docs: record final-review follow-ups in inbox
None blocking; the whole-branch review approved for production. Captured here
so the SDD workspace can be torn down without losing them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 00:04:36 +02:00
.forgejo/workflows fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
docs/superpowers fix(plan): assert the action.yml env mapping 2026-08-07 23:08:24 +02:00
scripts fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
tests fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
.gitignore chore: ignore worktree and SDD scratch dirs 2026-08-07 22:05:08 +02:00
action.yml fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
AGENTS.md docs(design): SFTP deploy action for YunoHost my_webapp 2026-08-07 21:04:49 +02:00
CHANGELOG.md fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
CLAUDE.md docs(design): SFTP deploy action for YunoHost my_webapp 2026-08-07 21:04:49 +02:00
inbox.md docs: record final-review follow-ups in inbox 2026-08-08 00:04:36 +02:00
LICENSE docs(design): SFTP deploy action for YunoHost my_webapp 2026-08-07 21:04:49 +02:00
Makefile docs(design): SFTP deploy action for YunoHost my_webapp 2026-08-07 21:04:49 +02:00
myproject.toml docs(design): SFTP deploy action for YunoHost my_webapp 2026-08-07 21:04:49 +02:00
pyproject.toml feat: add composite action definition 2026-08-07 23:04:26 +02:00
README.md fix: stop live downloads in tests, restore shellcheck gate, fix octal version bug, add max-delete input 2026-08-07 23:57:57 +02:00
uv.lock feat: add composite action definition 2026-08-07 23:04:26 +02:00

mr-sftp-deploy-action

A reusable Forgejo Action that uploads a folder to a YunoHost my_webapp instance over SFTP.

Purpose

Forgejo ships no file-transfer action, and scp/rsync -e ssh cannot reach a my_webapp web root: enabling SFTP puts the app's system user in group sftp.app, which YunoHost's sshd matches with internal-sftp and a chroot, so there is no remote shell. Only SFTP-protocol clients work.

This action fills that gap. It is upload-only, so it composes equally well with a preceding build job or with a repository that commits its output.

Inputs

Name Required Default Description
host yes SFTP host
port no 22 SSH port
user yes SFTP user (my_webapp__N)
password yes SFTP password — always pass from a secret
source yes Local folder to upload
target no www/ Remote path inside the SFTP chroot
mode no sync sync (mirror, deletes remote extras) or copy (never deletes)
dry-run no true Preview changes without modifying the remote
known-hosts no SSH host key line(s) for host — obtain with ssh-keyscan
insecure-skip-host-key no false Skip host key verification. Do not use in production.
max-delete no 10 Caps how many files a single sync may delete. -1 means unlimited. Ignored in copy mode.

mode: sync mirrors and deletes remote files absent locally. dry-run defaults to true — set it to false deliberately.

The empty-source guard below only catches a source directory with zero files. The more realistic failure is a half-failed build that leaves one stale file behind: the guard passes, sync runs, and — without a limit — the entire live web root would be deleted except that one file. max-delete (default 10) caps this blast radius by passing rclone's --max-delete flag. This is not an atomic safety net. rclone checks the delete count file-by-file, immediately before removing each one: it will delete files up to the limit and only then raise a fatal error and stop. If your sync legitimately needs to delete more than the default 10 files, raise max-delete (or set it to -1 for unlimited) rather than being surprised by a partial, non-rolled-back deletion.

dry-run and mode are validated strictly: deploy.sh accepts only the literal strings "true"/"false" and "sync"/"copy" respectively, and fails with an error on anything else. This is deliberate fail-closed behaviour.

Usage

- uses: https://forgejo.mayer.rocks/public/mr-sftp-deploy-action@v1
  with:
    host:        ${{ vars.DEPLOY_HOST }}
    port:        ${{ vars.DEPLOY_PORT }}
    user:        ${{ vars.DEPLOY_USER }}
    password:    ${{ secrets.DEPLOY_PASSWORD }}
    known-hosts: ${{ secrets.DEPLOY_KNOWN_HOSTS }}
    source: out/
    target: www/
    mode: sync
    dry-run: false

License

GPL-3.0