44REPO=" documentdb/documentdb"
55OUT_DIR=" out"
66DOCUMENTDB_VERSION=" ${DOCUMENTDB_VERSION:- latest} "
7- MULTI_VERSION=" ${MULTI_VERSION:- true} "
87SUITE=" ${SUITE:- stable} "
98COMPONENTS=" ${COMPONENTS:- main} "
109ORIGIN=" ${ORIGIN:- DocumentDB} "
1110DESCRIPTION=" ${DESCRIPTION:- DocumentDB APT and YUM Repository} "
11+ APT_METADATA_COMPONENTS=" main deb11 deb12 deb13 ubuntu22 ubuntu24"
1212
1313sign_deb_package () {
1414 local package_file=" $1 "
@@ -76,34 +76,20 @@ echo "Downloading packages from $REPO releases"
7676# ---------------------------------------------------------------------------
7777# Release selection
7878#
79- # The primary release supplies the site's release-info.json and is the version
80- # users are told about. But a release only ships the distributions that were
81- # in its own build matrix: v0.116-0, for example, ships Tier-1 (ubuntu24 +
82- # rhel9) only, while v0.114-0 shipped seven distributions. Rebuilding the
83- # repository from the primary release alone would therefore DELETE the
84- # deb11/deb12/deb13/ubuntu22 components and the whole rhel8 repository from
85- # documentdb.io, and every host already pointed at one of them would start
86- # failing `apt update` with "Component 'ubuntu22' is not defined". That is a
87- # client-visible outage, not a cosmetic regression.
88- #
89- # So the repository is built additively: the primary release fills every
90- # distribution it ships, then progressively older releases are consulted ONLY
91- # to fill distributions still missing. A distribution is claimed by the newest
92- # release that ships it and is never overwritten by an older one. Once a
93- # release ships every distribution again, the older ones stop contributing
94- # by themselves - no cleanup required.
79+ # The selected release is the package repository's single source of truth.
80+ # Older releases must not fill gaps: those combinations are on-demand builds,
81+ # not assets of the current official release, and mixing them into the pool
82+ # makes stale versions look supported.
9583# ---------------------------------------------------------------------------
96- MAX_RELEASES=" ${MAX_RELEASES:- 8} "
9784
9885RELEASES_JSON=$( mktemp)
9986if ! curl -fqs " https://api.github.com/repos/${REPO} /releases?per_page=100" > " $RELEASES_JSON " ; then
10087 echo " Error: Could not fetch release list"
10188 exit 1
10289fi
10390
104- # Ordered list of tags to consider, newest first. Drafts and prereleases are
105- # skipped: they are not what a repository-backed `apt install` should serve.
106- TAG_LIST=$( DOCUMENTDB_VERSION=" $DOCUMENTDB_VERSION " python3 - " $RELEASES_JSON " << 'PY '
91+ # Select exactly one published release. Drafts and prereleases are skipped.
92+ SELECTED_TAG=$( DOCUMENTDB_VERSION=" $DOCUMENTDB_VERSION " python3 - " $RELEASES_JSON " << 'PY '
10793import json, os, sys
10894
10995releases = json.load(open(sys.argv[1]))
@@ -113,33 +99,27 @@ if not published:
11399
114100requested = os.environ.get("DOCUMENTDB_VERSION", "latest")
115101if requested != "latest":
116- # The API returns releases newest-first.
117- index = next((i for i, r in enumerate(published)
118- if r["tag_name"] == requested), None)
119- if index is None:
102+ selected = next((r for r in published if r["tag_name"] == requested), None)
103+ if selected is None:
120104 sys.exit(f"Error: Version {requested} not found in releases")
121- # A pin means "serve this version". Only the pinned release and OLDER ones
122- # may contribute: pulling gap-fillers from NEWER releases would defeat the
123- # pin, and worse, it would mix releases that depend on each other. Pinning
124- # to a release that predates the multi-package layout would otherwise add a
125- # newer `documentdb` meta package whose `documentdb-N (>= X)` dependency the
126- # pinned extension cannot satisfy - an unsatisfiable repository.
127- ordered = published[index:]
128105else:
129- ordered = published
106+ selected = published[0]
130107
131- print("\n".join(r ["tag_name"] for r in ordered) )
108+ print(selected ["tag_name"])
132109PY
133110)
134111
135- PRIMARY_TAG=$( printf ' %s\n ' " $TAG_LIST " | head -n 1 )
112+ PRIMARY_TAG=" $SELECTED_TAG "
136113echo " Primary release: $PRIMARY_TAG "
137114
138115# Packages already placed, keyed by "pool|name|arch". A newer release always
139116# wins; an older release contributes only packages the newer ones do not
140117# provide at all. That is what keeps `postgresql-16-documentdb` alive on
141118# ubuntu24/rhel9 after v0.116-0 narrowed Tier 1 to PostgreSQL 17/18, instead of
142119# silently deleting a package the install docs still tell people to use.
120+ # The paragraph above describes the removed gap-fill implementation. The
121+ # current implementation accepts assets only from PRIMARY_TAG and preserves
122+ # retired URLs with empty metadata rather than stale packages.
143123SEEN_FILE=$( mktemp)
144124
145125is_claimed () { case " $1 " in * " $2 " * ) return 0 ;; * ) return 1 ;; esac ; }
@@ -223,13 +203,11 @@ rpm_pool_for() {
223203
224204mkdir -p out/packages
225205
226- for tag in $TAG_LIST ; do
227- MAX_RELEASES=$(( MAX_RELEASES - 1 ))
228- [ " $MAX_RELEASES " -lt 0 ] && break
206+ for tag in " $PRIMARY_TAG " ; do
229207
230208 if ! release=$( curl -fqs " https://api.github.com/repos/${REPO} /releases/tags/$tag " ) ; then
231- echo " ::warning ::Could not fetch release $tag , skipping "
232- continue
209+ echo " ::error ::Could not fetch selected release $tag "
210+ exit 1
233211 fi
234212
235213 ASSETS_FILE=$( mktemp)
@@ -263,7 +241,10 @@ for asset in data.get('assets', []):
263241 comp=$( deb_component_for " $filename " )
264242 [ -z " $comp " ] && continue
265243 claim_package " $comp " " $filename " || continue
266- wget -q -P out/packages " $download_url " || { echo " ::warning::download failed: $filename " ; continue ; }
244+ wget -q -P out/packages " $download_url " || {
245+ echo " ::error::Download failed: $filename "
246+ exit 1
247+ }
267248 GOT_DEB=1
268249 pool=$( deb_pool_for " $comp " )
269250 mkdir -p " $pool "
@@ -296,7 +277,10 @@ for asset in data.get('assets', []):
296277 * ) continue ;;
297278 esac
298279 if [ " $downloaded " -eq 0 ]; then
299- wget -q -P out/packages " $download_url " || { echo " ::warning::download failed: $filename " ; break ; }
280+ wget -q -P out/packages " $download_url " || {
281+ echo " ::error::Download failed: $filename "
282+ exit 1
283+ }
300284 downloaded=1
301285 GOT_RPM=1
302286 fi
@@ -309,7 +293,12 @@ for asset in data.get('assets', []):
309293 * )
310294 # Non-package assets (SHA256SUMS, manifest.txt, ...) are mirrored only
311295 # for the primary release, which is what the site links to.
312- [ " $tag " = " $PRIMARY_TAG " ] && wget -q -P out/packages " $download_url " ;;
296+ if [ " $tag " = " $PRIMARY_TAG " ]; then
297+ wget -q -P out/packages " $download_url " || {
298+ echo " ::error::Download failed: $filename "
299+ exit 1
300+ }
301+ fi ;;
313302 esac
314303 done < " $ASSETS_FILE "
315304
@@ -353,7 +342,7 @@ for pool in "$RPM_POOL_RHEL8" "$RPM_POOL_RHEL9"; do
353342done
354343
355344if [ " $GOT_DEB " = " 1" ]; then
356- echo " Building APT repository with multiple distribution components..."
345+ echo " Building APT repository with active and retired compatibility components..."
357346 pushd out/deb > /dev/null
358347
359348 if [ -d " pool/ubuntu22" ] && [ " $( ls -A pool/ubuntu22/* .deb 2> /dev/null) " ]; then
@@ -472,35 +461,35 @@ if [ "$GOT_DEB" = "1" ]; then
472461 dpkg-scanpackages --arch arm64 pool/ubuntu24/ > " ${DEB_DISTS_UBUNTU24_ARM64} /Packages"
473462 gzip -k -f " ${DEB_DISTS_UBUNTU24_ARM64} /Packages"
474463 fi
464+
465+ # Keep retired component URLs valid without retaining packages from older
466+ # releases. Existing apt sources can refresh cleanly, but package lookup
467+ # returns no stale binaries.
468+ for component in $APT_METADATA_COMPONENTS ; do
469+ for arch in amd64 arm64; do
470+ metadata_dir=" ${DEB_DISTS} /${component} /binary-${arch} "
471+ packages_file=" ${metadata_dir} /Packages"
472+ mkdir -p " $metadata_dir "
473+ if [ ! -f " $packages_file " ]; then
474+ : > " $packages_file "
475+ gzip -k -f " $packages_file "
476+ fi
477+ done
478+ done
475479
476480 pushd " ${DEB_DISTS} " > /dev/null
477481
478482 echo " Creating Release file"
479- # Determine which components we actually have
480- AVAILABLE_COMPONENTS=" "
481- [ -d " ${COMPONENTS} /binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} ${COMPONENTS} "
482- [ -d " deb11/binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} deb11"
483- [ -d " deb12/binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} deb12"
484- [ -d " deb13/binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} deb13"
485- [ -d " ubuntu22/binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} ubuntu22"
486- [ -d " ubuntu24/binary-amd64" ] && AVAILABLE_COMPONENTS=" ${AVAILABLE_COMPONENTS} ubuntu24"
487- AVAILABLE_COMPONENTS=$( echo $AVAILABLE_COMPONENTS | sed ' s/^ *//' )
488-
489- # Determine available architectures
490- AVAILABLE_ARCHITECTURES=" "
491- [ -d " ${COMPONENTS} /binary-amd64" ] || [ -d " deb11/binary-amd64" ] || [ -d " deb12/binary-amd64" ] || [ -d " deb13/binary-amd64" ] || [ -d " ubuntu22/binary-amd64" ] || [ -d " ubuntu24/binary-amd64" ] && AVAILABLE_ARCHITECTURES=" ${AVAILABLE_ARCHITECTURES} amd64"
492- [ -d " ${COMPONENTS} /binary-arm64" ] || [ -d " deb11/binary-arm64" ] || [ -d " deb12/binary-arm64" ] || [ -d " deb13/binary-arm64" ] || [ -d " ubuntu22/binary-arm64" ] || [ -d " ubuntu24/binary-arm64" ] && AVAILABLE_ARCHITECTURES=" ${AVAILABLE_ARCHITECTURES} arm64"
493- AVAILABLE_ARCHITECTURES=$( echo $AVAILABLE_ARCHITECTURES | sed ' s/^ *//' )
494483
495484 {
496485 echo " Origin: ${ORIGIN} "
497486 echo " Label: DocumentDB"
498487 echo " Suite: ${SUITE} "
499488 echo " Codename: ${SUITE} "
500489 echo " Version: 1.0"
501- echo " Architectures: ${AVAILABLE_ARCHITECTURES} "
502- echo " Components: ${AVAILABLE_COMPONENTS } "
503- echo " Description: ${DESCRIPTION} - Multiple distributions supported "
490+ echo " Architectures: amd64 arm64 "
491+ echo " Components: ${APT_METADATA_COMPONENTS } "
492+ echo " Description: ${DESCRIPTION} "
504493 echo " Date: $( date -Ru) "
505494 generate_hashes MD5Sum md5sum
506495 generate_hashes SHA1 sha1sum
@@ -526,7 +515,7 @@ if [ "$GOT_DEB" = "1" ]; then
526515 popd > /dev/null
527516
528517
529- echo " APT repository built successfully with multiple distribution support "
518+ echo " APT repository built successfully"
530519fi
531520
532521if [ " $GOT_RPM " = " 1" ]; then
@@ -544,52 +533,48 @@ if [ "$GOT_RPM" = "1" ]; then
544533 fi
545534
546535 for POOL in " $RHEL8_POOL " " $RHEL9_POOL " ; do
547- if [ -d " $POOL " ] && [ " $( find " $POOL " -name " *.rpm" -type f | wc -l) " -gt 0 ]; then
548- echo " Processing YUM repository: $POOL "
549- pushd " $POOL " > /dev/null
550-
551- if [ -n " $GPG_FINGERPRINT " ]; then
552- for rpm_file in * .rpm; do
553- rpm --define " %_signature gpg" --define " %_gpg_name ${GPG_FINGERPRINT} " --addsign " $rpm_file " 2> /dev/null || true
554- done
555- fi
556-
557- echo " Running createrepo_c in $( pwd) "
558- if createrepo_c . ; then
559- echo " Repository metadata created successfully"
560- ls -la repodata/ 2> /dev/null || echo " No repodata directory found"
561- else
562- echo " ERROR: createrepo_c failed for $POOL "
563- fi
564-
565- if [ -n " $GPG_FINGERPRINT " ] && [ -f repodata/repomd.xml ]; then
566- gpg --default-key " $GPG_FINGERPRINT " --detach-sign --armor repodata/repomd.xml 2> /dev/null || true
567- fi
568-
569- popd > /dev/null
570- else
571- echo " Skipping $POOL : directory not found or no RPM files"
536+ mkdir -p " $POOL "
537+ echo " Processing YUM repository: $POOL "
538+ pushd " $POOL " > /dev/null
539+
540+ if [ -n " $GPG_FINGERPRINT " ]; then
541+ for rpm_file in * .rpm; do
542+ [ -f " $rpm_file " ] || continue
543+ rpm --define " %_signature gpg" --define " %_gpg_name ${GPG_FINGERPRINT} " --addsign " $rpm_file "
544+ signature=$( rpm -qp --qf ' %{RSAHEADER:pgpsig}' " $rpm_file " 2> /dev/null)
545+ if [ -z " $signature " ] || [ " $signature " = " (none)" ]; then
546+ echo " ::error::$rpm_file was not signed"
547+ exit 1
548+ fi
549+ done
572550 fi
551+
552+ echo " Running createrepo_c in $( pwd) "
553+ createrepo_c .
554+
555+ if [ -n " $GPG_FINGERPRINT " ]; then
556+ gpg --batch --yes --default-key " $GPG_FINGERPRINT " \
557+ --detach-sign --armor repodata/repomd.xml
558+ fi
559+
560+ popd > /dev/null
573561 done
574562
575- # Create main repository for backward compatibility
576- if [ -d " $RHEL8_POOL " ] && [ " $( find " $RHEL8_POOL " -name " *.rpm" -type f | wc -l) " -gt 0 ]; then
577- echo " Creating main YUM repository"
578- mkdir -p " $MAIN_POOL "
563+ # Keep the legacy main URL valid. It mirrors RHEL 8 only when the selected
564+ # release actually contains RHEL 8 packages; otherwise it is an empty
565+ # compatibility repository.
566+ echo " Creating main YUM compatibility repository"
567+ mkdir -p " $MAIN_POOL "
568+ if [ " $( find " $RHEL8_POOL " -name " *.rpm" -type f | wc -l) " -gt 0 ]; then
579569 cp " $RHEL8_POOL " /* .rpm " $MAIN_POOL " / 2> /dev/null || true
580- pushd " $MAIN_POOL " > /dev/null
581- echo " Running createrepo_c for main repository in $( pwd) "
582- if createrepo_c . ; then
583- echo " Main repository metadata created successfully"
584- ls -la repodata/ 2> /dev/null || echo " No repodata directory found"
585- else
586- echo " ERROR: createrepo_c failed for main repository"
587- fi
588- if [ -n " $GPG_FINGERPRINT " ] && [ -f repodata/repomd.xml ]; then
589- gpg --default-key " $GPG_FINGERPRINT " --detach-sign --armor repodata/repomd.xml 2> /dev/null || true
590- fi
591- popd > /dev/null
592570 fi
571+ pushd " $MAIN_POOL " > /dev/null
572+ createrepo_c .
573+ if [ -n " $GPG_FINGERPRINT " ]; then
574+ gpg --batch --yes --default-key " $GPG_FINGERPRINT " \
575+ --detach-sign --armor repodata/repomd.xml
576+ fi
577+ popd > /dev/null
593578
594579 echo " YUM repositories built successfully"
595580fi
598583echo " Package repository setup complete!"
599584echo " "
600585echo " Repository URLs:"
601- echo " APT: https://documentdb.io/deb stable main"
602- echo " YUM: https://documentdb.io/rpm/rhel8 (or /rhel9, /main)"
586+ echo " APT: https://documentdb.io/deb stable ubuntu24"
587+ echo " YUM: https://documentdb.io/rpm/rhel9"
588+ echo " Retired URLs retain empty metadata for package-manager compatibility."
603589echo " Browse: https://documentdb.io/packages/"
0 commit comments