# CLI Commands devx provides a CLI with three command groups: `ci`, `tools`, and `molecule`. Each subcommand delegates to the corresponding Python module via `python -m devx.*`, so `devx ci release` is equivalent to `python -m devx.ci.release`. ```bash devx --help # show all command groups devx --version # show package version devx ci --help # show CI commands devx tools --help # show tools commands devx molecule --help # show molecule commands ``` ## CI Commands ### `devx ci auto-merge` Auto-merge a PR when all CI checks pass. Reads the task ID from the branch name (falling back to `.taskid` file), validates the PR title format against the Vikunja task title, extracts the conventional commit message from PR commits, and squash-merges with `{PREFIX}-N ` title. If the head branch is behind master (HTTP 405), automatically pulls master, rebases, force-pushes, and retries the merge. ```bash devx ci auto-merge # Example: devx ci auto-merge DEVX-12-add-feature "DEVX-12: Add feature" oblachno-oss/devx 42 ``` ### `devx ci check-translations` Check translation files for gaps, dead keys, and missing languages. Validates translation files against the Python source code that uses them. By default, checks `src/devx/translations.json` against `src/devx/**/*.py`. Checks performed: - **Missing keys** — a `_()` call in code has no entry in the translations file - **Dead keys** — a key in the translations file is not used in any code - **Missing languages** — a key exists but is missing one of the five supported languages (en, bg, de, ru, zh) ```bash devx ci check-translations devx ci check-translations --translations path/to/translations.json ``` ### `devx ci classify-changes` Classify git changes as user-facing or workflow-only. Used to skip releases for infrastructure-only changes. Classification rules are configured in `pyproject.toml` under `[tool.devx.classify]`. ```bash devx ci classify-changes --base origin/master --head HEAD devx ci classify-changes --base origin/master --head HEAD --github-output devx ci classify-changes --quiet --check user-facing devx ci classify-changes --check ansible # custom tag from pyproject.toml ``` Options: - `--base ` — base ref (default: latest tag) - `--head ` — head ref (default: HEAD) - `--quiet` — only output true/false - `--check ` — check specific category: `all` (default), `user-facing`, or any tag name defined in `[tool.devx.classify.tags]` - `--github-output` — write results to `$GITHUB_OUTPUT` for CI workflow steps Exit code 2 indicates workflow-only changes (no release needed). ### `devx ci detect-release-commit` Detect whether the latest git commit is a release commit (`release: vX.Y.Z [skip ci]`). Writes `is-release=true` or `is-release=false` to `$GITHUB_OUTPUT` for use in CI workflow conditionals. ```bash devx ci detect-release-commit ``` ### `devx ci discover-runners` 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 `DEFAULT_MAX_RUNNERS` (3). ```bash devx ci discover-runners --owner oblachno-oss --repo devx devx ci discover-runners --owner oblachno-oss --repo devx --count devx ci discover-runners --owner oblachno-oss --repo devx --indices ``` Options: - `--count` — print the number of available runners - `--indices` — print a JSON array `[0, 1, ..., N-1]` for use as a dynamic matrix in Gitea Actions ### `devx ci distribute-files` Distribute files across parallel runners (round-robin). Discovers files matching a glob pattern, sorts them for deterministic ordering, then assigns them round-robin to `max_runners` groups. The assigned group for `runner_index` is written to `$GITHUB_ENV`. ```bash devx ci distribute-files --pattern "tests/integration/test_*.py" \ --runner-index 1 --max-runners 3 --github-env ``` Options: - `--pattern ` — glob pattern for files to distribute - `--runner-index ` — current runner index (0-based) - `--max-runners ` — total number of runners (default: 3) - `--github-env` — write file list to `$GITHUB_ENV` - `--skip-if-excess` — skip if fewer files than runners ### `devx ci doc-coverage` Check documentation coverage for CLI commands and major modules. Parses Click commands from `cli.py` and checks if each has documentation in `docs/user/cli-commands.md`. Verifies core modules are documented in `architecture.md` and CI scripts in `ci-cd-workflow.md`. ```bash devx ci doc-coverage devx ci doc-coverage --docs-dir docs/ --fail-on-missing ``` Options: - `--docs-dir ` — path to the docs directory (default: `docs/`) - `--fail-on-missing` — exit with non-zero status if any documentation is missing ### `devx ci integration-guard` Run pytest with cross-runner failure detection and JUnit XML output. If any other integration-tests matrix runner reports failure, the current pytest subprocess is killed and this runner exits early with code 1. ```bash devx ci integration-guard --junit-output junit-results/runner-1.xml -- test_a.py test_b.py devx ci integration-guard --junit-output junit-results/runner-1.xml -- -x -v --tb=short test_a.py ``` Environment variables: - `GITEA_URL` — base URL of the Gitea instance - `REPO_TOKEN` — API token with repo access - `RUN_ID` — workflow run ID (`GITHUB_RUN_ID`) - `JOB_NAME` — base job name (`GITHUB_JOB`) - `MATRIX_INDEX` — current matrix index (runner-index) - `GITEA_REPOSITORY` — repository in `owner/repo` format ### `devx ci merge-junit` Merge multiple JUnit XML reports from parallel runners into a single consolidated report. Exit code is non-zero if any merged test suite reports failures, making it suitable as a CI gating step after matrix jobs. ```bash devx ci merge-junit --pattern "junit-results/runner-*.xml" --output junit-merged.xml ``` ### `devx ci notify-failure` Create a Gitea issue when a CI workflow fails. Uses the tea CLI for issue creation with a `bug` label if available. ```bash devx ci notify-failure --repo oblachno-oss/devx --run-id 123 \ --workflow ci --commit abc123def456 devx ci notify-failure --repo oblachno-oss/devx --run-id 123 \ --workflow post-merge/release --commit abc123def456 --auto-login ``` Options: - `--repo ` — repository (required) - `--run-id ` — CI run ID (required) - `--workflow ` — workflow name (required) - `--commit ` — commit SHA (required) - `--auto-login` — configure tea CLI login from `REPO_TOKEN` before creating the issue ### `devx ci post-merge` Update Vikunja task after a merge to master. Extracts the task ID from the commit message, marks the task as done, and posts a comment with the merge SHA. ```bash devx ci post-merge "DEVX-12 feat: add feature" --git-sha abc123def456 ``` ### `devx ci pr-review` Run automated PR review. Fetches the PR diff via the Gitea API and runs a series of checks, posting a structured review (`COMMENT` or `REQUEST_CHANGES`). Checks: architecture compliance, best practices, security, i18n, resource management, documentation, test coverage, and commit conventions. ```bash devx ci pr-review 42 oblachno-oss/devx ``` ### `devx ci publish` Build package, publish to Gitea PyPI registry (or standard PyPI), and create a Gitea release with git-cliff-generated notes. ```bash devx ci publish v1.0.0 oblachno-oss/devx devx ci publish v1.0.0 oblachno-oss/devx --registry-url https://git.example.com/api/packages/owner/pypi devx ci publish v1.0.0 oblachno-oss/devx --skip-build # Gitea release only ``` Options: - `--registry-url ` — Gitea PyPI registry URL. Defaults to `DEVX_PYPI_REGISTRY_URL` env var or a URL derived from `GITEA_API_URL`. When set, publishes to Gitea PyPI instead of standard PyPI (unless `PYPI_TOKEN` is also set). - `--skip-build` — skip package build and PyPI publish (for non-Python repos that only need a Gitea release) ### `devx ci push-badges` Generate badge SVG files and push them to the `badges` branch. Also updates `README.md` and `docs/index.md` on master with cache-busting `raw/commit//` URLs. ```bash devx ci push-badges devx ci push-badges --output-dir .badges/ --branch master devx ci push-badges --no-readme-update # skip README update (local testing) devx ci push-badges --retries 3 # retry on git push failures ``` Options: - `--output-dir ` — temporary directory for badge files (default: `.badges/`) - `--branch ` — branch to sync before generating badges (default: `master`) - `--no-readme-update` — skip updating README with cache-busting URLs - `--retries ` — number of attempts on git push failures (default: 1). Between attempts, fetches latest master and waits 10s. ### `devx ci release` Automated release: calculate next version, update files, tag, and push. Uses git-cliff to determine the next semver version from conventional commits. ```bash devx ci release devx ci release --dry-run # preview without making changes devx ci release --skip-tests # skip lint and tests (emergency only) devx ci release --verify # check tag/version/changelog alignment ``` Options: - `--dry-run` — show what would happen without making changes - `--skip-tests` — skip lint and test verification (NOT recommended — only for emergency releases) - `--verify` — verify tag/version/changelog alignment and exit (no changes made) ### `devx ci sync-wiki` Sync documentation from `docs/` to the Gitea wiki. Reads `docs/mapping.json` for file-to-page mapping. Pages that exist in the wiki but not in the mapping are left untouched. ```bash devx ci sync-wiki --repo oblachno-oss/devx devx ci sync-wiki --repo oblachno-oss/devx --dry-run devx ci sync-wiki --repo oblachno-oss/devx --verify devx ci sync-wiki --repo oblachno-oss/devx --strict ``` Options: - `--dry-run` — show what would happen without making changes - `--repo ` — repository (auto-detected if omitted) - `--verify` — after syncing, verify each page has non-empty content. Exit 1 if any page is empty or mismatched. - `--strict` — full integrity check: verify page count, missing pages, stale pages, and content. Implies `--verify`. ### `devx ci validate-commit-msg` Validate commit messages for conventional commit format. On feature branches: conventional commits only (no `{PREFIX}-N` prefix). On master: must have `{PREFIX}-N` prefix from auto-merge, followed by a conventional commit message. ```bash devx ci validate-commit-msg commit-msg.txt devx ci validate-commit-msg commit-msg.txt --branch master ``` Options: - `--branch ` — override branch detection (for CI use) ## Tools Commands ### `devx tools check-test-speed` 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) Runs `make test-unit` with `PYTEST_ADDOPTS=--durations=0` so pytest emits per-test timing lines. ```bash devx tools check-test-speed devx tools check-test-speed --max-seconds 10 devx tools check-test-speed --max-seconds 4 --max-single-seconds 0.5 ``` ### `devx tools configure-repo` Configure repository: branch protection and labels via the Gitea REST API. Sets up master branch protection (required status checks, block on rejected reviews, block on outdated branch) and creates standard labels. ```bash devx tools configure-repo --repo devx --owner oblachno-oss ``` Status check contexts are read from `DEVX_STATUS_CHECKS` (comma-separated) or default to `CI / quality (pull_request)`. ### `devx tools generate-badges` Generate self-contained SVG badge files from project metrics. Runs pytest-cov, doc-coverage, lint checks, and version extraction, then writes SVG files that can be served as static files from the Gitea raw file API. Badges generated: `coverage.svg`, `tests.svg`, `docs.svg`, `quality.svg`, `version.svg`, `python.svg`. ```bash devx tools generate-badges devx tools generate-badges --output-dir .badges/ ``` ### `devx tools generate-cliff-config` Generate a `cliff.toml` configuration file with the correct task ID prefix preprocessor. Eliminates the need to manually duplicate and maintain `cliff.toml` across repos that use devx. ```bash devx tools generate-cliff-config --prefix GRM devx tools generate-cliff-config --prefix GRM --output cliff.toml 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`) - `--force` — overwrite existing file ### `devx tools install-checkmake` Install checkmake (Makefile linter) if not already present. Tries `go install` first if Go is available, otherwise downloads the latest pre-built Linux binary from the official GitHub releases. ```bash devx tools install-checkmake ``` ### `devx tools install-tools` Install CI/CD development tools that are not Python packages: actionlint, git-cliff, act_runner, and tea. Each tool is installed to `~/.local/bin` if not already on PATH. Idempotent: skips tools that are already available. ```bash devx tools install-tools # install all devx tools install-tools --tool actionlint # install one devx tools install-tools --tool git-cliff --tool tea # install specific devx tools install-tools --list # list status ``` ### `devx tools setup` Project setup: install Python dependencies (editable mode with extras), Ansible Galaxy collections (if `ansible/requirements.yml` exists), pre-commit hooks (pre-commit, commit-msg, pre-push), and configure the tea CLI login profile from `.env`. ```bash devx tools setup --bin .venv/bin devx tools setup --bin .venv/bin --extras "ci,lint" devx tools setup --bin .venv/bin --no-pre-commit --no-tea-login ``` Options: - `--bin ` — virtualenv bin directory (required) - `--extras ` — pip extras to install (default: `dev`) - `--no-pre-commit` — skip pre-commit hook installation - `--no-tea-login` — skip tea CLI login configuration ## Molecule Commands Molecule commands require the `molecule` extra (`pip install devx[molecule]`). ### `devx molecule all` Run all molecule scenarios on all supported OS platforms. Sequential execution — CI uses the parallel matrix instead. ```bash devx molecule all devx molecule all --bin .venv/bin ``` ### `devx molecule discover-runners` Discover available Gitea Actions runners for molecule tests. Same logic as `devx ci discover-runners` but intended for molecule-specific workflows. ```bash devx molecule discover-runners --owner oblachno-oss --repo devx --indices ``` ### `devx molecule distribute` Distribute molecule (scenario, platform) pairs across N parallel runners. Discovers scenarios under `ansible/roles/*/molecule/` and crosses them with the supported OS platform matrix. ```bash devx molecule distribute --runner-index 1 --max-runners 3 devx molecule distribute --list # list all scenarios devx molecule distribute --list-platforms # list platforms devx molecule distribute --roles-root ansible/roles # multi-role repos ``` Options: - `--runner-index ` — current runner index (0-based) - `--max-runners ` — total number of runners (default: 3) - `--list` — list all scenarios, one per line - `--list-platforms` — list all platforms, one per line - `--roles-root ` — roles root directory for multi-role repos (default: `ansible/roles`) ### `devx molecule guard` Run molecule tests sequentially with CI failure polling. A background thread polls the Gitea API. If any other molecule matrix runner reports failure, the current molecule subprocess is killed and this runner exits early with code 1. ```bash devx molecule guard pair1 pair2 pair3 devx molecule guard --roles-root ansible/roles pair1 pair2 devx molecule guard --junit-output junit-results/runner-1.xml pair1 pair2 ``` Each pair is encoded as: - **Single-role (4-part):** `scenario|platform_name|platform_image|platform_command` - **Multi-role (5-part):** `role|scenario|platform_name|platform_image|platform_command` Options: - `--roles-root ` — roles root directory for multi-role repos - `--junit-output ` — generate JUnit XML report Environment variables: - `GITEA_URL` — base URL of the Gitea instance - `REPO_TOKEN` — API token with repo access - `RUN_ID` — workflow run ID (`GITHUB_RUN_ID`) - `JOB_NAME` — base job name (`GITHUB_JOB`) - `MATRIX_INDEX` — current matrix index (runner-index) - `GITEA_REPOSITORY` — repository in `owner/repo` format