Release ipx 1.0.0, ipx-directory 1.0.0 and ipx-web 1.0.0, as Gitea releases

Each release is now a Gitea release as well as an image: scripts/release.sh takes the binary (or
the page's files) out of the deployed image, checks its version, and attaches it as a tarball with
the changelog section as the notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 20:41:47 +00:00
parent 69958d6926
commit 25f4d23112
9 changed files with 71 additions and 12 deletions

View File

@@ -298,7 +298,11 @@ a bug no release ever had, is not there at all; and "instead of" and "no longer"
last release, not with last week. Issue numbers stay, all of them, on the line that survives. Then
rename `[Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD` and open a new empty `[Unreleased]` above it,
set the service's version to `X.Y.Z` (dropping `-dev`), tag the commit with the service's tag, and
update the compare links at the bottom of its changelog. Then, in the next commit, set its version
update the compare links at the bottom of its changelog. Push the commit and the tag, build and
deploy the service's image, then `sh scripts/release.sh ipx|directory|web` makes the Gitea
release: that version's changelog section as its notes, and a tarball of what the image runs (the
binary, or the page's files with the Caddyfile) attached, checked to be that version. Then, in the
next commit, set its version
to the next patch with `-dev` (after 0.9.0, `0.9.1-dev`), so a build between releases says so
instead of claiming to be the last release. The release that follows can still be a minor or major
one; `-dev` only says the work comes after `X.Y.Z`. A service never released is at `0.1.0-dev`,

4
Cargo.lock generated
View File

@@ -1820,7 +1820,7 @@ checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0"
[[package]]
name = "ipx"
version = "0.12.1-dev"
version = "1.0.0"
dependencies = [
"ammonia",
"anyhow",
@@ -1856,7 +1856,7 @@ dependencies = [
[[package]]
name = "ipx-directory"
version = "0.1.0-dev"
version = "1.0.0"
dependencies = [
"ammonia",
"anyhow",

View File

@@ -10,9 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [1.0.0] - 2026-10-12
### Added
- Anyone can browse the directory in a web browser, read only: the most subscribed, categories, every feed A to Z, a search by name, and each feed's page with its latest items and its address to copy into any podcast app (#215).
- `GET /v1/instances` lists the servers holding a snapshot, with their feeds and subscribers, for an admin token (#206).
- `ipx-directory`, a directory of public podcasts that ipx servers share: each sends the public feeds its people subscribe to, and any server with a token browses them, each feed listed once it has been read. Tokens are in its config file, each read-only, read-write or admin, and revoked one at a time (#204, #205).
- Traces: a span a request, joining the trace of the ipx server that called, and a trace a refresher round with a span a feed (#213).
[unreleased]: https://git.sdf1.net/rays/ipx/compare/directory-v1.0.0...main
[1.0.0]: https://git.sdf1.net/rays/ipx/releases/tag/directory-v1.0.0

View File

@@ -1,6 +1,6 @@
[package]
name = "ipx-directory"
version = "0.1.0-dev"
version = "1.0.0"
edition.workspace = true
[[bin]]

View File

@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [1.0.0] - 2026-10-12
### Added
- With a directory token that may administer it, ipx's admins remove a feed from the directory (blocking it) or check it now, list and unblock what is blocked, and list and drop the servers sharing (#206).
@@ -19,16 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- The Directory comes from a directory service that iPX servers share, set up in Admin, Directory with its address and this server's token, instead of only this server's feeds. Sharing this server's public feeds with it is a setting, never a private one, and subscriber counts are every sharing server's (#205).
- The Directory comes from a directory service that iPX servers share, set up in Admin, Directory with its address and this server's token, instead of only this server's feeds. Sharing this server's public feeds with it is a setting, never a private one, and subscriber counts are every sharing server's. ipx sends the directory its feeds when they change, and every half hour (#205, #211).
- A feed can be marked private, which keeps it out of the directory. A feed with a login, or whose address carries a key, is private already (#205).
- ipx serves no page: the page is ipx-web's, which passes the API on to ipx, and ipx is built without node (#203).
- `docker-compose.yml` is a sample to start from, ipx alone on SQLite with its folders beside the file, instead of a copy of the author's server (#208).
- The source is a Cargo workspace: the daemon in `crates/ipx`, feed fetching and parsing in `crates/feed`. `cargo build --release` still makes `target/release/ipx` (#202).
### Fixed
- ipx sends the directory its feeds when they change, and every half hour, instead of after every scan, which was every half minute or so (#211).
## [0.12.0] - 2026-10-11
### Added
@@ -803,7 +801,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Torrent enclosures through librqbit, seeding to a ratio or a time, with a stall timeout.
- `ipx import` and `ipx export` for OPML, and systemd units in `contrib/`.
[unreleased]: https://git.sdf1.net/rays/ipx/compare/v0.12.0...main
[unreleased]: https://git.sdf1.net/rays/ipx/compare/v1.0.0...main
[1.0.0]: https://git.sdf1.net/rays/ipx/compare/v0.12.0...v1.0.0
[0.12.0]: https://git.sdf1.net/rays/ipx/compare/v0.11.0...v0.12.0
[0.11.0]: https://git.sdf1.net/rays/ipx/compare/v0.10.3...v0.11.0
[0.10.3]: https://git.sdf1.net/rays/ipx/compare/v0.10.2...v0.10.3

View File

@@ -1,6 +1,6 @@
[package]
name = "ipx"
version = "0.12.1-dev"
version = "1.0.0"
edition.workspace = true
[dependencies]

View File

@@ -1,6 +1,6 @@
{
"name": "ipx-web",
"version": "0.1.0-dev",
"version": "1.0.0",
"private": true,
"description": "Builds the ipx web pages from web/src (web/build.mjs, run by build.rs) and tests them. The Rust tests cover the server.",
"scripts": {

46
scripts/release.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
# Publish a Gitea release for one service's tag, with a tarball taken from the image that was
# deployed, so what is attached is what runs on Tower. Run after the release commit is tagged,
# pushed and its image built and pushed: sh scripts/release.sh ipx|directory|web
set -eu
cd "$(dirname "$0")/.."
case "${1:-}" in
ipx) name=ipx; ver=$(sed -n 's/^version = "\(.*\)"/\1/p' crates/ipx/Cargo.toml | head -1)
tag=v$ver; log=crates/ipx/CHANGELOG.md; from=/usr/local/bin/ipx ;;
directory) name=ipx-directory; ver=$(sed -n 's/^version = "\(.*\)"/\1/p' crates/directory/Cargo.toml | head -1)
tag=directory-v$ver; log=crates/directory/CHANGELOG.md; from=/usr/local/bin/ipx-directory ;;
web) name=ipx-web; ver=$(node -p 'require("./package.json").version')
tag=web-v$ver; log=web/CHANGELOG.md; from=/srv ;;
*) echo "usage: $0 ipx|directory|web" >&2; exit 2 ;;
esac
case "$ver" in *-dev) echo "$name is at $ver: release it first" >&2; exit 1 ;; esac
git fetch -q --tags origin
git merge-base --is-ancestor "$tag" origin/main || { echo "$tag is not on origin/main" >&2; exit 1; }
out=$(mktemp -d); trap 'rm -rf "$out"' EXIT
dir=$out/$name-$ver; mkdir "$dir"
image=192.168.1.130:5000/$name:latest
c=$(docker create "$image"); trap 'docker rm -f "$c" >/dev/null; rm -rf "$out"' EXIT
if [ "$name" = ipx-web ]; then
docker cp -q "$c:$from/." "$dir/"
cp web/Caddyfile "$dir/"
# latest may be a later build than the tag: the page carries its version, so check it.
grep -qF "$ver" "$dir"/app.js || { echo "$image is not ipx-web $ver" >&2; exit 1; }
arch=any
else
docker cp -q "$c:$from" "$dir/"
"$dir/$name" --version | grep -qF " $ver" || { echo "$image is not $name $ver" >&2; exit 1; }
arch=linux-$(uname -m)
fi
cp LICENSE README.md "$dir/"; cp "$log" "$dir/CHANGELOG.md"
tarball=$out/$name-$ver-$arch.tar.gz
tar -C "$out" -czf "$tarball" "$name-$ver"
# The notes are this version's section of the changelog, without its heading.
awk -v h="## [$ver]" 'index($0, h) == 1 {p = 1; next} p && /^## \[/ {exit} p' "$log" > "$out/notes.md"
[ -s "$out/notes.md" ] || { echo "no [$ver] section in $log" >&2; exit 1; }
timeout 120 /src/tea releases create --login git.sdf1.net --repo rays/ipx --tag "$tag" \
--title "$name $ver" --note-file "$out/notes.md" --asset "$tarball" < /dev/null

View File

@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [1.0.0] - 2026-10-12
### Added
- With a directory token that may administer it, an admin has Check now and Remove from the directory on a Directory feed's page, and Servers and Blocked lists in Admin, Directory (#206).
@@ -29,3 +31,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- On a phone, the Subscribe button on a Directory feed's page is full size again, not squashed to a sliver (#212).
[unreleased]: https://git.sdf1.net/rays/ipx/compare/web-v1.0.0...main
[1.0.0]: https://git.sdf1.net/rays/ipx/releases/tag/web-v1.0.0