mirror of
https://github.com/rightup/pyMC_Repeater.git
synced 2026-03-28 17:43:06 +01:00
Add build scripts and setup for pyMC_Repeater
- Implemented build-dev.sh for creating development .deb packages from untagged commits. - Implemented build-prod.sh for creating production .deb packages from tagged commits, including checks for a clean git state. - Added setup-build-env.sh to automate the installation of required build dependencies for Debian/Ubuntu. - Created setup.py to manage package setup using setuptools with versioning from git tags.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ __pycache__/
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
repeater/_version.py
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
|
||||
10
.pybuild/cpython3_3.12_pymc-repeater/.pydistutils.cfg
Normal file
10
.pybuild/cpython3_3.12_pymc-repeater/.pydistutils.cfg
Normal file
@@ -0,0 +1,10 @@
|
||||
[clean]
|
||||
all=1
|
||||
[build]
|
||||
build_lib=/home/rightup/Documents/GIT/meshcore/pyMC_Repeater/.pybuild/cpython3_3.12_pymc-repeater/build
|
||||
[install]
|
||||
force=1
|
||||
install_layout=deb
|
||||
install_scripts=$base/bin
|
||||
install_lib=/usr/lib/python3.12/dist-packages
|
||||
prefix=/usr
|
||||
6
debian/.gitignore
vendored
Normal file
6
debian/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
*.debhelper
|
||||
*.debhelper.log
|
||||
*.substvars
|
||||
.debhelper/
|
||||
files
|
||||
pymc-repeater/
|
||||
6
debian/changelog
vendored
Normal file
6
debian/changelog
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
pymc-repeater (1.0.5~dev0) unstable; urgency=medium
|
||||
|
||||
* Development build from git commit 7112da9
|
||||
* Version: 1.0.5.post0
|
||||
|
||||
-- Lloyd <lloyd@rightup.co.uk> Tue, 30 Dec 2025 12:55:47 +0000
|
||||
34
debian/control
vendored
Normal file
34
debian/control
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
Source: pymc-repeater
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Lloyd <lloyd@rightup.co.uk>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
dh-python,
|
||||
python3-all,
|
||||
python3-setuptools,
|
||||
python3-setuptools-scm,
|
||||
python3-wheel,
|
||||
python3-pip,
|
||||
python3-yaml,
|
||||
python3-cherrypy3,
|
||||
python3-paho-mqtt,
|
||||
python3-psutil,
|
||||
git
|
||||
Standards-Version: 4.6.2
|
||||
Homepage: https://github.com/rightup/pyMC_Repeater
|
||||
X-Python3-Version: >= 3.8
|
||||
|
||||
Package: pymc-repeater
|
||||
Architecture: all
|
||||
Depends: ${python3:Depends},
|
||||
${misc:Depends},
|
||||
python3-yaml,
|
||||
python3-cherrypy3,
|
||||
python3-paho-mqtt,
|
||||
python3-psutil,
|
||||
python3-jwt
|
||||
Description: PyMC Repeater Daemon
|
||||
A mesh networking repeater daemon for LoRa devices.
|
||||
.
|
||||
This package provides the pymc-repeater service for managing
|
||||
mesh network repeater functionality with a web interface.
|
||||
1
debian/debhelper-build-stamp
vendored
Normal file
1
debian/debhelper-build-stamp
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pymc-repeater
|
||||
3
debian/pymc-repeater.dirs
vendored
Normal file
3
debian/pymc-repeater.dirs
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
etc/pymc-repeater
|
||||
var/log/pymc-repeater
|
||||
usr/share/pymc-repeater
|
||||
3
debian/pymc-repeater.install
vendored
Normal file
3
debian/pymc-repeater.install
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
config.yaml.example usr/share/pymc-repeater/
|
||||
radio-presets.json usr/share/pymc-repeater/
|
||||
radio-settings.json usr/share/pymc-repeater/
|
||||
29
debian/pymc-repeater.postinst
vendored
Executable file
29
debian/pymc-repeater.postinst
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# Create system user
|
||||
if ! getent passwd pymc-repeater >/dev/null; then
|
||||
adduser --system --group --home /var/lib/pymc-repeater \
|
||||
--gecos "PyMC Repeater Service" pymc-repeater
|
||||
fi
|
||||
|
||||
# Set permissions
|
||||
chown -R pymc-repeater:pymc-repeater /etc/pymc-repeater
|
||||
chown -R pymc-repeater:pymc-repeater /var/log/pymc-repeater
|
||||
chmod 750 /etc/pymc-repeater
|
||||
chmod 750 /var/log/pymc-repeater
|
||||
|
||||
# Copy example config if no config exists
|
||||
if [ ! -f /etc/pymc-repeater/config.yaml ]; then
|
||||
cp /usr/share/pymc-repeater/config.yaml.example /etc/pymc-repeater/config.yaml
|
||||
chown pymc-repeater:pymc-repeater /etc/pymc-repeater/config.yaml
|
||||
chmod 640 /etc/pymc-repeater/config.yaml
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
18
debian/pymc-repeater.postrm
vendored
Executable file
18
debian/pymc-repeater.postrm
vendored
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
# Remove user and directories
|
||||
if getent passwd pymc-repeater >/dev/null; then
|
||||
deluser --system pymc-repeater || true
|
||||
fi
|
||||
rm -rf /etc/pymc-repeater
|
||||
rm -rf /var/log/pymc-repeater
|
||||
rm -rf /var/lib/pymc-repeater
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
15
debian/pymc-repeater.service
vendored
Normal file
15
debian/pymc-repeater.service
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=PyMC Repeater Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=pymc-repeater
|
||||
Group=pymc-repeater
|
||||
WorkingDirectory=/etc/pymc-repeater
|
||||
ExecStart=/usr/bin/pymc-repeater
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
22
debian/rules
vendored
Executable file
22
debian/rules
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
export PYBUILD_NAME=pymc-repeater
|
||||
export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@ --with python3 --buildsystem=pybuild
|
||||
|
||||
override_dh_auto_test:
|
||||
# Skip tests - cherrypy-cors not available in Debian repos
|
||||
# Tests pass in development with: pip install cherrypy-cors
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean
|
||||
rm -rf build/
|
||||
rm -rf *.egg-info/
|
||||
rm -rf .pybuild/
|
||||
rm -f repeater/_version.py
|
||||
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd --name=pymc-repeater
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
@@ -1,10 +1,10 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0", "wheel"]
|
||||
requires = ["setuptools>=61.0", "wheel", "setuptools_scm>=8.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pymc_repeater"
|
||||
version = "1.0.5"
|
||||
dynamic = ["version"]
|
||||
authors = [
|
||||
{name = "Lloyd", email = "lloyd@rightup.co.uk"},
|
||||
]
|
||||
@@ -31,7 +31,7 @@ keywords = ["mesh", "networking", "lora", "repeater", "daemon", "iot"]
|
||||
|
||||
|
||||
dependencies = [
|
||||
"pymc_core[hardware] @ git+https://github.com/rightup/pyMC_core.git@feat/anon-req",
|
||||
"pymc_core[hardware]>=1.0.6",
|
||||
"pyyaml>=6.0.0",
|
||||
"cherrypy>=18.0.0",
|
||||
"paho-mqtt>=1.6.0",
|
||||
@@ -73,3 +73,8 @@ target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 100
|
||||
|
||||
[tool.setuptools_scm]
|
||||
write_to = "repeater/_version.py"
|
||||
version_scheme = "post-release"
|
||||
local_scheme = "no-local-version"
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
__version__ = "1.0.5-beta-3"
|
||||
try:
|
||||
from ._version import version as __version__
|
||||
except ImportError:
|
||||
try:
|
||||
from importlib.metadata import version
|
||||
__version__ = version("pymc_repeater")
|
||||
except Exception:
|
||||
__version__ = "unknown"
|
||||
|
||||
65
repeater/web/auth/middleware.py
Normal file
65
repeater/web/auth/middleware.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import cherrypy
|
||||
from functools import wraps
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def require_auth(func):
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
# Skip authentication for OPTIONS requests (CORS preflight)
|
||||
if cherrypy.request.method == 'OPTIONS':
|
||||
return func(*args, **kwargs)
|
||||
|
||||
# Get auth handlers from global cherrypy config (not app config)
|
||||
jwt_handler = cherrypy.config.get('jwt_handler')
|
||||
token_manager = cherrypy.config.get('token_manager')
|
||||
|
||||
if not jwt_handler or not token_manager:
|
||||
logger.error("Auth handlers not configured")
|
||||
raise cherrypy.HTTPError(500, "Authentication not configured")
|
||||
|
||||
# Try JWT authentication first
|
||||
auth_header = cherrypy.request.headers.get('Authorization', '')
|
||||
if auth_header.startswith('Bearer '):
|
||||
token = auth_header[7:] # Remove 'Bearer ' prefix
|
||||
payload = jwt_handler.verify_jwt(token)
|
||||
|
||||
if payload:
|
||||
# JWT is valid
|
||||
cherrypy.request.user = {
|
||||
'username': payload['sub'],
|
||||
'client_id': payload['client_id'],
|
||||
'auth_type': 'jwt'
|
||||
}
|
||||
return func(*args, **kwargs)
|
||||
else:
|
||||
logger.warning("Invalid or expired JWT token")
|
||||
|
||||
# Try API token authentication
|
||||
api_key = cherrypy.request.headers.get('X-API-Key', '')
|
||||
if api_key:
|
||||
token_info = token_manager.verify_token(api_key)
|
||||
|
||||
if token_info:
|
||||
# API token is valid
|
||||
cherrypy.request.user = {
|
||||
'username': 'api_token',
|
||||
'token_name': token_info['name'],
|
||||
'token_id': token_info['id'],
|
||||
'auth_type': 'api_token'
|
||||
}
|
||||
return func(*args, **kwargs)
|
||||
else:
|
||||
logger.warning("Invalid API token")
|
||||
|
||||
# No valid authentication found
|
||||
logger.warning(f"Unauthorized access attempt to {cherrypy.request.path_info}")
|
||||
|
||||
cherrypy.response.status = 401
|
||||
cherrypy.response.headers['Content-Type'] = 'application/json'
|
||||
return {'success': False, 'error': 'Unauthorized - Valid JWT or API token required'}
|
||||
|
||||
return wrapper
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
32
repeater/web/html/assets/index-Di_qhLFB.css
Normal file
32
repeater/web/html/assets/index-Di_qhLFB.css
Normal file
File diff suppressed because one or more lines are too long
@@ -8,8 +8,8 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script type="module" crossorigin src="/assets/index-ViklARR2.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DiNHIYsR.css">
|
||||
<script type="module" crossorigin src="/assets/index-DWtvChhM.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Di_qhLFB.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
134
scripts/build-dev.sh
Executable file
134
scripts/build-dev.sh
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
# Build development .deb package for pyMC_Repeater
|
||||
# Allows building from untagged commits with ~dev version suffix
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Change to project root
|
||||
cd "$(dirname "$0")/.."
|
||||
PROJECT_ROOT=$(pwd)
|
||||
|
||||
log_info "Building development .deb package for pyMC_Repeater..."
|
||||
log_info "Project root: $PROJECT_ROOT"
|
||||
|
||||
# Check if we're in a git repository
|
||||
if [ ! -d .git ]; then
|
||||
log_error "Not in a git repository. Cannot use setuptools_scm."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get version from setuptools_scm
|
||||
log_step "Detecting version from git..."
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
log_error "python3 not found. Please install python3."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to get version from setuptools_scm
|
||||
VERSION=$(python3 -m setuptools_scm 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
log_error "Failed to get version from setuptools_scm."
|
||||
log_error "Make sure setuptools_scm is installed: pip3 install setuptools_scm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Detected version: $VERSION"
|
||||
|
||||
# Convert version to Debian format
|
||||
# setuptools_scm format: 1.0.5.post3.dev0 or 1.0.5.dev3+g123abc
|
||||
# Debian format: 1.0.5~dev3
|
||||
DEBIAN_VERSION=$(echo "$VERSION" | sed -E 's/\.post([0-9]+).*$/~dev\1/' | sed -E 's/\.dev([0-9]+).*$/~dev\1/' | sed -E 's/\+.*$//')
|
||||
|
||||
log_info "Debian version: $DEBIAN_VERSION"
|
||||
|
||||
# Update debian/changelog
|
||||
log_step "Updating debian/changelog..."
|
||||
CHANGELOG_DATE=$(date -R)
|
||||
cat > debian/changelog << EOF
|
||||
pymc-repeater ($DEBIAN_VERSION) unstable; urgency=medium
|
||||
|
||||
* Development build from git commit $(git rev-parse --short HEAD)
|
||||
* Version: $VERSION
|
||||
|
||||
-- Lloyd <lloyd@rightup.co.uk> $CHANGELOG_DATE
|
||||
EOF
|
||||
|
||||
log_info "Changelog updated with version $DEBIAN_VERSION"
|
||||
|
||||
# Clean previous builds
|
||||
log_step "Cleaning previous builds..."
|
||||
rm -rf debian/pymc-repeater/
|
||||
rm -rf debian/.debhelper/
|
||||
rm -rf debian/files
|
||||
rm -f debian/pymc-repeater.*.debhelper
|
||||
rm -f debian/pymc-repeater.substvars
|
||||
rm -f debian/*.log
|
||||
rm -rf .pybuild/
|
||||
rm -rf build/
|
||||
rm -rf *.egg-info/
|
||||
rm -f repeater/_version.py
|
||||
rm -f ../*.deb
|
||||
rm -f ../*.buildinfo
|
||||
rm -f ../*.changes
|
||||
|
||||
# Build the package
|
||||
log_step "Building .deb package..."
|
||||
log_info "This may take a few minutes..."
|
||||
|
||||
# Build without signing (development builds don't need to be signed)
|
||||
if debuild -us -uc -b 2>&1 | tee /tmp/debuild-dev.log; then
|
||||
log_info "Build successful!"
|
||||
else
|
||||
log_error "Build failed. Check /tmp/debuild-dev.log for details."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find and display the built package
|
||||
DEB_FILE=$(find .. -maxdepth 1 -name "pymc-repeater_${DEBIAN_VERSION}_*.deb" -type f | head -n 1)
|
||||
|
||||
if [ -n "$DEB_FILE" ]; then
|
||||
log_info ""
|
||||
log_info "════════════════════════════════════════════════════════════"
|
||||
log_info "Build complete!"
|
||||
log_info "Package: $(basename "$DEB_FILE")"
|
||||
log_info "Location: $DEB_FILE"
|
||||
log_info "Size: $(du -h "$DEB_FILE" | cut -f1)"
|
||||
log_info "════════════════════════════════════════════════════════════"
|
||||
log_info ""
|
||||
log_info "To install:"
|
||||
log_info " sudo dpkg -i $DEB_FILE"
|
||||
log_info ""
|
||||
log_info "To inspect package contents:"
|
||||
log_info " dpkg-deb -c $DEB_FILE"
|
||||
log_info ""
|
||||
log_info "To check package info:"
|
||||
log_info " dpkg-deb -I $DEB_FILE"
|
||||
else
|
||||
log_warn "Built package not found in expected location"
|
||||
log_info "Searching for .deb files in parent directory..."
|
||||
ls -lh ../*.deb 2>/dev/null || log_warn "No .deb files found"
|
||||
fi
|
||||
181
scripts/build-prod.sh
Executable file
181
scripts/build-prod.sh
Executable file
@@ -0,0 +1,181 @@
|
||||
#!/bin/bash
|
||||
# Build production .deb package for pyMC_Repeater
|
||||
# Requires a clean git tag - fails if not on a tagged commit
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Change to project root
|
||||
cd "$(dirname "$0")/.."
|
||||
PROJECT_ROOT=$(pwd)
|
||||
|
||||
log_info "Building production .deb package for pyMC_Repeater..."
|
||||
log_info "Project root: $PROJECT_ROOT"
|
||||
|
||||
# Check if we're in a git repository
|
||||
if [ ! -d .git ]; then
|
||||
log_error "Not in a git repository. Cannot use setuptools_scm."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for uncommitted changes
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
log_error "You have uncommitted changes. Production builds require a clean git state."
|
||||
log_error "Please commit or stash your changes first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if current commit is tagged
|
||||
log_step "Verifying git tag..."
|
||||
CURRENT_COMMIT=$(git rev-parse HEAD)
|
||||
TAG=$(git describe --exact-match --tags "$CURRENT_COMMIT" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$TAG" ]; then
|
||||
log_error "Current commit is not tagged."
|
||||
log_error "Production builds require a git tag."
|
||||
log_error ""
|
||||
log_error "To create a tag:"
|
||||
log_error " git tag v1.0.5"
|
||||
log_error " git push origin v1.0.5"
|
||||
log_error ""
|
||||
log_error "For development builds, use: ./scripts/build-dev.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Building from tag: $TAG"
|
||||
|
||||
# Get version from setuptools_scm
|
||||
log_step "Detecting version from git tag..."
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
log_error "python3 not found. Please install python3."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to get version from setuptools_scm
|
||||
VERSION=$(python3 -m setuptools_scm 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
log_error "Failed to get version from setuptools_scm."
|
||||
log_error "Make sure setuptools_scm is installed: pip3 install setuptools_scm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Detected version: $VERSION"
|
||||
|
||||
# Verify version doesn't contain dev/post markers (should be clean release version)
|
||||
if echo "$VERSION" | grep -qE '(dev|post|\+)'; then
|
||||
log_error "Version '$VERSION' contains development markers."
|
||||
log_error "Production builds must be from a clean tag without uncommitted changes."
|
||||
log_error "Current tag: $TAG"
|
||||
log_error ""
|
||||
log_error "This might happen if:"
|
||||
log_error " - There are commits after the tag"
|
||||
log_error " - The working directory is dirty"
|
||||
log_error " - The tag format is not recognized"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use the version as-is for Debian (it should be clean like "1.0.5")
|
||||
DEBIAN_VERSION="$VERSION"
|
||||
|
||||
log_info "Debian version: $DEBIAN_VERSION"
|
||||
|
||||
# Update debian/changelog with production release info
|
||||
log_step "Updating debian/changelog..."
|
||||
CHANGELOG_DATE=$(date -R)
|
||||
cat > debian/changelog << EOF
|
||||
pymc-repeater ($DEBIAN_VERSION) stable; urgency=medium
|
||||
|
||||
* Production release $VERSION
|
||||
* Git tag: $TAG
|
||||
* Commit: $(git rev-parse --short HEAD)
|
||||
|
||||
-- Lloyd <lloyd@rightup.co.uk> $CHANGELOG_DATE
|
||||
EOF
|
||||
|
||||
log_info "Changelog updated with version $DEBIAN_VERSION"
|
||||
|
||||
# Clean previous builds
|
||||
log_step "Cleaning previous builds..."
|
||||
rm -rf debian/pymc-repeater/
|
||||
rm -rf debian/.debhelper/
|
||||
rm -rf debian/files
|
||||
rm -f debian/pymc-repeater.*.debhelper
|
||||
rm -f debian/pymc-repeater.substvars
|
||||
rm -f debian/*.log
|
||||
rm -rf .pybuild/
|
||||
rm -rf build/
|
||||
rm -rf *.egg-info/
|
||||
rm -f repeater/_version.py
|
||||
rm -f ../*.deb
|
||||
rm -f ../*.buildinfo
|
||||
rm -f ../*.changes
|
||||
|
||||
# Build the package
|
||||
log_step "Building production .deb package..."
|
||||
log_info "This may take a few minutes..."
|
||||
|
||||
# Build without signing (can be signed later if needed)
|
||||
if debuild -us -uc -b 2>&1 | tee /tmp/debuild-prod.log; then
|
||||
log_info "Build successful!"
|
||||
else
|
||||
log_error "Build failed. Check /tmp/debuild-prod.log for details."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find and display the built package
|
||||
DEB_FILE=$(find .. -maxdepth 1 -name "pymc-repeater_${DEBIAN_VERSION}_*.deb" -type f | head -n 1)
|
||||
|
||||
if [ -n "$DEB_FILE" ]; then
|
||||
# Run lintian to check package quality
|
||||
log_step "Running lintian checks..."
|
||||
lintian "$DEB_FILE" || log_warn "Lintian found some issues (non-fatal)"
|
||||
|
||||
log_info ""
|
||||
log_info "════════════════════════════════════════════════════════════"
|
||||
log_info "Production build complete!"
|
||||
log_info "Package: $(basename "$DEB_FILE")"
|
||||
log_info "Location: $DEB_FILE"
|
||||
log_info "Size: $(du -h "$DEB_FILE" | cut -f1)"
|
||||
log_info "Version: $VERSION"
|
||||
log_info "Git tag: $TAG"
|
||||
log_info "════════════════════════════════════════════════════════════"
|
||||
log_info ""
|
||||
log_info "To install:"
|
||||
log_info " sudo dpkg -i $DEB_FILE"
|
||||
log_info ""
|
||||
log_info "To inspect package contents:"
|
||||
log_info " dpkg-deb -c $DEB_FILE"
|
||||
log_info ""
|
||||
log_info "To check package info:"
|
||||
log_info " dpkg-deb -I $DEB_FILE"
|
||||
log_info ""
|
||||
log_info "To sign the package:"
|
||||
log_info " debsign $DEB_FILE"
|
||||
else
|
||||
log_warn "Built package not found in expected location"
|
||||
log_info "Searching for .deb files in parent directory..."
|
||||
ls -lh ../*.deb 2>/dev/null || log_warn "No .deb files found"
|
||||
fi
|
||||
81
scripts/setup-build-env.sh
Executable file
81
scripts/setup-build-env.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# Setup Debian/Ubuntu build environment for pyMC_Repeater
|
||||
# This script installs all required build dependencies using apt
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if running as root or with sudo
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
log_error "This script must be run with sudo or as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Setting up build environment for pyMC_Repeater..."
|
||||
|
||||
# Update package list
|
||||
log_info "Updating package lists..."
|
||||
apt-get update
|
||||
|
||||
# Install Debian packaging tools
|
||||
log_info "Installing Debian packaging tools..."
|
||||
apt-get install -y \
|
||||
debhelper \
|
||||
devscripts \
|
||||
build-essential \
|
||||
fakeroot \
|
||||
lintian \
|
||||
git
|
||||
|
||||
# Install Python build dependencies
|
||||
log_info "Installing Python build dependencies..."
|
||||
apt-get install -y \
|
||||
dh-python \
|
||||
python3-all \
|
||||
python3-setuptools \
|
||||
python3-setuptools-scm \
|
||||
python3-wheel \
|
||||
python3-pip \
|
||||
python3-dev
|
||||
|
||||
# Install Python runtime dependencies (for building)
|
||||
log_info "Installing Python runtime dependencies..."
|
||||
apt-get install -y \
|
||||
python3-yaml \
|
||||
python3-cherrypy3 \
|
||||
python3-paho-mqtt \
|
||||
python3-psutil \
|
||||
python3-jwt || {
|
||||
log_warn "python3-jwt not available via apt, will be installed via pip during build"
|
||||
}
|
||||
|
||||
# Note: cherrypy-cors is not available in Debian repos
|
||||
# For development testing: pip install cherrypy-cors
|
||||
|
||||
# Clean up
|
||||
log_info "Cleaning up..."
|
||||
apt-get autoremove -y
|
||||
apt-get clean
|
||||
|
||||
log_info "Build environment setup complete!"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info " - Run './scripts/build-dev.sh' to build a development .deb package"
|
||||
log_info " - Run './scripts/build-prod.sh' to build a production .deb package (requires git tag)"
|
||||
Reference in New Issue
Block a user