From af025e2b2501db75376156348afd04dcad1815c0 Mon Sep 17 00:00:00 2001 From: Devin CI Date: Sun, 9 Aug 2026 09:39:15 +0000 Subject: [PATCH] Sync wiki from docs/ [skip ci] --- Architecture.md | 12 ++--- CLI-Commands.-.md | 108 +++++++++++++++++++++++++++++++++++++++++-- Getting-Started.-.md | 4 +- Home.md | 18 ++++---- 4 files changed, 121 insertions(+), 21 deletions(-) diff --git a/Architecture.md b/Architecture.md index b124544..e5c6864 100644 --- a/Architecture.md +++ b/Architecture.md @@ -86,11 +86,11 @@ overridden via environment variables with the `DEVX_` prefix. Provides: - `GITEA_API_URL` / `VIKUNJA_API_URL` — API endpoints - `REPO_OWNER` — repository owner (must be set per-project) -- `TASK_PREFIX` / `TASK_ID_RE` — task ID prefix and regex (for example, `DEVX-N`) +- `TASK_PREFIX` / `TASK_ID_RE` — task ID prefix and regular expression (for example, `DEVX-N`) - `VIKUNJA_PROJECT_ID` — Vikunja project for task tracking - `DEFAULT_TIMEOUT`, `DEFAULT_PER_PAGE` — HTTP client defaults - `MAX_RETRIES`, `RETRY_BACKOFF_BASE`, `RETRY_STATUS_CODES` — retry config -- `CONVENTIONAL_RE` — conventional commit format regex +- `CONVENTIONAL_RE` — conventional commit format regular expression ### `exceptions.py` @@ -108,7 +108,7 @@ wraps user-facing strings for translation. Projects can extend translations by setting `DEVX_TRANSLATIONS_PATH` to a custom JSON file. Keys from the project's file are merged on top of devx's -built-in translations, allowing projects to override or add keys without +built-in translations, allowing projects to override, or add keys without modifying the package. ### `api_clients.py` @@ -170,7 +170,7 @@ from `devx.api_clients`, `devx.config`, `devx.gitea_cli`, and `devx.i18n`. Automated release using git-cliff. Calculates the next semver version from conventional commits since the last tag, updates `__version__` in -`__init__.py` and `CHANGELOG.md`, runs lint and tests to verify the release +`__init__.py` and `CHANGELOG.md`, runs lint, and tests to verify the release is healthy, commits with `release: vX.Y.Z [skip ci]`, creates an annotated tag, and pushes both to master. @@ -287,7 +287,7 @@ Click commands from `cli.py` and verifies each has documentation in ### `discover_runners.py` Discovers available Gitea Actions runners at three levels: repository, -organization, and instance (admin). Falls back to the `MOLECULE_RUNNERS` repo +organization, and instance (administrator). Falls back to the `MOLECULE_RUNNERS` repo variable or `DEFAULT_MAX_RUNNERS` (3). Outputs runner count or a JSON index array for use as a dynamic matrix in Gitea Actions. @@ -329,7 +329,7 @@ Supports `--tool` to install specific tools and `--list` to show status. Runs unit tests and enforces execution-time budgets. Two quality gates: total suite time must not exceed `--max-seconds` (default: 10s), and no individual test may exceed `--max-single-seconds` (default: 0.5s, 0 to -disable). Runs `make test-unit` with `PYTEST_ADDOPTS=--durations=0`. +off). Runs `make test-unit` with `PYTEST_ADDOPTS=--durations=0`. ### `check_test_isolation.py` diff --git a/CLI-Commands.-.md b/CLI-Commands.-.md index 3fdf9d1..8d90026 100644 --- a/CLI-Commands.-.md +++ b/CLI-Commands.-.md @@ -85,7 +85,7 @@ devx ci detect-release-commit Discover available Gitea Actions runners for dynamic job distribution. Queries the Gitea API for registered runners at repository, organization, and -instance (admin) levels. Falls back to `MOLECULE_RUNNERS` repo variable or +instance (administrator) levels. Falls back to `MOLECULE_RUNNERS` repo variable or `DEFAULT_MAX_RUNNERS` (3). ```bash @@ -315,6 +315,56 @@ devx ci validate-commit-msg commit-msg.txt --branch master Options: - `--branch ` — override branch detection (for CI use) +### `devx ci cancel-superseded-runs` + +Cancel in-flight CI runs for the same PR branch when a new push triggers +a new run. Uses the Gitea Actions API to list running pull_request runs +and cancel those with a lower run ID on the same branch. + +```bash +devx ci cancel-superseded-runs \ + --repo "$REPOSITORY" \ + --current-run-id "$GITHUB_RUN_ID" \ + --head-branch "$HEAD_REF" +``` + +Options: +- `--repo ` — repository (required) +- `--current-run-id ` — current run ID, not cancelled (required) +- `--head-branch ` — PR head branch name (required) +- `--dry-run` — list superseded runs without cancelling +- `--base-url ` — Gitea base URL (default: `GITEA_API_URL` env var) + +### `devx ci check-workflow-artifact-deps` + +Verify that workflow jobs downloading artifacts depend on the uploading +job. Prevents the class of bug where a download job runs in parallel +with the upload job and fails because the artifact isn't available yet. + +```bash +devx ci check-workflow-artifact-deps +devx ci check-workflow-artifact-deps --workflow .gitea/workflows/ci.yml +``` + +Options: +- `--workflow ` — check a specific workflow file +- `--workflows-dir ` — override workflows directory + +### `devx ci check-workflow-tofu-init` + +Verify that workflow jobs using tofu state (tofu output/plan/apply or +scripts that call them) have a tofu-init step in the same job. + +```bash +devx ci check-workflow-tofu-init +devx ci check-workflow-tofu-init --workflow .gitea/workflows/deploy.yml +``` + +Options: +- `--workflow ` — check a specific workflow file +- `--workflows-dir ` — override workflows directory +- `--state-script ` — add a script that uses tofu state (repeatable) + ## Tools Commands ### `devx tools check-test-speed` @@ -323,7 +373,7 @@ Run unit tests and enforce execution-time budgets. Two quality gates: - **Total suite time** must not exceed `--max-seconds` (default: 10s) - **Per-test time** — no individual test may exceed `--max-single-seconds` - (default: 0.5s, 0 to disable) + (default: 0.5s, 0 to turn off) Runs `make test-unit` with `PYTEST_ADDOPTS=--durations=0` so pytest emits per-test timing lines. @@ -369,7 +419,7 @@ devx tools check-test-isolation --src-dir src/ Pytest plugin options (automatic when devx is installed): -- `--no-test-isolation` — disable static analysis and runtime subprocess audit +- `--no-test-isolation` — turn off static analysis and runtime subprocess audit - `--test-isolation-max-loop N` — max iterations per loop (default: 100) ### `devx tools configure-repo` @@ -414,7 +464,7 @@ devx tools generate-cliff-config --prefix GRM --force # overwrite existing Options: - `--prefix ` — task ID prefix (default: `DEVX_TASK_PREFIX` env var or `DEVX`) -- `--output ` — output file path (default: `cliff.toml`) +- `--output ` — output path (default: `cliff.toml`) - `--force` — overwrite existing file ### `devx tools install-checkmake` @@ -488,6 +538,56 @@ devx tools pr-rebase # auto-detect PR from current branch Options (pass after `--`): - `--pr ` — PR number (auto-detected from current branch if omitted) +### `devx tools check-docker-init` + +Check that Docker Compose services with healthchecks have `init: true`. +Without `init: true`, CMD-SHELL healthchecks spawn child processes that +become zombies when PID 1 doesn't reap them. + +```bash +devx tools check-docker-init +devx tools check-docker-init --path path/to/docker-compose.yml.j2 +``` + +Options: +- `--path ` — check a specific file or directory +- `--templates-dir ` — override templates directory (default: `ansible/roles/`) + +### `devx tools check-ansible-set-fact-to-json` + +Check that Ansible `set_fact` tasks don't misuse `| to_json`. Using +`to_json` in `set_fact` converts native Python types to JSON strings, +causing iteration bugs (for example, iterating over characters instead +of list items). + +```bash +devx tools check-ansible-set-fact-to-json +devx tools check-ansible-set-fact-to-json --path path/to/playbook.yml +``` + +Options: +- `--path ` — check a specific file or directory +- `--ansible-dir ` — override ansible directories (repeatable) + +### `devx tools check-alert-rules` + +Validate rendered Prometheus alert rules with `promtool check rules`. +Renders a Jinja2 template with test values and validates the output. +Skips (exits 0) if promtool is not on PATH. + +```bash +devx tools check-alert-rules \ + --template-path ansible/roles/observability/templates +devx tools check-alert-rules \ + --template-path ansible/roles/observability/templates \ + --var grafana_base_url=https://grafana.example.com +``` + +Options: +- `--template-path ` — path to templates directory (required) +- `--template-name ` — template filename (default: `alert-rules.yml.j2`) +- `--var key=value` — template variables (repeatable) + ## Molecule Commands Molecule commands require the `molecule` extra (`pip install devx[molecule]`). diff --git a/Getting-Started.-.md b/Getting-Started.-.md index 7e9105d..190cb8b 100644 --- a/Getting-Started.-.md +++ b/Getting-Started.-.md @@ -48,12 +48,12 @@ Add devx to your `pyproject.toml`: ```toml [project] dependencies = [ - "devx>=0.48.2", + "devx>=0.49.0", ] [project.optional-dependencies] dev = [ - "devx>=0.48.2", + "devx>=0.49.0", ] ``` diff --git a/Home.md b/Home.md index 35e144d..b22e380 100644 --- a/Home.md +++ b/Home.md @@ -8,16 +8,16 @@ parallel test distribution, and more into a single installable package. It was extracted from the [GRM](https://git.oblachno.oblachno.fyi/oblachno-oss/grm) project to be reusable across all oblachno-oss repositories. -> An open-source project from **Oblachno** (облачно means *cloudy* in Bulgarian). +> An open source project from **Oblachno** (облачно means *cloudy* in Bulgarian). [![CI](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions/workflows/ci.yml/badge.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) [![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/src/branch/master/LICENSE) -[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) -[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) -[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki) -[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) -[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases) -[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/3ae96e9fe24eb247be074f92e4a9153033dc1ed7/python.svg)](https://www.python.org/downloads/) +[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) +[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) +[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki) +[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions) +[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases) +[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/8c02351c3190af51b1dfe545a7abbec665c51559/python.svg)](https://www.python.org/downloads/) ## Overview @@ -74,14 +74,14 @@ Add devx to your `pyproject.toml` dependencies and configure the registry: ```toml [project] dependencies = [ - "devx>=0.48.2", + "devx>=0.49.0", ] [tool.pip] extra-index-url = "https://git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple" ``` -Pin a specific version if needed: `"devx==0.48.2"` or `"devx>=0.48.2,<0.49"`. +Pin a specific version if needed: `"devx==0.49.0"` or `"devx>=0.49.0,<0.50"`. ### Optional extras