Report build starts and successes, not just failures, to their own chat

Only failures were reported, so a push could reach the mirror with no way to
know short of querying the database by hand. Release runs now report:

- start: channel, arch, host, and the commit being built
- published: the packages and versions that went out, duration, channel URL
- no-changes: the run found nothing to build
- promoted: what advance moved between channels, including the rc bootstrap
  and fast-ring replication
- failed: unchanged, plus the commit context the other reports carry

Release traffic goes to OMARCHY_RELEASE_CHATBOT_URL, falling back to
BASECAMP_CHATBOT_URL, so build reports stop drowning the repository chat the
sync workflows post to. bin/setup reports which destination is configured.

The published list is captured after the build step because promote moves the
files out of build-output, and is capped at 25 entries so a full rebuild does
not produce an unreadable wall of chat.
This commit is contained in:
Ryan Hughes
2026-08-27 01:10:33 -04:00
parent 71e72e581b
commit e3c3b3e50a
5 changed files with 208 additions and 10 deletions
+23
View File
@@ -15,6 +15,7 @@ source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
source "$BUILD_ROOT/helpers/lock-helpers.sh"
source "$BUILD_ROOT/helpers/package-metadata.sh"
source "$BUILD_ROOT/helpers/basecamp-notifier.sh"
FROM=""
TO=""
@@ -223,6 +224,7 @@ package_eligible() {
mkdir -p "$TARGET_DIR"
COPIED=0
COPIED_FILES=""
PRESENT=0
SKIPPED=0
MISSING_FILES=()
@@ -277,6 +279,7 @@ while IFS=$'\t' read -r name base filename; do
echo " copied: $filename (+ .sig)"
fi
COPIED=$((COPIED + 1))
COPIED_FILES+="$filename"$'\n'
done < <(read_manifest)
echo ""
@@ -330,3 +333,23 @@ SYNC_ARGS=("--mirror" "$TO" "--arch" "$ARCH")
}
print_success "Advance complete: $FROM -> $TO"
# A promotion is how something reaches users, so say what moved and where.
if ((COPIED > 0)); then
moved=""
shown=0
while IFS= read -r moved_file; do
[[ -z "$moved_file" ]] && continue
((shown >= 25)) && break
moved+="<br>• $(package_file_label "$moved_file" | basecamp_html_escape)"
shown=$((shown + 1))
done <<<"$COPIED_FILES"
((COPIED > shown)) && moved+="<br>• …and $((COPIED - shown)) more"
label="Promoted $FROM → $TO"
[[ "$BOOTSTRAP" == true ]] && label="Bootstrapped the $TO channel from $FROM"
[[ "$FAST_RING_ONLY" == true ]] && label="Replicated fast-ring $FROM → $TO"
notify_info "$label" \
"Arch: $ARCH · $(hostname -s 2>/dev/null || echo host)<br><strong>$COPIED package(s) moved:</strong>$moved<br><br>Live at https://pkgs.omarchy.org/$TO/$ARCH/"
fi
+44 -7
View File
@@ -92,6 +92,24 @@ if [[ "$DRY_RUN" != true ]]; then
acquire_release_lock || exit 1
fi
# --- reporting ---------------------------------------------------------------
RELEASE_STARTED_AT=$(date +%s)
RELEASE_COMMIT=$(git -C "$BUILD_ROOT" rev-parse --short HEAD 2>/dev/null || echo "unknown")
RELEASE_COMMIT_SUBJECT=$(git -C "$BUILD_ROOT" log -1 --pretty=%s 2>/dev/null || echo "")
RELEASE_CONTEXT="Channel: <strong>$MIRROR</strong> · Arch: $ARCH · $(hostname -s 2>/dev/null || echo host)"
if [[ "$RELEASE_COMMIT" != "unknown" ]]; then
RELEASE_CONTEXT+="<br>Commit: <code>$RELEASE_COMMIT</code> $(basecamp_html_escape <<<"$RELEASE_COMMIT_SUBJECT")"
fi
# Captured after the build step: promote MOVES these files out of build-output,
# so the list has to be taken while they are still there.
BUILT_FILES=""
if [[ "$DRY_RUN" != true ]]; then
notify_start "Release started: $MIRROR" "$RELEASE_CONTEXT"
fi
# Step 1: Build
echo ""
if [[ "$DRY_RUN" == true ]]; then
@@ -101,7 +119,7 @@ else
fi
"$BUILD_ROOT/bin/build" "${BUILD_ARGS[@]}" || {
print_error "Build failed"
notify_error "Release failed: Build step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Build step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -111,12 +129,17 @@ if [[ "$DRY_RUN" == true ]]; then
exit 0
fi
BUILT_FILES=$(built_package_files "$BUILD_OUTPUT_DIR")
BUILT_COUNT=$(grep -c '' <<<"$BUILT_FILES")
[[ -z "$BUILT_FILES" ]] && BUILT_COUNT=0
print_info "Built $BUILT_COUNT package(s) this run"
# Step 2: Sign
echo ""
print_info "Step 2/6: Signing packages..."
"$BUILD_ROOT/bin/sign" --arch "$ARCH" --mirror "$MIRROR" || {
print_error "Signing failed"
notify_error "Release failed: Signing step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Signing step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -125,7 +148,7 @@ echo ""
print_info "Step 3/6: Promoting to production..."
"$BUILD_ROOT/bin/promote-build" --arch "$ARCH" --mirror "$MIRROR" || {
print_error "Promotion failed"
notify_error "Release failed: Promotion step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Promotion step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -134,7 +157,7 @@ echo ""
print_info "Step 4/6: Cleaning old versions..."
"$BUILD_ROOT/bin/clean-repo" --arch "$ARCH" --mirror "$MIRROR" || {
print_error "Cleaning failed"
notify_error "Release failed: Clean step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Clean step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -143,7 +166,7 @@ echo ""
print_info "Step 5/6: Updating repository database..."
"$BUILD_ROOT/bin/update-repo" --arch "$ARCH" --mirror "$MIRROR" || {
print_error "Database update failed"
notify_error "Release failed: Database update step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Database update step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -159,7 +182,7 @@ if [[ "$SKIP_PROD_CHECK" == true ]]; then
fi
"$BUILD_ROOT/bin/sync-repo" "${SYNC_ARGS[@]}" || {
print_error "Sync failed"
notify_error "Release failed: Sync step failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: Sync step failed" "$RELEASE_CONTEXT"
exit 1
}
@@ -175,7 +198,7 @@ if [[ "$MIRROR" == "stable" ]]; then
[[ "$SKIP_PROD_CHECK" == true ]] && REPLICATE_ARGS+=(--skip-prod-check)
"$BUILD_ROOT/bin/advance-channel" "${REPLICATE_ARGS[@]}" || {
print_error "Fast-ring replication to rc failed"
notify_error "Release failed: rc parity replication failed" "Mirror: $MIRROR | Arch: $ARCH"
notify_error "Release failed: rc parity replication failed" "$RELEASE_CONTEXT"
exit 1
}
else
@@ -185,3 +208,17 @@ fi
echo ""
print_success "Release workflow completed successfully!"
duration=$(format_duration $(($(date +%s) - RELEASE_STARTED_AT)))
summary="$RELEASE_CONTEXT<br>Duration: $duration"
if ((BUILT_COUNT > 0)); then
summary+="<br><br><strong>$BUILT_COUNT package(s) published:</strong>"
summary+="$(format_package_list_html "$BUILT_FILES")"
summary+="<br><br>Live at https://pkgs.omarchy.org/$MIRROR/$ARCH/"
notify_success "Release published: $MIRROR" "$summary"
else
# Nothing to build usually means a queued run raced another that already did
# the work. Worth saying, but not worth dressing up as a publish.
summary+="<br>No packages needed building — the channel was already current."
notify_info "Release complete (no changes): $MIRROR" "$summary"
fi
+16
View File
@@ -274,6 +274,22 @@ else
echo " services source it before signing."
fi
# Release reporting is optional, but silence is indistinguishable from a
# broken hook, so say which chat (if any) will receive build reports.
if [[ -f "$CREDENTIALS" ]]; then
if grep -q 'OMARCHY_RELEASE_CHATBOT_URL' "$CREDENTIALS"; then
print_success "Release reports go to the dedicated release chat"
elif grep -q 'BASECAMP_CHATBOT_URL' "$CREDENTIALS"; then
print_warning "Release reports fall back to BASECAMP_CHATBOT_URL (the repository chat)"
echo " Export OMARCHY_RELEASE_CHATBOT_URL in $CREDENTIALS to send them"
echo " to their own chat instead."
else
print_warning "No chatbot URL in $CREDENTIALS — build reports are disabled"
echo " Export OMARCHY_RELEASE_CHATBOT_URL to receive start/publish/failure"
echo " reports in Basecamp."
fi
fi
if rclone listremotes 2>/dev/null | grep -q '^pkgs.omarchy.org:'; then
print_success "rclone remote 'pkgs.omarchy.org' configured"
else