Split the packages, publish releases from Gitea Actions, release 0.1.0
release / release (push) Successful in 7m7s

make deb now builds two packages: jarl-cli (the CLI, its completion and
the ACME hooks, no scripts) and jarl (the server), which depends on
jarl-cli of the same version.

Pushing a v* tag runs .gitea/workflows/release.yml: it tests, builds the
tarballs, the CLI for Linux, macOS and Windows (make cli-dist) and the
.debs for amd64 and arm64, then scripts/gitea-release.sh creates the
Gitea release and uploads the .debs to the Debian package registry, so
servers install and upgrade with apt. The stats package's inode lookup
is split by OS so the CLI builds for Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-09 08:40:56 +00:00
1 parent 293e6ddd33
commit 4d00be53c3
16 files changed
+450 -84

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
#!/bin/sh
# Publishes a built release (make dist, make cli-dist, make deb for each
# architecture) to Gitea:
#
# * a release for tag v<VERSION> with the CHANGELOG section for VERSION as
# its notes, and every file in dist/ (tarballs, CLI binaries, .debs)
# plus a SHA256SUMS of them attached;
# * the .debs in the owner's Debian package registry, so servers can
# 'apt install jarl' and get updates with apt (docs/install.md).
#
# Run by .gitea/workflows/release.yml when a v* tag is pushed. Running it
# again for the same version replaces the attachments and packages.
#
# Variables:
# GITEA_URL e.g. https://gitea.example.com (in Actions:
# GITHUB_SERVER_URL)
# GITEA_REPO owner/name (in Actions: GITHUB_REPOSITORY)
# GITEA_TOKEN a token with write:repository and write:package
# VERSION default: the VERSION file
# DEB_DISTRIBUTION the apt distribution (default: stable)
# DEB_COMPONENT the apt component (default: main)
#
# Needs curl and jq.
set -eu
: "${GITEA_URL:=${GITHUB_SERVER_URL:-}}" "${GITEA_REPO:=${GITHUB_REPOSITORY:-}}"
: "${GITEA_URL:?set GITEA_URL}" "${GITEA_REPO:?set GITEA_REPO}" "${GITEA_TOKEN:?set GITEA_TOKEN}"
VERSION=${VERSION:-$(cat VERSION)}
DEB_DISTRIBUTION=${DEB_DISTRIBUTION:-stable}
DEB_COMPONENT=${DEB_COMPONENT:-main}
GITEA_URL=${GITEA_URL%/}
owner=${GITEA_REPO%%/*}
tag=v$VERSION
api=$GITEA_URL/api/v1/repos/$GITEA_REPO
# curl with the token; fails on HTTP errors except the codes in $ok.
call() {
ok=$1
shift
out=$(mktemp)
code=$(curl -sS -o "$out" -w '%{http_code}' -H "Authorization: token $GITEA_TOKEN" "$@")
case " 200 201 204 $ok " in
*" $code "*) cat "$out"; rm -f "$out"; return 0 ;;
esac
echo "gitea-release: HTTP $code from $*" >&2
cat "$out" >&2
echo >&2
rm -f "$out"
return 1
}
files=$(find dist -maxdepth 1 -type f ! -name SHA256SUMS | sort)
[ -n "$files" ] || { echo "gitea-release: nothing in dist/" >&2; exit 1; }
for f in $files; do
case $f in *"$VERSION"*) ;; *) echo "gitea-release: $f is not version $VERSION" >&2; exit 1 ;; esac
done
# shellcheck disable=SC2046 # file names have no spaces
(cd dist && sha256sum $(printf '%s\n' "$files" | sed 's|^dist/||')) > dist/SHA256SUMS
files="$files dist/SHA256SUMS"
# The release notes: the CHANGELOG section for this version.
notes=$(awk -v v="$VERSION" '
/^## \[/ { if (on) exit; on = index($0, "## [" v "]") == 1; next }
on' CHANGELOG.md)
[ -n "$notes" ] || notes="See CHANGELOG.md."
prerelease=false
case $VERSION in *-*) prerelease=true ;; esac
# The release (created, or found when publishing again).
release=$(call 404 "$api/releases/tags/$tag")
id=$(printf '%s\n' "$release" | jq -r '.id // empty')
if [ -z "$id" ]; then
body=$(jq -n --arg tag "$tag" --arg notes "$notes" --argjson pre "$prerelease" \
'{tag_name: $tag, name: ("Jarl " + $tag), body: $notes, prerelease: $pre}')
release=$(call "" -X POST -H 'Content-Type: application/json' -d "$body" "$api/releases")
id=$(printf '%s\n' "$release" | jq -r .id)
echo "gitea-release: created release $tag"
fi
for f in $files; do
name=${f#dist/}
old=$(printf '%s\n' "$release" | jq -r --arg n "$name" '.assets[]? | select(.name == $n) | .id')
[ -z "$old" ] || call "" -X DELETE "$api/releases/$id/assets/$old" >/dev/null
call "" -X POST -F "attachment=@$f" "$api/releases/$id/assets?name=$name" >/dev/null
echo "gitea-release: attached $name"
done
# The Debian packages. Gitea refuses a package version it already has
# (409), so publishing again deletes it first.
pool=$GITEA_URL/api/packages/$owner/debian/pool/$DEB_DISTRIBUTION/$DEB_COMPONENT
for f in dist/*.deb; do
[ -e "$f" ] || continue
# shellcheck disable=SC2016,SC2046 # dpkg-deb's fields; split into "$@"
set -- $(dpkg-deb --showformat '${Package} ${Version} ${Architecture}' --show "$f")
if ! call 409 --upload-file "$f" "$pool/upload" >/dev/null; then
echo "gitea-release: upload of $f failed" >&2
exit 1
fi
if [ "$code" = 409 ]; then
call "" -X DELETE "$pool/$1/$2/$3" >/dev/null
call "" --upload-file "$f" "$pool/upload" >/dev/null
fi
echo "gitea-release: uploaded $1 $2 $3 to $DEB_DISTRIBUTION/$DEB_COMPONENT"
done