refactor: HTML tools live in website/releases/ as static files + symlink hierarchy
Rolls back the HTML-tool side of the Codeberg-as-canonical refactor (commits2dc9ad2,b28c4ae,bdac8dc) in favor of a simpler model: per-version HTML files committed under website/releases/ as immutable real files; partial-version pins (<tool>_v<X.Y>.html, <tool>_v<X>.html) and channel mirrors (<tool>_<channel>.html) are checked-in symlinks. Docker-tag pattern: :1.2.3 is pinned, :1.2 floats, :1 floats further, :stable floats furthest. URL scheme — every URL resolves to actual HTML via the symlink chain; no JS indirection, no manifest.json, no Caddy regex-rewrite: /releases/<tool>_v<X.Y.Z>.html exact version (real file) /releases/<tool>_v<X.Y>.html latest patch within X.Y.* (symlink) /releases/<tool>_v<X>.html latest within X.*.* (symlink) /releases/<tool>_stable.html current stable (symlink) /releases/<tool>_beta.html current beta (symlink to stable when no active beta; real file when beta is in flight) /releases/<tool>_alpha.html current alpha (similar — symlink to beta or stable when no active alpha) Cascade rule (in shared/build-lib.sh promote_release): --release [version] (stable cut) → write per-version file; refresh 5 symlinks (_v<X.Y>, _v<X>, _stable, _beta, _alpha) → new versioned file; tag <tool>-v<X.Y.Z>. --release beta → overwrite <tool>_beta.html with real bytes; cascade _alpha.html → _beta.html (symlink). No tag — channel URLs are stable URLs by design; counters defeat that. --release alpha → overwrite <tool>_alpha.html with real bytes. No tag, no other side-effects. Plain `sh tool/build.sh` → dist/ only. No website/releases/ side-effect, no commit. Code changes: - .gitignore — drop website/releases/*.html and website/releases/zddc-server-* exclusions; HTML tool files are tracked again. Replace the comment with the new model description. - shared/build-lib.sh — drop next_prerelease (no -alpha.N / -beta.N counter tags). Drop the Codeberg-upload path for HTML tools (no longer sourcing publish-codeberg-release.sh from build-lib). promote_release rewritten with two helpers: _promote_stable (per-version file + 5 symlinks + tag) and _promote_channel (overwrite mirror + cascade alpha→beta on beta cut). - zddc/release.sh — drop alpha/beta channel path entirely; binaries publish only on stable cuts. zddc-server's beta/alpha builds-from-source via the helm charts (next phase) — no binary distribution needed for those channels. - bootstrap/level2.html.tmpl — drop manifest.json fetch; resolve ?v= to a static URL via the symlink chain. New suffixFor() handles channel names, exact versions, and partial-version pins (?v=0.0, ?v=0). Same logic in level1.html.tmpl already works because the local-staging files (e.g. ../<tool>_v0.0.html) exist via the same symlink scheme. - build.sh build_releases_index — revert to filesystem scan of website/releases/ instead of Codeberg API call. Drop manifest.json generation. Per-tool sections list channel chips + per-version pin links; zddc-server section links to Codeberg release pages directly. - tests/build-label.spec.js — fix the channel-label regex to match the pre-release-semver format introduced in commit9459139("v0.0.3-alpha · ..."). Pre-existing test failure that wasn't caught at the time. Storage: - 30 new committed files under website/releases/ — 10 real (per-version) + 20 symlinks (5 tools × 4 partial/channel variants, plus alpha as a real file by default). - Initial state: stable v0.0.2 across all 5 tools; alpha/beta/v0.0/v0 symlinks all point at <tool>_v0.0.2.html. - manifest.json deleted (no longer needed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bdac8dc4fb
commit
408a1a0571
58 changed files with 65802 additions and 864 deletions
19
.gitignore
vendored
19
.gitignore
vendored
|
|
@ -20,15 +20,16 @@ test-results/
|
||||||
# New tool dist files must be force-added: git add -f tool/dist/tool.html
|
# New tool dist files must be force-added: git add -f tool/dist/tool.html
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
# Release artifacts — published to Codeberg release assets, not committed.
|
# Release artifacts under website/releases/ ARE committed — per-version HTML
|
||||||
# website/releases/index.html and website/releases/manifest.json are
|
# tool files (<tool>_v<X.Y.Z>.html) accumulate as immutable real files; partial
|
||||||
# regenerated by build.sh and DO get committed (they're tiny indices).
|
# version pins (<tool>_v<X.Y>.html, <tool>_v<X>.html) and channels
|
||||||
# Everything else under website/releases/ — versioned HTML tool files,
|
# (<tool>_<channel>.html) are checked-in symlinks. The build script
|
||||||
# zddc-server binaries — lives on Codeberg; the website's Caddy reverse-
|
# (shared/build-lib.sh promote_release) maintains the symlink chain on each
|
||||||
# proxies download URLs to Codeberg release-asset URLs.
|
# release. Caddy serves these as plain static files; no manifest, no proxy.
|
||||||
website/releases/*.html
|
#
|
||||||
!website/releases/index.html
|
# zddc-server binaries are NOT committed — they're per-platform multi-MB
|
||||||
website/releases/zddc-server-*
|
# binaries that ship as Codeberg release assets, attached to clean
|
||||||
|
# zddc-server-vX.Y.Z tags by zddc/release.sh.
|
||||||
|
|
||||||
# IDE and project files
|
# IDE and project files
|
||||||
.opencode/
|
.opencode/
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// {{CHANNEL}} channel; the URL parameter ?v= overrides it:
|
// {{CHANNEL}} channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the {{CHANNEL}} default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the {{CHANNEL}} default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = '{{TOOL}}';
|
const tool = '{{TOOL}}';
|
||||||
const defaultChannel = '{{CHANNEL}}';
|
const defaultChannel = '{{CHANNEL}}';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
172
build.sh
172
build.sh
|
|
@ -124,71 +124,20 @@ EOF
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Regenerate website/releases/index.html and manifest.json from the
|
# Regenerate website/releases/index.html from a filesystem scan of
|
||||||
# Codeberg release list. Single API call at build time, no runtime
|
# website/releases/. Lists per-version files (real .html files, immutable
|
||||||
# dependency on Codeberg from the page (it's static HTML when served).
|
# archives) plus channel mirrors and partial-version pins (symlinks).
|
||||||
#
|
#
|
||||||
# Page links use /releases/<tag>/<asset> URLs which the website's Caddy
|
# All URLs in the page resolve directly under <upstream>/releases/<file>
|
||||||
# reverse-proxies to codeberg.org/.../releases/download/<tag>/<asset>.
|
# — no Codeberg API call, no manifest, no proxy magic. Page is static
|
||||||
# Operators see one origin (zddc.varasys.io); Codeberg is the storage
|
# and current as of the last `sh build.sh` run.
|
||||||
# backend.
|
|
||||||
#
|
#
|
||||||
# Skips silently if curl/jq aren't on PATH (offline dev shouldn't blow
|
# zddc-server's section links to its Codeberg release pages directly
|
||||||
# up). Skips with a warning if the API call fails (network down, rate-
|
# (different distribution model — per-platform binaries).
|
||||||
# limited, etc.) — the existing index.html stays as-is.
|
|
||||||
build_releases_index() {
|
build_releases_index() {
|
||||||
_out="$RELEASES_DIR/index.html"
|
_out="$RELEASES_DIR/index.html"
|
||||||
_manifest="$RELEASES_DIR/manifest.json"
|
|
||||||
mkdir -p "$RELEASES_DIR"
|
mkdir -p "$RELEASES_DIR"
|
||||||
|
|
||||||
if ! command -v curl >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then
|
|
||||||
echo " (curl or jq missing — skipping releases index regeneration)"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
_api_resp=$(curl -fsSL --max-time 30 \
|
|
||||||
'https://codeberg.org/api/v1/repos/VARASYS/ZDDC/releases?limit=100' \
|
|
||||||
2>/dev/null) || _api_resp=""
|
|
||||||
|
|
||||||
if [ -z "$_api_resp" ]; then
|
|
||||||
echo " (Codeberg API unreachable — leaving releases/index.html as-is)"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build manifest.json: for each tool/channel, find the latest matching
|
|
||||||
# release and emit "<tool>-<channel>": "<tag>". Channel resolution:
|
|
||||||
# alpha = latest tag matching <tool>-vX.Y.Z-alpha.N
|
|
||||||
# beta = latest tag matching <tool>-vX.Y.Z-beta.N
|
|
||||||
# stable = latest tag matching <tool>-vX.Y.Z (no suffix)
|
|
||||||
# "Latest" via sort -V on the version part.
|
|
||||||
_tools="archive transmittal classifier mdedit landing zddc-server"
|
|
||||||
{
|
|
||||||
printf '{\n'
|
|
||||||
_first=1
|
|
||||||
for _tool in $_tools; do
|
|
||||||
for _ch in stable beta alpha; do
|
|
||||||
if [ "$_ch" = "stable" ]; then
|
|
||||||
_re="^${_tool}-v[0-9]+\\.[0-9]+\\.[0-9]+\$"
|
|
||||||
else
|
|
||||||
_re="^${_tool}-v[0-9]+\\.[0-9]+\\.[0-9]+-${_ch}\\.[0-9]+\$"
|
|
||||||
fi
|
|
||||||
_tag=$(printf '%s' "$_api_resp" \
|
|
||||||
| jq -r --arg re "$_re" '
|
|
||||||
[.[] | select(.tag_name | test($re)) | .tag_name]
|
|
||||||
| sort
|
|
||||||
| last // empty
|
|
||||||
')
|
|
||||||
if [ -n "$_tag" ]; then
|
|
||||||
[ "$_first" = "1" ] || printf ',\n'
|
|
||||||
printf ' "%s-%s": "%s"' "$_tool" "$_ch" "$_tag"
|
|
||||||
_first=0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
printf '\n}\n'
|
|
||||||
} > "$_manifest"
|
|
||||||
echo "Wrote $_manifest"
|
|
||||||
|
|
||||||
{
|
{
|
||||||
cat <<'HEAD'
|
cat <<'HEAD'
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
@ -252,109 +201,66 @@ build_releases_index() {
|
||||||
|
|
||||||
<main class="container" style="margin-bottom: var(--spacing-2xl);">
|
<main class="container" style="margin-bottom: var(--spacing-2xl);">
|
||||||
HEAD
|
HEAD
|
||||||
# Render one section per tool. The HTML tool releases publish a
|
# Render one section per HTML tool, scanning website/releases/ for
|
||||||
# single asset per tag (the inlined HTML); zddc-server publishes
|
# <tool>_v*.html real files (per-version archives) and resolving the
|
||||||
# per-platform binaries. The renderer handles both.
|
# current channel symlinks.
|
||||||
for _tool_entry in 'archive|Archive' \
|
for _tool_entry in 'archive|Archive' \
|
||||||
'transmittal|Transmittal' \
|
'transmittal|Transmittal' \
|
||||||
'classifier|Classifier' \
|
'classifier|Classifier' \
|
||||||
'mdedit|Markdown Editor' \
|
'mdedit|Markdown Editor' \
|
||||||
'landing|Landing (project picker)' \
|
'landing|Landing (project picker)'; do
|
||||||
'zddc-server|zddc-server (Go file server)'; do
|
|
||||||
_tool="${_tool_entry%%|*}"
|
_tool="${_tool_entry%%|*}"
|
||||||
_title="${_tool_entry#*|}"
|
_title="${_tool_entry#*|}"
|
||||||
_re_stable="^${_tool}-v[0-9]+\\.[0-9]+\\.[0-9]+\$"
|
|
||||||
_re_alpha="^${_tool}-v[0-9]+\\.[0-9]+\\.[0-9]+-alpha\\.[0-9]+\$"
|
|
||||||
_re_beta="^${_tool}-v[0-9]+\\.[0-9]+\\.[0-9]+-beta\\.[0-9]+\$"
|
|
||||||
|
|
||||||
_latest_stable=$(printf '%s' "$_api_resp" | jq -r --arg re "$_re_stable" \
|
# All per-version real files for this tool, semver-descending.
|
||||||
'[.[] | select(.tag_name | test($re)) | .tag_name] | sort | last // empty')
|
# Use find to filter out symlinks; grep + sort -Vr for ordering.
|
||||||
_latest_beta=$(printf '%s' "$_api_resp" | jq -r --arg re "$_re_beta" \
|
_versioned=$(find "$RELEASES_DIR" -maxdepth 1 -type f -name "${_tool}_v*.html" 2>/dev/null \
|
||||||
'[.[] | select(.tag_name | test($re)) | .tag_name] | sort | last // empty')
|
| sed "s|^${RELEASES_DIR}/||" \
|
||||||
_latest_alpha=$(printf '%s' "$_api_resp" | jq -r --arg re "$_re_alpha" \
|
| sort -Vr)
|
||||||
'[.[] | select(.tag_name | test($re)) | .tag_name] | sort | last // empty')
|
|
||||||
_all_stables=$(printf '%s' "$_api_resp" | jq -r --arg re "$_re_stable" \
|
|
||||||
'[.[] | select(.tag_name | test($re)) | .tag_name] | sort | reverse | .[]')
|
|
||||||
|
|
||||||
# Skip the section entirely if no releases exist for this tool.
|
if [ -z "$_versioned" ]; then
|
||||||
if [ -z "$_latest_stable$_latest_beta$_latest_alpha" ]; then
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf ' <section class="rel-tool">\n'
|
printf ' <section class="rel-tool">\n'
|
||||||
printf ' <h2>%s</h2>\n' "$_title"
|
printf ' <h2>%s</h2>\n' "$_title"
|
||||||
|
|
||||||
# Channel chips. Each link uses /releases/<tag>/<asset>
|
# Channel chips — only render if the symlink exists.
|
||||||
# which Caddy proxies to the Codeberg release-asset URL.
|
|
||||||
# Asset name is <tool>_v<version>.html for HTML tools; for
|
|
||||||
# zddc-server we link to the Codeberg release page since
|
|
||||||
# the asset is per-platform (operator picks one).
|
|
||||||
printf ' <div class="rel-channels">\n'
|
printf ' <div class="rel-channels">\n'
|
||||||
for _row in "stable|$_latest_stable" "beta|$_latest_beta" "alpha|$_latest_alpha"; do
|
for _ch in stable beta alpha; do
|
||||||
_ch="${_row%%|*}"
|
_link="${_tool}_${_ch}.html"
|
||||||
_tag="${_row#*|}"
|
if [ -e "$RELEASES_DIR/$_link" ]; then
|
||||||
[ -n "$_tag" ] || continue
|
printf ' <a class="%s" href="%s">%s</a>\n' "$_ch" "$_link" "$_ch"
|
||||||
if [ "$_tool" = "zddc-server" ]; then
|
|
||||||
printf ' <a class="%s" href="https://codeberg.org/VARASYS/ZDDC/releases/tag/%s">%s</a>\n' \
|
|
||||||
"$_ch" "$_tag" "$_ch"
|
|
||||||
else
|
|
||||||
_ver="${_tag#${_tool}-v}"
|
|
||||||
_asset="${_tool}_v${_ver}.html"
|
|
||||||
printf ' <a class="%s" href="/releases/%s/%s">%s</a>\n' \
|
|
||||||
"$_ch" "$_tag" "$_asset" "$_ch"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
printf ' </div>\n'
|
printf ' </div>\n'
|
||||||
|
|
||||||
# zddc-server: per-platform binary table, one row per channel.
|
# Pin-to-version row: every per-version real file, descending.
|
||||||
if [ "$_tool" = "zddc-server" ]; then
|
|
||||||
_platforms="linux-amd64 darwin-amd64 darwin-arm64 windows-amd64"
|
|
||||||
printf ' <h3 style="font-size:1rem;margin:0.75rem 0 0.4rem;">Standalone binaries</h3>\n'
|
|
||||||
printf ' <table class="rel-bin-table"><thead><tr><th>Channel</th>'
|
|
||||||
for _p in $_platforms; do printf '<th>%s</th>' "$_p"; done
|
|
||||||
printf '</tr></thead><tbody>\n'
|
|
||||||
for _row in "stable|$_latest_stable" "beta|$_latest_beta" "alpha|$_latest_alpha"; do
|
|
||||||
_ch="${_row%%|*}"
|
|
||||||
_tag="${_row#*|}"
|
|
||||||
printf ' <tr><td class="ch-%s">%s</td>' "$_ch" "$_ch"
|
|
||||||
if [ -z "$_tag" ]; then
|
|
||||||
for _p in $_platforms; do printf '<td class="empty">—</td>'; done
|
|
||||||
else
|
|
||||||
for _p in $_platforms; do
|
|
||||||
_ext=""; case "$_p" in windows-*) _ext=".exe" ;; esac
|
|
||||||
_asset="zddc-server-${_p}${_ext}"
|
|
||||||
printf '<td><a href="/releases/%s/%s">download</a></td>' "$_tag" "$_asset"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
printf '</tr>\n'
|
|
||||||
done
|
|
||||||
printf ' </tbody></table>\n'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Pin-to-version row. All stables (semver-descending). HTML
|
|
||||||
# tools link to the asset directly; zddc-server links to the
|
|
||||||
# Codeberg release page (per-platform asset choice).
|
|
||||||
if [ -n "$_all_stables" ]; then
|
|
||||||
printf ' <div class="rel-versions"><strong>Pin to version:</strong>\n'
|
printf ' <div class="rel-versions"><strong>Pin to version:</strong>\n'
|
||||||
printf '%s\n' "$_all_stables" | while read -r _t; do
|
printf '%s\n' "$_versioned" | while read -r _f; do
|
||||||
[ -n "$_t" ] || continue
|
[ -n "$_f" ] || continue
|
||||||
_v="${_t#${_tool}-v}"
|
# Display as v<X.Y.Z> stripped of <tool>_v prefix and .html suffix.
|
||||||
if [ "$_tool" = "zddc-server" ]; then
|
_v="${_f#${_tool}_v}"
|
||||||
printf ' <a href="https://codeberg.org/VARASYS/ZDDC/releases/tag/%s">v%s</a>\n' "$_t" "$_v"
|
_v="${_v%.html}"
|
||||||
else
|
printf ' <a href="%s">v%s</a>\n' "$_f" "$_v"
|
||||||
printf ' <a href="/releases/%s/%s_v%s.html">v%s</a>\n' "$_t" "$_tool" "$_v" "$_v"
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
printf ' </div>\n'
|
printf ' </div>\n'
|
||||||
fi
|
|
||||||
|
|
||||||
printf ' </section>\n'
|
printf ' </section>\n'
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# zddc-server section — links to Codeberg release pages directly,
|
||||||
|
# since binaries don't live under website/releases/.
|
||||||
|
printf ' <section class="rel-tool">\n'
|
||||||
|
printf ' <h2>zddc-server (Go file server)</h2>\n'
|
||||||
|
printf ' <p>Binaries are published as Codeberg release assets. Pick a platform from the release page; or build from source via the helm charts under <code>helm/</code>.</p>\n'
|
||||||
|
printf ' <p><a href="https://codeberg.org/VARASYS/ZDDC/releases">Browse zddc-server releases on Codeberg →</a></p>\n'
|
||||||
|
printf ' </section>\n'
|
||||||
|
|
||||||
cat <<'TAIL'
|
cat <<'TAIL'
|
||||||
|
|
||||||
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">
|
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">
|
||||||
<p>Append <code>?v=alpha</code>, <code>?v=beta</code>, <code>?v=stable</code>, or <code>?v=0.0.1</code> to any deployment URL to switch versions for a single request — see <a href="../">the home page</a>.</p>
|
<p>Append <code>?v=stable</code>, <code>?v=beta</code>, <code>?v=alpha</code>, <code>?v=0.0</code> (latest 0.0.x), or <code>?v=0.0.1</code> (exact) to any deployment URL to switch versions for a single request — see <a href="../">the home page</a>.</p>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,17 @@
|
||||||
# — sets globals: build_label, build_version,
|
# — sets globals: build_label, build_version,
|
||||||
# is_release, is_red, channel.
|
# is_release, is_red, channel.
|
||||||
# See "Channels and release args" below.
|
# See "Channels and release args" below.
|
||||||
# promote_release <tool> — for stable / alpha / beta, tag the
|
# promote_release <tool> — for stable / alpha / beta, copy the dist
|
||||||
# commit and upload the dist HTML as a
|
# HTML into website/releases/. Stable cuts
|
||||||
# Codeberg release asset. No local mirror
|
# write the immutable per-version file +
|
||||||
# under website/releases/ — the website
|
# refresh five symlinks (_v<X.Y>, _v<X>,
|
||||||
# reverse-proxies download URLs to Codeberg
|
# _stable, _beta, _alpha) and tag
|
||||||
# release-asset URLs. Stable cuts skip when
|
# <tool>-v<X.Y.Z>. Alpha/beta cuts
|
||||||
# the tool's source is unchanged since the
|
# overwrite the channel mirror in place
|
||||||
# latest stable tag.
|
# and cascade alpha → beta. No git tags
|
||||||
|
# for alpha/beta cuts; no Codeberg upload
|
||||||
|
# for HTML tools. See ARCHITECTURE.md
|
||||||
|
# "Channels" for the full table.
|
||||||
#
|
#
|
||||||
# Channels and release args:
|
# Channels and release args:
|
||||||
# <none> dev build, dist/ only, label
|
# <none> dev build, dist/ only, label
|
||||||
|
|
@ -36,13 +39,14 @@
|
||||||
# No website/releases/ side-effect. To publish, re-run
|
# No website/releases/ side-effect. To publish, re-run
|
||||||
# with `--release alpha`.
|
# with `--release alpha`.
|
||||||
# --release stable, auto-bump patch from latest tag (or 0.0.1).
|
# --release stable, auto-bump patch from latest tag (or 0.0.1).
|
||||||
# Label "vX.Y.Z" (black). Tags + uploads.
|
# Writes per-version file + symlinks; tags vX.Y.Z.
|
||||||
# --release X.Y.Z stable, explicit version. Tags + uploads.
|
# --release X.Y.Z stable, explicit version.
|
||||||
# --release alpha alpha channel cut at HEAD;
|
# --release alpha alpha channel cut at HEAD;
|
||||||
# label "v<next-stable>-alpha · <date> · <sha>" (red).
|
# label "v<next-stable>-alpha · <date> · <sha>" (red).
|
||||||
# Tags <tool>-vX.Y.Z-alpha.N + uploads.
|
# Overwrites <tool>_alpha.html. No tag.
|
||||||
# --release beta beta channel; label "v<next-stable>-beta · <date> · <sha>".
|
# --release beta beta channel; label "v<next-stable>-beta · <date> · <sha>".
|
||||||
# Tags + uploads.
|
# Overwrites <tool>_beta.html. Cascades <tool>_alpha.html
|
||||||
|
# → <tool>_beta.html (symlink). No tag.
|
||||||
# --release <other> error.
|
# --release <other> error.
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
|
|
@ -52,10 +56,9 @@ if [ -z "${root_dir:-}" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Pull in the Codeberg release-publish helper so promote_release can call
|
# NOTE: shared/publish-codeberg-release.sh is no longer sourced here.
|
||||||
# its publish_codeberg_release function. Sourced unconditionally — the
|
# HTML tools publish to website/releases/ as committed static files; only
|
||||||
# helper has no side effects when sourced (only defines functions).
|
# zddc-server/release.sh uploads to Codeberg (it sources the helper directly).
|
||||||
. "$root_dir/../shared/publish-codeberg-release.sh"
|
|
||||||
|
|
||||||
# Fail hard on any missing source file
|
# Fail hard on any missing source file
|
||||||
ensure_exists() {
|
ensure_exists() {
|
||||||
|
|
@ -101,58 +104,6 @@ escape_js_close_tags() {
|
||||||
sed 's#</\([sS][cC][rR][iI][pP][tT]\)#<\\/\1#g' "$1" > "$2"
|
sed 's#</\([sS][cC][rR][iI][pP][tT]\)#<\\/\1#g' "$1" > "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Echo the next pre-release version for a given channel + tag prefix.
|
|
||||||
# next_prerelease <channel> <tag_prefix>
|
|
||||||
#
|
|
||||||
# Channel must be alpha or beta. Tag prefix is the leading text on this
|
|
||||||
# tool's stable git tags — e.g. "zddc-server-v" or "archive-v" — so the
|
|
||||||
# function can be called from either the server release script or any
|
|
||||||
# HTML tool's build.sh against the same monorepo tag namespace.
|
|
||||||
#
|
|
||||||
# Algorithm:
|
|
||||||
# 1. Walk tags matching <prefix>X.Y.Z (clean stable, no suffix); pick the
|
|
||||||
# semver-highest. Default 0.0.0 if no stable tag exists yet.
|
|
||||||
# 2. Bump the patch component → next_patch.
|
|
||||||
# 3. Count existing tags of the form <prefix><next_patch>-<channel>.*
|
|
||||||
# and emit <next_patch>-<channel>.<count+1>.
|
|
||||||
#
|
|
||||||
# The patch-bump assumption: every active pre-release window targets the
|
|
||||||
# next patch of the latest stable. Cutting a real stable resets the
|
|
||||||
# counter naturally because next_patch advances. Operators wanting a
|
|
||||||
# minor or major bump cut stable explicitly with a version arg, then the
|
|
||||||
# subsequent alphas auto-derive against the new stable.
|
|
||||||
next_prerelease() {
|
|
||||||
_channel="$1"
|
|
||||||
_prefix="$2"
|
|
||||||
case "$_channel" in
|
|
||||||
alpha | beta) ;;
|
|
||||||
*) echo "next_prerelease: channel must be alpha or beta (got '$_channel')" >&2; return 1 ;;
|
|
||||||
esac
|
|
||||||
if [ -z "$_prefix" ]; then
|
|
||||||
echo "next_prerelease: tag prefix is required" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_latest=$(git -C "$root_dir" tag --list "${_prefix}*" 2>/dev/null \
|
|
||||||
| grep -E "^${_prefix}[0-9]+\.[0-9]+\.[0-9]+\$" \
|
|
||||||
| sed "s|^${_prefix}||" \
|
|
||||||
| sort -V \
|
|
||||||
| tail -1)
|
|
||||||
[ -n "$_latest" ] || _latest="0.0.0"
|
|
||||||
|
|
||||||
_major="${_latest%%.*}"
|
|
||||||
_rest="${_latest#*.}"
|
|
||||||
_minor="${_rest%%.*}"
|
|
||||||
_patch="${_rest#*.}"
|
|
||||||
_patch=$((_patch + 1))
|
|
||||||
_next_patch="${_major}.${_minor}.${_patch}"
|
|
||||||
|
|
||||||
_count=$(git -C "$root_dir" tag --list "${_prefix}${_next_patch}-${_channel}.*" 2>/dev/null | wc -l | tr -d ' ')
|
|
||||||
_count=$((_count + 1))
|
|
||||||
|
|
||||||
echo "${_next_patch}-${_channel}.${_count}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Validate that $1 is a strict X.Y.Z numeric version, where each component
|
# Validate that $1 is a strict X.Y.Z numeric version, where each component
|
||||||
# is a non-empty numeric string. Exits with an error if not.
|
# is a non-empty numeric string. Exits with an error if not.
|
||||||
_validate_semver() {
|
_validate_semver() {
|
||||||
|
|
@ -264,33 +215,44 @@ _next_stable_for_tool() {
|
||||||
echo "${_major}.${_minor}.$((_patch + 1))"
|
echo "${_major}.${_minor}.$((_patch + 1))"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Promote a built dist file to a Codeberg release.
|
# Promote a built dist file to website/releases/. Reads from caller scope:
|
||||||
# Reads from caller scope: $channel, $build_version, $output_html, $root_dir.
|
# $channel ("stable" / "alpha" / "beta"), $build_version (stable only),
|
||||||
|
# $output_html, $root_dir.
|
||||||
#
|
#
|
||||||
# All three channels (alpha, beta, stable) follow the same shape now:
|
# Stable cuts:
|
||||||
# 1. Compute the version (already done by compute_build_label for stable;
|
# 1. Skip if source unchanged since latest stable tag.
|
||||||
# for alpha/beta we compute next_prerelease here).
|
# 2. Copy dist HTML → website/releases/<tool>_v<X.Y.Z>.html (immutable).
|
||||||
# 2. Tag the commit <tool>-v<version> (or <tool>-v<version>-CHANNEL.N).
|
# 3. Refresh symlinks: _v<X.Y>, _v<X>, _stable, _beta, _alpha all → the
|
||||||
# 3. Upload the built dist HTML as a release asset to Codeberg.
|
# new versioned file. Cascade rule: stable cut means beta and alpha
|
||||||
|
# reset to stable (no active dev on either downstream channel).
|
||||||
|
# 4. Tag the commit <tool>-v<X.Y.Z>.
|
||||||
#
|
#
|
||||||
# Idempotent: the publish helper replaces a same-named asset on re-upload,
|
# Alpha/beta cuts:
|
||||||
# and the tag step is a no-op if the tag already points at HEAD.
|
# 1. Overwrite website/releases/<tool>_<channel>.html with dist HTML
|
||||||
|
# (replaces a symlink with real bytes if one was there).
|
||||||
|
# 2. For beta: cascade <tool>_alpha.html → <tool>_beta.html (symlink),
|
||||||
|
# since alpha defaults to beta when no active alpha.
|
||||||
|
# 3. No tag — channel URLs are stable URLs by design; counters defeat
|
||||||
|
# that. The on-page label encodes <date> · <sha> for traceability.
|
||||||
#
|
#
|
||||||
# For stable: the original "skip if no source change since latest stable
|
# Plain dev builds (no --release): never call promote_release.
|
||||||
# tag" guard still applies — pointless re-releases are silently no-op'd.
|
|
||||||
# For alpha/beta: the auto-incrementing counter already differentiates
|
|
||||||
# successive cuts, so no skip check.
|
|
||||||
#
|
#
|
||||||
# Requires $CODEBERG_TOKEN exported. publish_codeberg_release surfaces a
|
# No Codeberg upload — HTML tools live in git. zddc-server's release.sh
|
||||||
# clear error if it isn't.
|
# handles binary uploads to Codeberg directly (different distribution model).
|
||||||
promote_release() {
|
promote_release() {
|
||||||
_tool="$1"
|
_tool="$1"
|
||||||
|
_releases_dir="$root_dir/../website/releases"
|
||||||
|
|
||||||
|
if [ ! -d "$_releases_dir" ]; then
|
||||||
|
echo "promote_release: $_releases_dir not found" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
case "$channel" in
|
case "$channel" in
|
||||||
stable)
|
stable)
|
||||||
if [ -z "$build_version" ]; then
|
if [ -z "$build_version" ]; then
|
||||||
echo "promote_release: stable channel but no build_version" >&2
|
echo "promote_release: stable channel but no build_version" >&2
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_latest=$(git -C "$root_dir" tag --list "${_tool}-v*" 2>/dev/null \
|
_latest=$(git -C "$root_dir" tag --list "${_tool}-v*" 2>/dev/null \
|
||||||
| grep -E "^${_tool}-v[0-9]+\.[0-9]+\.[0-9]+\$" \
|
| grep -E "^${_tool}-v[0-9]+\.[0-9]+\.[0-9]+\$" \
|
||||||
|
|
@ -299,25 +261,49 @@ promote_release() {
|
||||||
echo "${_tool}: no source changes since $_latest — skipping"
|
echo "${_tool}: no source changes since $_latest — skipping"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
_version="$build_version"
|
_promote_stable "$_tool" "$build_version" "$_releases_dir"
|
||||||
;;
|
;;
|
||||||
alpha | beta)
|
alpha | beta)
|
||||||
_version=$(next_prerelease "$channel" "${_tool}-v")
|
_promote_channel "$_tool" "$channel" "$_releases_dir"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "promote_release: unknown channel '$channel'" >&2
|
echo "promote_release: unknown channel '$channel'" >&2
|
||||||
exit 1
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
_tag="${_tool}-v${_version}"
|
# Stable cut: per-version file + 5 symlinks + git tag.
|
||||||
|
_promote_stable() {
|
||||||
|
_t="$1"
|
||||||
|
_ver="$2"
|
||||||
|
_rdir="$3"
|
||||||
|
|
||||||
# Tag the commit (idempotent: skip if already at HEAD).
|
_major="${_ver%%.*}"
|
||||||
|
_rest="${_ver#*.}"
|
||||||
|
_minor="${_rest%%.*}"
|
||||||
|
_versioned="${_t}_v${_ver}.html"
|
||||||
|
|
||||||
|
cp "$output_html" "$_rdir/$_versioned"
|
||||||
|
echo "Wrote $_rdir/$_versioned"
|
||||||
|
|
||||||
|
# Refresh the 5 symlinks. Cascade: stable cut → beta + alpha both
|
||||||
|
# reset to stable (no active dev on either downstream channel).
|
||||||
|
for _sym in "${_t}_v${_major}.${_minor}.html" \
|
||||||
|
"${_t}_v${_major}.html" \
|
||||||
|
"${_t}_stable.html" \
|
||||||
|
"${_t}_beta.html" \
|
||||||
|
"${_t}_alpha.html"; do
|
||||||
|
ln -sfn "$_versioned" "$_rdir/$_sym"
|
||||||
|
echo " $_sym → $_versioned"
|
||||||
|
done
|
||||||
|
|
||||||
|
_tag="${_t}-v${_ver}"
|
||||||
if git -C "$root_dir" rev-parse -q --verify "refs/tags/$_tag" >/dev/null; then
|
if git -C "$root_dir" rev-parse -q --verify "refs/tags/$_tag" >/dev/null; then
|
||||||
_existing=$(git -C "$root_dir" rev-list -n 1 "$_tag")
|
_existing=$(git -C "$root_dir" rev-list -n 1 "$_tag")
|
||||||
_head=$(git -C "$root_dir" rev-parse HEAD)
|
_head=$(git -C "$root_dir" rev-parse HEAD)
|
||||||
if [ "$_existing" != "$_head" ]; then
|
if [ "$_existing" != "$_head" ]; then
|
||||||
echo "promote_release: tag $_tag already exists at $_existing, but HEAD is $_head" >&2
|
echo "promote_release: tag $_tag exists at $_existing but HEAD is $_head" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
echo "(tag $_tag already at HEAD)"
|
echo "(tag $_tag already at HEAD)"
|
||||||
|
|
@ -326,21 +312,28 @@ promote_release() {
|
||||||
echo "tagged $_tag"
|
echo "tagged $_tag"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Upload to Codeberg. The asset name embeds the version so consumers
|
echo "Released ${_t} v${_ver} (stable)"
|
||||||
# can pin to a specific build (e.g. <tool>_v0.0.3-alpha.1.html).
|
|
||||||
_asset="${_tool}_v${_version}.html"
|
|
||||||
_staged="$root_dir/$_tool/dist/$_asset"
|
|
||||||
cp "$output_html" "$_staged"
|
|
||||||
if ! command -v publish_codeberg_release >/dev/null 2>&1; then
|
|
||||||
# build-lib.sh is sourced before publish-codeberg-release.sh in the
|
|
||||||
# canonical wrapper scripts; if the helper isn't loaded yet, bail
|
|
||||||
# with a clear pointer.
|
|
||||||
echo "promote_release: publish_codeberg_release not available; source shared/publish-codeberg-release.sh first" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
publish_codeberg_release "VARASYS/ZDDC" "$_tag" "$_staged"
|
|
||||||
rm -f "$_staged"
|
|
||||||
|
|
||||||
echo "Released $_tag (channel: $channel, version: $_version)"
|
|
||||||
echo " publish git tag with: git push origin $_tag"
|
echo " publish git tag with: git push origin $_tag"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Alpha/beta cut: overwrite mutable channel mirror; cascade alpha → beta
|
||||||
|
# on a beta cut (alpha defaults to beta when no active alpha).
|
||||||
|
_promote_channel() {
|
||||||
|
_t="$1"
|
||||||
|
_ch="$2"
|
||||||
|
_rdir="$3"
|
||||||
|
|
||||||
|
_file="${_t}_${_ch}.html"
|
||||||
|
# Replace symlink (if present) with real bytes by removing first;
|
||||||
|
# cp -f follows symlinks and would overwrite the symlink target.
|
||||||
|
rm -f "$_rdir/$_file"
|
||||||
|
cp "$output_html" "$_rdir/$_file"
|
||||||
|
echo "Wrote $_rdir/$_file"
|
||||||
|
|
||||||
|
if [ "$_ch" = "beta" ]; then
|
||||||
|
ln -sfn "$_file" "$_rdir/${_t}_alpha.html"
|
||||||
|
echo " ${_t}_alpha.html → $_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Released ${_t} ${_ch}"
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,12 @@ for (const tool of tools) {
|
||||||
const match = html.match(/class="build-timestamp">(?:<span[^>]*>)?([^<]+?)(?:<\/span>)?</);
|
const match = html.match(/class="build-timestamp">(?:<span[^>]*>)?([^<]+?)(?:<\/span>)?</);
|
||||||
expect(match, 'build-timestamp element must have text content').toBeTruthy();
|
expect(match, 'build-timestamp element must have text content').toBeTruthy();
|
||||||
const label = match[1];
|
const label = match[1];
|
||||||
// Plain dev builds and --release alpha|beta:
|
// Plain dev builds and --release alpha|beta carry the next-stable
|
||||||
// "alpha · 2026-04-29 00:50:17 · 714faf6-dirty" (plain, with timestamp + dirty marker)
|
// target as a pre-release suffix:
|
||||||
// "alpha · 2026-04-29 · 714faf6" (--release alpha, date only)
|
// "v0.0.3-alpha · 2026-04-29 00:50:17 · 714faf6-dirty" (plain dev)
|
||||||
// "beta · 2026-04-29 · 714faf6" (--release beta)
|
// "v0.0.3-alpha · 2026-04-29 · 714faf6" (--release alpha)
|
||||||
const isChannel = /^(alpha|beta) · 20\d\d-\d\d-\d\d( \d\d:\d\d:\d\d)? · [0-9a-f]+(-dirty)?$/.test(label);
|
// "v0.0.3-beta · 2026-04-29 · 714faf6" (--release beta)
|
||||||
|
const isChannel = /^v\d+\.\d+\.\d+-(alpha|beta) · 20\d\d-\d\d-\d\d( \d\d:\d\d:\d\d)? · [0-9a-f]+(-dirty)?$/.test(label);
|
||||||
const isVersion = /^v\d+\.\d+\.\d+$/.test(label);
|
const isVersion = /^v\d+\.\d+\.\d+$/.test(label);
|
||||||
expect(isChannel || isVersion,
|
expect(isChannel || isVersion,
|
||||||
`Expected channel or version label, got: "${label}"`
|
`Expected channel or version label, got: "${label}"`
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// alpha channel; the URL parameter ?v= overrides it:
|
// alpha channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the alpha default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the alpha default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'archive';
|
const tool = 'archive';
|
||||||
const defaultChannel = 'alpha';
|
const defaultChannel = 'alpha';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// alpha channel; the URL parameter ?v= overrides it:
|
// alpha channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the alpha default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the alpha default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'classifier';
|
const tool = 'classifier';
|
||||||
const defaultChannel = 'alpha';
|
const defaultChannel = 'alpha';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// alpha channel; the URL parameter ?v= overrides it:
|
// alpha channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the alpha default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the alpha default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'landing';
|
const tool = 'landing';
|
||||||
const defaultChannel = 'alpha';
|
const defaultChannel = 'alpha';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// alpha channel; the URL parameter ?v= overrides it:
|
// alpha channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the alpha default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the alpha default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'mdedit';
|
const tool = 'mdedit';
|
||||||
const defaultChannel = 'alpha';
|
const defaultChannel = 'alpha';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// alpha channel; the URL parameter ?v= overrides it:
|
// alpha channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the alpha default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the alpha default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'transmittal';
|
const tool = 'transmittal';
|
||||||
const defaultChannel = 'alpha';
|
const defaultChannel = 'alpha';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// beta channel; the URL parameter ?v= overrides it:
|
// beta channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the beta default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the beta default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'archive';
|
const tool = 'archive';
|
||||||
const defaultChannel = 'beta';
|
const defaultChannel = 'beta';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// beta channel; the URL parameter ?v= overrides it:
|
// beta channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the beta default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the beta default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'classifier';
|
const tool = 'classifier';
|
||||||
const defaultChannel = 'beta';
|
const defaultChannel = 'beta';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// beta channel; the URL parameter ?v= overrides it:
|
// beta channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the beta default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the beta default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'landing';
|
const tool = 'landing';
|
||||||
const defaultChannel = 'beta';
|
const defaultChannel = 'beta';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// beta channel; the URL parameter ?v= overrides it:
|
// beta channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the beta default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the beta default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'mdedit';
|
const tool = 'mdedit';
|
||||||
const defaultChannel = 'beta';
|
const defaultChannel = 'beta';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// beta channel; the URL parameter ?v= overrides it:
|
// beta channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the beta default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the beta default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'transmittal';
|
const tool = 'transmittal';
|
||||||
const defaultChannel = 'beta';
|
const defaultChannel = 'beta';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// stable channel; the URL parameter ?v= overrides it:
|
// stable channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the stable default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the stable default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'archive';
|
const tool = 'archive';
|
||||||
const defaultChannel = 'stable';
|
const defaultChannel = 'stable';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// stable channel; the URL parameter ?v= overrides it:
|
// stable channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the stable default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the stable default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'classifier';
|
const tool = 'classifier';
|
||||||
const defaultChannel = 'stable';
|
const defaultChannel = 'stable';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// stable channel; the URL parameter ?v= overrides it:
|
// stable channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the stable default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the stable default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'landing';
|
const tool = 'landing';
|
||||||
const defaultChannel = 'stable';
|
const defaultChannel = 'stable';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// stable channel; the URL parameter ?v= overrides it:
|
// stable channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the stable default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the stable default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'mdedit';
|
const tool = 'mdedit';
|
||||||
const defaultChannel = 'stable';
|
const defaultChannel = 'stable';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,33 @@
|
||||||
// document.write()s it in place. The default upstream is the
|
// document.write()s it in place. The default upstream is the
|
||||||
// stable channel; the URL parameter ?v= overrides it:
|
// stable channel; the URL parameter ?v= overrides it:
|
||||||
//
|
//
|
||||||
// ?v=alpha|beta|stable switches to that channel
|
// ?v=stable | beta | alpha switch to that channel
|
||||||
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
|
// ?v=0.0.4 (or v0.0.4) pin to that exact stable version
|
||||||
// (none) uses the stable default
|
// ?v=0.0 (or v0.0) pin to latest patch within 0.0.x (symlink)
|
||||||
|
// ?v=0 (or v0) pin to latest within 0.x (symlink)
|
||||||
|
// (none) use the stable default
|
||||||
//
|
//
|
||||||
// Resolution path:
|
// Resolution is purely static — every URL maps to a real file or a
|
||||||
// 1. Channel mode (no ?v= or ?v={alpha,beta,stable}): fetch
|
// checked-in symlink under <upstream>/releases/. No manifest lookup,
|
||||||
// manifest.json from the same origin, look up
|
// no JS indirection, no client-side version arithmetic.
|
||||||
// "<tool>-<channel>" → tag, then fetch the asset.
|
|
||||||
// 2. Version pin: build the URL directly (skip manifest).
|
|
||||||
//
|
|
||||||
// The asset URL is /releases/<tag>/<tool>_v<version>.html. Caddy on
|
|
||||||
// zddc.varasys.io reverse-proxies that to the Codeberg release-asset
|
|
||||||
// URL — neither this stub nor the user's browser hits codeberg.org
|
|
||||||
// directly.
|
|
||||||
(async function () {
|
(async function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const v = params.get('v');
|
const v = params.get('v');
|
||||||
const tool = 'transmittal';
|
const tool = 'transmittal';
|
||||||
const defaultChannel = 'stable';
|
const defaultChannel = 'stable';
|
||||||
const channels = ['alpha', 'beta', 'stable'];
|
const channels = ['stable', 'beta', 'alpha'];
|
||||||
const base = 'https://zddc.varasys.io/releases/';
|
const base = 'https://zddc.varasys.io/releases/';
|
||||||
|
|
||||||
function isChannel(s) { return channels.indexOf(s) >= 0; }
|
function suffixFor(value) {
|
||||||
|
if (!value) return '_' + defaultChannel;
|
||||||
try {
|
if (channels.indexOf(value) >= 0) return '_' + value;
|
||||||
let assetUrl;
|
// Strip optional leading 'v', accept "0.0.4" / "0.0" / "0".
|
||||||
if (v && !isChannel(v)) {
|
const ver = value.startsWith('v') ? value.slice(1) : value;
|
||||||
// Explicit version pin (e.g. ?v=0.0.4 or ?v=v0.0.4).
|
return '_v' + ver;
|
||||||
const ver = v.replace(/^v/, '');
|
|
||||||
const tag = tool + '-v' + ver;
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
} else {
|
|
||||||
// Channel mode: resolve via manifest.
|
|
||||||
const channel = (v && isChannel(v)) ? v : defaultChannel;
|
|
||||||
const manifest = await (await fetch(base + 'manifest.json', { cache: 'no-cache', credentials: 'omit' })).json();
|
|
||||||
const tag = manifest[tool + '-' + channel];
|
|
||||||
if (!tag) throw new Error('manifest has no entry for ' + tool + '-' + channel);
|
|
||||||
const ver = tag.replace(tool + '-v', '');
|
|
||||||
assetUrl = base + tag + '/' + tool + '_v' + ver + '.html';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assetUrl = base + tool + suffixFor(v) + '.html';
|
||||||
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
const resp = await fetch(assetUrl, { cache: 'no-cache', credentials: 'omit' });
|
||||||
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
|
||||||
const html = await resp.text();
|
const html = await resp.text();
|
||||||
|
|
|
||||||
1
website/releases/archive_alpha.html
Symbolic link
1
website/releases/archive_alpha.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
archive_v0.0.2.html
|
||||||
1
website/releases/archive_beta.html
Symbolic link
1
website/releases/archive_beta.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
archive_v0.0.2.html
|
||||||
1
website/releases/archive_stable.html
Symbolic link
1
website/releases/archive_stable.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
archive_v0.0.2.html
|
||||||
7800
website/releases/archive_v0.0.1.html
Normal file
7800
website/releases/archive_v0.0.1.html
Normal file
File diff suppressed because it is too large
Load diff
7833
website/releases/archive_v0.0.2.html
Normal file
7833
website/releases/archive_v0.0.2.html
Normal file
File diff suppressed because it is too large
Load diff
1
website/releases/archive_v0.0.html
Symbolic link
1
website/releases/archive_v0.0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
archive_v0.0.2.html
|
||||||
1
website/releases/archive_v0.html
Symbolic link
1
website/releases/archive_v0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
archive_v0.0.2.html
|
||||||
1
website/releases/classifier_alpha.html
Symbolic link
1
website/releases/classifier_alpha.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
classifier_v0.0.2.html
|
||||||
1
website/releases/classifier_beta.html
Symbolic link
1
website/releases/classifier_beta.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
classifier_v0.0.2.html
|
||||||
1
website/releases/classifier_stable.html
Symbolic link
1
website/releases/classifier_stable.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
classifier_v0.0.2.html
|
||||||
6971
website/releases/classifier_v0.0.1.html
Normal file
6971
website/releases/classifier_v0.0.1.html
Normal file
File diff suppressed because it is too large
Load diff
6972
website/releases/classifier_v0.0.2.html
Normal file
6972
website/releases/classifier_v0.0.2.html
Normal file
File diff suppressed because it is too large
Load diff
1
website/releases/classifier_v0.0.html
Symbolic link
1
website/releases/classifier_v0.0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
classifier_v0.0.2.html
|
||||||
1
website/releases/classifier_v0.html
Symbolic link
1
website/releases/classifier_v0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
classifier_v0.0.2.html
|
||||||
|
|
@ -61,68 +61,71 @@
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>Archive</h2>
|
<h2>Archive</h2>
|
||||||
<div class="rel-channels">
|
<div class="rel-channels">
|
||||||
<a class="stable" href="/releases/archive-v0.0.2/archive_v0.0.2.html">stable</a>
|
<a class="stable" href="archive_stable.html">stable</a>
|
||||||
|
<a class="beta" href="archive_beta.html">beta</a>
|
||||||
|
<a class="alpha" href="archive_alpha.html">alpha</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="rel-versions"><strong>Pin to version:</strong>
|
<div class="rel-versions"><strong>Pin to version:</strong>
|
||||||
<a href="/releases/archive-v0.0.2/archive_v0.0.2.html">v0.0.2</a>
|
<a href="archive_v0.0.2.html">v0.0.2</a>
|
||||||
<a href="/releases/archive-v0.0.1/archive_v0.0.1.html">v0.0.1</a>
|
<a href="archive_v0.0.1.html">v0.0.1</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>Transmittal</h2>
|
<h2>Transmittal</h2>
|
||||||
<div class="rel-channels">
|
<div class="rel-channels">
|
||||||
<a class="stable" href="/releases/transmittal-v0.0.2/transmittal_v0.0.2.html">stable</a>
|
<a class="stable" href="transmittal_stable.html">stable</a>
|
||||||
|
<a class="beta" href="transmittal_beta.html">beta</a>
|
||||||
|
<a class="alpha" href="transmittal_alpha.html">alpha</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="rel-versions"><strong>Pin to version:</strong>
|
<div class="rel-versions"><strong>Pin to version:</strong>
|
||||||
<a href="/releases/transmittal-v0.0.2/transmittal_v0.0.2.html">v0.0.2</a>
|
<a href="transmittal_v0.0.2.html">v0.0.2</a>
|
||||||
<a href="/releases/transmittal-v0.0.1/transmittal_v0.0.1.html">v0.0.1</a>
|
<a href="transmittal_v0.0.1.html">v0.0.1</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>Classifier</h2>
|
<h2>Classifier</h2>
|
||||||
<div class="rel-channels">
|
<div class="rel-channels">
|
||||||
<a class="stable" href="/releases/classifier-v0.0.2/classifier_v0.0.2.html">stable</a>
|
<a class="stable" href="classifier_stable.html">stable</a>
|
||||||
|
<a class="beta" href="classifier_beta.html">beta</a>
|
||||||
|
<a class="alpha" href="classifier_alpha.html">alpha</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="rel-versions"><strong>Pin to version:</strong>
|
<div class="rel-versions"><strong>Pin to version:</strong>
|
||||||
<a href="/releases/classifier-v0.0.2/classifier_v0.0.2.html">v0.0.2</a>
|
<a href="classifier_v0.0.2.html">v0.0.2</a>
|
||||||
<a href="/releases/classifier-v0.0.1/classifier_v0.0.1.html">v0.0.1</a>
|
<a href="classifier_v0.0.1.html">v0.0.1</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>Markdown Editor</h2>
|
<h2>Markdown Editor</h2>
|
||||||
<div class="rel-channels">
|
<div class="rel-channels">
|
||||||
<a class="stable" href="/releases/mdedit-v0.0.2/mdedit_v0.0.2.html">stable</a>
|
<a class="stable" href="mdedit_stable.html">stable</a>
|
||||||
|
<a class="beta" href="mdedit_beta.html">beta</a>
|
||||||
|
<a class="alpha" href="mdedit_alpha.html">alpha</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="rel-versions"><strong>Pin to version:</strong>
|
<div class="rel-versions"><strong>Pin to version:</strong>
|
||||||
<a href="/releases/mdedit-v0.0.2/mdedit_v0.0.2.html">v0.0.2</a>
|
<a href="mdedit_v0.0.2.html">v0.0.2</a>
|
||||||
<a href="/releases/mdedit-v0.0.1/mdedit_v0.0.1.html">v0.0.1</a>
|
<a href="mdedit_v0.0.1.html">v0.0.1</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>Landing (project picker)</h2>
|
<h2>Landing (project picker)</h2>
|
||||||
<div class="rel-channels">
|
<div class="rel-channels">
|
||||||
<a class="stable" href="/releases/landing-v0.0.2/landing_v0.0.2.html">stable</a>
|
<a class="stable" href="landing_stable.html">stable</a>
|
||||||
|
<a class="beta" href="landing_beta.html">beta</a>
|
||||||
|
<a class="alpha" href="landing_alpha.html">alpha</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="rel-versions"><strong>Pin to version:</strong>
|
<div class="rel-versions"><strong>Pin to version:</strong>
|
||||||
<a href="/releases/landing-v0.0.2/landing_v0.0.2.html">v0.0.2</a>
|
<a href="landing_v0.0.2.html">v0.0.2</a>
|
||||||
<a href="/releases/landing-v0.0.1/landing_v0.0.1.html">v0.0.1</a>
|
<a href="landing_v0.0.1.html">v0.0.1</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="rel-tool">
|
<section class="rel-tool">
|
||||||
<h2>zddc-server (Go file server)</h2>
|
<h2>zddc-server (Go file server)</h2>
|
||||||
<div class="rel-channels">
|
<p>Binaries are published as Codeberg release assets. Pick a platform from the release page; or build from source via the helm charts under <code>helm/</code>.</p>
|
||||||
<a class="alpha" href="https://codeberg.org/VARASYS/ZDDC/releases/tag/zddc-server-v0.0.8-alpha.2">alpha</a>
|
<p><a href="https://codeberg.org/VARASYS/ZDDC/releases">Browse zddc-server releases on Codeberg →</a></p>
|
||||||
</div>
|
|
||||||
<h3 style="font-size:1rem;margin:0.75rem 0 0.4rem;">Standalone binaries</h3>
|
|
||||||
<table class="rel-bin-table"><thead><tr><th>Channel</th><th>linux-amd64</th><th>darwin-amd64</th><th>darwin-arm64</th><th>windows-amd64</th></tr></thead><tbody>
|
|
||||||
<tr><td class="ch-stable">stable</td><td class="empty">—</td><td class="empty">—</td><td class="empty">—</td><td class="empty">—</td></tr>
|
|
||||||
<tr><td class="ch-beta">beta</td><td class="empty">—</td><td class="empty">—</td><td class="empty">—</td><td class="empty">—</td></tr>
|
|
||||||
<tr><td class="ch-alpha">alpha</td><td><a href="/releases/zddc-server-v0.0.8-alpha.2/zddc-server-linux-amd64">download</a></td><td><a href="/releases/zddc-server-v0.0.8-alpha.2/zddc-server-darwin-amd64">download</a></td><td><a href="/releases/zddc-server-v0.0.8-alpha.2/zddc-server-darwin-arm64">download</a></td><td><a href="/releases/zddc-server-v0.0.8-alpha.2/zddc-server-windows-amd64.exe">download</a></td></tr>
|
|
||||||
</tbody></table>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">
|
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">
|
||||||
<p>Append <code>?v=alpha</code>, <code>?v=beta</code>, <code>?v=stable</code>, or <code>?v=0.0.1</code> to any deployment URL to switch versions for a single request — see <a href="../">the home page</a>.</p>
|
<p>Append <code>?v=stable</code>, <code>?v=beta</code>, <code>?v=alpha</code>, <code>?v=0.0</code> (latest 0.0.x), or <code>?v=0.0.1</code> (exact) to any deployment URL to switch versions for a single request — see <a href="../">the home page</a>.</p>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
||||||
1
website/releases/landing_alpha.html
Symbolic link
1
website/releases/landing_alpha.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
landing_v0.0.2.html
|
||||||
1
website/releases/landing_beta.html
Symbolic link
1
website/releases/landing_beta.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
landing_v0.0.2.html
|
||||||
1
website/releases/landing_stable.html
Symbolic link
1
website/releases/landing_stable.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
landing_v0.0.2.html
|
||||||
1029
website/releases/landing_v0.0.1.html
Normal file
1029
website/releases/landing_v0.0.1.html
Normal file
File diff suppressed because it is too large
Load diff
2199
website/releases/landing_v0.0.2.html
Normal file
2199
website/releases/landing_v0.0.2.html
Normal file
File diff suppressed because it is too large
Load diff
1
website/releases/landing_v0.0.html
Symbolic link
1
website/releases/landing_v0.0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
landing_v0.0.2.html
|
||||||
1
website/releases/landing_v0.html
Symbolic link
1
website/releases/landing_v0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
landing_v0.0.2.html
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"archive-stable": "archive-v0.0.2",
|
|
||||||
"transmittal-stable": "transmittal-v0.0.2",
|
|
||||||
"classifier-stable": "classifier-v0.0.2",
|
|
||||||
"mdedit-stable": "mdedit-v0.0.2",
|
|
||||||
"landing-stable": "landing-v0.0.2",
|
|
||||||
"zddc-server-alpha": "zddc-server-v0.0.8-alpha.2"
|
|
||||||
}
|
|
||||||
1
website/releases/mdedit_alpha.html
Symbolic link
1
website/releases/mdedit_alpha.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
mdedit_v0.0.2.html
|
||||||
1
website/releases/mdedit_beta.html
Symbolic link
1
website/releases/mdedit_beta.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
mdedit_v0.0.2.html
|
||||||
1
website/releases/mdedit_stable.html
Symbolic link
1
website/releases/mdedit_stable.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
mdedit_v0.0.2.html
|
||||||
5064
website/releases/mdedit_v0.0.1.html
Normal file
5064
website/releases/mdedit_v0.0.1.html
Normal file
File diff suppressed because one or more lines are too long
5416
website/releases/mdedit_v0.0.2.html
Normal file
5416
website/releases/mdedit_v0.0.2.html
Normal file
File diff suppressed because one or more lines are too long
1
website/releases/mdedit_v0.0.html
Symbolic link
1
website/releases/mdedit_v0.0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
mdedit_v0.0.2.html
|
||||||
1
website/releases/mdedit_v0.html
Symbolic link
1
website/releases/mdedit_v0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
mdedit_v0.0.2.html
|
||||||
1
website/releases/transmittal_alpha.html
Symbolic link
1
website/releases/transmittal_alpha.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
transmittal_v0.0.2.html
|
||||||
1
website/releases/transmittal_beta.html
Symbolic link
1
website/releases/transmittal_beta.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
transmittal_v0.0.2.html
|
||||||
1
website/releases/transmittal_stable.html
Symbolic link
1
website/releases/transmittal_stable.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
transmittal_v0.0.2.html
|
||||||
10998
website/releases/transmittal_v0.0.1.html
Normal file
10998
website/releases/transmittal_v0.0.1.html
Normal file
File diff suppressed because it is too large
Load diff
10999
website/releases/transmittal_v0.0.2.html
Normal file
10999
website/releases/transmittal_v0.0.2.html
Normal file
File diff suppressed because it is too large
Load diff
1
website/releases/transmittal_v0.0.html
Symbolic link
1
website/releases/transmittal_v0.0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
transmittal_v0.0.2.html
|
||||||
1
website/releases/transmittal_v0.html
Symbolic link
1
website/releases/transmittal_v0.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
transmittal_v0.0.2.html
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# release.sh — cut a zddc-server release: tag, compile binaries,
|
# release.sh — cut a zddc-server stable release: tag, cross-compile
|
||||||
# publish them as assets to a Codeberg release.
|
# binaries, publish them as assets to a Codeberg release.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# sh zddc/release.sh # alpha cut (default), version auto-derived
|
# sh zddc/release.sh # patch++ from latest stable tag
|
||||||
# sh zddc/release.sh alpha # same
|
# sh zddc/release.sh 0.1.0 # explicit version (X.Y.Z)
|
||||||
# sh zddc/release.sh beta # beta cut, version auto-derived
|
|
||||||
# sh zddc/release.sh stable # stable cut, patch++ from latest stable
|
|
||||||
# sh zddc/release.sh stable 0.1.0 # stable cut, explicit version
|
|
||||||
#
|
#
|
||||||
# What this is NOT: there's no container image build, no registry push.
|
# Why stable-only: zddc-server publishes binaries only on stable cuts.
|
||||||
# Those went away when the upstream codeberg.org/varasys/zddc-server
|
# Beta/alpha channels of zddc-server have no binary distribution — the
|
||||||
# image lost its only consumers (tnd-zddc-chart's two Dockerfiles now
|
# helm/zddc-server-{prod,dev} charts in this repo build from source at
|
||||||
# compile from source directly, fetching this Codeberg release tarball
|
# deploy time, so any commit on main is buildable. There's no
|
||||||
# / binary). See AGENTS.md "Releasing" for the full flow.
|
# cascade/symlink layer for binaries; if you need a specific build,
|
||||||
|
# pin the chart's commit ref.
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
# - Go 1.24+ on PATH.
|
# - Go 1.24+ on PATH.
|
||||||
|
|
@ -21,13 +19,12 @@
|
||||||
# - curl, jq, git.
|
# - curl, jq, git.
|
||||||
#
|
#
|
||||||
# What it does:
|
# What it does:
|
||||||
# 1. Determine version per the pre-release semver scheme:
|
# 1. Derive version: explicit arg, or patch-bumped from latest clean
|
||||||
# alpha/beta → next_prerelease (vX.Y.Z-CHANNEL.N from latest stable)
|
# zddc-server-vX.Y.Z tag.
|
||||||
# stable → operator-supplied or patch-bumped from latest stable
|
|
||||||
# 2. Tag the current commit zddc-server-v<version>.
|
# 2. Tag the current commit zddc-server-v<version>.
|
||||||
# 3. Cross-compile binaries (linux/darwin/windows × amd64/arm64)
|
# 3. Cross-compile binaries (linux/darwin/windows × amd64/arm64) into
|
||||||
# into zddc/dist/zddc-server-<os>-<arch>[.exe]. Native Go preferred.
|
# zddc/dist/zddc-server-<os>-<arch>[.exe]. Native Go.
|
||||||
# 4. Upload each binary as an asset to the new Codeberg release.
|
# 4. Upload each binary as a release asset on Codeberg.
|
||||||
# 5. Print the operator's next steps (push the tag).
|
# 5. Print the operator's next steps (push the tag).
|
||||||
#
|
#
|
||||||
# The script does NOT push the tag itself — that's a deliberate `git push`
|
# The script does NOT push the tag itself — that's a deliberate `git push`
|
||||||
|
|
@ -37,31 +34,19 @@ set -eu
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat >&2 <<'EOF'
|
cat >&2 <<'EOF'
|
||||||
usage: release.sh [alpha|beta|stable] [<version>]
|
usage: release.sh [<version>]
|
||||||
|
|
||||||
alpha (default) cut alpha. Auto-derive version from the latest clean
|
No args patch-bump from the latest clean zddc-server-vX.Y.Z tag.
|
||||||
zddc-server-vX.Y.Z tag plus next-patch + -alpha.N.
|
<version> explicit X.Y.Z (e.g. 0.1.0).
|
||||||
beta cut beta. Auto-derive version (vX.Y.Z + -beta.N).
|
|
||||||
stable cut stable. Without <version>, patch-bump from the
|
|
||||||
latest clean stable tag. With <version>, use it
|
|
||||||
verbatim (must be a clean X.Y.Z).
|
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
CHANNEL="${1:-alpha}"
|
case "${1:-}" in
|
||||||
case "$CHANNEL" in
|
|
||||||
alpha | beta | stable) ;;
|
|
||||||
-h | --help) usage ;;
|
-h | --help) usage ;;
|
||||||
*) echo "error: unknown channel '$CHANNEL'" >&2; usage ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
EXPLICIT_VERSION="${2:-}"
|
EXPLICIT_VERSION="${1:-}"
|
||||||
if [ -n "$EXPLICIT_VERSION" ] && [ "$CHANNEL" != "stable" ]; then
|
|
||||||
echo "error: an explicit <version> is only valid with the 'stable' channel" >&2
|
|
||||||
echo " alpha and beta versions are auto-derived." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${CODEBERG_TOKEN:-}" ]; then
|
if [ -z "${CODEBERG_TOKEN:-}" ]; then
|
||||||
echo "error: CODEBERG_TOKEN must be exported in the environment" >&2
|
echo "error: CODEBERG_TOKEN must be exported in the environment" >&2
|
||||||
|
|
@ -74,18 +59,13 @@ SCRIPT_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
||||||
TAG_PREFIX="zddc-server-v"
|
TAG_PREFIX="zddc-server-v"
|
||||||
REPO="VARASYS/ZDDC"
|
REPO="VARASYS/ZDDC"
|
||||||
|
|
||||||
# Source build-lib.sh for next_prerelease + _validate_semver. It
|
# Source build-lib.sh for _validate_semver. It requires root_dir set;
|
||||||
# requires root_dir set; pointing at the repo root works.
|
# pointing at the repo root works.
|
||||||
root_dir="$SCRIPT_DIR"
|
root_dir="$SCRIPT_DIR"
|
||||||
. "$SCRIPT_DIR/shared/build-lib.sh"
|
. "$SCRIPT_DIR/shared/build-lib.sh"
|
||||||
. "$SCRIPT_DIR/shared/publish-codeberg-release.sh"
|
. "$SCRIPT_DIR/shared/publish-codeberg-release.sh"
|
||||||
|
|
||||||
# --- Determine version -----------------------------------------------------
|
# --- Determine version -----------------------------------------------------
|
||||||
case "$CHANNEL" in
|
|
||||||
alpha | beta)
|
|
||||||
VERSION=$(next_prerelease "$CHANNEL" "$TAG_PREFIX")
|
|
||||||
;;
|
|
||||||
stable)
|
|
||||||
if [ -n "$EXPLICIT_VERSION" ]; then
|
if [ -n "$EXPLICIT_VERSION" ]; then
|
||||||
_validate_semver "$EXPLICIT_VERSION"
|
_validate_semver "$EXPLICIT_VERSION"
|
||||||
VERSION="$EXPLICIT_VERSION"
|
VERSION="$EXPLICIT_VERSION"
|
||||||
|
|
@ -102,13 +82,10 @@ case "$CHANNEL" in
|
||||||
_patch="${_rest#*.}"
|
_patch="${_rest#*.}"
|
||||||
VERSION="${_major}.${_minor}.$((_patch + 1))"
|
VERSION="${_major}.${_minor}.$((_patch + 1))"
|
||||||
fi
|
fi
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
GIT_TAG="${TAG_PREFIX}${VERSION}"
|
GIT_TAG="${TAG_PREFIX}${VERSION}"
|
||||||
|
|
||||||
echo "=== zddc-server release ==="
|
echo "=== zddc-server stable release ==="
|
||||||
echo "Channel: $CHANNEL"
|
|
||||||
echo "Version: $VERSION"
|
echo "Version: $VERSION"
|
||||||
echo "Git tag: $GIT_TAG"
|
echo "Git tag: $GIT_TAG"
|
||||||
echo
|
echo
|
||||||
|
|
@ -167,20 +144,3 @@ echo
|
||||||
echo "=== Done ==="
|
echo "=== Done ==="
|
||||||
echo "Release: https://codeberg.org/$REPO/releases/tag/$GIT_TAG"
|
echo "Release: https://codeberg.org/$REPO/releases/tag/$GIT_TAG"
|
||||||
echo "Git tag: $GIT_TAG (publish with: git push origin $GIT_TAG)"
|
echo "Git tag: $GIT_TAG (publish with: git push origin $GIT_TAG)"
|
||||||
echo
|
|
||||||
case "$CHANNEL" in
|
|
||||||
stable)
|
|
||||||
echo "Reminder (channel discipline rule 4): freshen alpha + beta now"
|
|
||||||
echo "so the floating channels resolve to at-least-current code:"
|
|
||||||
echo " ./freshen-channel zddc-server alpha"
|
|
||||||
echo " ./freshen-channel zddc-server beta"
|
|
||||||
;;
|
|
||||||
beta)
|
|
||||||
echo "Beta cut. Soak before promoting to stable."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo
|
|
||||||
echo "Don't forget to also regenerate the website releases page:"
|
|
||||||
echo " sh build.sh"
|
|
||||||
echo " git add website/releases/index.html website/releases/manifest.json"
|
|
||||||
echo " git commit && git push"
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue