feat: add debian packaging, CI/CD and update script
- Add debian/ packaging for .deb generation - Add .forgejo/workflows/build.yml for CI/CD (runner label: docker) - Add scripts/fullupdater and scripts/fullupdater-update - Remove obsolete install.sh - Update .gitignore for debian build artifacts
This commit is contained in:
parent
184b0e6033
commit
57e6b2557b
10 changed files with 281 additions and 30 deletions
95
.forgejo/workflows/build.yml
Normal file
95
.forgejo/workflows/build.yml
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
name: Build and Release .deb
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-deb:
|
||||||
|
runs-on: [docker]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # nécessaire pour les tags et le versioning
|
||||||
|
|
||||||
|
- name: Determine version
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
if git describe --tags --exact-match HEAD 2>/dev/null; then
|
||||||
|
# Le commit actuel est déjà un tag
|
||||||
|
VERSION=$(git describe --tags --exact-match HEAD | sed 's/^v//')
|
||||||
|
else
|
||||||
|
# Incrémente le patch du dernier tag
|
||||||
|
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
||||||
|
VERSION_BASE=${LAST_TAG#v}
|
||||||
|
MAJOR=$(echo "$VERSION_BASE" | cut -d. -f1)
|
||||||
|
MINOR=$(echo "$VERSION_BASE" | cut -d. -f2)
|
||||||
|
PATCH=$(echo "$VERSION_BASE" | cut -d. -f3)
|
||||||
|
NEW_PATCH=$((PATCH + 1))
|
||||||
|
VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"
|
||||||
|
# Créer un tag léger pour cette release
|
||||||
|
git config user.email "ci@geronzi.fr"
|
||||||
|
git config user.name "Forgejo CI"
|
||||||
|
git tag -a "v${VERSION}" -m "Release v${VERSION}"
|
||||||
|
git push origin "v${VERSION}" || true
|
||||||
|
fi
|
||||||
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Detected version: ${VERSION}"
|
||||||
|
|
||||||
|
- name: Update debian changelog
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.version.outputs.version }}
|
||||||
|
DATE=$(date -R)
|
||||||
|
cat > debian/changelog <<EOF
|
||||||
|
full-updater (${VERSION}) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Auto-built release from commit ${GITHUB_SHA}
|
||||||
|
|
||||||
|
-- Forgejo CI <ci@geronzi.fr> ${DATE}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y debhelper dh-python python3-all python3-venv devscripts
|
||||||
|
|
||||||
|
- name: Build .deb package
|
||||||
|
run: |
|
||||||
|
dpkg-buildpackage -us -uc -b -tc
|
||||||
|
mkdir -p dist
|
||||||
|
cp ../*.deb dist/
|
||||||
|
# Renommer proprement
|
||||||
|
mv dist/full-updater_*.deb "dist/full-updater_${{ steps.version.outputs.version }}_all.deb"
|
||||||
|
|
||||||
|
- name: Upload release asset
|
||||||
|
env:
|
||||||
|
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.version.outputs.version }}
|
||||||
|
TAG="v${VERSION}"
|
||||||
|
FILE="dist/full-updater_${VERSION}_all.deb"
|
||||||
|
# Créer la release si elle n'existe pas
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"tag_name\": \"${TAG}\", \"name\": \"Release ${TAG}\", \"body\": \"Automated build from main\"}" \
|
||||||
|
"https://git.geronzi.fr/api/v1/repos/geronzi/full_updater/releases" || true
|
||||||
|
# Récupérer l'ID de la release
|
||||||
|
RELEASE_ID=$(curl -s -H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||||
|
"https://git.geronzi.fr/api/v1/repos/geronzi/full_updater/releases/latest" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))")
|
||||||
|
if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "None" ]; then
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||||
|
-H "Content-Type: application/octet-stream" \
|
||||||
|
--data-binary @"${FILE}" \
|
||||||
|
"https://git.geronzi.fr/api/v1/repos/geronzi/full_updater/releases/${RELEASE_ID}/assets?name=$(basename ${FILE})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Store artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: full-updater-deb
|
||||||
|
path: dist/*.deb
|
||||||
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -22,3 +22,17 @@ wheels/
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
|
|
||||||
|
# Debian build artifacts
|
||||||
|
debian/files
|
||||||
|
debian/full-updater/
|
||||||
|
debian/*.debhelper
|
||||||
|
debian/*.substvars
|
||||||
|
debian/changelog.dch
|
||||||
|
*.deb
|
||||||
|
*.build
|
||||||
|
*.buildinfo
|
||||||
|
*.changes
|
||||||
|
|
||||||
|
# Cache
|
||||||
|
/tmp/full-updater-cache/
|
||||||
|
|
|
||||||
30
build_deb.sh
Normal file
30
build_deb.sh
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Script de build local du .deb (à lancer manuellement si besoin)
|
||||||
|
# Usage : bash build_deb.sh
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# Vérifier les dépendances
|
||||||
|
if ! command -v dpkg-buildpackage &> /dev/null; then
|
||||||
|
echo "Installation des dépendances de build..."
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y debhelper dh-python python3-all python3-venv devscripts
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mettre à jour le changelog avec la date actuelle
|
||||||
|
DATE=$(date -R)
|
||||||
|
cat > debian/changelog <<EOF
|
||||||
|
full-updater (1.0.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Local build
|
||||||
|
|
||||||
|
-- Enzo <admin@geronzi.fr> ${DATE}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Build
|
||||||
|
dpkg-buildpackage -us -uc -b -tc
|
||||||
|
|
||||||
|
echo "✅ Build terminé. Le .deb est dans ../"
|
||||||
|
ls -la ../*.deb
|
||||||
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
full-updater (1.0.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- Enzo <admin@geronzi.fr> Mon, 01 Jan 2024 00:00:00 +0000
|
||||||
15
debian/control
vendored
Normal file
15
debian/control
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
Source: full-updater
|
||||||
|
Section: admin
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Enzo <admin@geronzi.fr>
|
||||||
|
Build-Depends: debhelper-compat (= 13), dh-python, python3-all, python3-venv
|
||||||
|
Standards-Version: 4.6.0
|
||||||
|
|
||||||
|
Package: full-updater
|
||||||
|
Architecture: all
|
||||||
|
Depends: ${python3:Depends}, python3-textual, python3-pyperclip, python3-venv, git, pct
|
||||||
|
Description: TUI for APT/CVE updates on Proxmox host and LXC
|
||||||
|
Full Updater is a terminal user interface (TUI) that visualizes
|
||||||
|
available APT updates and CVEs for the Proxmox host and all LXC
|
||||||
|
containers. It supports keyboard and mouse controls, real-time
|
||||||
|
scanning, caching, and one-click upgrades via pct exec.
|
||||||
23
debian/postinst
vendored
Normal file
23
debian/postinst
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VENV_DIR="/opt/full-updater/.venv"
|
||||||
|
OPT_DIR="/opt/full-updater"
|
||||||
|
|
||||||
|
# Create venv and install deps
|
||||||
|
if [ ! -d "$VENV_DIR" ]; then
|
||||||
|
python3 -m venv "$VENV_DIR"
|
||||||
|
fi
|
||||||
|
"$VENV_DIR/bin/pip" install --upgrade pip
|
||||||
|
"$VENV_DIR/bin/pip" install -r "$OPT_DIR/requirements.txt"
|
||||||
|
|
||||||
|
# Ensure symlinks
|
||||||
|
ln -sf "$OPT_DIR/scripts/fullupdater" /usr/local/bin/fullupdater
|
||||||
|
|
||||||
|
# Ensure cache dir exists
|
||||||
|
mkdir -p /tmp/full-updater-cache
|
||||||
|
|
||||||
|
# Upgrade existing install if deps changed
|
||||||
|
"$VENV_DIR/bin/pip" install -r "$OPT_DIR/requirements.txt" --upgrade
|
||||||
|
|
||||||
|
exit 0
|
||||||
14
debian/rules
vendored
Normal file
14
debian/rules
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
export DH_VERBOSE = 1
|
||||||
|
export PYBUILD_NAME = full-updater
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with python3 --buildsystem=pybuild
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
dh_auto_install
|
||||||
|
install -D -m 755 scripts/fullupdater $(CURDIR)/debian/full-updater/opt/full-updater/scripts/fullupdater
|
||||||
|
install -D -m 755 scripts/fullupdater-update $(CURDIR)/debian/full-updater/usr/local/bin/fullupdater-update
|
||||||
|
install -D -m 644 requirements.txt $(CURDIR)/debian/full-updater/opt/full-updater/requirements.txt
|
||||||
|
cp -r full_updater $(CURDIR)/debian/full-updater/opt/full-updater/
|
||||||
30
install.sh
30
install.sh
|
|
@ -1,30 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
VENV_DIR="$SCRIPT_DIR/.venv"
|
|
||||||
BIN_PATH="/usr/local/bin/fullupdater"
|
|
||||||
|
|
||||||
echo "=== Full Updater - Installation ==="
|
|
||||||
|
|
||||||
# Créer le venv
|
|
||||||
if [ ! -d "$VENV_DIR" ]; then
|
|
||||||
echo "Création du venv..."
|
|
||||||
python3 -m venv "$VENV_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Installation des dépendances..."
|
|
||||||
"$VENV_DIR/bin/pip" install --upgrade pip
|
|
||||||
"$VENV_DIR/bin/pip" install -r "$SCRIPT_DIR/requirements.txt"
|
|
||||||
|
|
||||||
# Créer le wrapper
|
|
||||||
cat > "$BIN_PATH" << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
SCRIPT_DIR="/opt/full-updater"
|
|
||||||
source "$SCRIPT_DIR/.venv/bin/activate"
|
|
||||||
python3 -m full_updater "$@"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x "$BIN_PATH"
|
|
||||||
|
|
||||||
echo "Installation terminée. Lancez 'fullupdater'."
|
|
||||||
14
scripts/fullupdater
Normal file
14
scripts/fullupdater
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Wrapper script installed at /usr/local/bin/fullupdater
|
||||||
|
SCRIPT_DIR="/opt/full-updater"
|
||||||
|
VENV_DIR="$SCRIPT_DIR/.venv"
|
||||||
|
|
||||||
|
if [ ! -d "$VENV_DIR" ]; then
|
||||||
|
echo "Erreur : le venv n'existe pas. Réinstallez le paquet full-updater."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "$VENV_DIR/bin/activate"
|
||||||
|
python3 -m full_updater "$@"
|
||||||
71
scripts/fullupdater-update
Normal file
71
scripts/fullupdater-update
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REPO_URL="https://git.geronzi.fr"
|
||||||
|
OWNER="geronzi"
|
||||||
|
REPO="full_updater"
|
||||||
|
TOKEN_FILE="/etc/full-updater/token"
|
||||||
|
CONFIG_FILE="/etc/full-updater/config.ini"
|
||||||
|
INSTALLED_VERSION=$(dpkg -s full-updater 2>/dev/null | grep "^Version:" | awk '{print $2}' || echo "0.0.0")
|
||||||
|
|
||||||
|
echo "=== Full Updater Update ==="
|
||||||
|
echo "Version installée : ${INSTALLED_VERSION}"
|
||||||
|
|
||||||
|
# Build API headers
|
||||||
|
HEADERS=(-H "Content-Type: application/json")
|
||||||
|
if [ -f "$TOKEN_FILE" ]; then
|
||||||
|
TOKEN=$(cat "$TOKEN_FILE" | tr -d '[:space:]')
|
||||||
|
HEADERS+=("-H" "Authorization: token ${TOKEN}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fetch latest release
|
||||||
|
API_URL="${REPO_URL}/api/v1/repos/${OWNER}/${REPO}/releases/latest"
|
||||||
|
echo "Recherche de la dernière release..."
|
||||||
|
|
||||||
|
RESPONSE=$(curl -s -L "${HEADERS[@]}" "$API_URL")
|
||||||
|
if [ -z "$RESPONSE" ] || echo "$RESPONSE" | grep -q "Not Found"; then
|
||||||
|
echo "Erreur : impossible de récupérer la dernière release."
|
||||||
|
echo "Vérifiez l'URL : $API_URL"
|
||||||
|
echo "Pour un repo privé, créez /etc/full-updater/token avec un token d'accès Forgejo."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LATEST_TAG=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tag_name',''))")
|
||||||
|
if [ -z "$LATEST_TAG" ]; then
|
||||||
|
echo "Erreur : aucune release trouvée."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LATEST_VERSION=${LATEST_TAG#v}
|
||||||
|
echo "Dernière version : ${LATEST_VERSION}"
|
||||||
|
|
||||||
|
if [ "$INSTALLED_VERSION" = "$LATEST_VERSION" ]; then
|
||||||
|
echo "✅ Full Updater est déjà à jour (${INSTALLED_VERSION})."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find .deb asset
|
||||||
|
ASSET_URL=$(echo "$RESPONSE" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
d = json.load(sys.stdin)
|
||||||
|
for a in d.get('assets', []):
|
||||||
|
if a['name'].endswith('.deb'):
|
||||||
|
print(a['browser_download_url'])
|
||||||
|
break
|
||||||
|
")
|
||||||
|
|
||||||
|
if [ -z "$ASSET_URL" ]; then
|
||||||
|
echo "Erreur : aucun fichier .deb trouvé dans la release ${LATEST_TAG}."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_DEB="/tmp/full-updater-${LATEST_VERSION}.deb"
|
||||||
|
echo "Téléchargement de ${ASSET_URL}..."
|
||||||
|
curl -s -L -o "$TMP_DEB" "${HEADERS[@]}" "$ASSET_URL"
|
||||||
|
|
||||||
|
echo "Installation..."
|
||||||
|
dpkg -i "$TMP_DEB"
|
||||||
|
apt-get install -f -y
|
||||||
|
rm -f "$TMP_DEB"
|
||||||
|
|
||||||
|
echo "✅ Mise à jour terminée : ${INSTALLED_VERSION} → ${LATEST_VERSION}"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue