mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-06 00:01:24 +00:00
feat: add a one-command self-host installer at warmbly.com/install.sh with an interactive data-control wizard, give docker-compose.yml image keys and per-store volume variables, add an image-mode updater, move engagement/form/audit retention into instance settings, and add warmblyctl backup/restore
This commit is contained in:
@@ -6,7 +6,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
service:
|
||||
description: "Service to build (all, backend, consumer, worker, forms, tracking, realtime)"
|
||||
description: "Service to build (all, backend, consumer, worker, forms, updater, tracking, realtime)"
|
||||
required: false
|
||||
default: "all"
|
||||
|
||||
@@ -61,6 +61,12 @@ jobs:
|
||||
- 'cmd/forms/**'
|
||||
- 'forms/**'
|
||||
- 'deploy/docker/forms.Dockerfile'
|
||||
updater:
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'internal/updater/**'
|
||||
- 'cmd/updater/**'
|
||||
- 'deploy/docker/updater.Dockerfile'
|
||||
tracking:
|
||||
- 'tracking/**'
|
||||
realtime:
|
||||
@@ -75,6 +81,7 @@ jobs:
|
||||
CONSUMER: ${{ steps.filter.outputs.consumer }}
|
||||
WORKER: ${{ steps.filter.outputs.worker }}
|
||||
FORMS: ${{ steps.filter.outputs.forms }}
|
||||
UPDATER: ${{ steps.filter.outputs.updater }}
|
||||
TRACKING: ${{ steps.filter.outputs.tracking }}
|
||||
REALTIME: ${{ steps.filter.outputs.realtime }}
|
||||
run: |
|
||||
@@ -82,7 +89,7 @@ jobs:
|
||||
native=""
|
||||
if [ "$EVENT" = "workflow_dispatch" ]; then
|
||||
sel="${SELECTED:-all}"
|
||||
for s in backend consumer worker forms; do
|
||||
for s in backend consumer worker forms updater; do
|
||||
if [ "$sel" = "all" ] || [ "$sel" = "$s" ]; then go="$go\"$s\","; fi
|
||||
done
|
||||
for s in tracking realtime; do
|
||||
@@ -93,6 +100,7 @@ jobs:
|
||||
if [ "$CONSUMER" = "true" ]; then go="$go\"consumer\","; fi
|
||||
if [ "$WORKER" = "true" ]; then go="$go\"worker\","; fi
|
||||
if [ "$FORMS" = "true" ]; then go="$go\"forms\","; fi
|
||||
if [ "$UPDATER" = "true" ]; then go="$go\"updater\","; fi
|
||||
if [ "$TRACKING" = "true" ]; then native="$native\"tracking\","; fi
|
||||
if [ "$REALTIME" = "true" ]; then native="$native\"realtime\","; fi
|
||||
fi
|
||||
|
||||
@@ -34,6 +34,7 @@ jobs:
|
||||
forms: ${{ steps.filter.outputs.forms }}
|
||||
make: ${{ steps.filter.outputs.make }}
|
||||
ios: ${{ steps.filter.outputs.ios }}
|
||||
installer: ${{ steps.filter.outputs.installer }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v3
|
||||
@@ -70,6 +71,10 @@ jobs:
|
||||
- 'integrations/make/**'
|
||||
ios:
|
||||
- 'ios/**'
|
||||
installer:
|
||||
- 'site/public/install.sh'
|
||||
- 'site/public/install.sh.sha256'
|
||||
- 'scripts/check-installer.sh'
|
||||
|
||||
migrations-ci:
|
||||
name: Migrations
|
||||
@@ -229,6 +234,21 @@ jobs:
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
|
||||
# The installer is served verbatim from site/public, so what CI checks is
|
||||
# exactly what a `curl | sh` executes. The checksum is published next to it
|
||||
# for anyone who would rather download, verify and read before running, and
|
||||
# it is only useful if it cannot drift.
|
||||
installer-ci:
|
||||
name: Installer CI
|
||||
needs: changes
|
||||
if: needs.changes.outputs.installer == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check the installer
|
||||
run: ./scripts/check-installer.sh
|
||||
|
||||
make-ci:
|
||||
name: Make App CI
|
||||
needs: changes
|
||||
@@ -398,7 +418,7 @@ jobs:
|
||||
ci-status:
|
||||
name: CI Status
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changes, migrations-ci, go-ci, web-ci, admin-ci, site-ci, forms-ci, make-ci, rust-ci, elixir-ci, ios-ci, frontend-images]
|
||||
needs: [changes, migrations-ci, go-ci, web-ci, admin-ci, site-ci, forms-ci, installer-ci, make-ci, rust-ci, elixir-ci, ios-ci, frontend-images]
|
||||
if: always()
|
||||
steps:
|
||||
- name: Check CI status
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
service: [backend, consumer, worker]
|
||||
service: [backend, consumer, worker, forms, updater]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -225,6 +225,38 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# The installer verifies what it pulled against this file, so it is what
|
||||
# makes "curl | sh" checkable after the fact rather than only before it.
|
||||
# One line per service, because the thing that reads it is a POSIX shell.
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish the image manifest
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
{
|
||||
printf '{\n'
|
||||
printf ' "tag": "%s",\n' "$TAG"
|
||||
printf ' "registry": "%s",\n' "$IMAGE_PREFIX"
|
||||
printf ' "images": {\n'
|
||||
first=1
|
||||
for s in backend consumer worker forms updater web admin tracking realtime; do
|
||||
digest=$(docker buildx imagetools inspect "$IMAGE_PREFIX/$s:$TAG" \
|
||||
--format '{{json .Manifest.Digest}}' | tr -d '"')
|
||||
[ "$first" = 1 ] || printf ',\n'
|
||||
first=0
|
||||
printf ' "%s": "%s"' "$s" "$digest"
|
||||
done
|
||||
printf '\n }\n}\n'
|
||||
} > /tmp/images.json
|
||||
cat /tmp/images.json
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||||
@@ -240,6 +272,23 @@ jobs:
|
||||
cat /tmp/changelog.md
|
||||
cat <<'EOF'
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
curl -fsSL https://warmbly.com/install.sh | sh -s -- --version ${{ github.ref_name }}
|
||||
```
|
||||
|
||||
Add `--wizard` to be asked where each store lives, what is kept and
|
||||
for how long, and how it is backed up.
|
||||
|
||||
`images.json` below lists the manifest digest of every image in this
|
||||
release. The installer checks what it pulled against it, and you can
|
||||
too:
|
||||
|
||||
```
|
||||
docker image inspect ${{ env.IMAGE_PREFIX }}/backend:${{ github.ref_name }} --format '{{index .RepoDigests 0}}'
|
||||
```
|
||||
|
||||
## Docker Images
|
||||
|
||||
All images are available at `ghcr.io/${{ github.repository_owner }}/warmbly`:
|
||||
@@ -253,6 +302,8 @@ jobs:
|
||||
| Realtime | `${{ env.IMAGE_PREFIX }}/realtime:${{ github.ref_name }}` |
|
||||
| Dashboard (web) | `${{ env.IMAGE_PREFIX }}/web:${{ github.ref_name }}` |
|
||||
| Admin | `${{ env.IMAGE_PREFIX }}/admin:${{ github.ref_name }}` |
|
||||
| Forms | `${{ env.IMAGE_PREFIX }}/forms:${{ github.ref_name }}` |
|
||||
| Updater | `${{ env.IMAGE_PREFIX }}/updater:${{ github.ref_name }}` |
|
||||
|
||||
## Deployment
|
||||
|
||||
@@ -266,5 +317,6 @@ jobs:
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ${{ github.ref_name }}
|
||||
body_path: /tmp/release-body.md
|
||||
files: /tmp/images.json
|
||||
draft: false
|
||||
prerelease: ${{ contains(github.ref_name, '-') }}
|
||||
|
||||
Reference in New Issue
Block a user