#!/usr/bin/env sh # # Does this artifact need building, or is the channel already serving this exact # source? Prints `true` or `false`. # # should-build.sh # # Note 3127 §4, skip-if-exists — adapted, because §4 assumes a registry keyed by # VERSION and rule 145 removed exactly that. There is no `:` tag to ask # about. What there IS, for both clients, is a channel that publishes the version it # is serving, and that answers the same question: if the channel already serves what # this source derives, the artifact would be byte-identical and there is nothing to # build. # # WHAT THIS REPLACES, and why that matters more here than the cost saving: the # `paths:` filters in the workflows were a SECOND, independent statement of each # artifact's file set, hand-kept beside the one in `version.sh`. They disagreed # within a day of the sets being written — `packaging/` was added to the sets and # not to the filters, so the commit that fixed a derivation bug never ran on the two # lanes it fixed (85ead4d). §3 warns about exactly this duplication; one definition # with one reader is the fix, and the cost saving is a bonus. # # THE SERVER IS NOT LISTED HERE, DELIBERATELY. Its image build is ~15 seconds against # 6 and 9 minutes for the clients, so there is little to save — and always building # it is strictly better for a server that can face the internet, because it picks up # `python:3.12-slim` base updates on every push. That is also why the base-image # tension in §4 does not bite this project: the artifact most exposed to it never # skips. The clients' bases are CI runner images, pinned deliberately. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd)" artifact="${1:?usage: should-build.sh }" channel="${2:?usage: should-build.sh }" case "$artifact" in desktop|android) : ;; *) echo "should-build.sh: unknown artifact '$artifact'" >&2; exit 2 ;; esac case "$channel" in dev|stable) : ;; *) echo "should-build.sh: unknown channel '$channel'" >&2; exit 2 ;; esac # The value that answers "is this the same code?" — which is not the same as the one # the guard compares. # # desktop the ordering key IS the identity; one value, one clock. # android the NAME. Its versionCode is build-time and moves every run, so # comparing that would report a change on every push and never skip. case "$artifact" in desktop) derived="$(sh "$ROOT/packaging/version.sh" key desktop)" ;; android) derived="$(sh "$ROOT/packaging/version.sh" display android)" ;; esac published="$(sh "$ROOT/packaging/guard-forward.sh" published "$artifact" "$channel")" if [ -z "$published" ]; then echo "should-build: $channel serves no $artifact yet — building." >&2 echo true exit 0 fi if [ "$derived" = "$published" ]; then # UNCHANGED. The channel is already serving this exact source, so a build would # produce the same artifact under the same name and republish it for nothing. # # Skipping is safe here in a way it would not be if anything pinned: there is no # immutable tag to re-push with different bytes (rule 145 removed version tags), # so the immutability argument in §4.2 does not apply and this stands on cost # alone — which is the smaller, honest claim. echo "should-build: $channel already serves $artifact $derived — skipping." >&2 echo false exit 0 fi echo "should-build: $artifact moved $published -> $derived — building." >&2 echo true