Version 27.1-rc.1: the suite series versions #137

Merged
jcoffey-dev merged 1 commits from release/version-27.1-rc.1 into main 2026-10-28 16:47:09 +00:00
8 changed files with 123 additions and 25 deletions

No files matched your search

+12 -5
View File
@@ -38,10 +38,14 @@ name: ci
on:
push:
branches: [main]
# Only date tags publish (v2026.9.21, v2026.9.21.2). The repository still
# carries the inherited v1.0.x tags, and a tag of any other shape pushed
# by hand is not a release.
# Only release tags publish: a series (v27.1), its patches (v27.1.3) and
# release candidates (v27.1-rc.1), and the dated ones from before 27.1
# (v2026.9.21, v2026.9.21.2). The repository still carries the inherited
# v1.0.x tags, and a tag of any other shape pushed by hand is not a release.
tags:
- 'v[0-9][0-9].[0-9]+'
- 'v[0-9][0-9].[0-9]+.[0-9]+'
- 'v[0-9][0-9].[0-9]+-rc.[0-9]+'
- 'v[0-9][0-9][0-9][0-9].[0-9]+.[0-9]+'
- 'v[0-9][0-9][0-9][0-9].[0-9]+.[0-9]+.[0-9]+'
pull_request:
@@ -66,6 +70,7 @@ jobs:
- run: npm run lint
- run: npm run i18n:check
- run: npm test
- run: sh tools/release-version.test.sh
- run: npm run build
# A changed upstream file without the AGPL 5(a) notice, as inbuxa-server's
@@ -132,6 +137,9 @@ jobs:
exit 1
fi
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
# A release moves its series and latest; a release candidate its
# series' -rc tag, never latest.
echo "TAGS=$(sh tools/release-version.sh tags "$VERSION" | tr '\n' ' ')" >> "$GITHUB_ENV"
- run: |
test -n "$REGISTRY"
test -n "$PACKAGE_TOKEN" || { echo "PACKAGE_TOKEN secret is not set on this repository" >&2; exit 1; }
@@ -144,8 +152,7 @@ jobs:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--provenance=false --sbom=false \
--tag "$IMAGE:$VERSION" \
--tag "$IMAGE:latest" \
$(for t in $TAGS; do printf '%s %s:%s ' --tag "$IMAGE" "$t"; done) \
--push .
docker buildx imagetools inspect "$IMAGE:$VERSION"
# Gitea keeps a container package on its owner; linking it shows it on
+16 -8
View File
@@ -5,9 +5,12 @@
# release with nothing in it moves :latest to an identical build, spends a
# version number, and notifies everybody about nothing.
#
# The version is the date, YYYY.M.D unpadded, with a .N suffix from 2 for a
# second release on one day. It is committed to main in inbuxa-version.json
# and the tag names that commit, so the commit is the release.
# Since 27.1 the version is a series and its patches: this cuts the next patch
# of the current series (27.1 -> 27.1.1 -> 27.1.2, tools/release-version.sh
# next). A new series and its release candidates (27.1-rc.N) are cut by hand,
# so while main is on a release candidate it says so and stops. The version is
# committed to main in inbuxa-version.json and the tag names that commit, so
# the commit is the release.
#
# Mondays 09:37 UTC, as release.yml did. Run it by hand from the Actions tab
# (workflow_dispatch); dry_run defaults to true, so a manual run shows the
@@ -74,6 +77,12 @@ jobs:
set -euo pipefail
API="${CI_SERVER_INTERNAL}/api/v1/repos/${GITHUB_REPOSITORY}"
sha="$(git rev-parse HEAD)"
current="$(jq -er .version inbuxa-version.json)"
version="$(sh tools/release-version.sh next "$current")"
if [ -z "$version" ]; then
echo "main is on release candidate ${current}: release candidates are cut by hand, so there's no weekly release."
exit 0
fi
# The newest published release, or empty on a project that has never
# had one -- in which case everything counts as new.
@@ -92,12 +101,11 @@ jobs:
echo "Nothing to release: no commits since ${previous}."; exit 0
fi
today="$(date -u +%Y.%-m.%-d)"
version="$today"; n=2
while git show-ref --verify --quiet "refs/tags/v${version}"; do
version="${today}.${n}"; n=$((n + 1))
done
tag="v${version}"
if git show-ref --verify --quiet "refs/tags/${tag}"; then
echo "${tag} exists but main still says ${current}; fix main first." >&2
exit 1
fi
echo "Releasing ${tag} -- ${count} commit(s) since ${previous:-the beginning}, from ${sha}."
if [ "$DRY_RUN" = "1" ]; then echo "Dry run (RELEASE_LIVE='${{ vars.RELEASE_LIVE }}'): stopping here."; exit 0; fi
+18 -5
View File
@@ -32,10 +32,14 @@ name: ci
on:
push:
branches: ['**']
# Only date tags publish (v2026.9.21, v2026.9.21.2), the same filter as
# Gitea's ci.yml. The repository still carries the inherited v1.0.x tags,
# and a tag of any other shape pushed by hand is not a release.
# Only release tags publish, the same filter as Gitea's ci.yml: a series (v27.1), its patches (v27.1.3) and
# release candidates (v27.1-rc.1), and the dated ones from before 27.1
# (v2026.9.21, v2026.9.21.2). The repository still carries the inherited
# v1.0.x tags, and a tag of any other shape pushed by hand is not a release.
tags:
- 'v[0-9][0-9].[0-9]+'
- 'v[0-9][0-9].[0-9]+.[0-9]+'
- 'v[0-9][0-9].[0-9]+-rc.[0-9]+'
- 'v[0-9][0-9][0-9][0-9].[0-9]+.[0-9]+'
- 'v[0-9][0-9][0-9][0-9].[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch:
@@ -88,6 +92,7 @@ jobs:
- run: npm run lint
- run: npm run i18n:check
- run: npm test
- run: sh tools/release-version.test.sh
- run: npm run build
# ----------------------------------------------------------- publish ------
@@ -100,6 +105,9 @@ jobs:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.v.outputs.version }}
# A release moves its series and latest; a release candidate its
# series' -rc tag, never latest.
tags: ${{ steps.v.outputs.tags }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: v
@@ -111,6 +119,7 @@ jobs:
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tags=$(sh tools/release-version.sh tags "$VERSION" | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
# Each architecture on its own native runner, pushed as an untagged image by
# digest; `publish` joins the two digests into one multi-arch tag.
@@ -186,10 +195,12 @@ jobs:
- name: Create the manifest
env:
VERSION: ${{ needs.version.outputs.version }}
TAGS: ${{ needs.version.outputs.tags }}
run: |
refs=()
for f in /tmp/digests/*; do refs+=("${IMAGE}@sha256:$(basename "$f")"); done
docker buildx imagetools create -t "${IMAGE}:${VERSION}" -t "${IMAGE}:latest" "${refs[@]}"
tags=(); for t in $TAGS; do tags+=(-t "${IMAGE}:${t}"); done
docker buildx imagetools create "${tags[@]}" "${refs[@]}"
docker buildx imagetools inspect "${IMAGE}:${VERSION}"
# Shows the package on the repository's Packages tab. Idempotent.
- env:
@@ -265,13 +276,15 @@ jobs:
- env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.version.outputs.version }}
TAGS: ${{ needs.version.outputs.tags }}
run: |
set -euo pipefail
src="${{ vars.REGISTRY }}/${GITHUB_REPOSITORY,,}"
dst="ghcr.io/${GITHUB_REPOSITORY,,}"
tag="$TAG"
echo "$GH_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin
docker buildx imagetools create -t "$dst:$tag" -t "$dst:latest" "$src:$tag"
args=(); for t in $TAGS; do args+=(-t "$dst:$t"); done
docker buildx imagetools create "${args[@]}" "$src:$tag"
want="$(docker buildx imagetools inspect "$src:$tag" --format '{{json .Manifest.Digest}}')"
got="$(docker buildx imagetools inspect "$dst:$tag" --format '{{json .Manifest.Digest}}')"
echo "registry $src:$tag = $want"
+6 -3
View File
@@ -58,9 +58,12 @@ features are this fork's own.
## Versions
INBUXA Admin has its own dated version (`inbuxa-version.json`), shown with the
upstream release it was forked from: `INBUXA Admin 2026.9.18 (base 1.0.11)`.
`package.json` keeps that release's version.
INBUXA Admin is versioned with the rest of the suite (`inbuxa-version.json`):
a series and its patches (`27.1`, `27.1.3`), and release candidates before a
series ships (`27.1-rc.1`). Releases before 27.1 were dated (`2026.10.26.2`).
The weekly release cuts the next patch; a series and its release candidates
are cut by hand. `package.json`'s version is a leftover from the fork and
isn't shown anywhere.
## Source code
+1 -1
View File
@@ -1,3 +1,3 @@
{
"version": "2026.10.26.2"
"version": "27.1-rc.1"
}
+43
View File
@@ -0,0 +1,43 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2026 Coffey Labs LLC
# SPDX-License-Identifier: AGPL-3.0-only
#
# The suite's release versions, as tags and images name them: 27.1 for a
# series, 27.1.3 for its patches, 27.1-rc.1 for a release candidate. The
# server's tools/release/version.py is the same rule in its Cargo form.
#
# release-version.sh tags VERSION image tags, one per line: a release
# moves VERSION, its series and latest;
# a release candidate VERSION and
# <series>-rc, never latest
# release-version.sh prerelease VERSION exit 0 for a release candidate
# release-version.sh next VERSION the next weekly patch, or nothing
# while on a release candidate
#
# Anything else, including the old dated versions, is refused (exit 2).
# POSIX sh: it runs in the docker:cli image, which has no bash.
set -eu
usage() { sed -n '9,18p' "$0" >&2; exit 2; }
[ $# -eq 2 ] || usage
cmd=$1 v=$2
echo "$v" | grep -Eq '^[1-9][0-9]\.([1-9]|1[0-2])(\.[1-9][0-9]*|-rc\.[1-9][0-9]*)?$' \
|| { echo "$v is not YY.M, YY.M.N or YY.M-rc.N" >&2; exit 2; }
series=$(echo "$v" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
case $v in *-rc.*) rc=1 ;; *) rc=0 ;; esac
case $cmd in
tags)
if [ $rc = 1 ]; then printf '%s\n%s-rc\n' "$v" "$series"
elif [ "$v" = "$series" ]; then printf '%s\nlatest\n' "$v"
else printf '%s\n%s\nlatest\n' "$v" "$series"
fi ;;
prerelease) [ $rc = 1 ] ;;
next)
if [ $rc = 1 ]; then :
elif [ "$v" = "$series" ]; then echo "$series.1"
else echo "$series.$(( ${v##*.} + 1 ))"
fi ;;
*) usage ;;
esac
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2026 Coffey Labs LLC
# SPDX-License-Identifier: AGPL-3.0-only
# Tests for release-version.sh: sh tools/release-version.test.sh
set -u
here=$(dirname "$0"); s="$here/release-version.sh"; fail=0
check() { # expected, then the arguments
want=$1; shift
got=$(sh "$s" "$@" 2>/dev/null | tr '\n' ' ')"rc=$(sh "$s" "$@" >/dev/null 2>&1; echo $?)"
[ "$got" = "$want" ] || { echo "FAIL: $* -> '$got', want '$want'"; fail=1; }
}
check '27.1-rc.2 27.1-rc rc=0' tags 27.1-rc.2
check '27.1 latest rc=0' tags 27.1
check '27.1.4 27.1 latest rc=0' tags 27.1.4
check 'rc=0' prerelease 27.1-rc.1
check 'rc=1' prerelease 27.1
check 'rc=0' next 27.1-rc.3
check '27.1.1 rc=0' next 27.1
check '27.1.10 rc=0' next 27.1.9
for bad in 2026.10.26.2 2026.10.26 27.1.0 27.1.0-rc.1 27.13 27.1-rc.0 27.01 v27.1 ''; do
check 'rc=2' tags "$bad"
done
[ $fail = 0 ] && echo "release-version: all passed"
exit $fail
+3 -3
View File
@@ -8,15 +8,15 @@ import path from 'path'
import { configDefaults, defineConfig } from 'vitest/config'
import inbuxa from './inbuxa-version.json' with { type: 'json' }
import { version } from './package.json' with { type: 'json' }
import { sievePlayground } from './sieve-playground.ts'
export default defineConfig({
// Relative, so one build works at any mount point (/admin, /account).
base: './',
define: {
// The release's dated version; package.json still carries upstream's.
__APP_VERSION__: JSON.stringify(`${inbuxa.version} (base ${version})`),
// The release version as tags name it (27.1, 27.1.3, 27.1-rc.1). Only
// inbuxa's: package.json's is a leftover nothing shows.
__APP_VERSION__: JSON.stringify(inbuxa.version),
},
plugins: [react(), tailwindcss(), sievePlayground()],
resolve: { alias: { '@': path.resolve(import.meta.dirname, './src') } },