GRM-37: refactor: Split CI scripts, fix release PYTHONPATH, dynamic runner discovery

This commit is contained in:
2026-06-21 20:44:39 +00:00
parent 56eb241b77
commit 5511cba1b0
38 changed files with 908 additions and 422 deletions
+30 -12
View File
@@ -60,10 +60,10 @@ Review the full diff (`git diff master...HEAD`) focusing on:
- **User experience**: Clear error messages, intuitive CLI flags, helpful output
- **Documentation**: Completeness and relevance of docs, CHANGELOG entries, AGENTS.md updates
Post review comments using `scripts/review_pr.py`:
Post review comments using `scripts/ci/review_pr.py`:
```bash
REPO_TOKEN=<token> python3 scripts/review_pr.py <pr_number> <owner/repo> \
REPO_TOKEN=<token> python3 scripts/ci/review_pr.py <pr_number> <owner/repo> \
--event REQUEST_CHANGES \
--body "Review summary" \
--comments-json comments.json
@@ -78,7 +78,7 @@ Fix each comment one by one, commit, and push. Re-review until satisfied.
Once all comments are addressed:
```bash
REPO_TOKEN=<token> python3 scripts/review_pr.py <pr_number> <owner/repo> \
REPO_TOKEN=<token> python3 scripts/ci/review_pr.py <pr_number> <owner/repo> \
--event APPROVE \
--body "All comments addressed. LGTM."
```
@@ -96,7 +96,7 @@ Then add the `ready-to-merge` label. The auto-merge workflow will:
After the squash-merge:
- The **post-merge workflow** (`.gitea/workflows/post-merge.yml`) triggers on push to `master` and runs `scripts/post_merge.py` to mark the Vikunja task as done, extracting the task ID from the merge commit message.
- The **post-merge workflow** (`.gitea/workflows/post-merge.yml`) triggers on push to `master` and runs `scripts/ci/post_merge.py` to mark the Vikunja task as done, extracting the task ID from the merge commit message.
- The **release workflow** (`.gitea/workflows/release.yml`) triggers on push to `master` and automatically versions, tags, and publishes (see below).
## Branch Protection (Required Gitea Settings)
@@ -132,7 +132,7 @@ The `quality` job in `.gitea/workflows/ci.yml` runs:
2. `make lint-all` — ruff + pyright + bandit + ansible-lint + checkmake
3. `make pytest-cov` — unit tests with 100% coverage enforcement
4. `python3 scripts/check_test_speed.py --max-seconds 10` — verify unit tests run fast
5. `PYTHONPATH=src python3 scripts/release.py --dry-run` — release dry-run validation
5. `PYTHONPATH=src python3 scripts/ci/release.py --dry-run` — release dry-run validation
## Automated Release Pipeline
@@ -144,7 +144,7 @@ After a PR is merged to master, the release pipeline runs automatically.
- Sets up full dev environment (`make setup`) so lint and tests can run
- Installs git-cliff (version 2.13.0)
- Configures git as `grm-ci-bot`
- Runs `scripts/release.py` which uses **git-cliff** to:
- Runs `scripts/ci/release.py` which uses **git-cliff** to:
- Calculate the next semver version from conventional commits since the last tag
- Update `__version__` in `src/gitea_runner_manager/__init__.py` (single source of truth)
- Update `CHANGELOG.md` with the new version section
@@ -155,7 +155,7 @@ After a PR is merged to master, the release pipeline runs automatically.
- Push both the commit and tag to master
- `--skip-tests` flag bypasses test verification (emergency use only, not recommended)
- Loops are prevented by `has_unreleased_changes` — after a release commit is tagged, the next run finds no unreleased changes and exits
- On failure, creates a Gitea issue via `scripts/notify_failure.py`
- On failure, creates a Gitea issue via `scripts/ci/notify_failure.py`
### Publish Workflow (`.gitea/workflows/publish.yml`)
@@ -166,25 +166,25 @@ After a PR is merged to master, the release pipeline runs automatically.
- Builds the Python package
- Optionally publishes to PyPI (if `PYPI_TOKEN` is set)
- Creates a Gitea release with git-cliff-generated release notes
- Uses `scripts/publish.py` for build and publish orchestration
- On failure, creates a Gitea issue via `scripts/notify_failure.py`
- Uses `scripts/ci/publish.py` for build and publish orchestration
- On failure, creates a Gitea issue via `scripts/ci/notify_failure.py`
### Auto-Merge Workflow (`.gitea/workflows/auto-merge.yml`)
- Triggers on `pull_request` labeled events
- Runs `scripts/auto_merge.py` with the branch name, PR title, repository, PR number, and label name
- Runs `scripts/ci/auto_merge.py` with the branch name, PR title, repository, PR number, and label name
- Validates PR title format, checks for APPROVE review, waits for CI, and squash-merges
### Post-Merge Workflow (`.gitea/workflows/post-merge.yml`)
- Triggers on push to `master`
- Runs `scripts/post_merge.py` with the latest commit message and commit SHA
- Runs `scripts/ci/post_merge.py` with the latest commit message and commit SHA
- Marks the corresponding Vikunja task as done
### Smart CI: User-Facing vs Workflow-Only Changes
Not all changes require the full CI pipeline or a new release. The project uses
`scripts/classify_changes.py` to classify changed files into two categories:
`scripts/ci/classify_changes.py` to classify changed files into two categories:
**User-facing paths** (tool changes → release needed):
- `src/gitea_runner_manager/**` — Python CLI source
@@ -203,6 +203,24 @@ Not all changes require the full CI pipeline or a new release. The project uses
user-facing files changed since the last tag. If not, the release is skipped
entirely — no version bump, no tag, no publish.
### Dynamic Runner Discovery
Molecule tests are distributed across available Gitea Actions runners
dynamically. The `discover-runners` job runs `scripts/ci/discover_runners.py` which queries the Gitea API for
registered runners at three levels (repo, org, instance) and generates
a matrix of runner indices. If the API query fails (e.g., no admin
access for instance-level runners), it falls back to the
`MOLECULE_RUNNERS` repo variable, then to a default of 3.
The `molecule-tests` job uses `fromJSON()` to consume the dynamic
matrix, and passes the runner count to `distribute_molecule.py
--max-runners` so test pairs are evenly distributed.
When adding or removing Gitea runners:
1. If runners are registered at the repo/org level, they're auto-detected
2. If runners are at the instance level, update the `MOLECULE_RUNNERS` repo variable
3. The workflow automatically scales the matrix to match available runners
## git-cliff Commit Preprocessing
Merge commits on master have the format `GRM-N <conventional commit>`. The `GRM-N ` prefix is not a valid conventional commit prefix, so `cliff.toml` includes a `commit_preprocessors` entry that strips it before parsing: