Add package-first build and distribution workflow
This commit is contained in:
parent
4a69c3d333
commit
993f51712b
13 changed files with 462 additions and 52 deletions
21
.github/workflows/ci.yml
vendored
21
.github/workflows/ci.yml
vendored
|
|
@ -17,9 +17,18 @@ jobs:
|
|||
python -m pip install --upgrade pip
|
||||
python -m pip install uv build
|
||||
uv sync --extra x11
|
||||
- name: Compile
|
||||
run: python -m py_compile src/*.py tests/*.py
|
||||
- name: Unit tests
|
||||
run: python -m unittest discover -s tests -p 'test_*.py'
|
||||
- name: Build artifacts
|
||||
run: python -m build
|
||||
- name: Release quality checks
|
||||
run: make release-check
|
||||
- name: Build Debian package
|
||||
run: make package-deb
|
||||
- name: Build Arch package inputs
|
||||
run: make package-arch
|
||||
- name: Upload packaging artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: aman-artifacts
|
||||
path: |
|
||||
dist/*.whl
|
||||
dist/*.tar.gz
|
||||
dist/*.deb
|
||||
dist/arch/PKGBUILD
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,3 +4,5 @@ __pycache__/
|
|||
*.pyc
|
||||
outputs/
|
||||
models/
|
||||
build/
|
||||
dist/
|
||||
|
|
|
|||
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -4,6 +4,17 @@ All notable changes to Aman will be documented in this file.
|
|||
|
||||
The format is based on Keep a Changelog and this project follows Semantic Versioning.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Packaging scripts and templates for Debian (`.deb`) and Arch (`PKGBUILD` + source tarball).
|
||||
- Make targets for build/package/release-check workflows.
|
||||
- Persona and distribution policy documentation.
|
||||
|
||||
### Changed
|
||||
- README now documents package-first installation for non-technical users.
|
||||
- Release checklist now includes packaging artifacts.
|
||||
|
||||
## [0.1.0] - 2026-02-26
|
||||
|
||||
### Added
|
||||
|
|
|
|||
44
Makefile
44
Makefile
|
|
@ -1,10 +1,13 @@
|
|||
PYTHON ?= python3
|
||||
CONFIG := $(HOME)/.config/aman/config.json
|
||||
|
||||
.PHONY: run doctor self-check install sync test check
|
||||
DIST_DIR := $(CURDIR)/dist
|
||||
BUILD_DIR := $(CURDIR)/build
|
||||
|
||||
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||
RUN_CONFIG := $(if $(RUN_ARGS),$(abspath $(firstword $(RUN_ARGS))),$(CONFIG))
|
||||
|
||||
.PHONY: run doctor self-check sync test check build package package-deb package-arch release-check install-local install-service install clean-dist clean-build clean
|
||||
|
||||
ifneq ($(filter run,$(firstword $(MAKECMDGOALS))),)
|
||||
.PHONY: $(RUN_ARGS)
|
||||
$(RUN_ARGS):
|
||||
|
|
@ -24,14 +27,43 @@ sync:
|
|||
uv sync
|
||||
|
||||
test:
|
||||
python3 -m unittest discover -s tests -p 'test_*.py'
|
||||
$(PYTHON) -m unittest discover -s tests -p 'test_*.py'
|
||||
|
||||
check:
|
||||
python3 -m py_compile src/*.py
|
||||
$(PYTHON) -m py_compile src/*.py
|
||||
$(MAKE) test
|
||||
|
||||
install:
|
||||
uv pip install --user .
|
||||
build:
|
||||
$(PYTHON) -m build --no-isolation
|
||||
|
||||
package: package-deb package-arch
|
||||
|
||||
package-deb:
|
||||
./scripts/package_deb.sh
|
||||
|
||||
package-arch:
|
||||
./scripts/package_arch.sh
|
||||
|
||||
release-check:
|
||||
$(PYTHON) -m py_compile src/*.py tests/*.py
|
||||
$(MAKE) test
|
||||
$(MAKE) build
|
||||
|
||||
install-local:
|
||||
$(PYTHON) -m pip install --user ".[x11]"
|
||||
|
||||
install-service:
|
||||
mkdir -p $(HOME)/.config/systemd/user
|
||||
cp systemd/aman.service $(HOME)/.config/systemd/user/aman.service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now aman
|
||||
|
||||
install: install-local install-service
|
||||
|
||||
clean-dist:
|
||||
rm -rf $(DIST_DIR)
|
||||
|
||||
clean-build:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
clean: clean-build
|
||||
|
|
|
|||
123
README.md
123
README.md
|
|
@ -3,23 +3,61 @@
|
|||
|
||||
Python X11 STT daemon that records audio, runs Whisper, applies local AI cleanup, and injects text.
|
||||
|
||||
## Requirements
|
||||
## Target User
|
||||
|
||||
The canonical Aman user is a desktop professional who wants dictation and
|
||||
rewriting features without learning Python tooling.
|
||||
|
||||
- End-user path: native OS package install.
|
||||
- Developer path: Python/uv workflows.
|
||||
|
||||
Persona details and distribution policy are documented in
|
||||
[`docs/persona-and-distribution.md`](docs/persona-and-distribution.md).
|
||||
|
||||
## Install (Recommended)
|
||||
|
||||
End users do not need `uv`.
|
||||
|
||||
### Debian/Ubuntu (`.deb`)
|
||||
|
||||
Download a release artifact and install it:
|
||||
|
||||
```bash
|
||||
sudo apt install ./aman_<version>_<arch>.deb
|
||||
```
|
||||
|
||||
Then enable the user service:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now aman
|
||||
```
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Use the generated packaging inputs (`PKGBUILD` + source tarball) in `dist/arch/`
|
||||
or your own packaging pipeline.
|
||||
|
||||
## Distribution Matrix
|
||||
|
||||
| Channel | Audience | Status |
|
||||
| --- | --- | --- |
|
||||
| Debian package (`.deb`) | End users on Ubuntu/Debian | Canonical |
|
||||
| Arch `PKGBUILD` + source tarball | Arch maintainers/power users | Supported |
|
||||
| Python wheel/sdist | Developers/integrators | Supported |
|
||||
|
||||
## Runtime Dependencies
|
||||
|
||||
- X11
|
||||
- `sounddevice` (PortAudio)
|
||||
- `faster-whisper`
|
||||
- `llama-cpp-python`
|
||||
- Tray icon deps: `gtk3`, `libayatana-appindicator3`
|
||||
- Python deps (core): `numpy`, `pillow`, `faster-whisper`, `llama-cpp-python`, `sounddevice`
|
||||
- X11 extras: `PyGObject`, `python-xlib`
|
||||
|
||||
System packages (example names): `portaudio`/`libportaudio2`.
|
||||
- PortAudio runtime (`libportaudio2` or distro equivalent)
|
||||
- GTK3 and AppIndicator runtime (`gtk3`, `libayatana-appindicator3`)
|
||||
- Python GTK and X11 bindings (`python3-gi`/`python-gobject`, `python-xlib`)
|
||||
|
||||
<details>
|
||||
<summary>Ubuntu/Debian</summary>
|
||||
|
||||
```bash
|
||||
sudo apt install -y portaudio19-dev libportaudio2 python3-gi gir1.2-gtk-3.0 libayatana-appindicator3-1
|
||||
sudo apt install -y libportaudio2 python3-gi python3-xlib gir1.2-gtk-3.0 libayatana-appindicator3-1
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
@ -28,7 +66,7 @@ sudo apt install -y portaudio19-dev libportaudio2 python3-gi gir1.2-gtk-3.0 liba
|
|||
<summary>Arch Linux</summary>
|
||||
|
||||
```bash
|
||||
sudo pacman -S --needed portaudio gtk3 libayatana-appindicator
|
||||
sudo pacman -S --needed portaudio gtk3 libayatana-appindicator python-gobject python-xlib
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
@ -37,7 +75,7 @@ sudo pacman -S --needed portaudio gtk3 libayatana-appindicator
|
|||
<summary>Fedora</summary>
|
||||
|
||||
```bash
|
||||
sudo dnf install -y portaudio portaudio-devel gtk3 libayatana-appindicator-gtk3
|
||||
sudo dnf install -y portaudio gtk3 libayatana-appindicator-gtk3 python3-gobject python3-xlib
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
@ -46,25 +84,15 @@ sudo dnf install -y portaudio portaudio-devel gtk3 libayatana-appindicator-gtk3
|
|||
<summary>openSUSE</summary>
|
||||
|
||||
```bash
|
||||
sudo zypper install -y portaudio portaudio-devel gtk3 libayatana-appindicator3-1
|
||||
sudo zypper install -y portaudio gtk3 libayatana-appindicator3-1 python3-gobject python3-python-xlib
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Python Daemon
|
||||
|
||||
Install Python deps:
|
||||
|
||||
X11 (supported):
|
||||
|
||||
```bash
|
||||
uv sync --extra x11
|
||||
```
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
uv run aman run
|
||||
aman run
|
||||
```
|
||||
|
||||
On first launch, Aman opens a graphical settings window automatically.
|
||||
|
|
@ -191,15 +219,13 @@ STT hinting:
|
|||
## systemd user service
|
||||
|
||||
```bash
|
||||
uv pip install --user .
|
||||
cp systemd/aman.service ~/.config/systemd/user/aman.service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now aman
|
||||
make install-service
|
||||
```
|
||||
|
||||
Service notes:
|
||||
|
||||
- The user unit launches `aman` from `PATH`; ensure `~/.local/bin` is present in your user PATH.
|
||||
- The user unit launches `aman` from `PATH`.
|
||||
- Package installs should provide the `aman` command automatically.
|
||||
- Inspect failures with `systemctl --user status aman` and `journalctl --user -u aman -f`.
|
||||
|
||||
## Usage
|
||||
|
|
@ -228,21 +254,50 @@ AI processing:
|
|||
- Default local llama.cpp model.
|
||||
- Optional external API provider through `llm.provider=external_api`.
|
||||
|
||||
Build and packaging (maintainers):
|
||||
|
||||
```bash
|
||||
make build
|
||||
make package
|
||||
make package-deb
|
||||
make package-arch
|
||||
make release-check
|
||||
```
|
||||
|
||||
`make package-deb` installs Python dependencies while creating the package.
|
||||
For offline packaging, set `AMAN_WHEELHOUSE_DIR` to a directory containing the
|
||||
required wheels.
|
||||
|
||||
Control:
|
||||
|
||||
```bash
|
||||
make run
|
||||
make run config.example.json
|
||||
make doctor
|
||||
make self-check
|
||||
make check
|
||||
```
|
||||
|
||||
CLI (internal/support fallback, mostly for automation/tests):
|
||||
Developer setup (optional, `uv` workflow):
|
||||
|
||||
```bash
|
||||
uv sync --extra x11
|
||||
uv run aman run --config ~/.config/aman/config.json
|
||||
uv run aman doctor --config ~/.config/aman/config.json --json
|
||||
uv run aman self-check --config ~/.config/aman/config.json --json
|
||||
uv run aman version
|
||||
uv run aman init --config ~/.config/aman/config.json --force
|
||||
```
|
||||
|
||||
Developer setup (optional, `pip` workflow):
|
||||
|
||||
```bash
|
||||
make install-local
|
||||
aman run --config ~/.config/aman/config.json
|
||||
```
|
||||
|
||||
CLI (internal/support fallback):
|
||||
|
||||
```bash
|
||||
aman run --config ~/.config/aman/config.json
|
||||
aman doctor --config ~/.config/aman/config.json --json
|
||||
aman self-check --config ~/.config/aman/config.json --json
|
||||
aman version
|
||||
aman init --config ~/.config/aman/config.json --force
|
||||
```
|
||||
|
|
|
|||
50
docs/persona-and-distribution.md
Normal file
50
docs/persona-and-distribution.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Aman Target Persona and Distribution Strategy
|
||||
|
||||
## Primary Persona: Desktop Professional
|
||||
|
||||
This is the canonical Aman user.
|
||||
|
||||
- Uses Linux desktop daily (X11 today), mostly Ubuntu/Debian.
|
||||
- Wants fast dictation and rewriting without learning Python tooling.
|
||||
- Prefers GUI setup and tray usage over CLI.
|
||||
- Expects normal install/uninstall/update behavior from system packages.
|
||||
|
||||
Design implications:
|
||||
|
||||
- End-user install path must not require `uv`.
|
||||
- Runtime defaults should work with minimal input.
|
||||
- Documentation should prioritize package install first.
|
||||
|
||||
## Secondary Persona: Power User
|
||||
|
||||
- Comfortable with CLI, package internals, and model customization.
|
||||
- Uses advanced config, external APIs, or custom models.
|
||||
- Can run diagnostics and debug logs when needed.
|
||||
|
||||
Design implications:
|
||||
|
||||
- Keep Make and Python workflows available.
|
||||
- Keep explicit expert-mode knobs in settings and config.
|
||||
- Keep docs for development separate from standard install docs.
|
||||
|
||||
## Supported Distribution Path (Current)
|
||||
|
||||
Tiered distribution model:
|
||||
|
||||
1. Canonical: Debian package (`.deb`) for Ubuntu/Debian users.
|
||||
2. Secondary: Arch package inputs (`PKGBUILD` + source tarball).
|
||||
3. Developer: wheel/sdist from `python -m build`.
|
||||
|
||||
## Out of Scope for Initial Packaging
|
||||
|
||||
- Wayland production support.
|
||||
- Flatpak/snap-first distribution.
|
||||
- Cross-platform desktop installers outside Linux.
|
||||
|
||||
## Release and Support Policy
|
||||
|
||||
- App versioning follows SemVer (`0.y.z` until API/UX stabilizes).
|
||||
- Config schema versioning is independent (`config_version` in config).
|
||||
- Packaging docs must always separate:
|
||||
- End-user install path (package-first)
|
||||
- Developer setup path (uv/pip/build workflows)
|
||||
|
|
@ -2,11 +2,16 @@
|
|||
|
||||
1. Update `CHANGELOG.md` with final release notes.
|
||||
2. Bump `project.version` in `pyproject.toml`.
|
||||
3. Run:
|
||||
- `python3 -m py_compile src/*.py tests/*.py`
|
||||
- `python3 -m unittest discover -s tests -p 'test_*.py'`
|
||||
4. Build artifacts:
|
||||
- `python3 -m build`
|
||||
5. Tag release:
|
||||
3. Run quality and build gates:
|
||||
- `make release-check`
|
||||
4. Build packaging artifacts:
|
||||
- `make package`
|
||||
5. Verify artifacts:
|
||||
- `dist/*.whl`
|
||||
- `dist/*.tar.gz`
|
||||
- `dist/*.deb`
|
||||
- `dist/arch/PKGBUILD`
|
||||
6. Tag release:
|
||||
- `git tag vX.Y.Z`
|
||||
- `git push origin vX.Y.Z`
|
||||
7. Publish release and upload package artifacts from `dist/`.
|
||||
|
|
|
|||
33
packaging/arch/PKGBUILD.in
Normal file
33
packaging/arch/PKGBUILD.in
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Maintainer: Aman Maintainers <maintainers@example.com>
|
||||
pkgname=aman
|
||||
pkgver=__VERSION__
|
||||
pkgrel=1
|
||||
pkgdesc="Local amanuensis daemon for X11 desktops"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/example/aman"
|
||||
license=('MIT')
|
||||
depends=('python' 'python-pip' 'python-setuptools' 'portaudio' 'gtk3' 'libayatana-appindicator' 'python-gobject' 'python-xlib')
|
||||
makedepends=('python-build' 'python-installer' 'python-wheel')
|
||||
source=("__TARBALL_NAME__")
|
||||
sha256sums=('__TARBALL_SHA256__')
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/aman-${pkgver}"
|
||||
python -m build --wheel
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/aman-${pkgver}"
|
||||
install -dm755 "${pkgdir}/opt/aman"
|
||||
python -m venv --system-site-packages "${pkgdir}/opt/aman/venv"
|
||||
"${pkgdir}/opt/aman/venv/bin/python" -m pip install --upgrade pip
|
||||
"${pkgdir}/opt/aman/venv/bin/python" -m pip install "dist/aman-${pkgver}-"*.whl
|
||||
|
||||
install -Dm755 /dev/stdin "${pkgdir}/usr/bin/aman" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
exec /opt/aman/venv/bin/aman "$@"
|
||||
EOF
|
||||
|
||||
install -Dm644 "systemd/aman.service" "${pkgdir}/usr/lib/systemd/user/aman.service"
|
||||
}
|
||||
11
packaging/deb/control.in
Normal file
11
packaging/deb/control.in
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Package: __PACKAGE_NAME__
|
||||
Version: __VERSION__
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: __ARCH__
|
||||
Maintainer: Aman Maintainers <maintainers@example.com>
|
||||
Depends: python3, python3-venv, python3-gi, python3-xlib, libportaudio2, gir1.2-gtk-3.0, 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
|
||||
first-run graphical settings UI.
|
||||
10
packaging/deb/postinst
Executable file
10
packaging/deb/postinst
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
cat <<'EOF'
|
||||
Aman installed.
|
||||
|
||||
To enable auto-start for your user session:
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now aman
|
||||
EOF
|
||||
44
scripts/package_arch.sh
Executable file
44
scripts/package_arch.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/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 git
|
||||
require_command sha256sum
|
||||
|
||||
VERSION="$(project_version)"
|
||||
PACKAGE_NAME="$(project_name)"
|
||||
ARCH_DIST_DIR="${DIST_DIR}/arch"
|
||||
TARBALL_NAME="${PACKAGE_NAME}-${VERSION}.tar.gz"
|
||||
TARBALL_PATH="${ARCH_DIST_DIR}/${TARBALL_NAME}"
|
||||
PKGBUILD_PATH="${ARCH_DIST_DIR}/PKGBUILD"
|
||||
|
||||
mkdir -p "${ARCH_DIST_DIR}"
|
||||
|
||||
git -C "${ROOT_DIR}" archive \
|
||||
--format=tar.gz \
|
||||
--prefix="${PACKAGE_NAME}-${VERSION}/" \
|
||||
HEAD \
|
||||
> "${TARBALL_PATH}"
|
||||
|
||||
TARBALL_SHA256="$(sha256sum "${TARBALL_PATH}" | awk '{print $1}')"
|
||||
|
||||
render_template \
|
||||
"${ROOT_DIR}/packaging/arch/PKGBUILD.in" \
|
||||
"${PKGBUILD_PATH}" \
|
||||
"VERSION=${VERSION}" \
|
||||
"TARBALL_NAME=${TARBALL_NAME}" \
|
||||
"TARBALL_SHA256=${TARBALL_SHA256}"
|
||||
|
||||
echo "generated ${PKGBUILD_PATH}"
|
||||
echo "generated ${TARBALL_PATH}"
|
||||
|
||||
if [[ "${BUILD_ARCH_PACKAGE:-0}" == "1" ]]; then
|
||||
require_command makepkg
|
||||
(
|
||||
cd "${ARCH_DIST_DIR}"
|
||||
makepkg -f
|
||||
)
|
||||
fi
|
||||
84
scripts/package_common.sh
Executable file
84
scripts/package_common.sh
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
DIST_DIR="${ROOT_DIR}/dist"
|
||||
BUILD_DIR="${ROOT_DIR}/build"
|
||||
APP_NAME="aman"
|
||||
|
||||
mkdir -p "${DIST_DIR}" "${BUILD_DIR}"
|
||||
|
||||
require_command() {
|
||||
local cmd="$1"
|
||||
if command -v "${cmd}" >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
echo "missing required command: ${cmd}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
project_version() {
|
||||
require_command python3
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
text = Path("pyproject.toml").read_text(encoding="utf-8")
|
||||
match = re.search(r'(?m)^version\s*=\s*"([^"]+)"\s*$', text)
|
||||
if not match:
|
||||
raise SystemExit("project version not found in pyproject.toml")
|
||||
print(match.group(1))
|
||||
PY
|
||||
}
|
||||
|
||||
project_name() {
|
||||
require_command python3
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
text = Path("pyproject.toml").read_text(encoding="utf-8")
|
||||
match = re.search(r'(?m)^name\s*=\s*"([^"]+)"\s*$', text)
|
||||
if not match:
|
||||
raise SystemExit("project name not found in pyproject.toml")
|
||||
print(match.group(1))
|
||||
PY
|
||||
}
|
||||
|
||||
build_wheel() {
|
||||
require_command python3
|
||||
python3 -m build --wheel --no-isolation
|
||||
}
|
||||
|
||||
latest_wheel_path() {
|
||||
require_command python3
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
text = Path("pyproject.toml").read_text(encoding="utf-8")
|
||||
name_match = re.search(r'(?m)^name\s*=\s*"([^"]+)"\s*$', text)
|
||||
version_match = re.search(r'(?m)^version\s*=\s*"([^"]+)"\s*$', text)
|
||||
if not name_match or not version_match:
|
||||
raise SystemExit("project metadata not found in pyproject.toml")
|
||||
name = name_match.group(1).replace("-", "_")
|
||||
version = version_match.group(1)
|
||||
candidates = sorted(Path("dist").glob(f"{name}-{version}-*.whl"))
|
||||
if not candidates:
|
||||
raise SystemExit("no wheel artifact found in dist/")
|
||||
print(candidates[-1])
|
||||
PY
|
||||
}
|
||||
|
||||
render_template() {
|
||||
local template_path="$1"
|
||||
local output_path="$2"
|
||||
shift 2
|
||||
cp "${template_path}" "${output_path}"
|
||||
for mapping in "$@"; do
|
||||
local key="${mapping%%=*}"
|
||||
local value="${mapping#*=}"
|
||||
sed -i "s|__${key}__|${value}|g" "${output_path}"
|
||||
done
|
||||
}
|
||||
64
scripts/package_deb.sh
Executable file
64
scripts/package_deb.sh
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
#!/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 dpkg-deb
|
||||
require_command python3
|
||||
|
||||
VERSION="$(project_version)"
|
||||
PACKAGE_NAME="$(project_name)"
|
||||
ARCH="${DEB_ARCH:-}"
|
||||
if [[ -z "${ARCH}" ]]; then
|
||||
if command -v dpkg >/dev/null 2>&1; then
|
||||
ARCH="$(dpkg --print-architecture)"
|
||||
else
|
||||
ARCH="amd64"
|
||||
fi
|
||||
fi
|
||||
|
||||
build_wheel
|
||||
WHEEL_PATH="$(latest_wheel_path)"
|
||||
|
||||
STAGE_DIR="${BUILD_DIR}/deb/${PACKAGE_NAME}_${VERSION}_${ARCH}"
|
||||
PACKAGE_BASENAME="${PACKAGE_NAME}_${VERSION}_${ARCH}"
|
||||
DEB_PATH="${DIST_DIR}/${PACKAGE_BASENAME}.deb"
|
||||
VENV_DIR="${STAGE_DIR}/opt/${PACKAGE_NAME}/venv"
|
||||
PIP_ARGS=()
|
||||
if [[ -n "${AMAN_WHEELHOUSE_DIR:-}" ]]; then
|
||||
PIP_ARGS+=(--no-index --find-links "${AMAN_WHEELHOUSE_DIR}")
|
||||
fi
|
||||
|
||||
rm -rf "${STAGE_DIR}"
|
||||
mkdir -p "${STAGE_DIR}/DEBIAN"
|
||||
mkdir -p "${STAGE_DIR}/usr/bin"
|
||||
mkdir -p "${STAGE_DIR}/usr/lib/systemd/user"
|
||||
mkdir -p "${STAGE_DIR}/opt/${PACKAGE_NAME}"
|
||||
|
||||
render_template \
|
||||
"${ROOT_DIR}/packaging/deb/control.in" \
|
||||
"${STAGE_DIR}/DEBIAN/control" \
|
||||
"PACKAGE_NAME=${PACKAGE_NAME}" \
|
||||
"VERSION=${VERSION}" \
|
||||
"ARCH=${ARCH}"
|
||||
|
||||
cp "${ROOT_DIR}/packaging/deb/postinst" "${STAGE_DIR}/DEBIAN/postinst"
|
||||
chmod 0755 "${STAGE_DIR}/DEBIAN/postinst"
|
||||
|
||||
python3 -m venv --system-site-packages "${VENV_DIR}"
|
||||
"${VENV_DIR}/bin/python" -m pip install "${PIP_ARGS[@]}" "${WHEEL_PATH}"
|
||||
|
||||
cat >"${STAGE_DIR}/usr/bin/${PACKAGE_NAME}" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
exec /opt/${PACKAGE_NAME}/venv/bin/${PACKAGE_NAME} "\$@"
|
||||
EOF
|
||||
chmod 0755 "${STAGE_DIR}/usr/bin/${PACKAGE_NAME}"
|
||||
|
||||
cp "${ROOT_DIR}/systemd/aman.service" "${STAGE_DIR}/usr/lib/systemd/user/aman.service"
|
||||
|
||||
rm -f "${DEB_PATH}"
|
||||
dpkg-deb --build --root-owner-group "${STAGE_DIR}" "${DEB_PATH}"
|
||||
echo "built ${DEB_PATH}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue