Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72add0f0ac
|
||
|
|
e214631bae
|
||
|
|
426b871955
|
||
|
|
1d192f8bae
|
||
|
|
a06b8790c5
|
||
|
|
8206b7e96d
|
||
|
|
dee6d0b818
|
+71
-7
@@ -21,10 +21,41 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- 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
|
- name: Install uv
|
||||||
|
if: steps.uv.outputs.found != 'true'
|
||||||
uses: astral-sh/setup-uv@v3
|
uses: astral-sh/setup-uv@v3
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
if: steps.py.outputs.found != 'true'
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
@@ -62,10 +93,41 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- 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
|
- name: Install uv
|
||||||
|
if: steps.uv.outputs.found != 'true'
|
||||||
uses: astral-sh/setup-uv@v3
|
uses: astral-sh/setup-uv@v3
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
|
if: steps.py.outputs.found != 'true'
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.13"
|
python-version: "3.13"
|
||||||
@@ -74,9 +136,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt-get update -qq
|
sudo apt-get update -qq
|
||||||
sudo apt-get install -y -qq build-essential debhelper dh-python python3-all python3-hatchling
|
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
|
mkdir -p dist-deb
|
||||||
mv ./*.deb dist-deb/
|
mv ../*.deb dist-deb/
|
||||||
|
|
||||||
- name: Build wheel
|
- name: Build wheel
|
||||||
run: uv build --wheel --out-dir dist
|
run: uv build --wheel --out-dir dist
|
||||||
@@ -94,22 +159,21 @@ jobs:
|
|||||||
path: dist-deb/*.deb
|
path: dist-deb/*.deb
|
||||||
|
|
||||||
- name: Create Gitea release and upload assets
|
- name: Create Gitea release and upload assets
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
api="${{ github.server_url }}/api/v1"
|
api="${{ github.server_url }}/api/v1"
|
||||||
repo="${{ github.repository }}"
|
repo="${{ github.repository }}"
|
||||||
tag="${{ github.ref_name }}"
|
tag="${{ github.ref_name }}"
|
||||||
payload="{\"tag_name\":\"$tag\",\"name\":\"$tag\"}"
|
payload="{\"tag_name\":\"$tag\",\"name\":\"$tag\"}"
|
||||||
|
token="${{ secrets.GITEA_TOKEN }}"
|
||||||
|
|
||||||
out=$(curl -sS -X POST "$api/repos/$repo/releases" \
|
out=$(curl -sS -X POST "$api/repos/$repo/releases" \
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
-H "Authorization: token $token" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$payload" || true)
|
-d "$payload" || true)
|
||||||
if ! printf '%s' "$out" | grep -q '"id"'; then
|
if ! printf '%s' "$out" | grep -q '"id"'; then
|
||||||
out=$(curl -sS "$api/repos/$repo/releases/tags/$tag" \
|
out=$(curl -sS "$api/repos/$repo/releases/tags/$tag" \
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
-H "Authorization: token $token")
|
||||||
fi
|
fi
|
||||||
rid=$(printf '%s' "$out" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
rid=$(printf '%s' "$out" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
||||||
[ -n "$rid" ] || { echo "release id not found" >&2; exit 1; }
|
[ -n "$rid" ] || { echo "release id not found" >&2; exit 1; }
|
||||||
@@ -117,7 +181,7 @@ jobs:
|
|||||||
for f in dist/*.whl dist-deb/*.deb; do
|
for f in dist/*.whl dist-deb/*.deb; do
|
||||||
[ -e "$f" ] || continue
|
[ -e "$f" ] || continue
|
||||||
curl -fsS -X POST "$api/repos/$repo/releases/$rid/assets?name=$(basename "$f")" \
|
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"
|
--data-binary @"$f"
|
||||||
echo "Uploaded $(basename "$f")"
|
echo "Uploaded $(basename "$f")"
|
||||||
done
|
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/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/).
|
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
|
## [0.1.1] - 2026-09-12
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ build-wheel:
|
|||||||
python -m build --wheel
|
python -m build --wheel
|
||||||
|
|
||||||
build-deb: 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
|
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
|
build-all: clean check build-wheel build-deb
|
||||||
|
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ SSH configuration management toolkit — parse, validate, generate, and manage S
|
|||||||
```bash
|
```bash
|
||||||
pip install sshctl # once published to PyPI
|
pip install sshctl # once published to PyPI
|
||||||
# or install the built wheel directly from a release
|
# 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)
|
### dpkg (Debian/Ubuntu)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Download from latest release
|
# Download from latest release
|
||||||
wget https://src.panahifar.ir/ahp/sshctl/releases/download/v0.1.1/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.1-1_all.deb
|
sudo dpkg -i sshctl_0.1.2-1_all.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
### From source
|
### From source
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Amir Husayn Panahifar <ahp@panahifar.ir>
|
# Maintainer: Amir Husayn Panahifar <ahp@panahifar.ir>
|
||||||
|
|
||||||
pkgname=sshctl
|
pkgname=sshctl
|
||||||
pkgver=0.1.1
|
pkgver=0.1.2
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="SSH configuration management toolkit"
|
pkgdesc="SSH configuration management toolkit"
|
||||||
arch=('any')
|
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
|
sshctl (0.1.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Bug-fix release: parser, configops, jump, CLI type hardening.
|
* Bug-fix release: parser, configops, jump, CLI type hardening.
|
||||||
|
|||||||
+19
-3
@@ -4,9 +4,25 @@
|
|||||||
dh $@ --with python3
|
dh $@ --with python3
|
||||||
|
|
||||||
override_dh_auto_clean:
|
override_dh_auto_clean:
|
||||||
dh_auto_clean
|
|
||||||
find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
|
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:
|
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
|
.SH NAME
|
||||||
sshctl \- SSH configuration management toolkit
|
sshctl \- SSH configuration management toolkit
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|||||||
+2
-1
@@ -4,13 +4,14 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "sshctl"
|
name = "sshctl"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
description = "SSH configuration management toolkit"
|
description = "SSH configuration management toolkit"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
authors = [{name = "Amir Husayn Panahifar", email = "ahp@panahifar.ir"}]
|
authors = [{name = "Amir Husayn Panahifar", email = "ahp@panahifar.ir"}]
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"click>=8.1",
|
||||||
"typer>=0.12",
|
"typer>=0.12",
|
||||||
"rich>=13.0",
|
"rich>=13.0",
|
||||||
"structlog>=24.0",
|
"structlog>=24.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user