# Paperdoll Renderer — BlueGit CI (git.timfalken.com).
#
# Syntax checked on 6 November 2026 against GET /api/v1/ci/spec,
# timfa/bluegit docs/CI.md, and the public pipelines of timfa/posprint,
# timfa/minecart-trains and timfa/click-tween. The AUR job follows
# timfa/legacy-cycles (aur-ssh-setup.sh, publish-aur.sh).
#
# Requested graph:
# merge request and master/main push -> test
# tag push, after tests succeed -> AppImage, Ubuntu package, Arch package,
# Windows build, artifact check, one release publish, then the AUR
#
# Release (design.md, v0.1.0 decision, rechecked 7 November 2026 against the
# live OpenAPI): the release job publishes onto the tag that started this
# pipeline with POST /repos/$CI_PROJECT_PATH/releases/$CI_COMMIT_TAG/assets,
# BlueGit's create-only route for an existing tag (409 if a release exists;
# never creates, moves or deletes the tag). replace is never sent and the
# tag-creating release route is not called. Tags are pushed by hand on a green
# master; publish:aur then updates the AUR package paperdoll-renderer-bin.
#
# posprint notes two runner facts used below: jobs start in the checkout
# (CI_PROJECT_DIR is not set), and artifact paths are exact files.
# Windows is cross-compiled with MinGW, the same reason posprint gives:
# no Windows runner on BlueGit.
stages: [test, package, verify, release, publish]
variables:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: "1"
CARGO_PROFILE_DEV_DEBUG: "false"
CARGO_PROFILE_TEST_DEBUG: "false"
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "master"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG != ""
.rust:
image: rust:1.96-bookworm
timeout: 2h
before_script:
- export CARGO_HOME="$PWD/cargo-home"
- export PATH="$CARGO_HOME/bin:$PATH"
- apt-get update -qq
- apt-get install -y -qq pkg-config gcc libxcb1-dev libx11-dev libxkbcommon-dev libxkbcommon-x11-dev libgl1-mesa-dev python3
.on_tag:
rules:
- if: $CI_COMMIT_TAG != ""
test:
extends: .rust
stage: test
interruptible: true
cache:
key: cargo-test
paths: [target/, cargo-home/]
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "master"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG != ""
script:
- cargo fmt --check
- cargo check --workspace --all-targets --locked
- cargo clippy --workspace --all-targets --locked -- -D warnings
- cargo test --workspace --locked
package:appimage:
extends: [.rust, .on_tag]
stage: package
needs: [test]
interruptible: true
cache:
key: cargo-linux
paths: [target/, cargo-home/]
before_script:
- export CARGO_HOME="$PWD/cargo-home"
- export PATH="$CARGO_HOME/bin:$PATH"
- apt-get update -qq
- apt-get install -y -qq pkg-config gcc libxcb1-dev libx11-dev libxkbcommon-dev libxkbcommon-x11-dev libgl1-mesa-dev file
script:
- bash scripts/package/appimage.sh
artifacts:
paths: [dist/paperdoll-renderer-x86_64.AppImage]
expire_in: 30d
package:ubuntu:
extends: [.rust, .on_tag]
stage: package
needs: [test]
interruptible: true
cache:
key: cargo-linux
paths: [target/, cargo-home/]
before_script:
- export CARGO_HOME="$PWD/cargo-home"
- export PATH="$CARGO_HOME/bin:$PATH"
- apt-get update -qq
- apt-get install -y -qq pkg-config gcc libxcb1-dev libx11-dev libxkbcommon-dev libxkbcommon-x11-dev libgl1-mesa-dev dpkg-dev
script:
- bash scripts/package/deb.sh
artifacts:
paths: [dist/paperdoll-renderer_amd64.deb]
expire_in: 30d
package:arch:
extends: .on_tag
stage: package
image: archlinux/archlinux:base-devel
timeout: 2h
needs: [test]
interruptible: true
script:
- pacman -Syu --noconfirm
- pacman -S --noconfirm --needed base-devel rust pkgconf libxkbcommon libxcb libx11 libglvnd git
- bash scripts/package/arch.sh
artifacts:
paths: [dist/paperdoll-renderer-x86_64.pkg.tar.zst]
expire_in: 30d
# MinGW cross build. posprint documents this because BlueGit has no Windows runner.
package:windows:
extends: [.rust, .on_tag]
stage: package
needs: [test]
interruptible: true
cache:
key: cargo-windows
paths: [target/, cargo-home/]
before_script:
- export CARGO_HOME="$PWD/cargo-home"
- export PATH="$CARGO_HOME/bin:$PATH"
- apt-get update -qq
- apt-get install -y -qq gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64 zip python3
- rustup target add x86_64-pc-windows-gnu
- export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
- export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
script:
- bash scripts/package/windows.sh
artifacts:
paths: [dist/paperdoll-renderer-windows-x86_64.zip]
expire_in: 30d
verify:packages:
stage: verify
image: bluegit/base
extends: .on_tag
needs: [package:appimage, package:ubuntu, package:arch, package:windows]
script:
- bash scripts/ci/verify-packages.sh
artifacts:
paths: [dist/SHA256SUMS]
expire_in: 30d
release:
stage: release
image: bluegit/base
extends: .on_tag
needs: [verify:packages, package:appimage, package:ubuntu, package:arch, package:windows]
resource_group: release
script:
- bash scripts/ci/release.sh
# AUR (approach of timfa/legacy-cycles): after the release, publish
# paperdoll-renderer-bin from this tag's .deb release asset. Protected
# variables (AUR_SSH_PRIVATE_KEY_B64, AUR_GIT_AUTHOR_NAME, AUR_GIT_AUTHOR_EMAIL)
# reach only protected refs; v* is a protected tag pattern.
# allow_failure: an AUR outage does not turn the release red.
publish:aur:
stage: publish
image: archlinux/archlinux:base-devel
extends: .on_tag
needs: [release]
allow_failure: true
resource_group: aur
script:
- pacman -Syu --noconfirm --needed git openssh curl coreutils shadow util-linux
- bash scripts/ci/aur-ssh-setup.sh
- bash scripts/ci/publish-aur.sh paperdoll-renderer-bin