Simple conetent + restyled

This commit is contained in:
2026-09-21 17:59:29 +02:00
parent 0772462742
commit 467bf77d34
55 changed files with 2162 additions and 2070 deletions
+36 -3
View File
@@ -29,6 +29,37 @@ missing). Everything else runs inside containers.
| 3000 | Gitea | https://astro-git.isl-dev.grid.cyfronet.pl (ingress vhost) |
| 8080 | portal (nginx, static) | https://astro.isl-dev.grid.cyfronet.pl (ingress vhost) |
## Switch an existing demo to `simple`
1. In a checkout of `ctao/content`, create a `simple` branch from the existing
content branch. Copy `sample-content/pages/*.md` and
`sample-content/uploads/hero.jpg` from this code repository into its root
`pages/` and `uploads/` directories, then commit the seed files. Existing
news or other page files can remain in the content history; this portal
loads only the four Example files.
2. Push the content branch to Gitea as `ctao/content:simple`, and the code
branch as `ctao/portal:simple`. These are separate pushes; Bitbucket is
not the deployment remote.
3. Copy the updated `build.sh` to `~/ctao-portal-demo/bin/build.sh` and the
updated `ctao-portal-build.service` to `~/.config/systemd/user/`. Reload
systemd with `systemctl --user daemon-reload`. The service explicitly sets
`CODE_BRANCH=simple` and `CONTENT_BRANCH=simple`; the script defaults agree.
4. Start the build service or let its timer run. It overlays `pages/` and
`uploads/`, clears the previous news overlay, and runs `npm run check`
before the atomic release switch. Missing Example pages fail the build.
5. Verify the four `/example/…/` pages and empty `/news/`. Sign in at `/admin/`,
save an Example title, and check that a commit appears on
`ctao/content:simple` and the rebuilt page reflects it.
The OAuth client and public portal origin stay the same. Sveltia's
`backend.branch` in `public/admin/config.yml` must always match
`CONTENT_BRANCH`. Branches are selected independently; a single `BRANCH`
environment variable is no longer used. For a separate preview hostname,
update the site origin, OAuth redirect, and Gitea CORS together.
To roll back, restore the previous deployed release and the previous worker
script/service configuration. The original content `main` branch is retained.
## Install (each step reviewed before running; [W] = writes to the machine)
1. **[W]** `loginctl enable-linger $USER`. Without lingering every user unit
@@ -53,10 +84,12 @@ missing). Everything else runs inside containers.
password never lands in a file or shell history:
`podman exec -it ctao-demo-gitea gitea admin user create --admin --username <you> --email <you@…> --random-password`
7. **[W]** In the Gitea UI: create org `ctao` with repos `portal` and
`content` (both public read). Then, from your workstation, push both over
`content` (both public read). Seed the content `simple` branch with
`sample-content/pages/` and `sample-content/uploads/` as described above.
Then, from your workstation, push both over
the vhost with a repo-scoped token:
`git push https://<user>:<token>@astro-git.isl-dev.grid.cyfronet.pl/ctao/portal.git main`
`git push https://<user>:<token>@astro-git.isl-dev.grid.cyfronet.pl/ctao/content.git main`
`git push https://<user>:<token>@astro-git.isl-dev.grid.cyfronet.pl/ctao/portal.git simple`
`git push https://<user>:<token>@astro-git.isl-dev.grid.cyfronet.pl/ctao/content.git simple`
8. **[W]** `systemctl --user enable --now ctao-portal-build.timer`. The first run
clones + `npm ci` + builds (minutes); later runs are seconds. Wait until
`journalctl --user -u ctao-portal-build -n 5` shows `published <sha>`
+17 -15
View File
@@ -7,7 +7,7 @@
#
# Two repositories by design: code (templates/CSS, developed by the team) and
# content (Markdown + uploads, committed by the CMS). The build overlays
# content onto code, so an editor publishing an article and a developer
# content onto code, so an editor publishing a page and a developer
# shipping CSS never mix histories — either change republishes the site.
set -euo pipefail
@@ -17,7 +17,8 @@ BASE="${BASE:-$HOME/ctao-portal-demo}"
GITEA_URL="${GITEA_URL:-http://localhost:3000}" # published by ctao-demo-gitea
CODE_REPO="${CODE_REPO:-ctao/portal}" # owner/repo in Gitea
CONTENT_REPO="${CONTENT_REPO:-ctao/content}"
BRANCH="${BRANCH:-main}"
CODE_BRANCH="${CODE_BRANCH:-simple}"
CONTENT_BRANCH="${CONTENT_BRANCH:-simple}"
BUILD_IMAGE="${BUILD_IMAGE:-localhost/ctao-portal-build:1}"
# The build joins the Gitea container's network namespace: localhost inside
# the build = Gitea's loopback (port 3000), host loopback stays unreachable.
@@ -37,16 +38,16 @@ done
# --- 1. Cheap poll: both branch heads via the local Gitea API ---
head_of() {
curl -fsS --max-time 5 "$GITEA_URL/api/v1/repos/$1/branches/$BRANCH" \
curl -fsS --max-time 5 "$GITEA_URL/api/v1/repos/$1/branches/$2" \
| jq -r '.commit.id' || true
}
code_sha=$(head_of "$CODE_REPO")
content_sha=$(head_of "$CONTENT_REPO")
code_sha=$(head_of "$CODE_REPO" "$CODE_BRANCH")
content_sha=$(head_of "$CONTENT_REPO" "$CONTENT_BRANCH")
# Gitea down/unreachable is a transient, not a unit failure — exit 0 quietly
# instead of painting the journal red every 10 s. Name the repo: a 404 here
# also means "repo/branch missing or renamed", not just "Gitea down".
[[ "$code_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CODE_REPO@$BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
[[ "$content_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CONTENT_REPO@$BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
[[ "$code_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CODE_REPO@$CODE_BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
[[ "$content_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CONTENT_REPO@$CONTENT_BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
release="${code_sha:0:12}-${content_sha:0:12}" # code+content pin the release
# Skip only if this pair is both recorded AND still present in releases/
# (a deleted release dir must trigger a rebuild, not an eternal skip).
@@ -73,7 +74,7 @@ podman run --rm --network="$BUILD_NETNS" --memory=1g \
-e ASTRO_TELEMETRY_DISABLED=1 \
-e CODE_SHA="$code_sha" -e CODE_URL="$CODE_URL" \
-e CONTENT_SHA="$content_sha" -e CONTENT_URL="$CONTENT_URL" \
-e RELEASE="$release" -e BRANCH="$BRANCH" \
-e RELEASE="$release" -e CODE_BRANCH="$CODE_BRANCH" -e CONTENT_BRANCH="$CONTENT_BRANCH" \
-v "$BASE/repo:/work/repo:z" \
-v "$BASE/content:/work/content:z" \
-v "$BASE/releases:/work/releases:z" \
@@ -81,21 +82,20 @@ podman run --rm --network="$BUILD_NETNS" --memory=1g \
-w /work "$BUILD_IMAGE" sh -ec '
git config --global safe.directory "/work/repo"
git config --global --add safe.directory "/work/content"
sync_clone() { # $1 dir $2 url $3 sha
[ -d "$1/.git" ] || git clone --branch "$BRANCH" "$2" "$1"
sync_clone() { # $1 dir $2 url $3 sha $4 branch
[ -d "$1/.git" ] || git clone --branch "$4" "$2" "$1"
git -C "$1" remote set-url origin "$2" # self-heal if the URL changes
git -C "$1" fetch --quiet origin "$BRANCH"
git -C "$1" fetch --quiet origin "$4"
# --force: the working copy is disposable; a stray tracked-file edit
# must not wedge every future build.
git -C "$1" checkout --quiet --force "$3"
}
sync_clone repo "$CODE_URL" "$CODE_SHA"
sync_clone content "$CONTENT_URL" "$CONTENT_SHA"
sync_clone repo "$CODE_URL" "$CODE_SHA" "$CODE_BRANCH"
sync_clone content "$CONTENT_URL" "$CONTENT_SHA" "$CONTENT_BRANCH"
# Overlay content onto code (these paths are gitignored in the code repo).
# mkdir -p: checkout prunes the emptied parent dirs, cp needs them back.
rm -rf repo/src/content/news repo/src/content/pages repo/public/uploads
mkdir -p repo/src/content repo/public
cp -a content/news repo/src/content/news
cp -a content/pages repo/src/content/pages
cp -a content/uploads repo/public/uploads
cd repo
@@ -109,7 +109,9 @@ podman run --rm --network="$BUILD_NETNS" --memory=1g \
npm ci --ignore-scripts --no-audit --no-fund
echo "$lock" > .deps-hash
fi
npm run build
# Validate the overlay and links before publishing; never seed demo content
# in place of an incomplete content branch.
npm run check
rm -rf "../releases/$RELEASE"
cp -a dist "../releases/$RELEASE"
' || { echo "$release" > "$BASE/state/last-failed"; echo "BUILD FAILED for $release (see above) — will not retry until a new commit"; exit 1; }
+2
View File
@@ -8,6 +8,8 @@ Description=CTAO portal demo — rebuild if the code or content repo has new com
[Service]
Type=oneshot
Environment=CODE_BRANCH=simple
Environment=CONTENT_BRANCH=simple
ExecStart=%h/ctao-portal-demo/bin/build.sh
# Polite neighbour on the shared VM:
Nice=10