initial: action/site-publish @v1
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# action/site-publish
|
||||
|
||||
Composite Gitea Action that publishes a website to the fritzlab k8s cluster.
|
||||
Supports `static`, `hugo`, `mkdocs` (content → Garage S3 + ExternalName Service)
|
||||
and `docker` (Dockerfile → Deployment + headless Service). Handles manifest
|
||||
rendering, TLS via cert-manager, and Garage bucket aliases.
|
||||
|
||||
Renamed from `fritzlab/publish-site` → `action/site-publish` as part of the
|
||||
2026 action-org consolidation.
|
||||
|
||||
## Convention
|
||||
|
||||
Bucket name = repo name = canonical domain. Sibling hostnames (e.g. `www.`,
|
||||
`ipv6.`) are declared as `aliases:` in `site.yaml` — the action registers each
|
||||
as a Garage `globalAlias` on the bucket and adds it to the Ingress + Certificate
|
||||
on every deploy. Manual edits to manifests in the apps repo are clobbered;
|
||||
edit `site.yaml` instead.
|
||||
|
||||
## Usage
|
||||
|
||||
Scaffold a new site (handles repo creation + Garage bucket):
|
||||
|
||||
```sh
|
||||
./new-site.sh --name my-site.vino.network --domain my-site.vino.network --type static
|
||||
```
|
||||
|
||||
Or do it manually. `site.yaml`:
|
||||
|
||||
```yaml
|
||||
domain: my-site.vino.network
|
||||
type: static # static | hugo | mkdocs | docker
|
||||
# content_dir: html # subdirectory containing content (default: repo root)
|
||||
# aliases: # additional hostnames (each gets a globalAlias on the bucket)
|
||||
# - www.my-site.vino.network
|
||||
# tidy: true # set false to skip HTML tidy
|
||||
# enabled: true # set false to decommission
|
||||
```
|
||||
|
||||
`.gitea/workflows/publish.yaml`:
|
||||
|
||||
```yaml
|
||||
name: Publish
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: fritzlab
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://code.fritzlab.net/action/site-publish@v1
|
||||
with:
|
||||
token: ${{ secrets.CI_BOT_TOKEN }}
|
||||
s3-access-key: ${{ secrets.GARAGE_S3_ACCESS_KEY }}
|
||||
s3-secret-key: ${{ secrets.GARAGE_S3_SECRET_KEY }}
|
||||
garage-admin-token: ${{ secrets.GARAGE_ADMIN_TOKEN }}
|
||||
```
|
||||
|
||||
DNS: subdomains of `vino.network` are covered by the wildcard CNAME to
|
||||
`traefik.edge.svc…`. For other zones, add an explicit CNAME:
|
||||
|
||||
```
|
||||
my-site.fritzlab.net 300 IN CNAME traefik.edge.svc.k8s.sjc001.fritzlab.net.
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `token` | yes | | Gitea token for apps repo push |
|
||||
| `s3-access-key` | static/hugo/mkdocs | | Garage `ci-deploy-key` access key id |
|
||||
| `s3-secret-key` | static/hugo/mkdocs | | Garage `ci-deploy-key` secret key |
|
||||
| `s3-endpoint` | no | `http://garage.storage.svc:3900` | Garage S3 endpoint |
|
||||
| `garage-admin-token` | static/hugo/mkdocs (only if site has `aliases`) | | Garage admin API token (`admin-token` from `garage-rpc-secret` in `storage` ns) |
|
||||
| `garage-admin-endpoint` | no | `http://garage.storage.svc:3903` | Garage admin API endpoint |
|
||||
| `registry-password` | docker | inputs.token | Container registry password |
|
||||
| `username` | no | `ci-bot` | Gitea username |
|
||||
|
||||
Org secrets in `websites`: `CI_BOT_TOKEN`, `GARAGE_S3_ACCESS_KEY`,
|
||||
`GARAGE_S3_SECRET_KEY`, `GARAGE_ADMIN_TOKEN`.
|
||||
|
||||
## Tools
|
||||
|
||||
- **`new-site.sh`** — create a new site: Gitea repo, Garage bucket, web hosting enabled.
|
||||
- **`scripts/publish.py decommission <site>`** — remove a site's manifests from apps repo. Bucket purge is manual.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
push to websites/<repo>
|
||||
→ CI runs site-publish action
|
||||
→ reads site.yaml, builds content (static copy / hugo / mkdocs), runs tidy
|
||||
→ aws s3 sync → Garage bucket named after the repo
|
||||
→ admin API: ensures every alias from site.yaml is a globalAlias on the bucket
|
||||
→ renders manifests in fritzlab/apps from templates: ExternalName Service →
|
||||
garage.storage.svc, Traefik Ingress (canonical + aliases), cert-manager
|
||||
Certificate (canonical + aliases as SANs), kustomization
|
||||
→ commits + pushes apps repo only if diff is non-empty
|
||||
→ ArgoCD syncs → site live with TLS
|
||||
```
|
||||
|
||||
The Ingress + Certificate are re-rendered on every deploy from `site.yaml`.
|
||||
There is no "first-deploy vs. update" branching — every deploy is idempotent.
|
||||
|
||||
No nginx pods, no per-site Docker images. Garage matches `Host:` header to
|
||||
bucket name (or any of its globalAliases), so every site shares a single
|
||||
ExternalName target.
|
||||
Reference in New Issue
Block a user