From 3f5808d6be00f9eb78aff4c613d61ca8a3034c40 Mon Sep 17 00:00:00 2001 From: emil Date: Sun, 21 Jun 2026 21:58:29 +0000 Subject: [PATCH] GRM-42: fix: rewrite changelog and re-tag releases at user-facing milestones --- CHANGELOG.md | 201 ++++++++++++++++----------- cliff.toml | 19 +-- src/gitea_runner_manager/__init__.py | 2 +- 3 files changed, 128 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db0757..b5da689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,91 +2,124 @@ All notable changes to this project will be documented in this file. +## [0.4.0] - 2026-06-21 + +### Rootless Docker Support + +- Full rootless Docker installation and configuration via Ansible +- `docker_rootless_setup` variable controls whether rootless Docker tasks run +- User setup tasks (subuid/subgid, lingering, dockerd-rootless) +- Proper gating of all Docker-dependent and `systemctl --user` tasks + +### Runner Labels + +- `--labels` option on `grm install` — specify runner labels (e.g., `--labels "ubuntu-latest:docker://node:20"`) +- Labels passed through to runner config YAML + +### Security Fix (CWE-214) + +- **Critical**: Registration tokens and admin tokens are no longer passed via `--extra-vars` on the command line +- Extra-vars are now written to a temporary JSON file with `0600` permissions and passed via `--extra-vars @tempfile` +- This prevents secrets from being visible in the process list (`ps aux`) + +### Configuration via Environment Variables + +- API URLs and repo configuration in `config.py` are now overridable via environment variables: + - `GRM_GITEA_API_URL` + - `GRM_VIKUNJA_API_URL` + - `GRM_REPO_OWNER` + - `GRM_REPO_NAME` + - `GRM_VIKUNJA_PROJECT_ID` + +### Ansible Role Improvements + +- Dead code cleanup (removed `config.yml`, legacy system-level service, duplicate task includes) +- `remove-runner.yml` now disables lingering and removes subuid/subgid entries for complete cleanup +- Arch Linux: `gnupg` package name fix, pacman cache handling +- Docker APT repository: deb822 format, proper GPG handling, arch mapping +- Idempotence fixes for user_setup and download tasks + +## [0.3.0] - 2026-06-21 + +### New CLI Options + +- `--force` flag on `grm remove` — remove a runner even when the host is unreachable (skips Ansible playbook, only deregisters via API) +- `--url` option — override the Gitea URL for any command (useful for multiple Gitea instances) +- `--ask-become-pass` is now the default behavior (no need to pass it explicitly) + +### Status Detection Fixes + +- `grm list` now correctly retrieves runner status (was showing "unknown" for active runners) +- Docker mode status detection via `docker inspect` +- Host/user context added to status output + +### Output Improvements + +- Colorized output for better visual feedback (green/red/yellow) +- Translated operation reports for success and failure cases +- Dual logging: `click.echo()` for user-facing messages, `logging` for debug +- `GRM_LOG_LEVEL` environment variable for controlling verbosity +- Full i18n support (all user-facing strings translated) + +### Internal Refactoring + +- Validation moved from CLI layer to business layer +- Centralized API clients and HTTP status codes +- User-friendly Click errors with i18n + ## [0.2.0] - 2026-06-21 +### New CLI Commands + +- `grm start ` — start a runner's systemd service +- `grm stop ` — stop a runner's systemd service +- `grm enable ` — enable a runner to start on boot +- `grm disable ` — disable a runner from starting on boot +- `grm status ` — check runner service status +- `grm remove ` — deregister and remove a runner +- `grm list-runners` — list all runners from the local registry + +### Runner Registry + +- Runners are tracked in `~/.config/grm/runners.toml` for simplified CLI usage +- No need to specify `--url`, `--user`, `--key` for every command — the registry remembers + +### Multi-Instance Support + +- systemd template units (`gitea-runner@.service`) for running multiple runners per host +- Per-instance config and data directories + +### Ansible Role Improvements + +- Parameterized all hardcoded configuration values as Ansible variables +- Idempotence fixes for repeated runs +- Runner config converted from TOML to YAML format +- Registration timeout to prevent indefinite hangs +- Docker container entrypoint override and working directory fix for `.runner` persistence + +## [0.1.0] - 2026-06-21 + +### Initial Release + +The first release of GRM, a lean CLI for managing Gitea Actions runners via SSH. + +### CLI Commands + +- `grm install ` — install and register a Gitea Runner on a remote host via SSH +- `grm token` — generate a registration token via the Gitea API +- `grm list` — list all registered runners +- `grm update ` — update a runner to the latest version + +### Ansible Role + +- Installs Gitea Runner binary in binary or Docker mode +- Registers runner with Gitea instance +- Configures systemd service +- Supports Arch Linux, Ubuntu, and Debian + ### Features -- Fix 12 critical workflow gaps in release pipeline - -### Bug Fixes - -- Release push permission and notify_failure label IDs - -## [Unreleased] - -### Added - -- **Automated semver versioning and releases**: `scripts/release.py` — CI script that uses git-cliff to calculate the next version from conventional commits, update version files, create a release commit, tag, and push. -- `cliff.toml` — git-cliff configuration for conventional commit parsing, semver bumping, and changelog generation. -- Release workflow (`.gitea/workflows/release.yml`) — triggers on push to master, runs `scripts/release.py` to automatically version and tag releases. -- `publish.py` now uses git-cliff to generate release notes for Gitea releases (falls back to generic message if git-cliff is not available). -- `pyproject.toml` now uses `dynamic = ["version"]` with setuptools `attr` to source version from `__init__.py` (single source of truth — release script only updates `__init__.py`). -- **Mandatory PR review step**: `scripts/review_pr.py` — CLI to post Gitea PR reviews (COMMENT, APPROVE, REQUEST_CHANGES) with inline comments via `--comments-json` or `--comments-stdin`. -- `GiteaClient.get_pr_files`, `GiteaClient.get_pr_commits`, `GiteaClient.create_review` — API methods for PR review workflow. -- `VikunjaClient.get_task` — fetch a single task by numeric ID. -- PR title format: `GRM-N: ` (colon-separated, human-friendly). -- Merge commit format: `GRM-N ` (space-separated, conventional). -- `auto_merge.py` now extracts the conventional commit message from PR commits and constructs the merge title as `GRM-N `. -- `post_merge.py` `extract_conventional_msg` now handles both legacy (`GRM-N: `) and current (`GRM-N `) merge commit formats. -- Full PR workflow documented in `AGENTS.md` and `README.md` (Vikunja task → branch → implement → commit → PR → review → address comments → approve → merge). - -### Changed - -- Parameterized all hardcoded configuration values as Ansible variables in `defaults/main.yml`: - - `gitea_runner_data_dir` — Runtime data directory - - `gitea_runner_config_dir` — Config directory - - `gitea_runner_binary_path` — Binary install path - - `gitea_runner_prune_until` — Prune age filter - - `gitea_runner_prune_schedule` — Prune timer schedule - - `gitea_runner_prune_label` — Docker label for pruning - - `gitea_runner_service_restart_sec` — systemd restart interval - - `gitea_runner_service_user` — Service user - - `gitea_runner_log_level` — Runner log level - - `gitea_runner_container_label` — Container label - - `gitea_runner_file` — Runner metadata file - - `docker_gpg_key_path` — Docker GPG key path -- Added `console_scripts` entry point in `pyproject.toml` (`grm = "gitea_runner_manager.cli:cli"`). -- Added shared `molecule/common/prepare.yml` to eliminate duplicated prepare playbooks. -- Extracted repeated systemd availability check into `tasks/systemd_check.yml`. -- Added idempotence checks to all Molecule scenarios. -- Comprehensive README overhaul with Architecture, Configuration, Development, Testing, and Troubleshooting sections. -- API URLs and repo configuration in `config.py` are now overridable via environment variables (`GRM_GITEA_API_URL`, `GRM_VIKUNJA_API_URL`, `GRM_REPO_OWNER`, `GRM_REPO_NAME`, `GRM_VIKUNJA_PROJECT_ID`). -- `remove-runner.yml` now disables lingering and removes subuid/subgid entries for complete cleanup. - -### Security - -- **Critical fix**: Registration tokens and admin tokens are no longer passed via `--extra-vars` on the command line (CWE-214). Extra-vars are now written to a temporary JSON file with `0600` permissions and passed via `--extra-vars @tempfile`, which is deleted after execution. This prevents secrets from being visible in the process list (`ps aux`). - -### Changed - -- Replaced legacy runner terminology with `gitea_runner` / `gitea-runner` / `Gitea Runner`. -- Updated default Docker image from `gitea/gitea_runner` to `gitea/runner`. -- `Makefile` now uses the installed `grm` console script instead of `python grm`. -- `pyproject.toml` ruff and pyright target versions updated from `py311` to `py312` to match `requires-python = ">=3.12"`. -- `BRANCH_PROTECTION_CONFIG` updated with correct Gitea Actions status check contexts (including `(pull_request)` suffix) and `required_approvals: 0` for auto-merge. -- `CONVENTIONAL_RE` no longer matches `BREAKING CHANGE` as a commit type (it is a footer, not a type). -- `rootless_docker.yml` apt cache update now only runs when the Docker repo file changes (idempotent, but always refreshes on first add). -- `service.yml` and `prune.yml` template creation tasks are not guarded by `docker_rootless_setup` (templates just create files, they don't need Docker; molecule tests set `docker_rootless_setup: false` but still verify the service file exists). -- `molecule_all.sh` now sources the platform list from `distribute_molecule.py` to avoid duplication. - -### Removed - -- Deleted `setup.py` (redundant with `pyproject.toml`). -- Deleted `grm` shell entrypoint script (replaced by `console_scripts`). -- Deleted `initial-plan.md` and `tests/integration/test_provision.py` (dead code). -- Removed empty `__init__.py` files from `tests/` directories. -- Removed unused `runner_validated` fact from `validate.yml`. -- Removed duplicate `prune.yml` and `integration_test.yml` includes from `install_runner.yml` (already included from `main.yml`). -- Removed dead `tasks/config.yml` (never included by any playbook). -- Removed dead `templates/gitea-runner.service.j2` (legacy system-level service, replaced by rootless `gitea-runner-user.service.j2`). -- Removed dead "Reload systemd" handler (system-level reload, never notified, wrong scope for user services). -- Removed dead `scripts/run_molecule_parallel.py` and its test (replaced by `molecule_ci_guard.py`). - -### Fixed - -- Molecule idempotence failures caused by non-idempotent service restart. -- Missing `/etc/docker` directory handling in Molecule tests. -- `ansible-lint` formatting warnings (yaml empty lines). -- Verify playbooks now explicitly load role defaults so parameterized variables are available during verification. -- Duplicate execution of prune and integration test tasks during installation (were included from both `main.yml` and `install_runner.yml`). -- apt cache update reporting `changed` on every run due to `cache_valid_time: 0`. +- SSH-based remote execution via Ansible +- Automatic registration token generation +- Docker and binary installation modes +- Integration test verification after installation diff --git a/cliff.toml b/cliff.toml index 3273bd2..77766a1 100644 --- a/cliff.toml +++ b/cliff.toml @@ -46,19 +46,20 @@ commit_preprocessors = [ commit_parsers = [ { message = "^feat", group = "Features" }, { message = "^fix", group = "Bug Fixes" }, - { message = "^doc", group = "Documentation" }, { message = "^perf", group = "Performance" }, { message = "^refactor", group = "Refactor" }, - { message = "^style", group = "Styling" }, - { message = "^test", group = "Testing" }, - { message = "^chore\\(release\\): prepare for", skip = true }, - { message = "^chore\\(deps.*\\)", skip = true }, - { message = "^chore\\(pr\\)", skip = true }, - { message = "^chore\\(pull\\)", skip = true }, - { message = "^chore|^ci", group = "Miscellaneous Tasks" }, + # Skip infrastructure-only commits — they don't affect users + { message = "^doc", skip = true }, + { message = "^test", skip = true }, + { message = "^style", skip = true }, + { message = "^chore", skip = true }, + { message = "^ci", skip = true }, + # Skip release commits — they are release artifacts, not features + { message = "^release:", skip = true }, { body = ".*security", group = "Security" }, { message = "^revert", group = "Revert" }, - { message = ".*", group = "Other" }, + # Skip anything that doesn't match above — safe default + { message = ".*", skip = true }, ] [bump] diff --git a/src/gitea_runner_manager/__init__.py b/src/gitea_runner_manager/__init__.py index 82ae315..bd88d5b 100644 --- a/src/gitea_runner_manager/__init__.py +++ b/src/gitea_runner_manager/__init__.py @@ -1,3 +1,3 @@ """Gitea Runner Manager — lean CLI for managing Gitea Actions runners.""" -__version__ = "0.2.0" +__version__ = "0.4.0"