Batch 1 of the chart-vs-project split. The project now ships a
hardened runtime image as part of every zddc-server release; downstream
deployments (e.g. the Burns & McDonnell Helm chart) will FROM this
image instead of cloning and building from source.
zddc/Containerfile (target: server)
- Tag the runtime stage `server` so `podman build --target server`
is unambiguous (the existing `binaries` target still works).
- Bake the bundled landing + archive tool HTML at /opt/zddc-server/web.
Useful for self-contained demos (`ZDDC_ROOT=/opt/zddc-server/web`)
and as a fallback web root when no external mount is supplied.
- Set fixed UID/GID 1000 for the non-root zddc user so volume
permissions are predictable across hosts.
- Add ENV ZDDC_ROOT=/srv default so a `podman run -v data:/srv` works
with no further config; explicit ZDDC_ROOT overrides.
- Declare VOLUME /srv to make the data-mount expectation explicit.
- Add OCI image labels (title, description, source, documentation,
license, vendor).
- Install ca-certificates so any future outbound HTTPS works.
- Add a HEALTHCHECK for `docker run` users (Kubernetes overrides).
build.sh
- Make the cross-platform podman binary build conditional on `podman`
being present. CI doesn't need it (the runtime container image's
own builder stage produces linux/amd64 internally), but having
build.sh sh-only-runnable means CI doesn't have to do nested
containers just to assemble dist/web.
- Reorder so `zddc/dist/web/` is assembled before the binary build
(allows the binary build to be skipped without breaking the bundle).
.woodpecker.yml (new)
- Triggers on tag push matching `zddc-server-v*`.
- Step 1 (alpine + sh): runs `sh build.sh` to assemble dist/web,
computes the image tag (`${TAG#zddc-server-v}` plus `latest`).
- Step 2 (docker-buildx plugin): builds and publishes
codeberg.org/varasys/zddc-server:{X.Y.Z, latest}. Auth via the
codeberg_user / codeberg_token Woodpecker secrets — these need
one-time setup in repo Settings; documented in zddc/README.md.
zddc/README.md
- New "Container image" section: pull URL, image properties (alpine,
non-root UID 1000, EXPOSE 8443, VOLUME /srv, baked web bundle),
example `podman run` invocation.
- New "Env-var contract (for chart consumers)" table: the variables
Helm charts and Compose files should set explicitly when running
behind a TLS-terminating reverse proxy with SSO. This is the
documented interface between project and downstream charts.
- "Release Tagging" section now points at .woodpecker.yml and lists
the two Woodpecker secrets that must be configured.
Validated locally:
podman build --target server -t zddc-server-test .
podman run -e ZDDC_ROOT=/opt/zddc-server/web -e ZDDC_TLS_CERT=none \
-e ZDDC_INSECURE_DIRECT=1 -e ZDDC_ADDR=:8080 \
-p 18080:8080 zddc-server-test
curl http://localhost:18080/ → HTTP 200, bundled landing tool.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
155 lines
5.8 KiB
Bash
Executable file
155 lines
5.8 KiB
Bash
Executable file
#!/bin/sh
|
|
set -eu
|
|
|
|
# Top-level build script — builds all ZDDC HTML tools, the zddc-server
|
|
# binaries, and the downloadable bundles (install.zip and track-*.zip).
|
|
|
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
|
|
|
echo "=== Building ZDDC tools ==="
|
|
|
|
sh "$SCRIPT_DIR/transmittal/build.sh" "${1:-}" "${2:-}"
|
|
sh "$SCRIPT_DIR/archive/build.sh" "${1:-}" "${2:-}"
|
|
sh "$SCRIPT_DIR/classifier/build.sh" "${1:-}" "${2:-}"
|
|
sh "$SCRIPT_DIR/mdedit/build.sh" "${1:-}" "${2:-}"
|
|
sh "$SCRIPT_DIR/landing/build.sh" "${1:-}" "${2:-}"
|
|
|
|
echo ""
|
|
echo "=== Assembling zddc/dist/web/ ==="
|
|
# Only landing and archive ship inside the server bundle: they call the
|
|
# server's JSON API (GET / for the project list, directory listings for the
|
|
# archive) and are useless without it. transmittal, classifier, and mdedit
|
|
# are pure client-side tools that work from file:// or any static host;
|
|
# they are released to website/ for download but not bundled with the server.
|
|
mkdir -p "$SCRIPT_DIR/zddc/dist/web"
|
|
cp "$SCRIPT_DIR/landing/dist/index.html" "$SCRIPT_DIR/zddc/dist/web/index.html"
|
|
cp "$SCRIPT_DIR/archive/dist/archive.html" "$SCRIPT_DIR/zddc/dist/web/archive.html"
|
|
echo "Wrote zddc/dist/web/index.html"
|
|
echo "Wrote zddc/dist/web/archive.html"
|
|
|
|
# Cross-compiled zddc-server binaries are built via podman if available
|
|
# (no-op otherwise — CI builds the runtime container directly via the
|
|
# Containerfile's builder stage and doesn't need host-side binaries).
|
|
echo ""
|
|
echo "=== Building zddc-server binaries ==="
|
|
if command -v podman >/dev/null 2>&1; then
|
|
podman build --target binaries -o "$SCRIPT_DIR/zddc/dist/" "$SCRIPT_DIR/zddc/" 2>&1 | grep -v "^-->"
|
|
else
|
|
echo "podman not found — skipping cross-compiled binary build."
|
|
echo " (CI builds the container image directly; this step only matters"
|
|
echo " for releasing the standalone Linux/macOS/Windows binaries.)"
|
|
fi
|
|
|
|
# ─── Bootstrap zips ──────────────────────────────────────────────────────────
|
|
# Generated from bootstrap/level{1,2}.html.tmpl on every build so they are
|
|
# always in sync with the current bootstrap pattern.
|
|
#
|
|
# install.zip — drop into deployment root for self-contained install.
|
|
# Contains the 5 current-stable HTMLs at root plus a
|
|
# _template/ directory with 4 level-1 stubs that
|
|
# projects can use as their starting layout.
|
|
# track-<channel>.zip — drop the level-2 stubs over deployment root to make
|
|
# the whole site track <channel> from zddc.varasys.io.
|
|
#
|
|
# install.zip needs at least one stable release to exist under
|
|
# website/releases/; if none exist yet, that zip is skipped with a warning.
|
|
|
|
WEBSITE_DIR="$SCRIPT_DIR/website"
|
|
RELEASES_DIR="$WEBSITE_DIR/releases"
|
|
BOOTSTRAP_DIR="$SCRIPT_DIR/bootstrap"
|
|
|
|
mkdir -p "$WEBSITE_DIR"
|
|
|
|
# tool|filename|title
|
|
TOOL_TABLE='archive|archive.html|Archive
|
|
transmittal|transmittal.html|Transmittal
|
|
classifier|classifier.html|Classifier
|
|
mdedit|mdedit.html|Markdown Editor
|
|
landing|index.html|ZDDC'
|
|
|
|
# Substitute {{TOOL}}, {{TOOL_TITLE}}, {{CHANNEL}} in a template.
|
|
# Substitute {{TOOL}}, {{TOOL_TITLE}}, {{CHANNEL}} in a template.
|
|
render_stub() {
|
|
sed \
|
|
-e "s|{{TOOL_TITLE}}|$3|g" \
|
|
-e "s|{{TOOL}}|$2|g" \
|
|
-e "s|{{CHANNEL}}|${4:-}|g" \
|
|
"$1" > "$5"
|
|
}
|
|
|
|
build_install_zip() {
|
|
# Verify a stable release exists for every tool before staging.
|
|
_missing=""
|
|
while IFS='|' read -r _tool _file _title; do
|
|
[ -e "$RELEASES_DIR/${_tool}_latest.html" ] || _missing="$_missing $_tool"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
if [ -n "$_missing" ]; then
|
|
echo "Skipping install.zip — no stable release for:$_missing"
|
|
return 0
|
|
fi
|
|
|
|
_staging=$(mktemp -d)
|
|
while IFS='|' read -r _tool _file _title; do
|
|
cp "$RELEASES_DIR/${_tool}_latest.html" "$_staging/$_file"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
# _template/ holds level-1 bootstraps for the four interactive tools
|
|
# (landing only lives at deployment root; project directories do not
|
|
# have their own landing page).
|
|
mkdir -p "$_staging/_template"
|
|
while IFS='|' read -r _tool _file _title; do
|
|
render_stub "$BOOTSTRAP_DIR/level1.html.tmpl" "$_tool" "$_title" "" "$_staging/_template/$_file"
|
|
done <<EOF
|
|
archive|archive.html|Archive
|
|
transmittal|transmittal.html|Transmittal
|
|
classifier|classifier.html|Classifier
|
|
mdedit|mdedit.html|Markdown Editor
|
|
EOF
|
|
|
|
cp "$BOOTSTRAP_DIR/README.md" "$_staging/README.md"
|
|
|
|
rm -f "$WEBSITE_DIR/install.zip"
|
|
(cd "$_staging" && zip -qr "$WEBSITE_DIR/install.zip" .)
|
|
echo "Wrote $WEBSITE_DIR/install.zip"
|
|
rm -rf "$_staging"
|
|
}
|
|
|
|
build_track_zip() {
|
|
_channel="$1"
|
|
_staging=$(mktemp -d)
|
|
while IFS='|' read -r _tool _file _title; do
|
|
render_stub "$BOOTSTRAP_DIR/level2.html.tmpl" "$_tool" "$_title" "$_channel" "$_staging/$_file"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
rm -f "$WEBSITE_DIR/track-$_channel.zip"
|
|
(cd "$_staging" && zip -qr "$WEBSITE_DIR/track-$_channel.zip" .)
|
|
echo "Wrote $WEBSITE_DIR/track-$_channel.zip"
|
|
rm -rf "$_staging"
|
|
}
|
|
|
|
echo ""
|
|
echo "=== Building install.zip and track-*.zip ==="
|
|
build_install_zip
|
|
build_track_zip alpha
|
|
build_track_zip beta
|
|
build_track_zip latest
|
|
|
|
echo ""
|
|
echo "=== All tools built successfully ==="
|
|
echo ""
|
|
echo "Server deployment package: zddc/dist/"
|
|
echo " Binaries: zddc-server-{linux,darwin,windows}-*"
|
|
echo " Web files: web/ (copy contents to ZDDC_ROOT)"
|
|
echo ""
|
|
echo "Bootstrap downloads: website/"
|
|
echo " install.zip — self-contained install for deployment root"
|
|
echo " track-alpha.zip — level-2 stubs that track the alpha channel"
|
|
echo " track-beta.zip — level-2 stubs that track the beta channel"
|
|
echo " track-latest.zip — level-2 stubs that track the latest stable"
|