The build-images CI job failed because GitHub releases dropped
connections ("Remote end closed connection without response") for
actionlint, vale, and hadolint simultaneously. The previous code only
fell through to the next fallback URL — there was no retry on the same
URL for transient connection resets.
Now uses tenacity.Retrying with exponential backoff (2-10s, 3 attempts)
on URLError/OSError/ConnectionError, matching the pattern already used
in devx.utils.network. The _sleep kwarg allows tests to skip real
sleeping.
3 new tests cover: retry-then-success, exhaustion-after-max-retries,
and no-retry-on-non-transient-errors.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 1e-f of REFACTORING-PLAN.md:
- Register `devx ci wait-for-checks` in cli.py with test coverage
- Add ADR-0002 documenting the ansible_checks consolidation and
wait_for_checks extraction decisions
- Update AGENTS.md package structure to reflect ansible_checks/
subpackage and deprecated ci/discover_runners wrapper
- Update docs/user/cli-commands.md with wait-for-checks documentation
and discover-runners deprecation notice
- Update docs/tech/architecture.md with new modules and canonical
discover_runners location
- Update docs/mapping.json with ADR entries
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 1a-c of REFACTORING-PLAN.md:
- Extract devx.ci.wait_for_checks module (replaces inline polling in
grm ci.yml) with 100% test coverage (26 tests)
- Consolidate 5 Ansible check tools into composable
devx.tools.ansible_checks/ subpackage with shared utilities
(AnsibleFileFinder, AnsibleYAMLParser, ViolationReporter); old
modules remain as thin backward-compat wrappers
- Merge ci/discover_runners into molecule/discover_runners (canonical
implementation with improved error logging); ci/discover_runners
becomes a deprecated wrapper re-exporting from molecule
All 2393 existing tests pass; new modules at 100% coverage.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Gitea appends a ".-" suffix before ".md" for wiki page titles that
contain dashes, to distinguish literal dashes from space-to-dash
conversions. For example, "Getting-Started" becomes
"Getting-Started.-.md", while "Architecture" becomes "Architecture.md".
Previously the code wrote "Getting-Started.md" which Gitea couldn't
recognize as a valid wiki page, causing verification to fail with
"page not found" for 15 of 21 pages.
Also force-push to handle concurrent CI runs that may have pushed to
the wiki repo between our clone and push.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Gitea needs a few seconds to process pushed wiki commits before a
re-clone will see them. Add a 5s sleep after a successful push before
verification re-clones the wiki.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
CI environments may lack git user.email/user.name config, causing
git commit to fail with exit code 128. Set identity explicitly before
committing wiki changes.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Replace the unreliable Gitea wiki API with direct Git operations:
- Clone {repo}.wiki.git, copy docs with link transformation, push
- Faster: single git push vs N API calls
- More reliable: no API timeouts or rate limits
- Atomic: all pages sync in one commit
- Auto-pruning: stale wiki pages removed automatically
- Link transformation: [text](file.md) → [text](file) for wiki format
- 36 new tests covering transform_links, clone, sync_files, commit, verify
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Add check_single_h1: each markdown file should have at most one H1
- Add check_max_heading_depth: headings should not exceed H4 (configurable)
- Add check_line_length: warn on lines >120 chars (non-blocking — badge URLs)
- Add check_code_block_languages: fenced code blocks must specify a language
- Add check_orphan_docs: warn on docs not linked from index.md or mapping.json
- Fix all code blocks in docs to specify language (text for plain blocks)
- Fix duplicate H1 in .vale/styles/devx/README.md
- Add 18 new tests for full coverage of new checks
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Fix badge system: clean .badges dir from orphan branch, add version
verification, make badges job depend on release (avoids stale version
badge race condition)
- Add check_doc_versions.py: lint tool that verifies docs version
references match current __version__, with --fix for auto-update
- Integrate check_doc_versions into release process (auto-updates docs
on every release commit)
- Add Vale prose linter integration: .vale.ini, custom styles for
terminology and code block language, CI step, make target
- Fix stale version references in docs (0.27.0 → 0.33.4)
- Fix e.g. → for example in docs (Google.Latin Vale rule)
- Add CI steps for check_doc_versions and Vale to quality workflow
- Add make targets: devx-check-doc-versions, devx-vale
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>