Add pgrep diagnostics before/after pkill to identify lingering dockerd
processes. If pkill fails and pgrep still finds dockerd, kill by PID
directly via os.kill. When inner dockerd can't be killed (still alive),
use /dev/shm as data root since the overlay is still full.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The inner dockerd started by the CI image doesn't respond to SIGTERM.
Use pkill -9 to force-kill it, then verify it's actually dead by
running docker info. If the old daemon is still alive (can't be killed),
use /dev/shm/docker.sock as an alternate socket path to avoid conflicts.
Also moved the data root cleanup after the kill verification, so we
don't delete files while the old daemon might still be writing to them.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When no socket has sufficient space, don't fall back to the low-space
inner dockerd (which will fail on image pulls). Instead, kill the inner
dockerd, clean up its data root to free space, and start a local
dockerd on /dev/shm with vfs storage driver.
Also adds pkill of the inner dockerd and cleanup of its data root
(overlay2, image, volumes, containers) before starting the local
dockerd, to free up the 2.4GB used by the inner dockerd's data.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The start_docker.py script was checking /var/run/docker.sock first,
which inside CI containers is an inner dockerd (v29.5.3) with data
root on the container's 38G overlay (often 100% full). When
_get_docker_free_bytes() returned 0 (data root path not accessible
from inside container), the script assumed it was the host Docker
with plenty of space and returned True immediately — without trying
the host's rootless Docker socket at /run/host-docker.sock.
Fix: try /run/host-docker.sock FIRST (before /var/run/docker.sock).
The host socket is mounted by the gitea runner config and has access
to the host's full filesystem (455G). Only trust free_bytes == 0
(= data root not accessible from container) for /run/host-docker.sock,
since the host's root dir is genuinely outside the container. For
other sockets (inner dockerd), free_bytes == 0 means the path doesn't
exist inside the container — don't trust it.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The CI container can't access the host Docker's data root
(/home/grm-ci-runner-X/.local/share/docker) to check disk space.
When free_bytes=0, the root dir is on the host filesystem (455G).
Always use host Docker in that case instead of starting a local
dockerd on the 16G /dev/shm tmpfs (which fills up with images).
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The existing dockerd holds /var/run/docker.sock and can't be killed
from inside the container (different PID namespace). Use a new socket
path /dev/shm/docker.sock and data root /dev/shm/docker (16G tmpfs).
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The CI container's pre-existing dockerd (v29.5.3) uses the default
data root on the 38G overlay (100% full). Kill it before starting
the new dockerd with --data-root /dev/shm/docker (16G tmpfs).
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When a CI container has an inner dockerd (DinD) writing to the
container's overlay (e.g. 38 GB), image pulls fail with ENOSPC.
start_docker.py now checks the daemon's free disk space and tries
rootless sockets (which have access to the host's full filesystem)
when the default socket has less than 20 GB free.
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>