diff --git a/helpers/package-metadata.sh b/helpers/package-metadata.sh index f73cc19..bd44abe 100644 --- a/helpers/package-metadata.sh +++ b/helpers/package-metadata.sh @@ -12,6 +12,8 @@ # { "source": "aur", "pkgrel": { "suffix": 1, "offset": 1 } } # { "source": "aur", "rebuild_on": ["qt6-base"] } # { "source": "local" } +# { "source": "local", "channels": ["edge"] } +# { "source": "local", "channels": ["edge", "rc", "stable"] } # { "source": "local", "min_release_age": "24h" } # { "source": "local", "upstream": { "github": "owner/repo", "checksums": "SHASUMS256.txt", "assets": { "x86_64": "name-{tag}-x64.tar.xz" } } } # @@ -138,6 +140,28 @@ package_has_pkgbuild() { [[ -f "$pkgdir/PKGBUILD" ]] } +# Channel membership: where a package may be published. Packages without a +# `channels` key are members of every channel (they flow edge -> rc -> stable). +package_has_channels() { + local pkgdir="$1" metadata + metadata=$(metadata_file_for_dir "$pkgdir") + [[ -f "$metadata" ]] || return 1 + jq -e 'has("channels")' "$metadata" >/dev/null +} + +package_channels() { + local pkgdir="$1" metadata + metadata=$(metadata_file_for_dir "$pkgdir") + [[ -f "$metadata" ]] || return 0 + jq -r '(.channels // [])[]' "$metadata" +} + +package_in_channel() { + local pkgdir="$1" channel="$2" + package_has_channels "$pkgdir" || return 0 + package_channels "$pkgdir" | grep -qx "$channel" +} + package_builds_for_mirror() { local pkgdir="$1" local mirror="$2" @@ -145,6 +169,23 @@ package_builds_for_mirror() { package_has_pkgbuild "$pkgdir" || return 1 package_has_metadata "$pkgdir" || return 1 + # An explicit `channels` key pins where a package is BUILT: it builds in + # each listed channel except stable, which is only ever fed by promotion. + # Without the key, the defaults hold: everything builds for edge, and + # fast-ring packages also build directly for stable (bin/release then + # replicates those artifacts into rc to keep rc and stable in parity). + if package_has_channels "$pkgdir"; then + case "$mirror" in + edge | rc) + package_in_channel "$pkgdir" "$mirror" + return + ;; + *) + return 1 + ;; + esac + fi + case "$mirror" in edge) return 0 @@ -158,6 +199,16 @@ package_builds_for_mirror() { esac } +# Whether `bin/repo advance` may carry this package into the given channel: +# a member of that channel that is not built there natively. Native builds are +# authoritative — advancing over them could pair a published filename with +# different bytes, which the R2 cache would never recover from. +package_moves_to_channel() { + local pkgdir="$1" channel="$2" + package_in_channel "$pkgdir" "$channel" || return 1 + ! package_builds_for_mirror "$pkgdir" "$channel" +} + package_dirs() { [[ -d "$PKGBUILDS_DIR" ]] || return 0 @@ -361,6 +412,17 @@ validate_package_metadata() { *) echo "invalid release_ring for $(basename "$pkgdir"): $ring"; return 1 ;; esac + if ! jq -e ' + if has("channels") | not then true + else .channels | type == "array" and length > 0 + and all(. == "edge" or . == "rc" or . == "stable") + and (unique | length) == length + end + ' "$metadata" >/dev/null; then + echo "invalid channels for $(basename "$pkgdir"): must be a non-empty array of unique edge/rc/stable values" + return 1 + fi + if ! package_min_release_age_seconds "$pkgdir" >/dev/null; then echo "invalid min_release_age for $(basename "$pkgdir"): must be a number with optional s/m/h/d suffix" return 1 diff --git a/pkgbuilds/omarchy-dev/.omarchy/package.json b/pkgbuilds/omarchy-dev/.omarchy/package.json index 2a9719d..9adf372 100644 --- a/pkgbuilds/omarchy-dev/.omarchy/package.json +++ b/pkgbuilds/omarchy-dev/.omarchy/package.json @@ -1,3 +1 @@ -{ - "source": "local" -} +{ "source": "local", "channels": ["edge"] } diff --git a/pkgbuilds/omarchy-settings-dev/.omarchy/package.json b/pkgbuilds/omarchy-settings-dev/.omarchy/package.json index 2a9719d..9adf372 100644 --- a/pkgbuilds/omarchy-settings-dev/.omarchy/package.json +++ b/pkgbuilds/omarchy-settings-dev/.omarchy/package.json @@ -1,3 +1 @@ -{ - "source": "local" -} +{ "source": "local", "channels": ["edge"] } diff --git a/pkgbuilds/omarchy-settings/.omarchy/package.json b/pkgbuilds/omarchy-settings/.omarchy/package.json index 2a9719d..51920e3 100644 --- a/pkgbuilds/omarchy-settings/.omarchy/package.json +++ b/pkgbuilds/omarchy-settings/.omarchy/package.json @@ -1,3 +1 @@ -{ - "source": "local" -} +{ "source": "local", "channels": ["edge", "rc", "stable"] } diff --git a/pkgbuilds/omarchy/.omarchy/package.json b/pkgbuilds/omarchy/.omarchy/package.json index 2a9719d..51920e3 100644 --- a/pkgbuilds/omarchy/.omarchy/package.json +++ b/pkgbuilds/omarchy/.omarchy/package.json @@ -1,3 +1 @@ -{ - "source": "local" -} +{ "source": "local", "channels": ["edge", "rc", "stable"] }