Skip to content

Getting a release: what is published and how to check it

Mica OS is published as GitHub releases of micaoss/mica-build. Everything is anonymous: no token, no registry login. A release is one product:

Release Tag Carries
A product release <board>.<variant>.<YYYYMMDD-HHMM> mica-<board>.<variant>-<stamp>.img.gz, its .micaupd archives, mica-build.lock, SHA256SUMS

Each product releases on its own, so there is no index to start from: a product’s newest release is the newest tag that starts with <board>.<variant>..

The same files are on the resource service. The release run posts each release there (mica-build:README.md): the files are at https://dl.res.micaos.dev/mica/<board>.<variant>/<stamp>/<asset>, beside the release’s own index.json, which lists them with their sizes and digests, and the manifest under the update root https://res.micaos.dev/update/ names every product’s current release. That is what the website’s download pages and a device read; a release an administrator deleted there is gone from both.

status: shipped — evidence: docs/reference/release-lock.md, mica-build:README.md, mica-build:boards/products.md

Every board is a release target. Its products are <board>.basic, the default, on uefi-x64, uefi-arm64, cx3576, s905x5m, mini-x64 and qemu-armhf; <board>.full, which adds the container engine, on uefi-x64, uefi-arm64 and cx3576; uefi-x64.docker, full with Docker as its engine; and s905x5m.emmc-full and s905x5m.sd-full, that board’s container products for its eMMC and for an SD card. Which of them have a release is on the download page; a product without one has nothing to download and is built from source (build guide). A dev product is built locally and never released; there are no minimal products.

The round of 2026-10-21 released these, all with core 0.0.3 (core set core.general.20261021-2254):

Product Stamp What it carries
cx3576.full 20261021-2257 systemd, containers, WiFi and Bluetooth: factory access point, BLE provisioning
s905x5m.sd-full 20261021-2318 the same, on an SD card
s905x5m.emmc-full 20261021-2335 the same, on the eMMC
uefi-x64.full 20261021-2316 systemd, Podman, no radio
uefi-x64.docker 20261021-2338 systemd, Docker, no radio
mini-x64.basic 20261021-2317 OpenRC, the management plane and SSH, no console
qemu-armhf.basic 20261021-2319 OpenRC, the management plane and SSH, no console

status: shipped — evidence: mica-build:boards/products.md, mica-core:docs/mica-core.md

A published image is not a booted image. The cx3576 and s905x5m products are started by nothing automatic, because no suite boots a product’s FIT image (board status). Every amd64 product (uefi-x64.*, mini-x64.basic) is booted in its release run, and the uefi-arm64 ones carry hand-run QEMU rows (harness section 4). Being a release target means the images are built and published; it is not a claim about hardware (support tiers).

A release carries:

  • mica-<board>.<variant>-<stamp>.img.gz — the factory disk image, gzip-compressed. No raw .img is uploaded.
  • mica-<board>.<variant>-<stamp>.micaupd — the full update archive, always.
  • .root.micaupd and .kernel.micaupd — the partial archives, when the component they omit is unchanged since the product’s previous release (update packages).
  • mica-build.lock and SHA256SUMS, which lists the lock.

status: shipped — evidence: mica-build:boards/products.md, docs/operate/updates.md, docs/hardware/README.md

终端窗口
PRODUCT=uefi-x64.full
TAG=$(curl -fsSL "https://api.github.com/repos/micaoss/mica-build/releases?per_page=100" \
| jq -r --arg p "$PRODUCT." '[.[] | select(.draft == false and (.tag_name | startswith($p)))][0].tag_name')
echo "$TAG" # uefi-x64.full.<YYYYMMDD-HHMM>

The GitHub API lists releases newest first. gh release list -R micaoss/mica-build shows the same list.

status: shipped — evidence: mica-build:README.md

终端窗口
REL=https://github.com/micaoss/mica-build/releases/download/$TAG
STAMP=${TAG##*.}
curl -fsSLO "$REL/SHA256SUMS"
curl -fsSLO "$REL/mica-build.lock"
curl -fsSLO "$REL/mica-$PRODUCT-$STAMP.img.gz"
sha256sum -c SHA256SUMS # lists the lock
awk -F'\t' '$1 == "asset" && $5 == "mica-'"$PRODUCT-$STAMP"'.img.gz" {print $6 " " $5}' mica-build.lock \
| sha256sum -c - # the lock names the image's sha256

The chain is SHA256SUMS → the lock → the asset row’s sha256 → the file (release lock 1.2.2).

status: shipped — evidence: mica-build:src/release/scoped.ts, docs/reference/release-lock.md

Three independent statements cover one image, and they are checked in different places:

  1. SHA256SUMS lists the lock alone; sha256sum SHA256SUMS is the release’s trust hash, the value a lock that consumes this release quotes.
  2. The lock’s asset row names the digest of the compressed file:
    终端窗口
    awk -F'\t' '$1 == "asset" && $2 == "'"$PRODUCT"'"' mica-build.lock
  3. The OCI layer carries the same file and is readable anonymously: the layer digest equals the asset row’s sha256, and its mica.uncompressed-sha256 and mica.uncompressed-size annotations are what gzip -dc produces:
    终端窗口
    REF=$(awk -F'\t' '$1 == "bundle" && $2 == "'"$PRODUCT"'" && $3 == "image" {print $4}' mica-build.lock)
    T=$(curl -fsS "https://ghcr.io/token?scope=repository:micaoss/mica-build:pull&service=ghcr.io" | jq -r .token)
    curl -fsSL -H "Authorization: Bearer $T" \
    -H 'Accept: application/vnd.oci.image.manifest.v1+json' \
    "https://ghcr.io/v2/micaoss/mica-build/manifests/${REF##*@}" | jq '.layers'
    gzip -dc "mica-$PRODUCT-$STAMP.img.gz" | sha256sum

status: shipped — evidence: mica-build:src/release/scoped.ts, docs/reference/release-lock.md

The lock is a mica-lock v1 file naming the release’s commit and every input that went into it: the board’s pool, packages and components, the input releases of mica-build-env, mica-system-base, mica-core, mica-pkgs, mica-podman and mica-docker with their trust hashes, and the product’s signed deployment, bundles and assets (release lock 1.2.2).

A checksum next to a file proves only that the file arrived intact. What makes an image trustworthy is the signature chain inside it (release signing) and the platform trusting that signer; the hashes above are the integrity half, not the authenticity half.

status: shipped — evidence: docs/reference/release-lock.md, docs/security/signing.md

status: shipped — evidence: docs/start/flashing.md, docs/operate/updates.md, docs/start/build.md, docs/releases/how-releases-work.md