mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-07-06 01:42:11 +02:00
Initial AUR work
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
name: Publish AUR package
|
||||||
|
|
||||||
|
# Pushes the contents of pkg/aur/ to the remoteterm-meshcore AUR repository
|
||||||
|
# whenever a GitHub release is published. Can also be triggered manually for
|
||||||
|
# testing or out-of-band republishes.
|
||||||
|
#
|
||||||
|
# Required secrets:
|
||||||
|
# AUR_SSH_PRIVATE_KEY Private SSH key registered with the AUR maintainer
|
||||||
|
# account that owns the remoteterm-meshcore package.
|
||||||
|
# AUR_COMMIT_EMAIL Email used for the AUR git commit identity.
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Version to publish (no v prefix, e.g. 3.9.1)'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
# Serialize publishes so a fast back-to-back release sequence cannot race
|
||||||
|
# two pushes against the AUR repo. The later one wins by virtue of being
|
||||||
|
# the final state.
|
||||||
|
group: publish-aur
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-aur:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Resolve version from event
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
else
|
||||||
|
VERSION="${{ github.event.release.tag_name }}"
|
||||||
|
fi
|
||||||
|
VERSION="${VERSION#v}"
|
||||||
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Publishing AUR package for version $VERSION"
|
||||||
|
|
||||||
|
- name: Stamp pkgver into PKGBUILD
|
||||||
|
run: |
|
||||||
|
sed -i "s/^pkgver=.*/pkgver=${{ steps.version.outputs.version }}/" pkg/aur/PKGBUILD
|
||||||
|
sed -i "s/^pkgrel=.*/pkgrel=1/" pkg/aur/PKGBUILD
|
||||||
|
|
||||||
|
- name: Publish to AUR
|
||||||
|
uses: KSXGitHub/github-actions-deploy-aur@v4.1.2
|
||||||
|
with:
|
||||||
|
pkgname: remoteterm-meshcore
|
||||||
|
pkgbuild: pkg/aur/PKGBUILD
|
||||||
|
assets: |
|
||||||
|
pkg/aur/remoteterm-meshcore.install
|
||||||
|
pkg/aur/remoteterm-meshcore.service
|
||||||
|
pkg/aur/remoteterm.env
|
||||||
|
commit_username: jkingsman
|
||||||
|
commit_email: ${{ secrets.AUR_COMMIT_EMAIL }}
|
||||||
|
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||||
|
commit_message: "Update to ${{ steps.version.outputs.version }}"
|
||||||
|
# Recompute sha256sums from the live release tarball + the bundled
|
||||||
|
# service/env files. The committed PKGBUILD has SKIP placeholders.
|
||||||
|
updpkgsums: true
|
||||||
|
# Validate the PKGBUILD parses and sources download, but skip the
|
||||||
|
# actual build (which would run uv sync + npm install for several
|
||||||
|
# minutes of CI time on every release).
|
||||||
|
test: true
|
||||||
|
test_flags: --clean --cleanbuild --nodeps --nobuild
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# Maintainer: Jack Kingsman <jack.kingsman@gmail.com>
|
||||||
|
|
||||||
|
pkgname=remoteterm-meshcore
|
||||||
|
# pkgver is rewritten by .github/workflows/publish-aur.yml on each release.
|
||||||
|
pkgver=3.9.0
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc='Web interface for MeshCore mesh radio networks'
|
||||||
|
arch=(x86_64 aarch64)
|
||||||
|
url='https://github.com/jkingsman/Remote-Terminal-for-MeshCore'
|
||||||
|
license=('MIT')
|
||||||
|
# No system python dependency — we bundle a standalone interpreter via
|
||||||
|
# python-build-standalone so the package is immune to Arch python ABI bumps.
|
||||||
|
depends=(glibc)
|
||||||
|
makedepends=(uv nodejs npm)
|
||||||
|
optdepends=('bluez: BLE transport support')
|
||||||
|
backup=(etc/remoteterm-meshcore/remoteterm.env)
|
||||||
|
# The bundled python-build-standalone binary ships pre-stripped. makepkg's
|
||||||
|
# default strip pass corrupts its unusual ELF layout (.dynstr not in segment),
|
||||||
|
# so we disable stripping for the whole package.
|
||||||
|
options=(!strip)
|
||||||
|
install=remoteterm-meshcore.install
|
||||||
|
source=(
|
||||||
|
"$pkgname-$pkgver.tar.gz::https://github.com/jkingsman/Remote-Terminal-for-MeshCore/archive/refs/tags/$pkgver.tar.gz"
|
||||||
|
"remoteterm-meshcore.service"
|
||||||
|
"remoteterm.env"
|
||||||
|
)
|
||||||
|
# sha256sums are recomputed by `updpkgsums` in the publish workflow before
|
||||||
|
# the PKGBUILD is pushed to AUR. The committed values are intentionally SKIP
|
||||||
|
# so the file is honest about not tracking real hashes in this repo.
|
||||||
|
sha256sums=('SKIP'
|
||||||
|
'SKIP'
|
||||||
|
'SKIP')
|
||||||
|
|
||||||
|
# python-build-standalone: stripped install_only builds (~30 MB each).
|
||||||
|
# Bump _pyver and _pybuilddate when updating the bundled interpreter.
|
||||||
|
_pyver=3.13.13
|
||||||
|
_pybuilddate=20260408
|
||||||
|
|
||||||
|
source_x86_64=("python-${_pyver}-x86_64.tar.gz::https://github.com/astral-sh/python-build-standalone/releases/download/${_pybuilddate}/cpython-${_pyver}+${_pybuilddate}-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz")
|
||||||
|
sha256sums_x86_64=('SKIP')
|
||||||
|
|
||||||
|
source_aarch64=("python-${_pyver}-aarch64.tar.gz::https://github.com/astral-sh/python-build-standalone/releases/download/${_pybuilddate}/cpython-${_pyver}+${_pybuilddate}-aarch64-unknown-linux-gnu-install_only_stripped.tar.gz")
|
||||||
|
sha256sums_aarch64=('SKIP')
|
||||||
|
|
||||||
|
_srcname="Remote-Terminal-for-MeshCore-$pkgver"
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$_srcname"
|
||||||
|
|
||||||
|
# Build frontend
|
||||||
|
cd frontend
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Create venv using the bundled standalone Python interpreter, then install
|
||||||
|
# Python dependencies into it. This produces a fully self-contained venv
|
||||||
|
# that does not reference the system Python at all.
|
||||||
|
uv venv --python "$srcdir/python/bin/python3" .venv
|
||||||
|
uv sync --no-dev --frozen
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$_srcname"
|
||||||
|
|
||||||
|
local _optdir=/opt/remoteterm-meshcore
|
||||||
|
local _instdir="$pkgdir$_optdir"
|
||||||
|
|
||||||
|
# App source
|
||||||
|
install -d "$_instdir"
|
||||||
|
cp -r app "$_instdir/"
|
||||||
|
cp pyproject.toml uv.lock "$_instdir/"
|
||||||
|
|
||||||
|
# Frontend build
|
||||||
|
install -d "$_instdir/frontend"
|
||||||
|
cp -r frontend/dist "$_instdir/frontend/"
|
||||||
|
|
||||||
|
# Bundled Python interpreter
|
||||||
|
cp -a "$srcdir/python" "$_instdir/python"
|
||||||
|
|
||||||
|
# Python venv
|
||||||
|
cp -a .venv "$_instdir/"
|
||||||
|
|
||||||
|
# Fix shebangs and venv config: replace build-time paths with final
|
||||||
|
# install paths so the venv works from /opt after installation.
|
||||||
|
# sed only operates on regular file contents, so symlinks need separate
|
||||||
|
# fixup below.
|
||||||
|
find "$_instdir/.venv/bin" -type f -exec \
|
||||||
|
sed -i "s|$srcdir/$_srcname/.venv|$_optdir/.venv|g" {} +
|
||||||
|
find "$_instdir/.venv/bin" -type f -exec \
|
||||||
|
sed -i "s|$srcdir/python|$_optdir/python|g" {} +
|
||||||
|
sed -i \
|
||||||
|
-e "s|$srcdir/$_srcname/.venv|$_optdir/.venv|g" \
|
||||||
|
-e "s|$srcdir/python|$_optdir/python|g" \
|
||||||
|
"$_instdir/.venv/pyvenv.cfg" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Recreate the venv interpreter symlinks — these are symlinks (not files),
|
||||||
|
# so sed cannot fix them. Point them at the bundled Python.
|
||||||
|
ln -sf "$_optdir/python/bin/python3" "$_instdir/.venv/bin/python"
|
||||||
|
ln -sf python "$_instdir/.venv/bin/python3"
|
||||||
|
ln -sf python "$_instdir/.venv/bin/python3.13"
|
||||||
|
|
||||||
|
# Data directory symlink
|
||||||
|
ln -s /var/lib/remoteterm-meshcore "$_instdir/data"
|
||||||
|
|
||||||
|
# Systemd service
|
||||||
|
install -Dm644 "$srcdir/remoteterm-meshcore.service" \
|
||||||
|
"$pkgdir/usr/lib/systemd/system/remoteterm-meshcore.service"
|
||||||
|
|
||||||
|
# Environment file
|
||||||
|
install -Dm640 "$srcdir/remoteterm.env" \
|
||||||
|
"$pkgdir/etc/remoteterm-meshcore/remoteterm.env"
|
||||||
|
|
||||||
|
# License
|
||||||
|
install -Dm644 LICENSE.md \
|
||||||
|
"$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
pre_install() {
|
||||||
|
getent group remoteterm > /dev/null || groupadd -r remoteterm
|
||||||
|
getent passwd remoteterm > /dev/null || \
|
||||||
|
useradd -r -g remoteterm -d /var/lib/remoteterm-meshcore -s /sbin/nologin \
|
||||||
|
-c "RemoteTerm for MeshCore" remoteterm
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_upgrade() {
|
||||||
|
pre_install
|
||||||
|
}
|
||||||
|
|
||||||
|
post_install() {
|
||||||
|
echo "==> Set your radio connection (serial, TCP, or BLE) in"
|
||||||
|
echo "==> /etc/remoteterm-meshcore/remoteterm.env"
|
||||||
|
echo "==> Start the service with: systemctl enable --now remoteterm-meshcore"
|
||||||
|
echo "==> The web UI will be at http://localhost:8000"
|
||||||
|
}
|
||||||
|
|
||||||
|
post_upgrade() {
|
||||||
|
# Clean orphaned __pycache__ dirs left by the previous Python version
|
||||||
|
find /opt/remoteterm-meshcore -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
if systemctl is-active --quiet remoteterm-meshcore; then
|
||||||
|
systemctl restart remoteterm-meshcore
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=RemoteTerm for MeshCore
|
||||||
|
Documentation=https://github.com/jkingsman/Remote-Terminal-for-MeshCore
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=remoteterm
|
||||||
|
Group=remoteterm
|
||||||
|
WorkingDirectory=/opt/remoteterm-meshcore
|
||||||
|
EnvironmentFile=/etc/remoteterm-meshcore/remoteterm.env
|
||||||
|
ExecStart=/opt/remoteterm-meshcore/.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
StateDirectory=remoteterm-meshcore
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
|
||||||
|
# Serial port access (uucp group on Arch)
|
||||||
|
SupplementaryGroups=uucp
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# RemoteTerm for MeshCore configuration
|
||||||
|
# https://github.com/jkingsman/Remote-Terminal-for-MeshCore
|
||||||
|
|
||||||
|
# Transport: uncomment ONE section below
|
||||||
|
|
||||||
|
# Serial auto-detect (default — no config needed)
|
||||||
|
|
||||||
|
# Serial manual port
|
||||||
|
#MESHCORE_SERIAL_PORT=/dev/ttyUSB0
|
||||||
|
|
||||||
|
# TCP
|
||||||
|
#MESHCORE_TCP_HOST=192.168.1.100
|
||||||
|
#MESHCORE_TCP_PORT=4000
|
||||||
|
|
||||||
|
# BLE (also requires the optional `bluez` package)
|
||||||
|
#MESHCORE_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
|
||||||
|
#MESHCORE_BLE_PIN=123456
|
||||||
|
|
||||||
|
# Database
|
||||||
|
MESHCORE_DATABASE_PATH=/var/lib/remoteterm-meshcore/meshcore.db
|
||||||
|
|
||||||
|
# Bots can run arbitrary Python on the server. Leave this set to 'true' unless
|
||||||
|
# you trust everyone on your network.
|
||||||
|
MESHCORE_DISABLE_BOTS=true
|
||||||
|
|
||||||
|
# HTTP Basic Auth (recommended when bots are enabled)
|
||||||
|
#MESHCORE_BASIC_AUTH_USERNAME=
|
||||||
|
#MESHCORE_BASIC_AUTH_PASSWORD=
|
||||||
Reference in New Issue
Block a user