Adds a "Show" selector (10 / 25 / 50 / 100) to the card header and drops the default row count from 15 to 10. The chosen value rides on the card's own polling URL (`/executions?limit=N`), so it survives the 5s htmx refresh with no client-side state; a config default outside those four is rendered as an extra option instead of disappearing. The query is parsed permissively — a stale or hand-edited polling URL clamps or falls back to the config default rather than 422-ing a card that would otherwise render. Ordering is now explicit rather than inherited from whatever Gitea returns: newest first, a not-yet-started (queued) run above everything, ties broken on Gitea's run id so matrix runs sharing a timestamp keep a stable order.
145 lines
6.4 KiB
TOML
145 lines
6.4 KiB
TOML
# ci-orchestrator config example.
|
||
#
|
||
# Copy to $CI_ROOT/config.toml or set $CI_CONFIG to the file path.
|
||
# Environment variables (CI_ROOT, CI_TEMPLATES, CI_BUILD_VMS, CI_ARTIFACTS,
|
||
# CI_KEYS, CI_VMRUN_PATH, CI_SSH_KEY_PATH, CI_GUEST_CRED_TARGET) override
|
||
# anything set here.
|
||
#
|
||
# IMPORTANT (TOML rule): top-level keys must appear BEFORE any [section] header.
|
||
# Keys placed after a [section] belong to that section, not to the root table.
|
||
|
||
# Top-level orchestrator settings.
|
||
vmrun_path = "C:/Program Files (x86)/VMware/VMware Workstation/vmrun.exe"
|
||
ssh_key_path = "F:/CI/keys/ci_linux"
|
||
guest_cred_target = "BuildVMGuest"
|
||
|
||
# --------------------------------------------------------------- Windows host
|
||
[paths]
|
||
root = "F:/CI"
|
||
templates = "F:/CI/Templates"
|
||
build_vms = "F:/CI/BuildVMs"
|
||
artifacts = "F:/CI/Artifacts"
|
||
keys = "F:/CI/keys"
|
||
|
||
# Phase B (Linux host) — uncomment after migration.
|
||
# [paths]
|
||
# root = "/var/lib/ci"
|
||
# templates = "/var/lib/ci/templates"
|
||
# build_vms = "/var/lib/ci/build-vms"
|
||
# artifacts = "/var/lib/ci/artifacts"
|
||
# keys = "/etc/ci/keys"
|
||
|
||
# Phase C hook: backend selector. Only "workstation" is implemented in Phase A.
|
||
[backend]
|
||
type = "workstation"
|
||
|
||
# Optional: pre-assign static IPs to build VMs via VMX guestinfo injection.
|
||
# Eliminates VMware-Tools IP-detect polling (20–180 s variance) — the host
|
||
# injects guestinfo.ip-assignment into each cloned VMX before vmrun start,
|
||
# and the guest boot script applies the static IP immediately.
|
||
#
|
||
# Prerequisite: install the guest-side startup script from
|
||
# template/guest-setup/linux/ci-report-ip.sh (Linux guests)
|
||
# template/guest-setup/windows/ci-static-ip.ps1 (Windows guests)
|
||
# and re-take the BaseClean / BaseClean-Linux snapshot.
|
||
#
|
||
# Pool size should equal runner capacity (default 4).
|
||
# Addresses must be outside the VMnet8 DHCP range (check
|
||
# /etc/vmware/vmnet8/dhcpd/dhcpd.conf — typically .128–.254).
|
||
#
|
||
# [ip_pool]
|
||
# addresses = ["192.168.79.201", "192.168.79.202",
|
||
# "192.168.79.203", "192.168.79.204"]
|
||
# netmask = "255.255.255.0"
|
||
# gateway = "192.168.79.2" # VMnet8 gateway; leave empty to skip default route
|
||
# lease_file = "/var/lib/ci/ip-pool.json"
|
||
|
||
# ------------------------------------------------- cargo dependency cache
|
||
# Compiled Rust dependency artifacts, reused between jobs. Engages only for
|
||
# Linux guests whose build workdir contains a Cargo.lock, so non-Rust jobs
|
||
# need no flag. Workspace crates are stripped before an entry is stored and
|
||
# the job refuses to publish if any survive, so a restored entry cannot carry
|
||
# the code under test.
|
||
#
|
||
# One immutable file per key under `root`; a key is
|
||
# sha256(Cargo.lock) + rustc version + host triple. Deleting entries by hand
|
||
# is always safe -- each one costs exactly one cold build to regenerate.
|
||
#
|
||
# `root` defaults to <paths.root>/cache/cargo and follows CI_ROOT unless set
|
||
# here explicitly. Measured on LinuxRust2404: an entry is ~645 MB and a warm
|
||
# job pays ~8s to skip ~120s of dependency compilation.
|
||
[cargo_cache]
|
||
enabled = true
|
||
# root = "/var/lib/ci/cache/cargo"
|
||
retention_days = 30
|
||
|
||
# --------------------------------------------------------------------- web UI
|
||
# Optional management web UI (`ci web serve`). Disabled unless `enabled = true`.
|
||
# Server-rendered dashboard for VM/host management, auth'd via Gitea OIDC.
|
||
#
|
||
# SECURITY:
|
||
# * `bind_host` defaults to 127.0.0.1 (localhost only). Only set it to a
|
||
# LAN IP explicitly and deliberately -- never "0.0.0.0" (that exposes the
|
||
# dashboard, which can kill VMs and purge caches, to every network the
|
||
# host is reachable from).
|
||
# * `session_secret_cred` and `[web.oidc] client_secret_cred` below are
|
||
# KEYRING KEY NAMES, not the secrets themselves. The actual secret
|
||
# values are never written to this file -- set them with:
|
||
# ci creds set WebSessionSecret
|
||
# ci creds set WebOidcClientSecret
|
||
# (the `_cred` values here just tell the app which keyring entry to read
|
||
# at request time).
|
||
#
|
||
# [web]
|
||
# enabled = true
|
||
# bind_host = "192.168.1.50" # explicit LAN IP; never 0.0.0.0
|
||
# bind_port = 8800
|
||
# audit_log = "/var/lib/ci/logs/web-audit.jsonl"
|
||
# allowed_users = ["simone"] # Gitea usernames allowed to log in
|
||
# session_secret_cred = "WebSessionSecret" # keyring KEY NAME, not the secret
|
||
#
|
||
# Executions card (recent Gitea Actions runs, live ones included). It normally
|
||
# reuses the access token from the operator's own OIDC login, held server-side
|
||
# only -- so neither key below is required. Set them to cover the cases that
|
||
# token cannot: a service restart (which forgets the logged-in tokens) or a
|
||
# non-admin operator.
|
||
# executions_limit = 10 # default rows in the card's selector (1..100)
|
||
# gitea_token_cred = "GiteaApiToken" # keyring KEY NAME of a fallback PAT
|
||
#
|
||
# Gitea OIDC client registration: Gitea -> Settings -> Applications -> OAuth2,
|
||
# redirect URI must exactly match `redirect_url` below (host+port+path).
|
||
#
|
||
# `scopes` needs an API read scope on top of the OIDC ones for the Executions
|
||
# card: `read:repository` lists the operator's own repos, `read:admin` (admin
|
||
# accounts only) lists every repo on the instance. Adding a scope requires one
|
||
# fresh login to re-consent.
|
||
#
|
||
# [web.oidc]
|
||
# issuer = "https://gitea.lan"
|
||
# client_id = "ci-web"
|
||
# redirect_url = "http://192.168.1.50:8800/auth/callback"
|
||
# client_secret_cred = "WebOidcClientSecret" # keyring KEY NAME, not the secret
|
||
# scopes = ["openid", "profile", "read:repository"]
|
||
#
|
||
# Optional: override the default systemd-unit allow-list the dashboard's
|
||
# service-management panel (Stage D) is allowed to start/stop/restart. Leave
|
||
# unset to use the built-in default (act-runner, act-runner-rust,
|
||
# vmware-host, ci-web -- see operations/services.py::MANAGED_SERVICES).
|
||
# A malformed row (missing/wrong-typed key) is skipped, never crashes
|
||
# startup. Every command reaching sudo is an exact-match systemctl/systemd-run
|
||
# invocation approved in deploy/sudoers.d/ci-web -- adding a unit here without
|
||
# also adding its NOPASSWD entries there just means every action for it fails
|
||
# (sudo prompts for a password that is never supplied, exit non-zero).
|
||
#
|
||
# [[web.managed_services]]
|
||
# id = "act-runner"
|
||
# unit = "act-runner.service"
|
||
# label = "Runner"
|
||
# allow_stop = true
|
||
#
|
||
# [[web.managed_services]]
|
||
# id = "ci-web"
|
||
# unit = "ci-web.service"
|
||
# label = "Web UI"
|
||
# allow_stop = false # restart-only -- stopping it would lock the operator out
|