diff --git a/.env.example b/.env.example index c7f3964..fc2483b 100644 --- a/.env.example +++ b/.env.example @@ -37,6 +37,10 @@ GITEA_REGISTRATION_TOKEN=your-registration-token # Supported: en, bg, de, ru, zh # GRM_LANG=en +# Gitea PyPI registry username (for private package access) +# Used by PIP_INSTALL to configure PIP_EXTRA_INDEX_URL +GITEA_REGISTRY_USERNAME=emil + # devx configuration (GRM-specific overrides) # Task prefix for Vikunja task IDs DEVX_TASK_PREFIX=GRM diff --git a/Makefile b/Makefile index 86b5211..79c9f75 100644 --- a/Makefile +++ b/Makefile @@ -9,20 +9,21 @@ CHECKMAKE := $(shell command -v checkmake 2>/dev/null || echo $(HOME)/go/bin/che all: setup -# Helper: run pip install with Gitea registry configured -# Usage: $(PIP_INSTALL) install -e '.[ci,lint]' -PIP_INSTALL := if [ -z "$$REPO_TOKEN" ]; then . ./.env 2>/dev/null; fi; \ - REPO_TOKEN="$${REPO_TOKEN:-$$GITEA_REGISTRY_TOKEN}"; \ - if [ -n "$$REPO_TOKEN" ]; then export PIP_EXTRA_INDEX_URL="https://emil:$$REPO_TOKEN@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/"; fi; \ - $(BIN)/pip +# --- devx.mak include (shared Makefile targets) ------------------------------- +# Set DEVX_PYTHON before including devx.mak so it uses the venv Python. +DEVX_PYTHON := $(BIN)/python +DEVX_VENV := $(VENV) +DEVX_BIN := $(BIN) +DEVX_COV_PKG := src/gitea_runner_manager -# Configure Gitea private PyPI registry so pip can find devx and other -# private packages. In CI, REPO_TOKEN is set as a secret. Locally, it's in .env. -configure-gitea-pypi: - @if [ -z "$$REPO_TOKEN" ]; then . ./.env 2>/dev/null; fi; \ - REPO_TOKEN="$${REPO_TOKEN:-$$GITEA_REGISTRY_TOKEN}"; \ - if [ -z "$$REPO_TOKEN" ]; then echo "[configure-gitea-pypi] REPO_TOKEN not set — skipping (devx must be on public PyPI)"; exit 0; fi; \ - echo "[configure-gitea-pypi] Gitea PyPI registry configured (REPO_TOKEN present)." +# Include shared targets from devx package (create-task, create-pr, push-with-pr, +# check-config, workflow-lint, lint-ruff, clean, venv, .env, activate-scripts, +# install-hooks, install-tools, configure-gitea-pypi, checkmake, etc.) +# Silent if devx not installed yet — run 'make setup' first. +DEVX_MAK := $(shell $(BIN)/python -c \ + "from pathlib import Path; import devx; print(Path(devx.__file__).parent / 'make' / 'devx.mak')" \ + 2>/dev/null) +-include $(DEVX_MAK) # Full setup for local development (all deps, tools, collections, hooks) # devx is installed via pip install -e .[dev] (devx is in dev extra) @@ -61,33 +62,30 @@ setup-release: $(VENV)/bin/activate .env configure-gitea-pypi @export PATH="$(HOME)/.local/bin:$$PATH"; \ $(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install --no-ansible-collections --no-pre-commit -.env: - @if [ ! -f .env ]; then \ - cp .env.example .env; \ - echo "Created .env from .env.example — please edit it with your credentials."; \ - fi +# Helper: run pip install with Gitea registry configured +# Usage: $(PIP_INSTALL) install -e '.[ci,lint]' +PIP_INSTALL := if [ -z "$$REPO_TOKEN" ]; then . ./.env 2>/dev/null; fi; \ + REPO_TOKEN="$${REPO_TOKEN:-$$GITEA_REGISTRY_TOKEN}"; \ + _PYPI_USER="$${GITEA_REGISTRY_USERNAME:-emil}"; \ + if [ -n "$$REPO_TOKEN" ]; then export PIP_EXTRA_INDEX_URL="https://$$_PYPI_USER:$$REPO_TOKEN@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/"; fi; \ + $(BIN)/pip $(VENV)/bin/activate: @python3 -c "import sys; v=sys.version_info; assert v >= (3, 12), f'Python 3.12+ required, found {v.major}.{v.minor}'; print(f'Python {v.major}.{v.minor}.{v.micro} OK')" $(PYTHON) -m venv $(VENV) $(BIN)/pip install --upgrade pip setuptools wheel +.env: + @if [ ! -f .env ]; then \ + cp .env.example .env; \ + echo "Created .env from .env.example — please edit it with your credentials."; \ + fi + activate-scripts: $(VENV)/bin/activate @test -f activate.sh || (echo '#!/usr/bin/env bash' > activate.sh && echo 'source "$$(cd "$$(dirname "$${BASH_SOURCE[0]}")" && pwd)/.venv/bin/activate"' >> activate.sh && chmod +x activate.sh) @test -f activate.fish || (echo '#!/usr/bin/env fish' > activate.fish && echo 'set -l script_dir (dirname (status --current-filename))' >> activate.fish && echo 'source "$$script_dir/.venv/bin/activate.fish"' >> activate.fish && chmod +x activate.fish) @test -f activate.zsh || (echo '#!/usr/bin/env zsh' > activate.zsh && echo '0="$${ZERO:-$${0:#$$ZSH_ARGZERO}}"' >> activate.zsh && echo '0="$${$${(M)0:#/*}:-$$PWD/$$0}"' >> activate.zsh && echo 'source "$${0:A:h}/.venv/bin/activate"' >> activate.zsh && chmod +x activate.zsh) -install-hooks: - @git config core.hooksPath hooks - @chmod +x hooks/pre-commit hooks/pre-push 2>/dev/null || true - @echo "core.hooksPath set to hooks/ — tracked hooks are now live." - -checkmake: - @$(BIN)/python -m devx.tools.install_checkmake - -install-tools: - @$(BIN)/python -m devx.tools.install_tools - install: @if [ -z "$(HOST)" ]; then echo "HOST is required. Example: make install HOST=192.168.1.10"; exit 1; fi $(BIN)/grm install $(HOST) $(if $(USER),--user $(USER),) $(if $(KEY),--key $(KEY),) $(if $(NAME),--name $(NAME),) $(if $(TOKEN),--token $(TOKEN),) $(if $(ASK_BECOME_PASS),--ask-become-pass,) @@ -120,25 +118,28 @@ remove: @if [ -z "$(HOST)" ]; then echo "HOST is required. Example: make remove HOST=192.168.1.10"; exit 1; fi $(BIN)/grm remove $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(TOKEN),--token $(TOKEN),) $(if $(ASK_BECOME_PASS),--ask-become-pass,) -lint-ruff: - $(BIN)/ruff check src/ tests/ +# --- Aliases to devx.mak targets ---------------------------------------------- +lint-ruff: devx-lint-ruff +lint-format: devx-lint-format +typecheck: devx-typecheck +lint-bandit: devx-lint-bandit +lint-deps: devx-lint-deps +lint: devx-lint +checkmake: devx-checkmake +install-tools: devx-install-tools +install-hooks: devx-install-hooks +clean: devx-clean +test-unit: devx-test-unit +pytest-cov: devx-pytest-cov +workflow-lint: devx-workflow-lint +workflow-dryrun: devx-workflow-dryrun +workflow-check: devx-workflow-check -lint-format: - $(BIN)/ruff format --check src/ tests/ - -typecheck: - $(BIN)/pyright - -lint: lint-ruff lint-format typecheck lint-bandit - -lint-bandit: - $(BIN)/bandit -r src/ - -lint-deps: - @echo "Checking dependencies for known vulnerabilities..." - @.venv/bin/python -m ensurepip 2>/dev/null || true - @PIPAPI_PYTHON_LOCATION=$$(pwd)/.venv/bin/python \ - .venv/bin/pip-audit --desc --skip-editable 2>&1 || true +configure-gitea-pypi: + @if [ -z "$$REPO_TOKEN" ]; then . ./.env 2>/dev/null; fi; \ + REPO_TOKEN="$${REPO_TOKEN:-$$GITEA_REGISTRY_TOKEN}"; \ + if [ -z "$$REPO_TOKEN" ]; then echo "[configure-gitea-pypi] REPO_TOKEN not set — skipping (devx must be on public PyPI)"; exit 0; fi; \ + echo "[configure-gitea-pypi] Gitea PyPI registry configured (REPO_TOKEN present)." ansible-lint: PATH="$(PWD)/$(BIN):$$PATH" $(BIN)/ansible-lint ansible/ @@ -152,30 +153,9 @@ makefile-lint: lint-all: lint ansible-lint makefile-lint workflow-lint -workflow-lint: - @command -v actionlint >/dev/null 2>&1 || { \ - echo "actionlint not found. Install: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)"; \ - exit 1; \ - } - actionlint -config-file .gitea/actionlint.yaml .gitea/workflows/*.yml - -workflow-dryrun: - @command -v act_runner >/dev/null 2>&1 || { echo "act_runner not found. Install: https://gitea.com/gitea/act_runner/releases"; exit 1; } - @echo "Dry-running all workflows (no Docker containers started)..." - act_runner exec --dryrun -W .gitea/workflows/ 2>&1 | grep -E 'DRYRUN|ERROR|FAIL|Job' - -workflow-check: workflow-lint workflow-dryrun - @echo "Workflow checks passed (static lint + dry-run)." - -test-unit: - $(BIN)/pytest tests/unit/ -v --no-cov - test-integration: $(BIN)/pytest tests/integration/ -v --no-cov -pytest-cov: - $(BIN)/pytest tests/ -v --cov=src/gitea_runner_manager --cov-report=term-missing --cov-fail-under=100 - MOLECULE := $(realpath $(BIN))/molecule MOLECULE_BASE := cd $(CURDIR)/ansible/roles/gitea-runner && ANSIBLE_ALLOW_BROKEN_CONDITIONALS=true ANSIBLE_INJECT_INVOCATION=1 $(MOLECULE) @@ -191,23 +171,7 @@ test: test-all test-all: pytest-cov molecule -clean: - find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true - find . -type f -name "*.pyc" -delete 2>/dev/null || true - rm -rf .coverage htmlcov/ .molecule/ - # --- Vikunja task and PR management (via devx.mak fragment) ------------------- -# Project config (task prefix, Vikunja project ID, repo owner/name) is read -# from [tool.devx] in pyproject.toml by devx.config — no Makefile variables needed. -DEVX_PYTHON := $(BIN)/python - -# Include shared targets from devx package (create-task, create-pr, push-with-pr, check-config) -# Silent if devx not installed yet — run 'make setup' first. -DEVX_MAK := $(shell $(BIN)/python -c \ - "from pathlib import Path; import devx; print(Path(devx.__file__).parent / 'make' / 'devx.mak')" \ - 2>/dev/null) --include $(DEVX_MAK) - # Aliases for project-specific target names create-task: devx-create-task create-pr: devx-create-pr