Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72add0f0ac
|
||
|
|
e214631bae
|
||
|
|
426b871955
|
||
|
|
1d192f8bae
|
||
|
|
a06b8790c5
|
||
|
|
8206b7e96d
|
||
|
|
dee6d0b818
|
+71
-7
@@ -21,10 +21,41 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Enable uv from toolcache
|
||||
id: uv
|
||||
run: |
|
||||
uv_path="$(find /opt/hostedtoolcache/uv -maxdepth 4 -type f -name uv -perm -111 2>/dev/null | head -1)"
|
||||
if [ -n "$uv_path" ]; then
|
||||
dirname "$uv_path" >> "$GITHUB_PATH"
|
||||
echo "found=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "uv not found in toolcache"
|
||||
fi
|
||||
|
||||
- name: Enable Python from toolcache
|
||||
id: py
|
||||
run: |
|
||||
py_bin="$(find /opt/hostedtoolcache/Python -maxdepth 4 -type f -name 'python3*' -perm -111 2>/dev/null | grep -v -- '-config$' | head -1)"
|
||||
if [ -n "$py_bin" ]; then
|
||||
dirname "$py_bin" >> "$GITHUB_PATH"
|
||||
echo "found=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "python not found in toolcache"
|
||||
fi
|
||||
|
||||
- name: Persist uv download cache
|
||||
run: |
|
||||
mkdir -p /opt/hostedtoolcache/uv-cache
|
||||
echo "UV_CACHE_DIR=/opt/hostedtoolcache/uv-cache" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install uv
|
||||
if: steps.uv.outputs.found != 'true'
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
enable-cache: true
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
if: steps.py.outputs.found != 'true'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
@@ -62,10 +93,41 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Enable uv from toolcache
|
||||
id: uv
|
||||
run: |
|
||||
uv_path="$(find /opt/hostedtoolcache/uv -maxdepth 4 -type f -name uv -perm -111 2>/dev/null | head -1)"
|
||||
if [ -n "$uv_path" ]; then
|
||||
dirname "$uv_path" >> "$GITHUB_PATH"
|
||||
echo "found=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "uv not found in toolcache"
|
||||
fi
|
||||
|
||||
- name: Enable Python from toolcache
|
||||
id: py
|
||||
run: |
|
||||
py_bin="$(find /opt/hostedtoolcache/Python -maxdepth 4 -type f -name 'python3*' -perm -111 2>/dev/null | grep -v -- '-config$' | head -1)"
|
||||
if [ -n "$py_bin" ]; then
|
||||
dirname "$py_bin" >> "$GITHUB_PATH"
|
||||
echo "found=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "python not found in toolcache"
|
||||
fi
|
||||
|
||||
- name: Persist uv download cache
|
||||
run: |
|
||||
mkdir -p /opt/hostedtoolcache/uv-cache
|
||||
echo "UV_CACHE_DIR=/opt/hostedtoolcache/uv-cache" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install uv
|
||||
if: steps.uv.outputs.found != 'true'
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
enable-cache: true
|
||||
|
||||
- name: Set up Python
|
||||
if: steps.py.outputs.found != 'true'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
@@ -74,9 +136,12 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y -qq build-essential debhelper dh-python python3-all python3-hatchling
|
||||
cd linux && dpkg-buildpackage -us -uc -b && cd ..
|
||||
rm -rf debian
|
||||
cp -r linux/debian debian
|
||||
dpkg-buildpackage -us -uc -b
|
||||
rm -rf debian
|
||||
mkdir -p dist-deb
|
||||
mv ./*.deb dist-deb/
|
||||
mv ../*.deb dist-deb/
|
||||
|
||||
- name: Build wheel
|
||||
run: uv build --wheel --out-dir dist
|
||||
@@ -94,22 +159,21 @@ jobs:
|
||||
path: dist-deb/*.deb
|
||||
|
||||
- name: Create Gitea release and upload assets
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
api="${{ github.server_url }}/api/v1"
|
||||
repo="${{ github.repository }}"
|
||||
tag="${{ github.ref_name }}"
|
||||
payload="{\"tag_name\":\"$tag\",\"name\":\"$tag\"}"
|
||||
token="${{ secrets.GITEA_TOKEN }}"
|
||||
|
||||
out=$(curl -sS -X POST "$api/repos/$repo/releases" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Authorization: token $token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" || true)
|
||||
if ! printf '%s' "$out" | grep -q '"id"'; then
|
||||
out=$(curl -sS "$api/repos/$repo/releases/tags/$tag" \
|
||||
-H "Authorization: token $GITEA_TOKEN")
|
||||
-H "Authorization: token $token")
|
||||
fi
|
||||
rid=$(printf '%s' "$out" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
||||
[ -n "$rid" ] || { echo "release id not found" >&2; exit 1; }
|
||||
@@ -117,7 +181,7 @@ jobs:
|
||||
for f in dist/*.whl dist-deb/*.deb; do
|
||||
[ -e "$f" ] || continue
|
||||
curl -fsS -X POST "$api/repos/$repo/releases/$rid/assets?name=$(basename "$f")" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Authorization: token $token" \
|
||||
--data-binary @"$f"
|
||||
echo "Uploaded $(basename "$f")"
|
||||
done
|
||||
|
||||
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [0.1.2] - 2026-09-12
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Packaging**: Debian `.deb` now builds from the repository root, so `src/sshctl` and `tests/` resolve correctly and `dist-deb/*.deb` is produced
|
||||
- **Dependencies**: `click` declared explicitly (typer >= 0.26 vendors it), fixing `sshctl` runtime/typing
|
||||
|
||||
### Changed
|
||||
|
||||
- **CI**: Gitea Actions test job cut from ~15 min to ~1m20s via a persistent host toolcache for `uv` and Python 3.13; uv download cache persisted
|
||||
- Version bumped to 0.1.2
|
||||
|
||||
## [0.1.1] - 2026-09-12
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -37,9 +37,12 @@ build-wheel:
|
||||
python -m build --wheel
|
||||
|
||||
build-deb: build-wheel
|
||||
cd linux && dpkg-buildpackage -us -uc -b
|
||||
rm -rf debian
|
||||
cp -r linux/debian debian
|
||||
dpkg-buildpackage -us -uc -b
|
||||
rm -rf debian
|
||||
mkdir -p dist-deb
|
||||
mv ./*.deb dist-deb/ 2>/dev/null || true
|
||||
mv ../*.deb dist-deb/ 2>/dev/null || true
|
||||
|
||||
build-all: clean check build-wheel build-deb
|
||||
|
||||
|
||||
@@ -28,15 +28,15 @@ SSH configuration management toolkit — parse, validate, generate, and manage S
|
||||
```bash
|
||||
pip install sshctl # once published to PyPI
|
||||
# or install the built wheel directly from a release
|
||||
pip install ./sshctl-0.1.1-py3-none-any.whl
|
||||
pip install ./sshctl-0.1.2-py3-none-any.whl
|
||||
```
|
||||
|
||||
### dpkg (Debian/Ubuntu)
|
||||
|
||||
```bash
|
||||
# Download from latest release
|
||||
wget https://src.panahifar.ir/ahp/sshctl/releases/download/v0.1.1/sshctl_0.1.1-1_all.deb
|
||||
sudo dpkg -i sshctl_0.1.1-1_all.deb
|
||||
wget https://src.panahifar.ir/ahp/sshctl/releases/download/v0.1.2/sshctl_0.1.2-1_all.deb
|
||||
sudo dpkg -i sshctl_0.1.2-1_all.deb
|
||||
```
|
||||
|
||||
### From source
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Amir Husayn Panahifar <ahp@panahifar.ir>
|
||||
|
||||
pkgname=sshctl
|
||||
pkgver=0.1.1
|
||||
pkgver=0.1.2
|
||||
pkgrel=1
|
||||
pkgdesc="SSH configuration management toolkit"
|
||||
arch=('any')
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
sshctl (0.1.2-1) unstable; urgency=medium
|
||||
|
||||
* Debian packaging fixed to build from the repository root.
|
||||
* wheel and deb artifacts now share the root build outputs (dist/, dist-deb/).
|
||||
* click declared as an explicit dependency (typer >= 0.26 vendors it).
|
||||
* uv and Python 3.13 CI toolchains resolved from a persistent host toolcache.
|
||||
|
||||
-- Amir Husayn Panahifar <ahp@panahifar.ir> Sat, 12 Sep 2026 01:00:00 +0330
|
||||
|
||||
sshctl (0.1.1-1) unstable; urgency=medium
|
||||
|
||||
* Bug-fix release: parser, configops, jump, CLI type hardening.
|
||||
|
||||
+19
-3
@@ -4,9 +4,25 @@
|
||||
dh $@ --with python3
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean
|
||||
find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf dist/ dist-deb/
|
||||
|
||||
override_dh_auto_build:
|
||||
@true
|
||||
|
||||
override_dh_auto_install:
|
||||
@true
|
||||
|
||||
override_dh_auto_test:
|
||||
python3 -m pytest tests/ --ignore=tests/__pycache__ -q || true
|
||||
python3 -m pytest --help >/dev/null 2>&1 && python3 -m pytest -q || true
|
||||
|
||||
override_dh_install:
|
||||
dh_install
|
||||
mkdir -p debian/sshctl/usr/bin
|
||||
printf '%s\n' \
|
||||
'#!/usr/bin/python3' \
|
||||
'import sys' \
|
||||
'from sshctl.cli.app import serve' \
|
||||
'if __name__ == "__main__":' \
|
||||
' sys.exit(serve())' \
|
||||
> debian/sshctl/usr/bin/sshctl
|
||||
chmod 755 debian/sshctl/usr/bin/sshctl
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.TH SSHCTL 1 "2026-09-12" "sshctl v0.1.1" "SSH Configuration Management"
|
||||
.TH SSHCTL 1 "2026-09-12" "sshctl v0.1.2" "SSH Configuration Management"
|
||||
.SH NAME
|
||||
sshctl \- SSH configuration management toolkit
|
||||
.SH SYNOPSIS
|
||||
|
||||
+2
-1
@@ -4,13 +4,14 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "sshctl"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
description = "SSH configuration management toolkit"
|
||||
requires-python = ">=3.13"
|
||||
license = {text = "MIT"}
|
||||
authors = [{name = "Amir Husayn Panahifar", email = "ahp@panahifar.ir"}]
|
||||
|
||||
dependencies = [
|
||||
"click>=8.1",
|
||||
"typer>=0.12",
|
||||
"rich>=13.0",
|
||||
"structlog>=24.0",
|
||||
|
||||
Reference in New Issue
Block a user