diff --git a/README.md b/README.md index ad2b051..d63b0eb 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,18 @@ bin/repo push --package nvidia-580xx-utils # Upload + publish on the host `bin/upload-prebuilt` there. Do not publish from a local checkout instead: only the repository host holds the complete repository and the signing key. +**Name the package.** `build` asks the local repository database which packages +are already built, and a build machine has no such database, so an unscoped run +treats every package as out of date and rebuilds the whole repository. `deploy` +refuses to run unscoped when that database is missing. Unscoped builds belong on +the repository host, where `bin/repo release` does the same job against a real +database. + +Every other command in `bin/` — `sign`, `promote`, `update`, `clean`, `migrate`, +`remove`, `sync`, `release` — works on the published tree directly and is meant +to run on the repository host. `build`, `push` and `deploy` are the three that +may run elsewhere. + ## Commands ### Global Flags diff --git a/bin/deploy b/bin/deploy index 622a228..cfcf171 100755 --- a/bin/deploy +++ b/bin/deploy @@ -94,6 +94,26 @@ if [[ "$PACKAGE_FLAG_GIVEN" == true && ${#PACKAGES[@]} -eq 0 ]]; then exit 1 fi +# bin/build asks the local repository database what is already built. On a build +# machine that database does not exist, so every package looks unbuilt and an +# unscoped run rebuilds the entire repository and publishes it. Deploying from +# here is for the occasional heavy package, so name it. +if [[ ${#PACKAGES[@]} -eq 0 ]] && ! on_repo_host; then + print_error "--package is required when deploying from a build machine" + echo "" + echo "There is no repository database in:" + echo " $REPO_DIR" + echo "" + echo "bin/build uses it to tell which packages are already built, so without it" + echo "every package looks out of date and this would build and publish all of" + echo "them. Name the package you came here to build:" + echo " bin/repo deploy --package " + echo "" + echo "Unscoped builds belong on the repository host, where 'bin/repo release'" + echo "does the same job against a real database." + exit 1 +fi + echo "" print_info "This will:" echo " 1. Build packages locally" diff --git a/bin/push-build b/bin/push-build index b9d2fe5..21523e8 100755 --- a/bin/push-build +++ b/bin/push-build @@ -126,6 +126,23 @@ if [[ "$PACKAGE_FLAG_GIVEN" == true && -z "$PACKAGES" ]]; then exit 1 fi +# On a build machine an unscoped build leaves the whole repository in +# build-output, because there is no local database to tell it what already +# exists. Interactively that is survivable — the confirmation below lists every +# package first — but with --yes nobody sees the list, so require an explicit +# selection instead. +if [[ -z "$PACKAGES" && "$ASSUME_YES" == true ]] && ! on_repo_host; then + print_error "--package is required to publish unattended from a build machine" + echo "" + echo "There is no repository database in $REPO_DIR, so a preceding unscoped" + echo "build would have rebuilt everything rather than only what changed, and" + echo "--yes would publish all ${#ALL_FILES[@]} of them without showing the list." + echo "" + echo "Name the packages to publish:" + echo " bin/repo push --package " + exit 1 +fi + FILES=() if [[ -z "$PACKAGES" ]]; then FILES=("${ALL_FILES[@]}") diff --git a/helpers/host-helpers.sh b/helpers/host-helpers.sh index 1d5fbe8..9f693d6 100644 --- a/helpers/host-helpers.sh +++ b/helpers/host-helpers.sh @@ -33,6 +33,16 @@ resolve_repo_host() { return 1 } +# True when this checkout holds the published repository, which in practice means +# this machine is the repository host. Every other command in bin/ works on that +# tree directly; build, push and deploy are the ones that may run elsewhere. +# +# The database is the marker rather than the directory: bin/build creates empty +# mirror directories as a side effect, so their presence proves nothing. +on_repo_host() { + [[ -f "$REPO_DIR/omarchy.db" || -f "$REPO_DIR/omarchy.db.tar.zst" ]] +} + # Shared wording so every command explains configuration the same way. print_no_repo_host() { print_error "No repository host configured"