The release job feeds packages.arasaka.software itself; YoloCICD is gone
Build / Desktop, server and tools (push) Successful in 1m17s
Build / Desktop, server and tools (push) Successful in 1m17s
.gitea/scripts/packages.sh signs the rpm with the org secret PACKAGES_SIGNING_KEY, publishes the deb and rpm into a new snapshot of the repository, signs its metadata and rewrites SHA256SUMS.txt, on the nuvola runner. Tested against a copy of the live repository with Debian 13 apt and Fedora 44 dnf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KizzWs2WQPWN2qgE7G6r8B
This commit is contained in:
1 parent
50eaf7d0b3
commit
599ea2bf84
4 files changed
+116
-14
No files matched your search
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
version=$1
|
||||
releases=$(pwd)/releases/$version
|
||||
root=${PACKAGES_ROOT:-/var/www/packages.arasaka.software}
|
||||
keep=${PACKAGES_KEEP:-5}
|
||||
url=https://packages.arasaka.software
|
||||
fingerprint=F92C166E9B1C13EDD1629E76888DCF969D133FB2
|
||||
deb=$releases/MeWeb-$version-linux-x64.deb
|
||||
rpm=$releases/MeWeb-$version-linux-x64.rpm
|
||||
test -f "$deb"
|
||||
test -f "$rpm"
|
||||
|
||||
exec 9>>"$root/.lock"
|
||||
flock -w 2700 9
|
||||
|
||||
keys=$(mktemp -d)
|
||||
trap 'rm -rf "$keys"' EXIT
|
||||
export GNUPGHOME="$keys"
|
||||
printf '%s\n' "$PACKAGES_SIGNING_KEY" | gpg --batch --quiet --import
|
||||
gpg --batch --with-colons --list-secret-keys | grep -q "^fpr:::::::::$fingerprint:$"
|
||||
gpg --batch --armor --export "$fingerprint" > "$keys/public.asc"
|
||||
|
||||
rpmsign --define "__gpg /usr/bin/gpg" --define "_gpg_name $fingerprint" --define "_gpg_path $keys" --addsign "$rpm" >/dev/null
|
||||
rpmkeys --dbpath "$keys/rpmdb" --import "$keys/public.asc"
|
||||
rpmkeys --dbpath "$keys/rpmdb" -K "$rpm" | grep -q 'digests signatures OK'
|
||||
|
||||
full=$(dpkg-deb -f "$deb" Version)
|
||||
test "$(dpkg-deb -f "$deb" Package)" = meweb
|
||||
test "${full%-*}" = "$version"
|
||||
debname=meweb_${full}_$(dpkg-deb -f "$deb" Architecture).deb
|
||||
rpmname=$(rpm -qp --nosignature --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm' "$rpm")
|
||||
test "$(rpm -qp --nosignature --qf '%{NAME} %{VERSION}' "$rpm")" = "meweb $version"
|
||||
|
||||
snap=$root/.snap/$(date -u +%Y%m%d%H%M%S)-$version
|
||||
mkdir -p "$snap/apt/pool/main" "$snap/rpm"
|
||||
if [ -d "$root/apt/pool/main" ]; then cp -al "$root/apt/pool/main/." "$snap/apt/pool/main/"; fi
|
||||
if [ -d "$root/rpm" ]; then
|
||||
for folder in "$root"/rpm/*/; do
|
||||
[ "$(basename "$folder")" = repodata ] || cp -al "$folder" "$snap/rpm/"
|
||||
done
|
||||
fi
|
||||
mkdir -p "$snap/apt/pool/main/m/meweb" "$snap/rpm/meweb"
|
||||
rm -f "$snap/apt/pool/main/m/meweb/$debname" "$snap/rpm/meweb/$rpmname"
|
||||
cp "$deb" "$snap/apt/pool/main/m/meweb/$debname"
|
||||
cp "$rpm" "$snap/rpm/meweb/$rpmname"
|
||||
for folder in "$snap/apt/pool/main/m/meweb" "$snap/rpm/meweb"; do
|
||||
ls "$folder" | sed -E 's/^meweb[_-]([0-9.]+)-.*/\1/' | sort -uV | head -n "-$keep" | while read -r old; do
|
||||
rm -f "$folder/meweb_$old-"* "$folder/meweb-$old-"*
|
||||
done
|
||||
done
|
||||
|
||||
binary=$snap/apt/dists/stable/main/binary-amd64
|
||||
mkdir -p "$binary"
|
||||
(cd "$snap/apt" && apt-ftparchive packages pool) > "$binary/Packages"
|
||||
gzip -9nc "$binary/Packages" > "$binary/Packages.gz"
|
||||
(cd "$snap/apt/dists/stable" && apt-ftparchive \
|
||||
-o APT::FTPArchive::Release::Origin=Arasaka -o APT::FTPArchive::Release::Label=Arasaka \
|
||||
-o APT::FTPArchive::Release::Suite=stable -o APT::FTPArchive::Release::Codename=stable \
|
||||
-o APT::FTPArchive::Release::Architectures=amd64 -o APT::FTPArchive::Release::Components=main \
|
||||
-o APT::FTPArchive::Release::NotAutomatic=yes -o APT::FTPArchive::Release::ButAutomaticUpgrades=yes \
|
||||
-o "APT::FTPArchive::Release::Description=Arasaka packages" release .) > "$keys/Release"
|
||||
mv "$keys/Release" "$snap/apt/dists/stable/Release"
|
||||
gpg --batch --yes --local-user "$fingerprint" --clearsign -o "$snap/apt/dists/stable/InRelease" "$snap/apt/dists/stable/Release"
|
||||
gpg --batch --yes --local-user "$fingerprint" --armor --detach-sign -o "$snap/apt/dists/stable/Release.gpg" "$snap/apt/dists/stable/Release"
|
||||
|
||||
createrepo_c --quiet "$snap/rpm"
|
||||
repodata=$snap/rpm/repodata
|
||||
gpg --batch --yes --local-user "$fingerprint" --armor --detach-sign -o "$repodata/repomd.xml.asc" "$repodata/repomd.xml"
|
||||
cp "$keys/public.asc" "$repodata/repomd.xml.key"
|
||||
if [ -f "$root/rpm/repodata/repomd.xml" ]; then
|
||||
grep -o 'repodata/[^"]*' "$root/rpm/repodata/repomd.xml" | while read -r href; do
|
||||
[ -e "$snap/rpm/$href" ] || cp "$root/rpm/$href" "$snap/rpm/$href"
|
||||
done
|
||||
fi
|
||||
chmod -R u=rwX,go=rX "$snap"
|
||||
|
||||
for part in apt rpm; do
|
||||
ln -sfn ".snap/$(basename "$snap")/$part" "$root/$part.new"
|
||||
mv -T -f "$root/$part.new" "$root/$part"
|
||||
done
|
||||
ls -1d "$root"/.snap/* | sort | head -n -3 | while read -r old; do
|
||||
find "$old" -maxdepth 0 -mmin +1440 -exec rm -rf {} +
|
||||
done
|
||||
echo "published $debname and $rpmname in $root"
|
||||
|
||||
(cd "$releases" && for file in $(ls | LC_ALL=C sort); do [ "$file" = SHA256SUMS.txt ] || sha256sum "$file"; done) > "$keys/sums"
|
||||
mv "$keys/sums" "$releases/SHA256SUMS.txt"
|
||||
|
||||
if [ "$root" = /var/www/packages.arasaka.software ]; then
|
||||
curl -fsS "$url/apt/dists/stable/main/binary-amd64/Packages" | grep -qx "Version: $full"
|
||||
curl -fsS "$url/apt/dists/stable/InRelease" > "$keys/InRelease"
|
||||
gpg --batch --quiet --verify "$keys/InRelease"
|
||||
curl -fsS "$url/rpm/repodata/repomd.xml" > "$keys/repomd.xml"
|
||||
curl -fsS "$url/rpm/repodata/repomd.xml.asc" > "$keys/repomd.xml.asc"
|
||||
gpg --batch --quiet --verify "$keys/repomd.xml.asc" "$keys/repomd.xml"
|
||||
curl -fsSI "$url/rpm/meweb/$rpmname" > /dev/null
|
||||
echo "live at $url: meweb $version"
|
||||
fi
|
||||
@@ -46,12 +46,8 @@ jobs:
|
||||
- name: The deb and rpm on packages.arasaka.software, the rpm signed
|
||||
if: ${{ github.ref_type == 'tag' }}
|
||||
env:
|
||||
YOLO_TOKEN: ${{ secrets.YOLO_TOKEN }}
|
||||
YOLO_GITEA: http://localhost:3000
|
||||
YOLO_MIN: "0.1.0"
|
||||
run: |
|
||||
yolo repo submit --project meweb --version "$VERSION" --replace-signed "releases/$VERSION/MeWeb-$VERSION-linux-x64.deb" "releases/$VERSION/MeWeb-$VERSION-linux-x64.rpm"
|
||||
yolo sums "releases/$VERSION"
|
||||
PACKAGES_SIGNING_KEY: ${{ secrets.PACKAGES_SIGNING_KEY }}
|
||||
run: .gitea/scripts/packages.sh "$VERSION"
|
||||
|
||||
- name: Publish the release
|
||||
if: ${{ github.ref_type == 'tag' || inputs.publish == 'true' }}
|
||||
|
||||
@@ -143,13 +143,20 @@ The Android release key: alias `meweb`, certificate SHA-256
|
||||
the network and the block without the publisher's server. A change to any knowledge file's format bumps
|
||||
`KnowledgeFeeder.Format` and the `"format":N` that `wait-knowledge.sh` waits for: the feeder rebuilds only when a
|
||||
source changes or the format differs, and a release must not embed the previous build.
|
||||
- **The deb and rpm reach packages.arasaka.software through YoloCICD.** `release.yml` runs `yolo repo submit
|
||||
--replace-signed` on tags (org secret `YOLO_TOKEN`, `yolo` installed on nuvola by YoloCICD): the files go to the
|
||||
bot's private inbox, YoloCICD's `publish.yml` checks this run against the tag, signs the rpm, gates on an upgrade
|
||||
check in containers and publishes; the signed rpm replaces the local one, then `yolo sums` rewrites SHA256SUMS.
|
||||
`packaging/arasaka-repository.sh` is generated (`yolo repo kit --out`, never edited by hand) and is written into
|
||||
both maintainer scripts by `tools/release.cs`; the package owns `/usr/share/arasaka-repository/meweb`, the marker
|
||||
that keeps the repository configured while any Arasaka package is installed.
|
||||
- **The deb and rpm reach packages.arasaka.software from this repository's own release job.** On tags,
|
||||
`.gitea/scripts/packages.sh` runs on the `nuvola` runner (host mode, user `gitea-runner`, which owns
|
||||
`/var/www/packages.arasaka.software`). It imports the org secret `PACKAGES_SIGNING_KEY` into a throwaway
|
||||
`GNUPGHOME`, refuses any key but `F92C166E…3FB2`, signs the rpm in place, hard-links the current pool into a new
|
||||
`.snap/` folder, adds this version, keeps the newest five, rebuilds and signs the apt (`InRelease`, `Release.gpg`)
|
||||
and rpm (`repomd.xml.asc`) metadata, carries over the files the previous `repomd.xml` named so a client mid-refresh
|
||||
still finds them, swaps the `apt` and `rpm` links, rewrites `SHA256SUMS.txt` for the signed rpm, and checks the live
|
||||
site. Never copy a package over a pool file: the pools are hard links into older snapshots, so it is `rm` then `cp`.
|
||||
`PACKAGES_ROOT` and `PACKAGES_KEEP` exist for a test against a copy. YoloCICD, which used to do this, was erased on
|
||||
23 Oct 2026. `packaging/arasaka-repository.sh` is written into both maintainer scripts by `tools/release.cs`; it is
|
||||
now maintained here by hand, and any change to a file it writes needs the old content's SHA-256 kept in
|
||||
`arasaka_repository_known`, or installed copies are treated as edited by hand and left alone. The package owns
|
||||
`/usr/share/arasaka-repository/meweb`, the marker that keeps the repository configured while any Arasaka package
|
||||
is installed. The signing key's only copies are that secret and the owner's Nextcloud backup.
|
||||
- **The server cannot ping**: `NoNewPrivileges` drops `ping`'s file capability and `ping_group_range` is closed, so
|
||||
the trace back to a caller uses `tracepath` (UDP, unprivileged) and keeps only public hops outside `Probe:Refuse`,
|
||||
so the box's own network never reaches an app.
|
||||
|
||||
@@ -50,7 +50,7 @@ Linux (deb, rpm), Windows, macOS and Android. Builds are published as releases o
|
||||
On Linux the deb and the rpm add the Arasaka package repository, packages.arasaka.software, when they are installed,
|
||||
so later versions arrive through the package manager. The rpm is signed with the repository's key; on openSUSE,
|
||||
import it first with `sudo rpm --import https://packages.arasaka.software/arasaka.asc`. The script the packages run
|
||||
is `packaging/arasaka-repository.sh`, generated by YoloCICD (`yolo repo kit`); it never calls the package manager,
|
||||
is `packaging/arasaka-repository.sh`; it never calls the package manager,
|
||||
leaves files you edited alone, and removes the repository only when no Arasaka package is left (purge or erase).
|
||||
|
||||
## Privacy
|
||||
|
||||
Reference in new issue
Block a user