Align CI with the validated Ubuntu support floor
Stop implying that one Ubuntu 3.11 unit lane validates the full Linux support surface Aman documents.\n\nSplit CI into an Ubuntu CPython 3.10/3.11/3.12 unit-package matrix, a portable install plus doctor smoke lane, and a packaging lane gated on both. Add a reproducible ci_portable_smoke.sh helper with fake systemctl coverage, and force the installer onto /usr/bin/python3 so the smoke path uses the distro-provided GI and X11 Python packages it is meant to validate.\n\nUpdate the README, release/distribution docs, and Debian metadata to distinguish the automated Ubuntu CI floor from broader manual GA signoff families, and add the missing AppIndicator introspection package to the Ubuntu/Debian dependency lists.\n\nValidate with python3 -m unittest discover -s tests -p 'test_*.py', python3 -m py_compile src/*.py tests/*.py, and bash -n scripts/ci_portable_smoke.sh. The full xvfb-backed smoke could not be run locally in this sandbox because xvfb-run is unavailable.
This commit is contained in:
parent
4d0081d1d0
commit
dd2813340b
9 changed files with 270 additions and 9 deletions
108
.github/workflows/ci.yml
vendored
108
.github/workflows/ci.yml
vendored
|
|
@ -5,18 +5,120 @@ on:
|
|||
pull_request:
|
||||
|
||||
jobs:
|
||||
test-and-build:
|
||||
unit-matrix:
|
||||
name: Unit Matrix (${{ matrix.python-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install Ubuntu runtime dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
gobject-introspection \
|
||||
libcairo2-dev \
|
||||
libgirepository1.0-dev \
|
||||
libportaudio2 \
|
||||
pkg-config \
|
||||
python3-gi \
|
||||
python3-xlib \
|
||||
gir1.2-gtk-3.0 \
|
||||
gir1.2-ayatanaappindicator3-0.1 \
|
||||
libayatana-appindicator3-1
|
||||
- name: Create project environment
|
||||
run: |
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install uv build
|
||||
uv sync --active --frozen
|
||||
echo "${GITHUB_WORKSPACE}/.venv/bin" >> "${GITHUB_PATH}"
|
||||
- name: Run compile check
|
||||
run: python -m py_compile src/*.py tests/*.py
|
||||
- name: Run unit and package-logic test suite
|
||||
run: python -m unittest discover -s tests -p 'test_*.py'
|
||||
|
||||
portable-ubuntu-smoke:
|
||||
name: Portable Ubuntu Smoke
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Install dependencies
|
||||
- name: Install Ubuntu runtime dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
gobject-introspection \
|
||||
libcairo2-dev \
|
||||
libgirepository1.0-dev \
|
||||
libportaudio2 \
|
||||
pkg-config \
|
||||
python3-gi \
|
||||
python3-xlib \
|
||||
gir1.2-gtk-3.0 \
|
||||
gir1.2-ayatanaappindicator3-0.1 \
|
||||
libayatana-appindicator3-1 \
|
||||
xvfb
|
||||
- name: Create project environment
|
||||
run: |
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install uv build
|
||||
uv sync
|
||||
uv sync --active --frozen
|
||||
echo "${GITHUB_WORKSPACE}/.venv/bin" >> "${GITHUB_PATH}"
|
||||
- name: Run portable install and doctor smoke with distro python
|
||||
env:
|
||||
AMAN_CI_SYSTEM_PYTHON: /usr/bin/python3
|
||||
run: bash ./scripts/ci_portable_smoke.sh
|
||||
- name: Upload portable smoke logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: aman-portable-smoke-logs
|
||||
path: build/ci-smoke
|
||||
|
||||
package-artifacts:
|
||||
name: Package Artifacts
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- unit-matrix
|
||||
- portable-ubuntu-smoke
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Install Ubuntu runtime dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
gobject-introspection \
|
||||
libcairo2-dev \
|
||||
libgirepository1.0-dev \
|
||||
libportaudio2 \
|
||||
pkg-config \
|
||||
python3-gi \
|
||||
python3-xlib \
|
||||
gir1.2-gtk-3.0 \
|
||||
gir1.2-ayatanaappindicator3-0.1 \
|
||||
libayatana-appindicator3-1
|
||||
- name: Create project environment
|
||||
run: |
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install uv build
|
||||
uv sync --active --frozen
|
||||
echo "${GITHUB_WORKSPACE}/.venv/bin" >> "${GITHUB_PATH}"
|
||||
- name: Prepare release candidate artifacts
|
||||
run: make release-prep
|
||||
- name: Upload packaging artifacts
|
||||
|
|
|
|||
|
|
@ -19,12 +19,16 @@ Support requests and bug reports go to
|
|||
| Supported daily-use mode | `systemd --user` service |
|
||||
| Manual foreground mode | `aman run` for setup, support, and debugging |
|
||||
| Canonical recovery sequence | `aman doctor` -> `aman self-check` -> `journalctl --user -u aman` -> `aman run --verbose` |
|
||||
| Representative GA validation families | Debian/Ubuntu, Arch, Fedora, openSUSE |
|
||||
| Automated CI floor | Ubuntu CI: CPython `3.10`, `3.11`, `3.12` for unit/package coverage, plus portable install and `aman doctor` smoke with Ubuntu system `python3` |
|
||||
| Manual GA signoff families | Debian/Ubuntu, Arch, Fedora, openSUSE |
|
||||
| Portable installer prerequisite | System CPython `3.10`, `3.11`, or `3.12` |
|
||||
|
||||
Distribution policy and user persona details live in
|
||||
[`docs/persona-and-distribution.md`](docs/persona-and-distribution.md).
|
||||
|
||||
The wider distro-family list is a manual validation target for release signoff.
|
||||
It is not the current automated CI surface yet.
|
||||
|
||||
## 60-Second Quickstart
|
||||
|
||||
First, install the runtime dependencies for your distro:
|
||||
|
|
@ -33,7 +37,7 @@ First, install the runtime dependencies for your distro:
|
|||
<summary>Ubuntu/Debian</summary>
|
||||
|
||||
```bash
|
||||
sudo apt install -y libportaudio2 python3-gi python3-xlib gir1.2-gtk-3.0 libayatana-appindicator3-1
|
||||
sudo apt install -y libportaudio2 python3-gi python3-xlib gir1.2-gtk-3.0 gir1.2-ayatanaappindicator3-0.1 libayatana-appindicator3-1
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
|
|||
|
|
@ -14,10 +14,13 @@ make package-arch
|
|||
make runtime-check
|
||||
make release-check
|
||||
make release-prep
|
||||
bash ./scripts/ci_portable_smoke.sh
|
||||
```
|
||||
|
||||
- `make package-portable` builds `dist/aman-x11-linux-<version>.tar.gz` plus
|
||||
its `.sha256` file.
|
||||
- `bash ./scripts/ci_portable_smoke.sh` reproduces the Ubuntu CI portable
|
||||
install plus `aman doctor` smoke path locally.
|
||||
- `make release-prep` runs `make release-check`, builds the packaged artifacts,
|
||||
and writes `dist/SHA256SUMS` for the release page upload set.
|
||||
- `make package-deb` installs Python dependencies while creating the package.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ For X11 GA, Aman supports:
|
|||
- Runtime dependencies installed from the distro package manager.
|
||||
- `systemd --user` as the supported daily-use path.
|
||||
- `aman run` as the foreground setup, support, and debugging path.
|
||||
- Representative validation across Debian/Ubuntu, Arch, Fedora, and openSUSE.
|
||||
- Automated validation floor on Ubuntu CI: CPython `3.10`, `3.11`, and `3.12`
|
||||
for unit/package coverage, plus portable install and `aman doctor` smoke with
|
||||
Ubuntu system `python3`.
|
||||
- Manual GA signoff families: Debian/Ubuntu, Arch, Fedora, openSUSE.
|
||||
- The recovery sequence `aman doctor` -> `aman self-check` ->
|
||||
`journalctl --user -u aman` -> `aman run --verbose`.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ Download published bundles, checksums, and release notes from
|
|||
- System CPython `3.10`, `3.11`, or `3.12`
|
||||
- Runtime dependencies installed from the distro package manager
|
||||
|
||||
Current automated validation covers Ubuntu CI on CPython `3.10`, `3.11`, and
|
||||
`3.12` for unit/package coverage, plus a portable install and `aman doctor`
|
||||
smoke path with Ubuntu system `python3`. The other distro-family instructions
|
||||
below remain manual validation targets.
|
||||
|
||||
## Runtime dependencies
|
||||
|
||||
Install the runtime dependencies for your distro before running `install.sh`.
|
||||
|
|
@ -22,7 +27,7 @@ Install the runtime dependencies for your distro before running `install.sh`.
|
|||
### Ubuntu/Debian
|
||||
|
||||
```bash
|
||||
sudo apt install -y libportaudio2 python3-gi python3-xlib gir1.2-gtk-3.0 libayatana-appindicator3-1
|
||||
sudo apt install -y libportaudio2 python3-gi python3-xlib gir1.2-gtk-3.0 gir1.2-ayatanaappindicator3-0.1 libayatana-appindicator3-1
|
||||
```
|
||||
|
||||
### Arch Linux
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ This is the first GA-targeted X11 release for Aman.
|
|||
- `systemd --user` for supported daily use
|
||||
- System CPython `3.10`, `3.11`, or `3.12` for the portable installer
|
||||
- Runtime dependencies installed from the distro package manager
|
||||
- Representative validation families: Debian/Ubuntu, Arch, Fedora, openSUSE
|
||||
- Automated validation floor: Ubuntu CI on CPython `3.10`, `3.11`, and `3.12`
|
||||
for unit/package coverage, plus portable install and `aman doctor` smoke
|
||||
with Ubuntu system `python3`
|
||||
- Manual GA signoff families: Debian/Ubuntu, Arch, Fedora, openSUSE
|
||||
|
||||
## Artifacts
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ state.
|
|||
|
||||
## Evidence sources
|
||||
|
||||
- Automated CI validation:
|
||||
GitHub Actions Ubuntu lanes for CPython `3.10`, `3.11`, and `3.12` for
|
||||
unit/package coverage, plus a portable install and `aman doctor` smoke lane
|
||||
with Ubuntu system `python3`
|
||||
- Portable lifecycle matrix:
|
||||
[`portable-validation-matrix.md`](./portable-validation-matrix.md)
|
||||
- Runtime reliability matrix:
|
||||
|
|
@ -52,6 +56,7 @@ state.
|
|||
| Milestone 2 portable lifecycle | Complete for now | Arch row in `portable-validation-matrix.md` plus [`user-readiness/1773357669.md`](../../user-readiness/1773357669.md) |
|
||||
| Milestone 3 runtime reliability | Complete for now | Arch runtime rows in `runtime-validation-report.md` plus [`user-readiness/1773357669.md`](../../user-readiness/1773357669.md) |
|
||||
| Milestone 4 first-run UX/docs | Complete | `first-run-review-notes.md` and `user-readiness/1773352170.md` |
|
||||
| Automated validation floor | Repo-complete | GitHub Actions Ubuntu matrix on CPython `3.10`-`3.12` plus portable smoke with Ubuntu system `python3` |
|
||||
| Release metadata and support surface | Repo-complete | `LICENSE`, `SUPPORT.md`, `pyproject.toml`, packaging templates |
|
||||
| Release artifacts and checksums | Repo-complete | `make release-prep`, `dist/SHA256SUMS`, `docs/releases/1.0.0.md` |
|
||||
| Full four-family GA validation | Pending | Complete the remaining Debian/Ubuntu, Fedora, and openSUSE rows in both validation matrices |
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Section: utils
|
|||
Priority: optional
|
||||
Architecture: __ARCH__
|
||||
Maintainer: Thales Maciel <thales@thalesmaciel.com>
|
||||
Depends: python3, python3-venv, python3-gi, python3-xlib, libportaudio2, gir1.2-gtk-3.0, libayatana-appindicator3-1
|
||||
Depends: python3, python3-venv, python3-gi, python3-xlib, libportaudio2, gir1.2-gtk-3.0, gir1.2-ayatanaappindicator3-0.1, libayatana-appindicator3-1
|
||||
Description: Aman local amanuensis daemon for X11 desktops
|
||||
Aman records microphone input, transcribes speech, optionally rewrites output,
|
||||
and injects text into the focused desktop app. Includes tray controls and a
|
||||
|
|
|
|||
136
scripts/ci_portable_smoke.sh
Executable file
136
scripts/ci_portable_smoke.sh
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
source "${SCRIPT_DIR}/package_common.sh"
|
||||
|
||||
require_command mktemp
|
||||
require_command tar
|
||||
require_command xvfb-run
|
||||
|
||||
DISTRO_PYTHON="${AMAN_CI_SYSTEM_PYTHON:-/usr/bin/python3}"
|
||||
require_command "${DISTRO_PYTHON}"
|
||||
|
||||
LOG_DIR="${BUILD_DIR}/ci-smoke"
|
||||
RUN_DIR="${LOG_DIR}/run"
|
||||
HOME_DIR="${RUN_DIR}/home"
|
||||
FAKE_BIN_DIR="${RUN_DIR}/fake-bin"
|
||||
EXTRACT_DIR="${RUN_DIR}/bundle"
|
||||
RUNTIME_DIR="${RUN_DIR}/xdg-runtime"
|
||||
COMMAND_LOG="${LOG_DIR}/commands.log"
|
||||
SYSTEMCTL_LOG="${LOG_DIR}/systemctl.log"
|
||||
|
||||
dump_logs() {
|
||||
local path
|
||||
for path in "${COMMAND_LOG}" "${SYSTEMCTL_LOG}" "${LOG_DIR}"/*.stdout.log "${LOG_DIR}"/*.stderr.log; do
|
||||
if [[ -f "${path}" ]]; then
|
||||
echo "=== ${path#${ROOT_DIR}/} ==="
|
||||
cat "${path}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
on_exit() {
|
||||
local status="$1"
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
dump_logs
|
||||
fi
|
||||
}
|
||||
trap 'on_exit $?' EXIT
|
||||
|
||||
run_logged() {
|
||||
local name="$1"
|
||||
shift
|
||||
local stdout_log="${LOG_DIR}/${name}.stdout.log"
|
||||
local stderr_log="${LOG_DIR}/${name}.stderr.log"
|
||||
{
|
||||
printf "+"
|
||||
printf " %q" "$@"
|
||||
printf "\n"
|
||||
} >>"${COMMAND_LOG}"
|
||||
"$@" >"${stdout_log}" 2>"${stderr_log}"
|
||||
}
|
||||
|
||||
rm -rf "${LOG_DIR}"
|
||||
mkdir -p "${HOME_DIR}" "${FAKE_BIN_DIR}" "${EXTRACT_DIR}" "${RUNTIME_DIR}"
|
||||
: >"${COMMAND_LOG}"
|
||||
: >"${SYSTEMCTL_LOG}"
|
||||
|
||||
cat >"${FAKE_BIN_DIR}/systemctl" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
log_path="${SYSTEMCTL_LOG:?}"
|
||||
if [[ "${1:-}" == "--user" ]]; then
|
||||
shift
|
||||
fi
|
||||
printf '%s\n' "$*" >>"${log_path}"
|
||||
|
||||
case "$*" in
|
||||
"daemon-reload")
|
||||
;;
|
||||
"enable --now aman")
|
||||
;;
|
||||
"stop aman")
|
||||
;;
|
||||
"disable --now aman")
|
||||
;;
|
||||
"is-system-running")
|
||||
printf 'running\n'
|
||||
;;
|
||||
"show aman --property=FragmentPath --value")
|
||||
printf '%s\n' "${AMAN_CI_SERVICE_PATH:?}"
|
||||
;;
|
||||
"is-enabled aman")
|
||||
printf 'enabled\n'
|
||||
;;
|
||||
"is-active aman")
|
||||
printf 'active\n'
|
||||
;;
|
||||
*)
|
||||
echo "unexpected systemctl command: $*" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
EOF
|
||||
chmod 0755 "${FAKE_BIN_DIR}/systemctl"
|
||||
|
||||
run_logged package-portable bash "${SCRIPT_DIR}/package_portable.sh"
|
||||
|
||||
VERSION="$(project_version)"
|
||||
PACKAGE_NAME="$(project_name)"
|
||||
PORTABLE_TARBALL="${DIST_DIR}/${PACKAGE_NAME}-x11-linux-${VERSION}.tar.gz"
|
||||
BUNDLE_DIR="${EXTRACT_DIR}/${PACKAGE_NAME}-x11-linux-${VERSION}"
|
||||
|
||||
run_logged extract tar -C "${EXTRACT_DIR}" -xzf "${PORTABLE_TARBALL}"
|
||||
|
||||
export HOME="${HOME_DIR}"
|
||||
export PATH="${FAKE_BIN_DIR}:${HOME_DIR}/.local/bin:${PATH}"
|
||||
export SYSTEMCTL_LOG
|
||||
export AMAN_CI_SERVICE_PATH="${HOME_DIR}/.config/systemd/user/aman.service"
|
||||
|
||||
run_logged distro-python "${DISTRO_PYTHON}" --version
|
||||
|
||||
(
|
||||
cd "${BUNDLE_DIR}"
|
||||
run_logged install env \
|
||||
PATH="${FAKE_BIN_DIR}:${HOME_DIR}/.local/bin:$(dirname "${DISTRO_PYTHON}"):${PATH}" \
|
||||
./install.sh
|
||||
)
|
||||
|
||||
run_logged version "${HOME_DIR}/.local/bin/aman" version
|
||||
run_logged init "${HOME_DIR}/.local/bin/aman" init --config "${HOME_DIR}/.config/aman/config.json"
|
||||
run_logged doctor xvfb-run -a env \
|
||||
HOME="${HOME_DIR}" \
|
||||
PATH="${PATH}" \
|
||||
SYSTEMCTL_LOG="${SYSTEMCTL_LOG}" \
|
||||
AMAN_CI_SERVICE_PATH="${AMAN_CI_SERVICE_PATH}" \
|
||||
XDG_RUNTIME_DIR="${RUNTIME_DIR}" \
|
||||
XDG_SESSION_TYPE="x11" \
|
||||
"${HOME_DIR}/.local/bin/aman" doctor --config "${HOME_DIR}/.config/aman/config.json"
|
||||
run_logged uninstall "${HOME_DIR}/.local/share/aman/current/uninstall.sh" --purge
|
||||
|
||||
echo "portable smoke passed"
|
||||
echo "logs: ${LOG_DIR}"
|
||||
cat "${LOG_DIR}/doctor.stdout.log"
|
||||
Loading…
Add table
Add a link
Reference in a new issue