2026-07-15 16:18:50 +02:00
|
|
|
# Static Site Deploy
|
|
|
|
|
|
|
|
|
|
A small, dependency-free Forgejo Action that synchronizes a completed static
|
|
|
|
|
website build to a dedicated Bunny Storage Zone.
|
|
|
|
|
|
2026-07-15 16:20:07 +02:00
|
|
|
The runner needs Bash and Python 3.11 or newer. The action itself installs no
|
|
|
|
|
packages and executes no code from the Gandalf repository.
|
|
|
|
|
|
2026-07-15 16:18:50 +02:00
|
|
|
The deployer requires `index.html`, rejects symbolic links, compares files with
|
|
|
|
|
a checksum manifest, uploads changed assets before HTML, deletes stale files
|
|
|
|
|
only after successful uploads, and publishes the new manifest last.
|
|
|
|
|
|
|
|
|
|
## Forgejo Actions
|
|
|
|
|
|
|
|
|
|
Store the website-specific Storage Zone password as the repository secret
|
|
|
|
|
`BUNNY_STORAGE_PASSWORD`, then pin the action to an immutable commit from the
|
|
|
|
|
public action repository:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
---
|
|
|
|
|
name: Deploy website
|
|
|
|
|
|
|
|
|
|
on:
|
|
|
|
|
push:
|
|
|
|
|
branches:
|
|
|
|
|
- main
|
|
|
|
|
|
|
|
|
|
jobs:
|
|
|
|
|
deploy:
|
|
|
|
|
runs-on: docker
|
|
|
|
|
steps:
|
|
|
|
|
- uses: https://data.forgejo.org/actions/checkout@v6
|
|
|
|
|
- run: npm ci
|
|
|
|
|
- run: npm run build
|
|
|
|
|
- name: Deploy to Bunny
|
|
|
|
|
uses: https://forge.tionis.dev/actions/static-site-deploy@<commit-sha>
|
|
|
|
|
with:
|
|
|
|
|
directory: dist
|
|
|
|
|
storage-zone: example-org
|
2026-07-21 21:16:03 +02:00
|
|
|
purge-endpoint: https://gandalf.tionis.dev
|
2026-07-15 16:18:50 +02:00
|
|
|
env:
|
|
|
|
|
BUNNY_STORAGE_PASSWORD: ${{ secrets.BUNNY_STORAGE_PASSWORD }}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Only run deployments for trusted branches. A contributor able to change a
|
|
|
|
|
workflow that receives production secrets can attempt to expose those secrets.
|
|
|
|
|
|
2026-07-21 23:26:34 +02:00
|
|
|
`purge-endpoint` is the backward-compatible name of the optional Gandalf
|
|
|
|
|
deployment gateway input. Before uploading, the action acquires an expiring
|
|
|
|
|
per-zone lease. After publishing the manifest, Gandalf verifies its SHA-256
|
|
|
|
|
digest, records the revision and deployment outcome, and purges the mapped Pull
|
|
|
|
|
Zones only when the manifest changed from the previous successful deployment.
|
|
|
|
|
Interrupted uploads are aborted best-effort; abandoned leases expire after 30
|
|
|
|
|
minutes. The dedicated Storage Zone password authorizes this workflow without
|
|
|
|
|
exposing an account-wide API key to the project.
|
2026-07-17 19:50:31 +02:00
|
|
|
|
2026-07-15 16:18:50 +02:00
|
|
|
## Command line
|
|
|
|
|
|
|
|
|
|
The script can also be used directly with Python 3.11 or newer:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
export BUNNY_STORAGE_ZONE=example-org
|
|
|
|
|
export BUNNY_STORAGE_PASSWORD='zone-specific password'
|
|
|
|
|
python3 static_site.py bunny dist --dry-run
|
|
|
|
|
python3 static_site.py bunny dist
|
|
|
|
|
```
|
|
|
|
|
|
2026-07-20 02:02:47 +02:00
|
|
|
Changed files are transferred with 16 workers by default while preserving the
|
|
|
|
|
asset-before-HTML and manifest-last publication order. Set
|
|
|
|
|
`BUNNY_TRANSFER_WORKERS` or pass `--workers` to tune the limit.
|
|
|
|
|
|
2026-07-15 16:18:50 +02:00
|
|
|
Set `BUNNY_STORAGE_ENDPOINT` when the Storage Zone is outside Frankfurt.
|
|
|
|
|
|
|
|
|
|
## Development
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-15 16:34:06 +02:00
|
|
|
python3 -m unittest discover -s tests
|
2026-07-15 16:18:50 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The canonical source lives in the private Gandalf infrastructure repository
|
|
|
|
|
and is published to this repository as a Git subtree.
|