- Python 70.3%
- Shell 19.1%
- Makefile 10.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Test / test (push) Successful in 24s
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> |
||
| .forgejo/workflows | ||
| docs/superpowers | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| action.yml | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| inbox.md | ||
| LICENSE | ||
| Makefile | ||
| myproject.toml | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
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: syncmirrors and deletes remote files absent locally.dry-rundefaults totrue— set it tofalsedeliberately.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,
syncruns, and — without a limit — the entire live web root would be deleted except that one file.max-delete(default10) caps this blast radius by passing rclone's--max-deleteflag. 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, raisemax-delete(or set it to-1for 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