clawdie-iso/skills/iso-publish/SKILL.md

6.6 KiB

name description
iso-publish Publish a completed Clawdie operator USB image from tmp/output to the OSA nginx downloads webroot, generating compression/checksum/manifest when needed, rotating public symlinks, updating the simple index.html, and verifying download URLs.

iso-publish

Use this skill after iso-build succeeds and the operator wants the image made available at https://osa.smilepowered.org/downloads/iso/.

Only publish when the operator explicitly assigns it. Publishing changes the public download target.

Paths

  • Repo root: /home/clawdie/clawdie-iso
  • Build output: tmp/output
  • Public webroot: /usr/local/www/osa/downloads/iso
  • Public base URL: https://osa.smilepowered.org/downloads/iso

Manifest contract

scripts/write-artifact-manifest.sh writes the canonical clawdie.iso.publish.v1 manifest beside the image as tmp/output/<image>.manifest.json. Hermes consumes that file for iso-flash-verify; Colibri can ingest it directly. See docs/ISO-MANIFESTS.md for shared fields and handoff rules.

Preconditions

Run from the repo root on the FreeBSD host. Use one command at a time.

git fetch origin
git status --short --branch
git rev-parse --short HEAD
ls -lh tmp/output
find tmp/output -maxdepth 1 -type f -name 'clawdie-xfce-*.img*' -ls

Confirm the image filename includes the current commit suffix. Do not publish an old unsuffixed or wrong-commit image.

If tmp/output is root-owned from the build, use an elevated shell for publish steps that write beside the artifact, or use the sudo variants shown below.

1. Select the image

Set IMG to the raw image produced by the current build. Example:

IMG="tmp/output/clawdie-xfce-quindecim-usb-22.05.26-8c8dd5f.img"
test -f "$IMG"
GZ="${IMG}.gz"
SHA="${GZ}.sha256"

2. Compress if needed

If ${GZ} already exists for the same raw image, inspect it before reusing it:

ls -lh "$IMG" "$GZ"

If ${GZ} is missing or stale, create it:

gzip -c "$IMG" > "$GZ"

Record the published file size:

stat -f '%z %N' "$GZ"

3. Generate checksum and manifest

sha256 "$GZ" > "$SHA"
cat "$SHA"
MANIFEST="$(scripts/write-artifact-manifest.sh "$GZ" --base-url https://osa.smilepowered.org/downloads/iso)"
cat "$MANIFEST"

If tmp/output artifacts are root-owned, run the manifest step with sudo and preserve the base URL:

MANIFEST="$(sudo env BUILT_BY="Codex ISO Builder" scripts/write-artifact-manifest.sh "$GZ" --base-url https://osa.smilepowered.org/downloads/iso)"
ls -l /usr/local/www/osa/downloads/iso

Remove only the old public Clawdie image/checksum symlinks, not the new output files under tmp/output:

sudo find /usr/local/www/osa/downloads/iso -maxdepth 1 -type l -name 'clawdie-xfce-*.img.gz' -delete
sudo find /usr/local/www/osa/downloads/iso -maxdepth 1 -type l -name 'clawdie-xfce-*.img.gz.sha256' -delete
sudo find /usr/local/www/osa/downloads/iso -maxdepth 1 -type l -name 'clawdie-xfce-*.manifest.json' -delete
sudo ln -s "$(pwd)/$GZ" "/usr/local/www/osa/downloads/iso/$(basename "$GZ")"
sudo ln -s "$(pwd)/$SHA" "/usr/local/www/osa/downloads/iso/$(basename "$SHA")"
sudo ln -s "$(pwd)/$MANIFEST" "/usr/local/www/osa/downloads/iso/$(basename "$MANIFEST")"
sudo chgrp -h webmaster "/usr/local/www/osa/downloads/iso/$(basename "$GZ")"
sudo chgrp -h webmaster "/usr/local/www/osa/downloads/iso/$(basename "$SHA")"
sudo chgrp -h webmaster "/usr/local/www/osa/downloads/iso/$(basename "$MANIFEST")"

6. Update index.html

Set helper variables:

GZ_BASE="$(basename "$GZ")"
SHA_BASE="$(basename "$SHA")"
MANIFEST_BASE="$(basename "$MANIFEST")"

Write the simple public index:

sudo sh -c "cat > /usr/local/www/osa/downloads/iso/index.html" <<EOF
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Clawdie ISO Downloads</title>
</head>
<body>
  <h1>Clawdie ISO Downloads</h1>
  <ul>
    <li><a href="${GZ_BASE}">${GZ_BASE}</a></li>
    <li><a href="${SHA_BASE}">${SHA_BASE}</a></li>
    <li><a href="${MANIFEST_BASE}">${MANIFEST_BASE}</a></li>
  </ul>
</body>
</html>
EOF
sudo chown root:webmaster /usr/local/www/osa/downloads/iso/index.html
sudo chmod 0644 /usr/local/www/osa/downloads/iso/index.html

7. Verify local webroot

ls -l /usr/local/www/osa/downloads/iso
readlink "/usr/local/www/osa/downloads/iso/$(basename "$GZ")"
readlink "/usr/local/www/osa/downloads/iso/$(basename "$SHA")"
readlink "/usr/local/www/osa/downloads/iso/$(basename "$MANIFEST")"
cat /usr/local/www/osa/downloads/iso/index.html

8. Verify public URLs

fetch -qo - https://osa.smilepowered.org/downloads/iso/
fetch -qo - "https://osa.smilepowered.org/downloads/iso/$(basename "$SHA")"
fetch -qo - "https://osa.smilepowered.org/downloads/iso/$(basename "$MANIFEST")"

This downloads the full compressed image to /dev/null; run it so the direct image URL is proven, but expect it to take time:

fetch -o /dev/null "https://osa.smilepowered.org/downloads/iso/$(basename "$GZ")"

9. Report back

Report these items to the operator:

  • image URL
  • checksum URL
  • manifest URL
  • index URL
  • SHA256 hash
  • published compressed size in bytes
  • Hermes deploy block
  • any root-owned output or permission hiccups

Example:

Published:
- https://osa.smilepowered.org/downloads/iso/<image>.img.gz
- https://osa.smilepowered.org/downloads/iso/<image>.img.gz.sha256
- https://osa.smilepowered.org/downloads/iso/<image>.manifest.json
- https://osa.smilepowered.org/downloads/iso/

Checksum: <sha256>
Size: <bytes> bytes

HERMES_USB_DEPLOY_READY=1
IMAGE_URL=https://osa.smilepowered.org/downloads/iso/<image>.img.gz
SHA256_URL=https://osa.smilepowered.org/downloads/iso/<image>.img.gz.sha256
MANIFEST_URL=https://osa.smilepowered.org/downloads/iso/<image>.manifest.json
COMMIT=<short-commit>
SIZE_BYTES=<compressed-size-bytes>
SHA256=<sha256>
EXPECTED_USB_MODEL=<operator-supplied-model>
EXPECTED_USB_SIZE=<operator-supplied-size>
USB_ATTACHED_TO=linux-hermes | freebsd-host

Safety notes

  • Do not delete tmp/output artifacts during publish.
  • Do not publish an image whose filename lacks the current commit suffix.
  • Do not replace unrelated files in the webroot.
  • Prefer symlinks into tmp/output for current internal testing; if this becomes a public release process, switch to copied immutable artifacts outside the build workspace.