7 Commits
Author SHA1 Message Date
ahp 72add0f0ac ci: drop env token; rely on permissions: releases: write for release upload
CI / test (3.13) (push) Successful in 1m12s
CI / build (push) Successful in 3m46s
2026-09-12 16:06:30 +03:30
ahp e214631bae ci: use built-in github.token for release upload (permissions: releases: write)
CI / test (3.13) (push) Successful in 1m16s
CI / build (push) Successful in 2m11s
2026-09-12 16:03:51 +03:30
ahp 426b871955 build(linux): fix deb packaging to build from repo root, add console script; bump v0.1.2
CI / test (3.13) (push) Successful in 1m37s
CI / build (push) Skipped
2026-09-12 15:57:53 +03:30
ahp 1d192f8bae feat(cli): add click as explicit dependency (typer>=0.26 vendors it)
CI / test (3.13) (push) Successful in 1m14s
CI / build (push) Failing after 1m25s
Keep uv and Python toolchain in a persistent host cache and bypass
setup-* actions when present; persist uv download cache on the host.
2026-09-12 15:34:10 +03:30
ahp a06b8790c5 ci: resolve Python from persistent toolcache, bypass setup-python download
CI / test (3.13) (push) Failing after 17m33s
CI / build (push) Skipped
2026-09-12 15:04:16 +03:30
ahp 8206b7e96d ci: use pre-seeded toolcache for uv, fall back to setup-uv
CI / build (push) Canceled after 0s
CI / test (3.13) (push) Canceled after 12m23s
2026-09-12 14:47:37 +03:30
ahp dee6d0b818 ci: cache uv and Python toolchain in gitea workflow
CI / test (3.13) (push) Failing after 1m17s
CI / build (push) Skipped
2026-09-12 14:35:00 +03:30
9 changed files with 123 additions and 18 deletions
+71 -7
View File
@@ -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
+12
View File
@@ -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
+5 -2
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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')
+9
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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",