diff --git a/README.md b/README.md index 37b3c4f..dcc648e 100644 --- a/README.md +++ b/README.md @@ -733,7 +733,7 @@ reaches the mirror in minutes rather than hours: 1. **check-versions** (`*:0/5`): Pulls latest from git, compares PKGBUILD versions to published versions, creates state files if builds are needed 2. **auto-release-edge** (`*:1/5`): If a state file exists, builds all edge packages that need updates -3. **auto-release-rc** (`*:2/5`): Builds the rc channel from the `rc` branch worktree (`/root/omarchy-pkgs-rc`), publishing into the shared channel tree. The orchestrator also triggers this immediately over ssh when cutting an RC +3. **auto-release-rc** (`*:2/5`): Builds the rc channel from the `rc` branch worktree (`/root/omarchy-pkgs-rc`), publishing into the shared channel tree. It runs from the main checkout and creates that worktree on demand, so a host with no rc branch yet is a no-op rather than a failing unit. The orchestrator also triggers this immediately over ssh when cutting an RC 4. **auto-release-stable** (`*:3/5`): If a state file exists, builds `release_ring=fast` packages for stable and replicates them to rc That cadence is only safe because of three guards: diff --git a/bin/auto-release-rc b/bin/auto-release-rc new file mode 100755 index 0000000..07dfc31 --- /dev/null +++ b/bin/auto-release-rc @@ -0,0 +1,43 @@ +#!/bin/bash +# Scheduled entry point for the rc channel. +# +# The rc channel builds from the standing `rc` branch in its own worktree, but +# that branch does not exist until the first RC is cut — and a host set up +# before then has no worktree either. This runs from the MAIN checkout, which +# always exists, and makes both conditions non-events: no branch means nothing +# to build, and a missing worktree is created on demand rather than failing +# the unit every five minutes. + +set -e + +BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..") +source "$BUILD_ROOT/helpers/message-helpers.sh" + +RC_WORKTREE="${OMARCHY_RC_WORKTREE:-/root/omarchy-pkgs-rc}" +STATE_DIR="${OMARCHY_STATE_DIR:-/root/.state}" + +# Nothing queued: the common case. Exit before touching the network. +[[ -f "$STATE_DIR/.sync-needed-rc" ]] || exit 0 + +git -C "$BUILD_ROOT" fetch --quiet origin rc 2>/dev/null || true + +if ! git -C "$BUILD_ROOT" show-ref --verify --quiet refs/remotes/origin/rc; then + print_info "No rc branch yet — nothing to build (the first RC cut creates it)" + exit 0 +fi + +if [[ ! -d "$RC_WORKTREE" ]]; then + print_info "Creating rc worktree at $RC_WORKTREE..." + if git -C "$BUILD_ROOT" show-ref --verify --quiet refs/heads/rc; then + git -C "$BUILD_ROOT" worktree add "$RC_WORKTREE" rc + else + git -C "$BUILD_ROOT" worktree add --track -b rc "$RC_WORKTREE" origin/rc + fi +fi + +# The rc branch is rebuilt as master + pins for each cut and force-pushed, so +# this follows with a hard reset rather than a fast-forward pull. +git -C "$RC_WORKTREE" fetch origin rc +git -C "$RC_WORKTREE" reset --hard origin/rc + +exec "$RC_WORKTREE/bin/auto-release" rc diff --git a/bin/setup b/bin/setup index a12559e..83cf5ec 100755 --- a/bin/setup +++ b/bin/setup @@ -229,8 +229,8 @@ else elif git -C "$BUILD_ROOT" show-ref --verify --quiet refs/remotes/origin/rc; then git -C "$BUILD_ROOT" worktree add --track -b rc "$RC_WORKTREE" origin/rc else - print_info "No rc branch yet — the first RC cut creates it, and the rc build" - echo " trigger creates this worktree on demand. Nothing to do." + print_info "No rc branch yet — the first RC cut creates it, and the rc" + echo " release unit creates this worktree on demand. Nothing to do." fi fi echo "" diff --git a/systemd/omarchy-auto-release-rc.service b/systemd/omarchy-auto-release-rc.service index 21b9a4e..86bb943 100644 --- a/systemd/omarchy-auto-release-rc.service +++ b/systemd/omarchy-auto-release-rc.service @@ -5,13 +5,11 @@ Wants=network-online.target [Service] Type=oneshot -# The rc channel builds from the rc branch worktree, but publishes into the -# primary checkout's channel tree via OMARCHY_REPO_ROOT. The rc branch is -# rebuilt (master + pin commits) each release train and force-pushed, so this -# worktree follows with a hard reset rather than a fast-forward pull. -ExecStartPre=/usr/bin/git -C /root/omarchy-pkgs-rc fetch origin rc -ExecStartPre=/usr/bin/git -C /root/omarchy-pkgs-rc reset --hard origin/rc -ExecStart=/bin/bash -c 'source /root/.omarchy/build-credentials && /root/omarchy-pkgs-rc/bin/auto-release rc' +# Runs from the main checkout: bin/auto-release-rc creates and syncs the rc +# branch worktree itself, so a host with no rc branch yet is a no-op instead +# of a unit that fails every five minutes. Builds happen in the worktree but +# publish into the primary checkout's channel tree via OMARCHY_REPO_ROOT. +ExecStart=/bin/bash -c 'source /root/.omarchy/build-credentials && /root/omarchy-pkgs/bin/auto-release-rc' Environment=OMARCHY_STATE_DIR=/root/.state Environment=OMARCHY_REPO_ROOT=/root/omarchy-pkgs/pkgs.omarchy.org TimeoutStartSec=7200