.github/workflows/release.yml built and published the bakery binary itself, but it lived under .github/ and targeted runs-on: [self-hosted, hestia] — a runner label only registered against Forgejo, never against GitHub Actions. It has therefore never run; get.sh has been pointing at dl.breadway.dev/bakery/... this whole time with nothing actually publishing there. Recreated the same logic as .forgejo/workflows/release-bakery.yml, matching the sibling release-bread-theme.yml in this repo (manual clone instead of actions/checkout, GH_RELEASE_TOKEN instead of the GitHub-provided GITHUB_TOKEN, same dormant-until-provisioned minisign signing step). Removed the dead .github copy.
133 lines
4.5 KiB
Bash
Executable file
133 lines
4.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# doctor-channels.sh — detect drift between a repo's declared distribution
|
|
# channel(s) and its actual .forgejo/workflows/ + packaging metadata.
|
|
#
|
|
# See docs/release-channels.md for the policy this checks against.
|
|
#
|
|
# Usage:
|
|
# scripts/doctor-channels.sh [BASE_DIR]
|
|
#
|
|
# BASE_DIR defaults to the parent of this repo checkout (i.e. run from a
|
|
# normal ~/Projects/bread-ecosystem checkout, it scans sibling ~/Projects/*
|
|
# repos). Point it at a directory of worktrees (e.g. ~/Projects, which is
|
|
# also where *-fix-worktree checkouts live) to check those instead:
|
|
#
|
|
# scripts/doctor-channels.sh ~/Projects
|
|
#
|
|
# Exits 0 if no drift found, 1 if any repo has drift (so it's CI-friendly).
|
|
#
|
|
# Requires: python3 (tomllib, stdlib since 3.11)
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
BASE_DIR="${1:-$(dirname "${SCRIPT_DIR}")}"
|
|
REGISTRY="${SCRIPT_DIR}/registry/bread-ecosystem.toml"
|
|
|
|
if [[ ! -f "${REGISTRY}" ]]; then
|
|
echo "error: registry not found at ${REGISTRY}" >&2
|
|
exit 2
|
|
fi
|
|
|
|
# repo (last path segment of registry `repo = "Breadway/x"`) -> 1
|
|
mapfile -t registry_repos < <(python3 -c "
|
|
import tomllib
|
|
with open('${REGISTRY}', 'rb') as f:
|
|
d = tomllib.load(f)
|
|
for p in d['products']:
|
|
print(p['repo'].split('/')[-1])
|
|
")
|
|
|
|
is_in_registry() {
|
|
local name="$1"
|
|
for r in "${registry_repos[@]}"; do
|
|
[[ "${r}" == "${name}" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Repos with a deliberately non-standard packaging shape that the
|
|
# single-PKGBUILD/single-package.yml heuristic below doesn't fit. Extend
|
|
# this if another repo grows a legitimately special-cased layout.
|
|
PACKAGE_CHECK_EXEMPT=("bos") # ships an ISO via release-iso.yml; its PKGBUILDs
|
|
# under packaging/*/ build bundled AUR deps
|
|
# (bibata, calamares, ...), each with its own
|
|
# dedicated workflow — not a pacman-channel package.
|
|
|
|
is_package_check_exempt() {
|
|
local name="$1"
|
|
for r in "${PACKAGE_CHECK_EXEMPT[@]}"; do
|
|
[[ "${r}" == "${name}" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
drift=0
|
|
checked=0
|
|
|
|
for dir in "${BASE_DIR}"/*/; do
|
|
name="$(basename "${dir}")"
|
|
name="${name%-fix-worktree}" # normalize worktree checkouts back to the repo name
|
|
[[ -d "${dir}/.git" || -f "${dir}/.git" ]] || continue
|
|
# Skip bread-ecosystem itself — it's a multi-product repo the registry
|
|
# membership check above doesn't map 1:1, and it's already reviewed by
|
|
# hand above (bakery + bread-theme products).
|
|
[[ "${name}" == "bread-ecosystem" ]] && continue
|
|
|
|
checked=$((checked + 1))
|
|
has_bakery_toml=0
|
|
[[ -f "${dir}/bakery.toml" ]] && has_bakery_toml=1
|
|
|
|
has_release_wf=0
|
|
compgen -G "${dir}/.forgejo/workflows/release*.yml" >/dev/null 2>&1 && has_release_wf=1
|
|
|
|
in_registry=0
|
|
is_in_registry "${name}" && in_registry=1
|
|
|
|
has_pkgbuild=0
|
|
find "${dir}" -maxdepth 3 -iname 'PKGBUILD' -not -path '*/.git/*' 2>/dev/null \
|
|
| grep -q . && has_pkgbuild=1
|
|
|
|
has_package_wf=0
|
|
[[ -f "${dir}/.forgejo/workflows/package.yml" ]] && has_package_wf=1
|
|
|
|
issues=()
|
|
|
|
if [[ "${has_bakery_toml}" == 1 && "${in_registry}" == 0 ]]; then
|
|
issues+=("has bakery.toml but no registry/bread-ecosystem.toml entry")
|
|
fi
|
|
if [[ "${in_registry}" == 1 && "${has_bakery_toml}" == 0 ]]; then
|
|
issues+=("registered in bread-ecosystem.toml but has no bakery.toml")
|
|
fi
|
|
if [[ "${in_registry}" == 1 && "${has_release_wf}" == 0 ]]; then
|
|
issues+=("registered + has bakery.toml but no release*.yml workflow")
|
|
fi
|
|
if [[ "${has_bakery_toml}" == 1 && "${in_registry}" == 0 && "${has_release_wf}" == 1 ]]; then
|
|
issues+=("has a release workflow for a product not in the registry (index.json will never include it)")
|
|
fi
|
|
if ! is_package_check_exempt "${name}"; then
|
|
if [[ "${has_pkgbuild}" == 1 && "${has_package_wf}" == 0 ]]; then
|
|
issues+=("has a PKGBUILD but no package.yml workflow")
|
|
fi
|
|
if [[ "${has_package_wf}" == 1 && "${has_pkgbuild}" == 0 ]]; then
|
|
issues+=("has package.yml but no PKGBUILD")
|
|
fi
|
|
fi
|
|
|
|
if [[ ${#issues[@]} -gt 0 ]]; then
|
|
drift=1
|
|
echo "${name}:"
|
|
for i in "${issues[@]}"; do
|
|
echo " - ${i}"
|
|
done
|
|
fi
|
|
done
|
|
|
|
echo
|
|
echo "checked ${checked} repos under ${BASE_DIR}"
|
|
if [[ "${drift}" == 0 ]]; then
|
|
echo "no channel drift found"
|
|
else
|
|
echo "drift found — see docs/release-channels.md for the policy"
|
|
fi
|
|
exit "${drift}"
|