Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Build and Release

on:
push:
branches:
- main
- build-test

jobs:
publish:
name: "Build and Release"
runs-on: ubuntu-latest
steps:
- name: "Clone project repository"
uses: actions/checkout@v6
- name: "Install uv"
uses: astral-sh/setup-uv@v7
- name: "Install Python"
run: uv python install 3.13
- name: "Get release tag"
id: release-tag
run: |
release_tag=$(./sh/make-release-tag.sh)
echo "release-tag=v${release_tag}" >> $GITHUB_OUTPUT
- name: "Build shiv package"
run: |
./sh/build-package.sh
- name: "Upload package as a github release"
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.release-tag.outputs.release-tag }}
draft: ${{ endsWith('build-test', github.ref ) }}
files: ./build/cluster
27 changes: 27 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Lint

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
lint:
name: "Lint"
runs-on: ubuntu-latest
steps:
- name: "Clone project repository"
uses: actions/checkout@v6
- name: "Install uv"
uses: astral-sh/setup-uv@v7
- name: "Install Python"
run: uv python install 3.13
- name: "Install dependencies"
run: uv sync
- name: "Run ruff check"
run: uv run ruff check cluster/
- name: "Run ruff format check"
run: uv run ruff format --check cluster/
16 changes: 12 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
/dev
/build
/cluster.egg-info
__pycache__
# Ignore byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# Ignore Egg files
*.egg-info/
# Ignore virtual environments
dev
.venv
# Ignore the zipfile build directory
build
# Generated at build time
cluster/version.txt
10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# Setup dev environment
dev:
@echo Please run this command: source scripts/dev-setup.sh
uv sync

build: ./build/cluster

./build/machine:
build:
./sh/build-package.sh

lint:
flake8

uv run ruff check cluster/
uv run ruff format --check cluster/
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
# cluster
Utility for provisioning k8s clusters

## Prerequisites

This project uses [uv](https://docs.astral.sh/uv/) for dependency management and builds.

Install uv:
```
curl -LsSf https://astral.sh/uv/install.sh | sh
```

## Development Setup

```
uv sync
```

This creates a `.venv` virtual environment and installs all dependencies (including dev tools like ruff).

Run the CLI during development:
```
uv run cluster --help
```

Run the linter:
```
uv run ruff check cluster/
```

## Build

Build a self-contained executable using [shiv](https://github.com/linkedin/shiv):
```
./sh/build-package.sh
```

This produces `build/cluster`, a single-file Python zipapp.

## Install

Install directly from the GitHub repository using uv:
```
uv tool install git+https://github.com/stirlingbridge/cluster.git
```

Alternatively, download the `cluster` binary from the [releases page](https://github.com/stirlingbridge/cluster/releases), make it executable, and place it on your PATH:
```
chmod +x cluster
sudo mv cluster /usr/local/bin/
```
15 changes: 14 additions & 1 deletion cluster/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os

import click

from cluster import config
from cluster.di import d
from cluster.log import output
from cluster.types import CliOptions, MainCmdCtx
from cluster.subcommands import status, install_dns

Expand All @@ -18,6 +21,10 @@
def main(context, debug, quiet, verbose, dry_run, kube_config_file):
options = CliOptions(debug, quiet, verbose, dry_run)
d.opt = options
# Skip config loading for version subcommand since it doesn't need it
# and should work even when no config file exists
if context.invoked_subcommand == "version":
return
config.set(kube_config_file)
main_context = MainCmdCtx(config.get())
context.obj = main_context
Expand All @@ -26,7 +33,13 @@ def main(context, debug, quiet, verbose, dry_run, kube_config_file):
@main.command()
@click.pass_context
def version(context):
print("Version command")
try:
version_file = os.path.join(os.path.dirname(__file__), "version.txt")
with open(version_file) as f:
version_string = f.read().strip()
except FileNotFoundError:
version_string = "dev"
output(version_string)


main.add_command(status.command, "status")
Expand Down
46 changes: 46 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[project]
name = "cluster"
version = "1.0.0"
description = "Utility for configuring k8s clusters"
readme = "README.md"
license = "AGPL-3.0-only"
requires-python = ">=3.10"
authors = [
{ name = "Stirlingbridge", email = "info@stirlingbridge.website" },
]
classifiers = [
"Programming Language :: Python :: 3.10",
"Operating System :: OS Independent",
]
dependencies = [
"click==8.1.7",
"python-digitalocean==1.17.0",
"ruamel.yaml>=0.17.32",
"kubernetes>=28.1.0",
]

[project.scripts]
cluster = "cluster.main:main"

[project.urls]
Homepage = "https://github.com/stirlingbridge/cluster"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[dependency-groups]
dev = [
"ruff",
"pytest",
]

[tool.ruff]
line-length = 132

[tool.ruff.lint]
select = ["E", "F", "W", "C90"]
ignore = ["E203"]

[tool.ruff.lint.mccabe]
max-complexity = 25
5 changes: 0 additions & 5 deletions requirements.txt

This file was deleted.

29 changes: 0 additions & 29 deletions setup.py

This file was deleted.

5 changes: 4 additions & 1 deletion sh/build-package.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
#!/bin/bash
set -e
mkdir -p ./build
shiv -c cluster -o build/cluster .
./sh/make-release-tag.sh > ./cluster/version.txt
uvx shiv -c cluster -o build/cluster .
6 changes: 1 addition & 5 deletions sh/dev-setup.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
python3 -m venv dev
source ./dev/bin/activate
python3 -m pip install --upgrade pip setuptools wheel
pip install shiv
pip install --editable .
uv sync
9 changes: 9 additions & 0 deletions sh/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

if [[ "$1" == "--fix" ]]; then
uv run ruff format cluster/
uv run ruff check --fix cluster/
else
uv run ruff format --check cluster/
uv run ruff check cluster/
fi
5 changes: 5 additions & 0 deletions sh/make-release-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
git_commit=$( git rev-parse --short HEAD )
date_time=$(date +'%Y%m%d%H%M')
tag=${date_time}-${git_commit}
echo ${tag}
5 changes: 0 additions & 5 deletions tox.ini

This file was deleted.

Loading
Loading