Release onto the existing tag (create-only route) and AUR paperdoll-renderer-bin job
@@ -2,27 +2,28 @@
2
2
#
3
3
# Syntax checked on 6 November 2026 against GET /api/v1/ci/spec,
4
4
# timfa/bluegit docs/CI.md, and the public pipelines of timfa/posprint,
5
# timfa/minecart-trains and timfa/click-tween. legacy-cycles publishes
6
# releases only; its pipeline file is not public and was not copied.
5
# timfa/minecart-trains and timfa/click-tween. The AUR job follows
6
# timfa/legacy-cycles (aur-ssh-setup.sh, publish-aur.sh).
7
7
#
8
8
# Requested graph:
9
9
# merge request and master/main push -> test
10
10
# tag push, after tests succeed -> AppImage, Ubuntu package, Arch package,
11
# Windows build, artifact check, then one release publish
11
# Windows build, artifact check, one release publish, then the AUR
12
12
#
13
# Verified release limit, rechecked against api_routes.go on master: no route
14
# attaches artifacts to an existing tag or release. POST /repos/$CI_PROJECT_PATH/releases
15
# creates the git tag (409 if it exists). replace=true is 403 on a tag pipeline.
16
# scripts/ci/release.sh does not call that route and does not send replace.
17
# The release job exits 3 until BlueGit adds the attach route in design.md.
18
# This file does not create a tag. No release has been started here.
13
# Release (design.md, v0.1.0 decision, rechecked 7 November 2026 against the
14
# live OpenAPI): the release job publishes onto the tag that started this
15
# pipeline with POST /repos/$CI_PROJECT_PATH/releases/$CI_COMMIT_TAG/assets,
16
# BlueGit's create-only route for an existing tag (409 if a release exists;
17
# never creates, moves or deletes the tag). replace is never sent and the
18
# tag-creating release route is not called. Tags are pushed by hand on a green
19
# master; publish:aur then updates the AUR package paperdoll-renderer-bin.
19
20
#
20
21
# posprint notes two runner facts used below: jobs start in the checkout
21
22
# (CI_PROJECT_DIR is not set), and artifact paths are exact files.
22
23
# Windows is cross-compiled with MinGW, the same reason posprint gives:
23
24
# no Windows runner on BlueGit.
24
25
25
stages: [test, package, verify, release]
26
stages: [test, package, verify, release, publish]
26
27
27
28
variables:
28
29
CARGO_TERM_COLOR: always
@@ -164,4 +165,22 @@ release:
164
165
needs: [verify:packages, package:appimage, package:ubuntu, package:arch, package:windows]
165
166
resource_group: release
166
167
script:
168
- apk add --no-cache jq
167
169
- bash scripts/ci/release.sh
170
171
# AUR (approach of timfa/legacy-cycles): after the release, publish
172
# paperdoll-renderer-bin from this tag's .deb release asset. Protected
173
# variables (AUR_SSH_PRIVATE_KEY_B64, AUR_GIT_AUTHOR_NAME, AUR_GIT_AUTHOR_EMAIL)
174
# reach only protected refs; v* is a protected tag pattern.
175
# allow_failure: an AUR outage does not turn the release red.
176
publish:aur:
177
stage: publish
178
image: archlinux/archlinux:base-devel
179
extends: .on_tag
180
needs: [release]
181
allow_failure: true
182
resource_group: aur
183
script:
184
- pacman -Syu --noconfirm --needed git openssh curl coreutils shadow util-linux
185
- bash scripts/ci/aur-ssh-setup.sh
186
- bash scripts/ci/publish-aur.sh paperdoll-renderer-bin
@@ -2,27 +2,28 @@2
#2
#3
# Syntax checked on 6 November 2026 against GET /api/v1/ci/spec,3
# Syntax checked on 6 November 2026 against GET /api/v1/ci/spec,4
# timfa/bluegit docs/CI.md, and the public pipelines of timfa/posprint,4
# timfa/bluegit docs/CI.md, and the public pipelines of timfa/posprint,5
# timfa/minecart-trains and timfa/click-tween. legacy-cycles publishes5
# timfa/minecart-trains and timfa/click-tween. The AUR job follows6
# releases only; its pipeline file is not public and was not copied.6
# timfa/legacy-cycles (aur-ssh-setup.sh, publish-aur.sh).7
#7
#8
# Requested graph:8
# Requested graph:9
# merge request and master/main push -> test9
# merge request and master/main push -> test10
# tag push, after tests succeed -> AppImage, Ubuntu package, Arch package,10
# tag push, after tests succeed -> AppImage, Ubuntu package, Arch package,11
# Windows build, artifact check, then one release publish11
# Windows build, artifact check, one release publish, then the AUR12
#12
#13
# Verified release limit, rechecked against api_routes.go on master: no route13
# Release (design.md, v0.1.0 decision, rechecked 7 November 2026 against the14
# attaches artifacts to an existing tag or release. POST /repos/$CI_PROJECT_PATH/releases14
# live OpenAPI): the release job publishes onto the tag that started this15
# creates the git tag (409 if it exists). replace=true is 403 on a tag pipeline.15
# pipeline with POST /repos/$CI_PROJECT_PATH/releases/$CI_COMMIT_TAG/assets,16
# scripts/ci/release.sh does not call that route and does not send replace.16
# BlueGit's create-only route for an existing tag (409 if a release exists;17
# The release job exits 3 until BlueGit adds the attach route in design.md.17
# never creates, moves or deletes the tag). replace is never sent and the18
# This file does not create a tag. No release has been started here.18
# tag-creating release route is not called. Tags are pushed by hand on a green19
# master; publish:aur then updates the AUR package paperdoll-renderer-bin.19
#20
#20
# posprint notes two runner facts used below: jobs start in the checkout21
# posprint notes two runner facts used below: jobs start in the checkout21
# (CI_PROJECT_DIR is not set), and artifact paths are exact files.22
# (CI_PROJECT_DIR is not set), and artifact paths are exact files.22
# Windows is cross-compiled with MinGW, the same reason posprint gives:23
# Windows is cross-compiled with MinGW, the same reason posprint gives:23
# no Windows runner on BlueGit.24
# no Windows runner on BlueGit.24
25
25
stages: [test, package, verify, release]26
stages: [test, package, verify, release, publish]26
27
27
variables:28
variables:28
CARGO_TERM_COLOR: always29
CARGO_TERM_COLOR: always@@ -164,4 +165,22 @@ release:164
needs: [verify:packages, package:appimage, package:ubuntu, package:arch, package:windows]165
needs: [verify:packages, package:appimage, package:ubuntu, package:arch, package:windows]165
resource_group: release166
resource_group: release166
script:167
script:168
- apk add --no-cache jq167
- bash scripts/ci/release.sh169
- bash scripts/ci/release.sh170
171
# AUR (approach of timfa/legacy-cycles): after the release, publish172
# paperdoll-renderer-bin from this tag's .deb release asset. Protected173
# variables (AUR_SSH_PRIVATE_KEY_B64, AUR_GIT_AUTHOR_NAME, AUR_GIT_AUTHOR_EMAIL)174
# reach only protected refs; v* is a protected tag pattern.175
# allow_failure: an AUR outage does not turn the release red.176
publish:aur:177
stage: publish178
image: archlinux/archlinux:base-devel179
extends: .on_tag180
needs: [release]181
allow_failure: true182
resource_group: aur183
script:184
- pacman -Syu --noconfirm --needed git openssh curl coreutils shadow util-linux185
- bash scripts/ci/aur-ssh-setup.sh186
- bash scripts/ci/publish-aur.sh paperdoll-renderer-bin@@ -0,0 +1,44 @@
1
# Maintainer: Tim Falken <tim@timfalken.com>
2
# CI (scripts/ci/publish-aur.sh) sets pkgver, _tag and sha256sums.
3
pkgname=paperdoll-renderer-bin
4
pkgver=0.1.0
5
pkgrel=1
6
_tag=v0.1.0
7
pkgdesc='Paperdoll Renderer: sprite/paperdoll renders from glTF/FBX bodies with a live preview (prebuilt binary)'
8
arch=('x86_64')
9
url='https://git.timfalken.com/golden-age/paperdoll-renderer'
10
license=('MIT' 'custom:Sketchfab-Standard')
11
depends=('gcc-libs' 'glibc' 'libxcb' 'libx11' 'libxkbcommon' 'libxkbcommon-x11' 'libglvnd'
12
'shared-mime-info' 'desktop-file-utils' 'xdg-desktop-portal' 'zenity')
13
provides=('paperdoll-renderer')
14
conflicts=('paperdoll-renderer')
15
options=('!strip' '!debug')
16
source=("paperdoll-renderer-${_tag}-amd64.deb::${url}/-/releases/${_tag}/assets/paperdoll-renderer-${_tag}-amd64.deb")
17
sha256sums=('SKIP')
18
noextract=("paperdoll-renderer-${_tag}-amd64.deb")
19
20
prepare() {
21
mkdir -p "$srcdir/deb"
22
cd "$srcdir/deb"
23
bsdtar -xf "$srcdir/paperdoll-renderer-${_tag}-amd64.deb"
24
mkdir -p root
25
bsdtar -xf data.tar.* -C root
26
}
27
28
package() {
29
local r="$srcdir/deb/root/usr"
30
install -Dm755 "$r/bin/paperdoll-renderer" "$pkgdir/usr/bin/paperdoll-renderer"
31
install -Dm644 "$r/share/applications/paperdoll-renderer.desktop" \
32
"$pkgdir/usr/share/applications/paperdoll-renderer.desktop"
33
install -Dm644 "$r/share/mime/packages/paperdoll-project.xml" \
34
"$pkgdir/usr/share/mime/packages/paperdoll-project.xml"
35
install -Dm644 "$r/share/metainfo/paperdoll-renderer.metainfo.xml" \
36
"$pkgdir/usr/share/metainfo/paperdoll-renderer.metainfo.xml"
37
local icon
38
for icon in "$r"/share/icons/hicolor/*/apps/paperdoll-renderer.*; do
39
install -Dm644 "$icon" "$pkgdir/usr/share/icons/hicolor/${icon#"$r/share/icons/hicolor/"}"
40
done
41
install -Dm644 "$r/share/licenses/paperdoll-renderer/LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
42
install -Dm644 "$r/share/licenses/paperdoll-renderer/THIRD_PARTY_NOTICES.md" \
43
"$pkgdir/usr/share/licenses/$pkgname/THIRD_PARTY_NOTICES.md"
44
}
@@ -0,0 +1,44 @@1
# Maintainer: Tim Falken <tim@timfalken.com>2
# CI (scripts/ci/publish-aur.sh) sets pkgver, _tag and sha256sums.3
pkgname=paperdoll-renderer-bin4
pkgver=0.1.05
pkgrel=16
_tag=v0.1.07
pkgdesc='Paperdoll Renderer: sprite/paperdoll renders from glTF/FBX bodies with a live preview (prebuilt binary)'8
arch=('x86_64')9
url='https://git.timfalken.com/golden-age/paperdoll-renderer'10
license=('MIT' 'custom:Sketchfab-Standard')11
depends=('gcc-libs' 'glibc' 'libxcb' 'libx11' 'libxkbcommon' 'libxkbcommon-x11' 'libglvnd'12
'shared-mime-info' 'desktop-file-utils' 'xdg-desktop-portal' 'zenity')13
provides=('paperdoll-renderer')14
conflicts=('paperdoll-renderer')15
options=('!strip' '!debug')16
source=("paperdoll-renderer-${_tag}-amd64.deb::${url}/-/releases/${_tag}/assets/paperdoll-renderer-${_tag}-amd64.deb")17
sha256sums=('SKIP')18
noextract=("paperdoll-renderer-${_tag}-amd64.deb")19
20
prepare() {21
mkdir -p "$srcdir/deb"22
cd "$srcdir/deb"23
bsdtar -xf "$srcdir/paperdoll-renderer-${_tag}-amd64.deb"24
mkdir -p root25
bsdtar -xf data.tar.* -C root26
}27
28
package() {29
local r="$srcdir/deb/root/usr"30
install -Dm755 "$r/bin/paperdoll-renderer" "$pkgdir/usr/bin/paperdoll-renderer"31
install -Dm644 "$r/share/applications/paperdoll-renderer.desktop" \32
"$pkgdir/usr/share/applications/paperdoll-renderer.desktop"33
install -Dm644 "$r/share/mime/packages/paperdoll-project.xml" \34
"$pkgdir/usr/share/mime/packages/paperdoll-project.xml"35
install -Dm644 "$r/share/metainfo/paperdoll-renderer.metainfo.xml" \36
"$pkgdir/usr/share/metainfo/paperdoll-renderer.metainfo.xml"37
local icon38
for icon in "$r"/share/icons/hicolor/*/apps/paperdoll-renderer.*; do39
install -Dm644 "$icon" "$pkgdir/usr/share/icons/hicolor/${icon#"$r/share/icons/hicolor/"}"40
done41
install -Dm644 "$r/share/licenses/paperdoll-renderer/LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"42
install -Dm644 "$r/share/licenses/paperdoll-renderer/THIRD_PARTY_NOTICES.md" \43
"$pkgdir/usr/share/licenses/$pkgname/THIRD_PARTY_NOTICES.md"44
}@@ -0,0 +1,78 @@
1
#!/usr/bin/env bash
2
# Write ~/.ssh/id_ed25519 for AUR pushes from CI or local scripts.
3
#
4
# Supported CI variables (pick one):
5
# AUR_SSH_PRIVATE_KEY_B64 — base64 of the private key (Variable type, one line; Masked OK)
6
# or File type whose contents are that base64 string
7
# AUR_SSH_PRIVATE_KEY — raw OpenSSH private key (File type preferred), or raw key text
8
# File contents may also be base64 (auto-detected)
9
#
10
# Always normalizes CRLF → LF (Windows pastes into GitLab often break OpenSSH otherwise).
11
set -euo pipefail
12
13
KEY_PATH="${1:-$HOME/.ssh/id_ed25519}"
14
15
install -d -m 700 "$(dirname "$KEY_PATH")"
16
17
is_raw_ssh_key() {
18
grep -qE 'BEGIN (OPENSSH |RSA |EC )?PRIVATE KEY' "$1" 2>/dev/null
19
}
20
21
normalize_key_file() {
22
local tmp
23
tmp="$(mktemp)"
24
tr -d '\r' < "$KEY_PATH" > "$tmp"
25
if [[ -s "$tmp" ]] && [[ "$(tail -c1 "$tmp" | wc -l)" -eq 0 ]]; then
26
printf '\n' >> "$tmp"
27
fi
28
mv "$tmp" "$KEY_PATH"
29
chmod 600 "$KEY_PATH"
30
}
31
32
decode_b64_to_key() {
33
local src="$1"
34
if [[ -f "$src" ]]; then
35
tr -d '\r\n[:space:]' < "$src" | base64 -d > "$KEY_PATH"
36
else
37
printf '%s' "$src" | tr -d '\r\n[:space:]' | base64 -d > "$KEY_PATH"
38
fi
39
}
40
41
if [[ -n "${AUR_SSH_PRIVATE_KEY_B64:-}" ]]; then
42
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY_B64"
43
elif [[ -n "${AUR_SSH_PRIVATE_KEY:-}" && -f "${AUR_SSH_PRIVATE_KEY}" ]]; then
44
if is_raw_ssh_key "$AUR_SSH_PRIVATE_KEY"; then
45
cp "$AUR_SSH_PRIVATE_KEY" "$KEY_PATH"
46
else
47
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY"
48
fi
49
elif [[ -n "${AUR_SSH_PRIVATE_KEY:-}" ]]; then
50
if printf '%s' "$AUR_SSH_PRIVATE_KEY" | grep -qE 'BEGIN (OPENSSH |RSA |EC )?PRIVATE KEY'; then
51
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > "$KEY_PATH"
52
else
53
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY"
54
fi
55
elif [[ -f "$HOME/.ssh/id_ed25519" ]]; then
56
cp "$HOME/.ssh/id_ed25519" "$KEY_PATH"
57
else
58
echo "No AUR SSH key found. Set AUR_SSH_PRIVATE_KEY_B64 or AUR_SSH_PRIVATE_KEY." >&2
59
exit 1
60
fi
61
62
normalize_key_file
63
64
if ! is_raw_ssh_key "$KEY_PATH"; then
65
echo "AUR SSH key is not a valid OpenSSH private key after setup." >&2
66
echo "Use either:" >&2
67
echo " - AUR_SSH_PRIVATE_KEY as File with raw key (BEGIN ... PRIVATE KEY)" >&2
68
echo " - AUR_SSH_PRIVATE_KEY_B64 as Variable with one-line base64 of that key" >&2
69
echo "Tip: generate base64 from a LF-normalized key (see docs/CI.md)." >&2
70
exit 1
71
fi
72
73
if ! ssh-keygen -y -f "$KEY_PATH" >/dev/null 2>&1; then
74
echo "AUR SSH key failed ssh-keygen validation (often CRLF or truncated paste)." >&2
75
exit 1
76
fi
77
78
ssh-keyscan aur.archlinux.org >> "$HOME/.ssh/known_hosts" 2>/dev/null || true
@@ -0,0 +1,78 @@1
#!/usr/bin/env bash2
# Write ~/.ssh/id_ed25519 for AUR pushes from CI or local scripts.3
#4
# Supported CI variables (pick one):5
# AUR_SSH_PRIVATE_KEY_B64 — base64 of the private key (Variable type, one line; Masked OK)6
# or File type whose contents are that base64 string7
# AUR_SSH_PRIVATE_KEY — raw OpenSSH private key (File type preferred), or raw key text8
# File contents may also be base64 (auto-detected)9
#10
# Always normalizes CRLF → LF (Windows pastes into GitLab often break OpenSSH otherwise).11
set -euo pipefail12
13
KEY_PATH="${1:-$HOME/.ssh/id_ed25519}"14
15
install -d -m 700 "$(dirname "$KEY_PATH")"16
17
is_raw_ssh_key() {18
grep -qE 'BEGIN (OPENSSH |RSA |EC )?PRIVATE KEY' "$1" 2>/dev/null19
}20
21
normalize_key_file() {22
local tmp23
tmp="$(mktemp)"24
tr -d '\r' < "$KEY_PATH" > "$tmp"25
if [[ -s "$tmp" ]] && [[ "$(tail -c1 "$tmp" | wc -l)" -eq 0 ]]; then26
printf '\n' >> "$tmp"27
fi28
mv "$tmp" "$KEY_PATH"29
chmod 600 "$KEY_PATH"30
}31
32
decode_b64_to_key() {33
local src="$1"34
if [[ -f "$src" ]]; then35
tr -d '\r\n[:space:]' < "$src" | base64 -d > "$KEY_PATH"36
else37
printf '%s' "$src" | tr -d '\r\n[:space:]' | base64 -d > "$KEY_PATH"38
fi39
}40
41
if [[ -n "${AUR_SSH_PRIVATE_KEY_B64:-}" ]]; then42
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY_B64"43
elif [[ -n "${AUR_SSH_PRIVATE_KEY:-}" && -f "${AUR_SSH_PRIVATE_KEY}" ]]; then44
if is_raw_ssh_key "$AUR_SSH_PRIVATE_KEY"; then45
cp "$AUR_SSH_PRIVATE_KEY" "$KEY_PATH"46
else47
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY"48
fi49
elif [[ -n "${AUR_SSH_PRIVATE_KEY:-}" ]]; then50
if printf '%s' "$AUR_SSH_PRIVATE_KEY" | grep -qE 'BEGIN (OPENSSH |RSA |EC )?PRIVATE KEY'; then51
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > "$KEY_PATH"52
else53
decode_b64_to_key "$AUR_SSH_PRIVATE_KEY"54
fi55
elif [[ -f "$HOME/.ssh/id_ed25519" ]]; then56
cp "$HOME/.ssh/id_ed25519" "$KEY_PATH"57
else58
echo "No AUR SSH key found. Set AUR_SSH_PRIVATE_KEY_B64 or AUR_SSH_PRIVATE_KEY." >&259
exit 160
fi61
62
normalize_key_file63
64
if ! is_raw_ssh_key "$KEY_PATH"; then65
echo "AUR SSH key is not a valid OpenSSH private key after setup." >&266
echo "Use either:" >&267
echo " - AUR_SSH_PRIVATE_KEY as File with raw key (BEGIN ... PRIVATE KEY)" >&268
echo " - AUR_SSH_PRIVATE_KEY_B64 as Variable with one-line base64 of that key" >&269
echo "Tip: generate base64 from a LF-normalized key (see docs/CI.md)." >&270
exit 171
fi72
73
if ! ssh-keygen -y -f "$KEY_PATH" >/dev/null 2>&1; then74
echo "AUR SSH key failed ssh-keygen validation (often CRLF or truncated paste)." >&275
exit 176
fi77
78
ssh-keyscan aur.archlinux.org >> "$HOME/.ssh/known_hosts" 2>/dev/null || true@@ -0,0 +1,48 @@
1
#!/usr/bin/env bash
2
# publish-aur.sh PKGNAME — adapted from timfa/legacy-cycles.
3
# Runs in the tag pipeline after `release`: downloads this tag's .deb release
4
# asset, sets pkgver/_tag/sha256sums in packaging/aur/PKGNAME/PKGBUILD,
5
# regenerates .SRCINFO and pushes to aur.archlinux.org (the first push creates
6
# the AUR package). Uses AUR_GIT_AUTHOR_NAME / AUR_GIT_AUTHOR_EMAIL; the SSH
7
# key comes from aur-ssh-setup.sh (AUR_SSH_PRIVATE_KEY_B64).
8
set -euo pipefail
9
pkg="$1"
10
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
11
SRC="$ROOT/packaging/aur/$pkg"
12
: "${CI_COMMIT_TAG:?}" "${CI_PROJECT_URL:?}" "${AUR_GIT_AUTHOR_NAME:?}" "${AUR_GIT_AUTHOR_EMAIL:?}"
13
tag="$CI_COMMIT_TAG"
14
[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "not a release tag: $tag" >&2; exit 1; }
15
ver="${tag#v}"
16
url="$CI_PROJECT_URL/-/releases/$tag/assets/paperdoll-renderer-${tag}-amd64.deb"
17
18
WORKDIR="$(mktemp -d)"; export WORKDIR
19
trap 'rm -rf "$WORKDIR"' EXIT
20
curl -fsSL "$url" -o "$WORKDIR/asset.deb"
21
sha="$(sha256sum "$WORKDIR/asset.deb" | awk '{print $1}')"
22
echo "$pkg $ver $url $sha"
23
24
dest="$WORKDIR/$pkg"
25
remote="ssh://aur@aur.archlinux.org/${pkg}.git"
26
if ! git clone "$remote" "$dest"; then
27
echo "AUR repo $pkg does not exist yet; the first push creates it"
28
mkdir -p "$dest"; git -C "$dest" init -q -b master; git -C "$dest" remote add origin "$remote"
29
fi
30
git -C "$dest" symbolic-ref HEAD refs/heads/master
31
find "$dest" -mindepth 1 -maxdepth 1 ! -name .git -exec rm -rf {} +
32
cp -a "$SRC/." "$dest/"
33
cd "$dest"
34
sed -i "s/^pkgver=.*/pkgver=${ver}/; s/^pkgrel=.*/pkgrel=1/; s/^_tag=.*/_tag=${tag}/; s/^sha256sums=.*/sha256sums=('${sha}')/" PKGBUILD
35
36
useradd -m aurbuild 2>/dev/null || true
37
chmod 755 "$WORKDIR"; chown -R aurbuild "$dest"
38
runuser -u aurbuild -- makepkg --printsrcinfo > "$WORKDIR/srcinfo"
39
mv "$WORKDIR/srcinfo" .SRCINFO
40
chown -R root:root "$dest"
41
git config --global --add safe.directory '*'
42
git config user.name "$AUR_GIT_AUTHOR_NAME"
43
git config user.email "$AUR_GIT_AUTHOR_EMAIL"
44
git add -A
45
if git diff --cached --quiet; then echo "AUR $pkg already up to date ($ver)"; exit 0; fi
46
git commit -qm "$ver"
47
git push -u origin HEAD:master
48
echo "AUR updated: $pkg $ver"
@@ -0,0 +1,48 @@1
#!/usr/bin/env bash2
# publish-aur.sh PKGNAME — adapted from timfa/legacy-cycles.3
# Runs in the tag pipeline after `release`: downloads this tag's .deb release4
# asset, sets pkgver/_tag/sha256sums in packaging/aur/PKGNAME/PKGBUILD,5
# regenerates .SRCINFO and pushes to aur.archlinux.org (the first push creates6
# the AUR package). Uses AUR_GIT_AUTHOR_NAME / AUR_GIT_AUTHOR_EMAIL; the SSH7
# key comes from aur-ssh-setup.sh (AUR_SSH_PRIVATE_KEY_B64).8
set -euo pipefail9
pkg="$1"10
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"11
SRC="$ROOT/packaging/aur/$pkg"12
: "${CI_COMMIT_TAG:?}" "${CI_PROJECT_URL:?}" "${AUR_GIT_AUTHOR_NAME:?}" "${AUR_GIT_AUTHOR_EMAIL:?}"13
tag="$CI_COMMIT_TAG"14
[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "not a release tag: $tag" >&2; exit 1; }15
ver="${tag#v}"16
url="$CI_PROJECT_URL/-/releases/$tag/assets/paperdoll-renderer-${tag}-amd64.deb"17
18
WORKDIR="$(mktemp -d)"; export WORKDIR19
trap 'rm -rf "$WORKDIR"' EXIT20
curl -fsSL "$url" -o "$WORKDIR/asset.deb"21
sha="$(sha256sum "$WORKDIR/asset.deb" | awk '{print $1}')"22
echo "$pkg $ver $url $sha"23
24
dest="$WORKDIR/$pkg"25
remote="ssh://aur@aur.archlinux.org/${pkg}.git"26
if ! git clone "$remote" "$dest"; then27
echo "AUR repo $pkg does not exist yet; the first push creates it"28
mkdir -p "$dest"; git -C "$dest" init -q -b master; git -C "$dest" remote add origin "$remote"29
fi30
git -C "$dest" symbolic-ref HEAD refs/heads/master31
find "$dest" -mindepth 1 -maxdepth 1 ! -name .git -exec rm -rf {} +32
cp -a "$SRC/." "$dest/"33
cd "$dest"34
sed -i "s/^pkgver=.*/pkgver=${ver}/; s/^pkgrel=.*/pkgrel=1/; s/^_tag=.*/_tag=${tag}/; s/^sha256sums=.*/sha256sums=('${sha}')/" PKGBUILD35
36
useradd -m aurbuild 2>/dev/null || true37
chmod 755 "$WORKDIR"; chown -R aurbuild "$dest"38
runuser -u aurbuild -- makepkg --printsrcinfo > "$WORKDIR/srcinfo"39
mv "$WORKDIR/srcinfo" .SRCINFO40
chown -R root:root "$dest"41
git config --global --add safe.directory '*'42
git config user.name "$AUR_GIT_AUTHOR_NAME"43
git config user.email "$AUR_GIT_AUTHOR_EMAIL"44
git add -A45
if git diff --cached --quiet; then echo "AUR $pkg already up to date ($ver)"; exit 0; fi46
git commit -qm "$ver"47
git push -u origin HEAD:master48
echo "AUR updated: $pkg $ver"@@ -1,17 +1,12 @@
1
1
#!/usr/bin/env bash
2
# Tag-pipeline publish step.
2
# Tag-pipeline publish step (design.md, "v0.1.0 release" decision).
3
3
#
4
# Inspected BlueGit master on 6 November 2026 (api_routes.go, ops_ci.go
5
# opPublishRelease, release_replace.go checkReplace, gitrepo.Tag):
6
# there is no route that attaches artifacts to an existing git tag or an
7
# existing release. POST /api/v1/repos/{owner}/{repo}/releases always creates
8
# the annotated tag. An existing tag returns HTTP 409 unless replace=true,
9
# and replace=true is HTTP 403 on a tag pipeline.
10
#
11
# This script therefore does not call that endpoint and does not send
12
# replace. It exits 3 until BlueGit grows an attach route. It does not
13
# invent a second tag and it does not switch the pipeline onto a branch
14
# release. The required server change is recorded in design.md section 15.
4
# Publishes the release for the tag that started this pipeline with
5
# POST $CI_API_URL/repos/{owner}/{repo}/releases/{tag}/assets — BlueGit's
6
# create-only route for an existing tag: an existing release is HTTP 409, it
7
# never creates, moves or deletes the tag, and the assets are artifacts of
8
# successful jobs of this same pipeline. `replace` is never sent and the
9
# tag-creating route POST .../releases is never called.
15
10
set -euo pipefail
16
11
17
12
: "${CI_API_URL:?}" "${CI_JOB_TOKEN:?}" "${CI_COMMIT_SHA:?}" "${CI_PROJECT_PATH:?}" "${CI_COMMIT_TAG:?}"
@@ -19,10 +14,35 @@ set -euo pipefail
19
14
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
20
15
cd "$root"
21
16
version="$(bash scripts/ci/package-version.sh)"
17
tag="$CI_COMMIT_TAG"
18
[[ "$tag" == "v$version" ]] || { echo "tag $tag does not match package version $version" >&2; exit 1; }
19
20
b="paperdoll-renderer-${tag}"
21
asset() { jq -n --arg j "$1" --arg p "$2" --arg n "$3" '{job:$j,path:$p,name:$n}'; }
22
assets="$(jq -s . \
23
<(asset package:appimage dist/paperdoll-renderer-x86_64.AppImage "${b}-x86_64.AppImage") \
24
<(asset package:ubuntu dist/paperdoll-renderer_amd64.deb "${b}-amd64.deb") \
25
<(asset package:arch dist/paperdoll-renderer-x86_64.pkg.tar.zst "${b}-x86_64.pkg.tar.zst") \
26
<(asset package:windows dist/paperdoll-renderer-windows-x86_64.zip "${b}-windows-x86_64.zip") \
27
<(asset verify:packages dist/SHA256SUMS "${b}-SHA256SUMS.txt"))"
28
desc="Paperdoll Renderer ${version}.
29
30
* Linux AppImage (portable).
31
* Debian/Ubuntu .deb: /usr/bin/paperdoll-renderer, desktop entry, icons, .ppd MIME type.
32
* Arch .pkg.tar.zst, built from packaging/arch/PKGBUILD. AUR: paperdoll-renderer-bin.
33
* Windows zip (x86_64, MinGW build).
34
* SHA256SUMS of the package files.
35
36
The default starter bodies are \"Animated walking Male Base Mesh\" and \"Animated Female Base Mesh\" by assetfactory (Sketchfab Standard licence); see THIRD_PARTY_NOTICES.md."
37
body="$(jq -n --arg n "Paperdoll Renderer ${tag}" --arg b "$desc" --argjson a "$assets" '{name:$n,body:$b,assets:$a}')"
22
38
23
echo "release-blocked: no-attach-endpoint" >&2
24
echo "tag ${CI_COMMIT_TAG} version ${version} commit ${CI_COMMIT_SHA} project ${CI_PROJECT_PATH}" >&2
25
echo "BlueGit has no request that publishes these package artifacts onto the tag that already started this pipeline." >&2
26
echo "The create-release route would make a new annotated tag. This script does not call it." >&2
27
echo "The overwrite flag is not sent. No second tag is created." >&2
28
exit 3
39
echo "Release $tag on $CI_COMMIT_SHA (existing tag, create-only)"
40
resp="$(mktemp)"
41
code="$(curl -sS -o "$resp" -w '%{http_code}' -X POST \
42
"$CI_API_URL/repos/$CI_PROJECT_PATH/releases/$tag/assets" \
43
-H "Authorization: Bearer $CI_JOB_TOKEN" -H "Content-Type: application/json" -d "$body")" || code=000
44
cat "$resp"; echo
45
if [[ "$code" != 2* ]]; then
46
echo "release API returned HTTP $code (see response above)" >&2
47
exit 1
48
fi
@@ -1,17 +1,12 @@1
#!/usr/bin/env bash1
#!/usr/bin/env bash2
# Tag-pipeline publish step.2
# Tag-pipeline publish step (design.md, "v0.1.0 release" decision).3
#3
#4
# Inspected BlueGit master on 6 November 2026 (api_routes.go, ops_ci.go4
# Publishes the release for the tag that started this pipeline with5
# opPublishRelease, release_replace.go checkReplace, gitrepo.Tag):5
# POST $CI_API_URL/repos/{owner}/{repo}/releases/{tag}/assets — BlueGit's6
# there is no route that attaches artifacts to an existing git tag or an6
# create-only route for an existing tag: an existing release is HTTP 409, it7
# existing release. POST /api/v1/repos/{owner}/{repo}/releases always creates7
# never creates, moves or deletes the tag, and the assets are artifacts of8
# the annotated tag. An existing tag returns HTTP 409 unless replace=true,8
# successful jobs of this same pipeline. `replace` is never sent and the9
# and replace=true is HTTP 403 on a tag pipeline.9
# tag-creating route POST .../releases is never called.10
#11
# This script therefore does not call that endpoint and does not send12
# replace. It exits 3 until BlueGit grows an attach route. It does not13
# invent a second tag and it does not switch the pipeline onto a branch14
# release. The required server change is recorded in design.md section 15.15
set -euo pipefail10
set -euo pipefail16
11
17
: "${CI_API_URL:?}" "${CI_JOB_TOKEN:?}" "${CI_COMMIT_SHA:?}" "${CI_PROJECT_PATH:?}" "${CI_COMMIT_TAG:?}"12
: "${CI_API_URL:?}" "${CI_JOB_TOKEN:?}" "${CI_COMMIT_SHA:?}" "${CI_PROJECT_PATH:?}" "${CI_COMMIT_TAG:?}"@@ -19,10 +14,35 @@ set -euo pipefail19
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"14
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"20
cd "$root"15
cd "$root"21
version="$(bash scripts/ci/package-version.sh)"16
version="$(bash scripts/ci/package-version.sh)"17
tag="$CI_COMMIT_TAG"18
[[ "$tag" == "v$version" ]] || { echo "tag $tag does not match package version $version" >&2; exit 1; }19
20
b="paperdoll-renderer-${tag}"21
asset() { jq -n --arg j "$1" --arg p "$2" --arg n "$3" '{job:$j,path:$p,name:$n}'; }22
assets="$(jq -s . \23
<(asset package:appimage dist/paperdoll-renderer-x86_64.AppImage "${b}-x86_64.AppImage") \24
<(asset package:ubuntu dist/paperdoll-renderer_amd64.deb "${b}-amd64.deb") \25
<(asset package:arch dist/paperdoll-renderer-x86_64.pkg.tar.zst "${b}-x86_64.pkg.tar.zst") \26
<(asset package:windows dist/paperdoll-renderer-windows-x86_64.zip "${b}-windows-x86_64.zip") \27
<(asset verify:packages dist/SHA256SUMS "${b}-SHA256SUMS.txt"))"28
desc="Paperdoll Renderer ${version}.29
30
* Linux AppImage (portable).31
* Debian/Ubuntu .deb: /usr/bin/paperdoll-renderer, desktop entry, icons, .ppd MIME type.32
* Arch .pkg.tar.zst, built from packaging/arch/PKGBUILD. AUR: paperdoll-renderer-bin.33
* Windows zip (x86_64, MinGW build).34
* SHA256SUMS of the package files.35
36
The default starter bodies are \"Animated walking Male Base Mesh\" and \"Animated Female Base Mesh\" by assetfactory (Sketchfab Standard licence); see THIRD_PARTY_NOTICES.md."37
body="$(jq -n --arg n "Paperdoll Renderer ${tag}" --arg b "$desc" --argjson a "$assets" '{name:$n,body:$b,assets:$a}')"22
38
23
echo "release-blocked: no-attach-endpoint" >&239
echo "Release $tag on $CI_COMMIT_SHA (existing tag, create-only)"24
echo "tag ${CI_COMMIT_TAG} version ${version} commit ${CI_COMMIT_SHA} project ${CI_PROJECT_PATH}" >&240
resp="$(mktemp)"25
echo "BlueGit has no request that publishes these package artifacts onto the tag that already started this pipeline." >&241
code="$(curl -sS -o "$resp" -w '%{http_code}' -X POST \26
echo "The create-release route would make a new annotated tag. This script does not call it." >&242
"$CI_API_URL/repos/$CI_PROJECT_PATH/releases/$tag/assets" \27
echo "The overwrite flag is not sent. No second tag is created." >&243
-H "Authorization: Bearer $CI_JOB_TOKEN" -H "Content-Type: application/json" -d "$body")" || code=00028
exit 344
cat "$resp"; echo45
if [[ "$code" != 2* ]]; then46
echo "release API returned HTTP $code (see response above)" >&247
exit 148
fi