Files
EpicNext-Cms/.gitea/workflows/pack.yaml
T

282 lines
14 KiB
YAML

name: Site Pack
on:
push:
branches:
- main
repository_dispatch:
types:
- build-pack
schedule:
# Poll all source repos every 15 minutes; rebuild only if a component changed.
- cron: "*/15 * * * *"
workflow_dispatch:
inputs:
force:
description: "Force rebuild even if nothing changed"
required: false
default: "false"
jobs:
pack:
runs-on: shell
env:
GITEA_API: https://gitlab.epicnabbo.nl/api/v1
GITEA_REPO: remco/EpicNext-Cms
TOKEN: ${{ secrets.GITEA_TOKEN }}
PACK_VERSION: pack-$(date +%Y%m%d-%H%M)
FORCE: ${{ github.event.inputs.force }}
CACHE_DIR: /var/tmp/pack-cache
steps:
- name: Check for upstream changes
id: check
run: |
set -e
exec 2>&1
CMS_REF="$(git -C /docker/gitea/gitea/git/repositories/remco/epicnext-cms.git rev-parse main 2>/dev/null \
|| git ls-remote https://gitlab.epicnabbo.nl/remco/EpicNext-Cms.git main 2>/dev/null | awk '{print $1}')"
CAT_REF="$(git ls-remote https://gitlab.epicnabbo.nl/remco/Epicnabbo-Catalogus-Updated-Daily.git Beta-3 2>/dev/null | awk '{print $1}')"
NITRO_REF="$(git ls-remote https://github.com/duckietm/Nitro-V3.git main 2>/dev/null | awk '{print $1}')"
RENDER_REF="$(git ls-remote https://github.com/duckietm/Nitro_Render_V3.git main 2>/dev/null | awk '{print $1}')"
EMU_REF="$(git ls-remote https://github.com/duckietm/Polaris-Emulator.git main 2>/dev/null | awk '{print $1}')"
COMBINED="${CMS_REF}:${CAT_REF}:${NITRO_REF}:${RENDER_REF}:${EMU_REF}"
echo "Current refs: $COMBINED"
STATE="$CACHE_DIR/refs.state"
mkdir -p "$CACHE_DIR"
PREV="$(cat "$STATE" 2>/dev/null || echo "")"
CHANGED=""
if [ "${FORCE:-false}" = "true" ]; then
CHANGED="force"
elif [ "$COMBINED" != "$PREV" ]; then
CHANGED="upstream"
fi
if [ -n "$CHANGED" ]; then
echo "Change detected ($CHANGED)"
echo "changed=true" >> "$GITHUB_OUTPUT"
else
echo "No upstream changes since last pack"
echo "changed=false" >> "$GITHUB_OUTPUT"
fi
echo "$COMBINED" > "$STATE"
# Expose individual refs so later steps can compare per-component.
echo "cms_ref=$CMS_REF" >> "$GITHUB_OUTPUT"
echo "cat_ref=$CAT_REF" >> "$GITHUB_OUTPUT"
echo "nitro_ref=$NITRO_REF" >> "$GITHUB_OUTPUT"
echo "render_ref=$RENDER_REF" >> "$GITHUB_OUTPUT"
echo "emu_ref=$EMU_REF" >> "$GITHUB_OUTPUT"
- name: Skip if unchanged
if: steps.check.outputs.changed != 'true'
run: |
echo "Nothing to rebuild. Exiting."
exit 0
- name: Setup
if: steps.check.outputs.changed == 'true'
run: |
set -e
exec 2>&1
echo "=== Building site pack ${PACK_VERSION} ==="
WORK="/tmp/pack-build"
rm -rf "$WORK" && mkdir -p "$WORK/src" "$WORK/out" "$CACHE_DIR"
echo "WORK=$WORK" >> "$GITHUB_ENV"
# ---- Per-component: pull only if ref changed, reuse cached build otherwise ----
- name: CMS (this repo)
if: steps.check.outputs.changed == 'true'
run: |
set -e
S="$CACHE_DIR/cms"; mkdir -p "$S"
BARE="/docker/gitea/gitea/git/repositories/remco/epicnext-cms.git"
if [ "${{ steps.check.outputs.cms_ref }}" != "$(cat "$S/ref" 2>/dev/null)" ]; then
rm -rf "$WORK/src/cms"
git clone --depth 1 "file://$BARE" "$WORK/src/cms" 2>/dev/null \
|| git clone --depth 1 "${{ gitea.server_url }}/${{ gitea.repository }}.git" "$WORK/src/cms" 2>/dev/null \
|| git -C "$WORK/src/cms" pull --ff-only 2>/dev/null
echo "${{ steps.check.outputs.cms_ref }}" > "$S/ref"
rm -rf "$S/snapshot"; cp -r "$WORK/src/cms" "$S/snapshot"
else
cp -r "$S/snapshot" "$WORK/src/cms"
echo "CMS unchanged — reused cache"
fi
echo "cms: $(git -C "$WORK/src/cms" rev-parse --short HEAD 2>/dev/null)" | tee -a "$WORK/components.txt"
- name: Catalogus (sparse)
if: steps.check.outputs.changed == 'true'
run: |
set -e
S="$CACHE_DIR/catalogus"; mkdir -p "$S"
if [ "${{ steps.check.outputs.cat_ref }}" != "$(cat "$S/ref" 2>/dev/null)" ]; then
rm -rf "$WORK/src/catalogus"
for attempt in 1 2 3; do
if git clone --depth 1 --filter=blob:none --sparse \
https://gitlab.epicnabbo.nl/remco/Epicnabbo-Catalogus-Updated-Daily.git "$WORK/src/catalogus" 2>/dev/null; then
break
fi
echo "Catalogus clone attempt $attempt failed, retrying..." >&2
sleep 5
done
git -C "$WORK/src/catalogus" sparse-checkout set . 2>/dev/null || true
echo "${{ steps.check.outputs.cat_ref }}" > "$S/ref"
rm -rf "$S/snapshot"; cp -r "$WORK/src/catalogus" "$S/snapshot"
else
cp -r "$S/snapshot" "$WORK/src/catalogus"
echo "Catalogus unchanged — reused cache"
fi
echo "catalogus: $(git -C "$WORK/src/catalogus" rev-parse --short HEAD 2>/dev/null)" | tee -a "$WORK/components.txt"
- name: Nitro-Render-V3
if: steps.check.outputs.changed == 'true'
run: |
set -e
S="$CACHE_DIR/render"; mkdir -p "$S"
# Nitro-V3's vite.config expects the renderer at ../Nitro_Render_V3
RENDER_DIR="$WORK/src/Nitro_Render_V3"
if [ "${{ steps.check.outputs.render_ref }}" != "$(cat "$S/ref" 2>/dev/null)" ]; then
rm -rf "$RENDER_DIR"
for attempt in 1 2 3; do
if git clone --depth 1 https://github.com/duckietm/Nitro_Render_V3.git "$RENDER_DIR" 2>/dev/null; then
break
fi
echo "Render clone attempt $attempt failed, retrying..." >&2
sleep 5
done
[ -f "$RENDER_DIR/package.json" ] || { echo "Render clone failed"; exit 1; }
cd "$RENDER_DIR"
yarn install --frozen-lockfile --prefer-offline 2>&1 || yarn install 2>&1
rm -rf "$S/files"; mkdir -p "$S/files"; cp -r . "$S/files/" 2>/dev/null || true
rm -rf "$S/files/node_modules"
echo "${{ steps.check.outputs.render_ref }}" > "$S/ref"
else
echo "Render unchanged — reused cache"
rm -rf "$RENDER_DIR"; mkdir -p "$RENDER_DIR"; cp -r "$S/files/"* "$RENDER_DIR/" 2>/dev/null || true
fi
mkdir -p "$WORK/out/render"; cp -r "$S/files/"* "$WORK/out/render/" 2>/dev/null || true
echo "render: $(git -C "$RENDER_DIR" rev-parse --short HEAD 2>/dev/null || echo cached)" | tee -a "$WORK/components.txt"
- name: Nitro-V3
if: steps.check.outputs.changed == 'true'
run: |
set -e
S="$CACHE_DIR/nitro"; mkdir -p "$S"
if [ "${{ steps.check.outputs.nitro_ref }}" != "$(cat "$S/ref" 2>/dev/null)" ]; then
rm -rf "$WORK/src/nitro"
for attempt in 1 2 3; do
if git clone --depth 1 https://github.com/duckietm/Nitro-V3.git "$WORK/src/nitro" 2>/dev/null; then
break
fi
echo "Nitro clone attempt $attempt failed, retrying..." >&2
sleep 5
done
[ -f "$WORK/src/nitro/package.json" ] || { echo "Nitro clone failed"; exit 1; }
cd "$WORK/src/nitro"
yarn install --frozen-lockfile --prefer-offline 2>&1 || yarn install 2>&1
yarn build
rm -rf "$S/dist"; mkdir -p "$S/dist"; cp -r dist/* "$S/dist/" 2>/dev/null || true
echo "${{ steps.check.outputs.nitro_ref }}" > "$S/ref"
else
echo "Nitro unchanged — reused cached dist"
fi
mkdir -p "$WORK/out/nitro"; cp -r "$S/dist/"* "$WORK/out/nitro/" 2>/dev/null || true
echo "nitro: $(git -C "$WORK/src/nitro" rev-parse --short HEAD 2>/dev/null || echo cached)" | tee -a "$WORK/components.txt"
- name: Polaris Emulator
if: steps.check.outputs.changed == 'true'
run: |
set -e
S="$CACHE_DIR/emulator"; mkdir -p "$S"
if [ "${{ steps.check.outputs.emu_ref }}" != "$(cat "$S/ref" 2>/dev/null)" ]; then
rm -rf "$WORK/src/emulator"
for attempt in 1 2 3; do
if git clone --depth 1 https://github.com/duckietm/Polaris-Emulator.git "$WORK/src/emulator" 2>/dev/null; then
break
fi
echo "Emulator clone attempt $attempt failed, retrying..." >&2
sleep 5
done
[ -f "$WORK/src/emulator/Emulator/pom.xml" ] || { echo "Emulator clone failed (no pom.xml)"; exit 1; }
cd "$WORK/src/emulator/Emulator"
mvn package -q -T 1C -o -Dmaven.test.skip=true 2>&1 \
|| mvn package -q -T 1C -Dmaven.test.skip=true 2>&1
rm -f "$S"/*.jar; find target -maxdepth 1 -name 'Polaris-*-jar-with-dependencies.jar' -exec cp {} "$S/" \; 2>/dev/null || true
echo "${{ steps.check.outputs.emu_ref }}" > "$S/ref"
else
echo "Emulator unchanged — reused cached jar"
fi
mkdir -p "$WORK/out/emulator"; cp "$S"/*.jar "$WORK/out/emulator/" 2>/dev/null || true
echo "emulator: $(git -C "$WORK/src/emulator" rev-parse --short HEAD 2>/dev/null || echo cached)" | tee -a "$WORK/components.txt"
- name: Assemble Pack
if: steps.check.outputs.changed == 'true'
run: |
set -e
cd "$WORK/out"
cp -r "$WORK/src/cms" "$WORK/out/cms" 2>/dev/null || true
rm -rf "$WORK/out/cms/.git" "$WORK/out/cms/node_modules" 2>/dev/null || true
cp -r "$WORK/src/catalogus" "$WORK/out/catalogus" 2>/dev/null || true
rm -rf "$WORK/out/catalogus/.git" 2>/dev/null || true
cp "$WORK/components.txt" "$WORK/out/COMPONENTS.txt"
echo "Built at $(date -u)" > "$WORK/out/BUILD_INFO.txt"
cat "$WORK/components.txt" >> "$WORK/out/BUILD_INFO.txt"
PACK_FILE="/tmp/${PACK_VERSION}.tar.gz"
tar -czf "$PACK_FILE" -C "$WORK/out" .
echo "PACK_FILE=$PACK_FILE" >> "$GITHUB_ENV"
echo "Pack created: $(du -h "$PACK_FILE" | cut -f1)"
- name: Build Changelog
if: steps.check.outputs.changed == 'true'
run: |
set -e
BARE="/docker/gitea/gitea/git/repositories/remco/epicnext-cms.git"
PREV="$(git -C "$BARE" tag --list 'pack-*' --sort=-creatordate | head -1 || echo '')"
PREV_NOTE="${PREV:-initial}"
{
echo "## Site Pack ${PACK_VERSION}"
echo ""
echo "### Component versions"
echo '```'
cat "$WORK/components.txt"
echo '```'
echo ""
echo "### Changes since pack ${PREV_NOTE}"
for pair in "cms:$WORK/src/cms" "catalogus:$WORK/src/catalogus" "nitro:$WORK/src/nitro" "render:$WORK/src/Nitro_Render_V3" "emulator:$WORK/src/emulator"; do
label="${pair%%:*}"; repo="${pair##*:}"
echo "**${label}**"
echo '```'
git -C "$repo" log --oneline --no-decorate -10 2>/dev/null || echo "n/a"
echo '```'
done
} > /tmp/pack-body.md
cat /tmp/pack-body.md
- name: Create Release + Upload Pack
if: steps.check.outputs.changed == 'true'
run: |
set -e
: "${PACK_FILE:?PACK_FILE not set}"
: "${GITEA_API:?GITEA_API not set}"
: "${GITEA_REPO:?GITEA_REPO not set}"
T="${TOKEN:-${GITEA_TOKEN}}"
[ -n "$T" ] || { echo "No token available"; exit 1; }
BODY="$(jq -Rs '.' < /tmp/pack-body.md)"
PAYLOAD="$(jq -n --arg tag "${PACK_VERSION}" --arg name "${PACK_VERSION}" --arg body "$BODY" '{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}')"
echo "Creating release via ${GITEA_API}/repos/${GITEA_REPO}/releases"
HTTP="$(curl -s -w '%{http_code}' -o /tmp/pack-rel.json \
-X POST "${GITEA_API}/repos/${GITEA_REPO}/releases" \
-H "Authorization: token ${T}" -H "Content-Type: application/json" -d "$PAYLOAD" || echo 000)"
echo "Create release HTTP: ${HTTP}"
cat /tmp/pack-rel.json | head -c 500; echo
if [ "${HTTP}" = "409" ]; then
REL_ID="$(curl -sf "${GITEA_API}/repos/${GITEA_REPO}/releases" -H "Authorization: token ${T}" | jq -r ".[] | select(.tag_name==\"${PACK_VERSION}\") | .id" || true)"
HTTP="$(curl -s -w '%{http_code}' -o /tmp/pack-rel.json -X PATCH "${GITEA_API}/repos/${GITEA_REPO}/releases/${REL_ID}" -H "Authorization: token ${T}" -H "Content-Type: application/json" -d "$PAYLOAD" || echo 000)"
echo "Patch release HTTP: ${HTTP}"
fi
REL_ID="$(jq -r '.id' /tmp/pack-rel.json 2>/dev/null || echo "")"
[ -n "$REL_ID" ] || { echo "No release ID from response"; exit 1; }
echo "Uploading asset to release ${REL_ID}"
UP="$(curl -s -w '%{http_code}' -o /tmp/pack-asset.json \
-X POST "${GITEA_API}/repos/${GITEA_REPO}/releases/${REL_ID}/assets?name=${PACK_VERSION}.tar.gz" \
-H "Authorization: token ${T}" -H "Content-Type: application/gzip" --data-binary @"${PACK_FILE}" || echo 000)"
echo "Asset upload HTTP: ${UP}"
cat /tmp/pack-asset.json | head -c 300; echo
echo "Release ${PACK_VERSION} created with pack asset"