Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48ddac033e | ||
|
|
91635b5a5d | ||
|
|
bd0910287a | ||
|
|
063623cb9f | ||
|
|
ae52aab843 |
@@ -0,0 +1,135 @@
|
|||||||
|
# dependency-graph
|
||||||
|
|
||||||
|
Map of the oblachno ecosystem. Knows which repo produces what, which
|
||||||
|
repos depend on which, and the correct order for cross-repo changes.
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
Invoke this skill when:
|
||||||
|
- Changes span multiple repos
|
||||||
|
- A change in one repo requires version bumps in downstream repos
|
||||||
|
- Deploying infrastructure that depends on published packages/images
|
||||||
|
- Verifying the ecosystem is in a consistent state before deployment
|
||||||
|
- Determining which repos to update and in what order
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- All repos cloned under `/home/emo/dev/ideas/oblachno/`
|
||||||
|
- `.env` with `DEVELOPER_GITEA_API_TOKEN` in each repo
|
||||||
|
|
||||||
|
## Ecosystem Map
|
||||||
|
|
||||||
|
```
|
||||||
|
devx (PyPI package)
|
||||||
|
/ | \
|
||||||
|
/ | \
|
||||||
|
grm sso-bridge infra
|
||||||
|
(PyPI) (PyPI+Docker) (deploys all)
|
||||||
|
| | |
|
||||||
|
v v v
|
||||||
|
infra bump infra bump staging
|
||||||
|
(auto PR) (auto PR) production
|
||||||
|
|
|
||||||
|
mattermost-oidc (Docker image)
|
||||||
|
(infra pulls :latest at deploy)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repositories
|
||||||
|
|
||||||
|
| Repo | Produces | Consumers | Release Trigger |
|
||||||
|
|------|----------|-----------|-----------------|
|
||||||
|
| `devx` | PyPI package `devx` | grm, sso-bridge, infra | User-facing changes to `src/devx/**` |
|
||||||
|
| `grm` | PyPI package `grm` | infra | User-facing changes to `src/grm/**` or `ansible/**` |
|
||||||
|
| `sso-bridge` | PyPI package `sso_bridge` + Docker image | infra | User-facing changes to `src/sso_bridge/**` or `ansible/**` |
|
||||||
|
| `infra` | Staging/production deployment | (end users) | User-facing changes + nightly gate |
|
||||||
|
| `mattermost-oidc` | Docker image `mattermost-oidc` | infra (pulls at deploy) | `Dockerfile` or `build.yml` changes |
|
||||||
|
|
||||||
|
## Dependency Chain
|
||||||
|
|
||||||
|
### devx → all repos
|
||||||
|
|
||||||
|
devx publishes to the Gitea PyPI registry. grm, sso-bridge, and infra
|
||||||
|
pin devx in `pyproject.toml`:
|
||||||
|
```toml
|
||||||
|
"devx @ git+https://git.oblachno.oblachno.fyi/oblachno-oss/devx.git@vX.Y.Z"
|
||||||
|
```
|
||||||
|
|
||||||
|
When devx publishes a new version:
|
||||||
|
1. grm, sso-bridge, and infra must bump their pinned devx version
|
||||||
|
2. This is currently manual — no auto-dependency-PR from devx
|
||||||
|
3. Each repo must `make setup` to pick up the new version
|
||||||
|
|
||||||
|
### grm → infra
|
||||||
|
|
||||||
|
grm publishes to PyPI. Its post-merge workflow auto-creates an infra
|
||||||
|
dependency PR via `devx.ci.create_dependency_pr --repo oblachno/infra
|
||||||
|
--package grm`. The PR bumps the pinned grm version in infra's
|
||||||
|
`pyproject.toml`.
|
||||||
|
|
||||||
|
### sso-bridge → infra
|
||||||
|
|
||||||
|
sso-bridge publishes to PyPI AND builds a Docker image. Its post-merge
|
||||||
|
workflow auto-creates an infra dependency PR via
|
||||||
|
`devx.ci.create_dependency_pr --repo oblachno/infra --package
|
||||||
|
sso_bridge`. The PR bumps the pinned sso_bridge version.
|
||||||
|
|
||||||
|
The Docker image is pulled by infra at deploy time (`sso-bridge:latest`).
|
||||||
|
|
||||||
|
### mattermost-oidc → infra
|
||||||
|
|
||||||
|
mattermost-oidc builds a Docker image tagged `:latest` and `:MM_VERSION`.
|
||||||
|
infra pulls `mattermost-oidc:latest` at deploy time. There is no
|
||||||
|
auto-dependency-PR — infra simply pulls the latest image.
|
||||||
|
|
||||||
|
### infra → staging/production
|
||||||
|
|
||||||
|
infra deploys to staging and production. The deployment:
|
||||||
|
1. Provisions VMs from golden images
|
||||||
|
2. Runs Ansible roles (including grm and sso-bridge roles)
|
||||||
|
3. Pulls Docker images (sso-bridge, mattermost-oidc)
|
||||||
|
4. Configures services
|
||||||
|
|
||||||
|
## Correct Order for Cross-Repo Changes
|
||||||
|
|
||||||
|
When a change spans multiple repos, follow this order:
|
||||||
|
|
||||||
|
1. **devx first** — if the change starts in devx, merge and publish devx
|
||||||
|
first. Wait for the PyPI publish job to complete.
|
||||||
|
2. **Bump devx in consumers** — in grm/sso-bridge/infra, bump the pinned
|
||||||
|
devx version, run `make setup`, verify tests pass, merge.
|
||||||
|
3. **grm/sso-bridge second** — merge and publish grm/sso-bridge. Wait
|
||||||
|
for the PyPI publish + Docker image build to complete.
|
||||||
|
4. **Auto-dependency-PRs** — grm/sso-bridge post-merge auto-creates infra
|
||||||
|
PRs to bump pinned versions. Wait for these PRs to appear.
|
||||||
|
5. **Merge infra dependency PRs** — review and merge the auto-created
|
||||||
|
infra PRs.
|
||||||
|
6. **infra last** — deploy to staging, validate, promote to production.
|
||||||
|
|
||||||
|
## State Verification Before Deployment
|
||||||
|
|
||||||
|
Before deploying infra, verify:
|
||||||
|
|
||||||
|
1. **devx version consistent** — all repos pin the same devx version
|
||||||
|
2. **grm published** — latest grm tag exists in PyPI
|
||||||
|
3. **sso-bridge published** — latest sso_bridge tag exists in PyPI
|
||||||
|
4. **sso-bridge image built** — latest sso-bridge Docker image exists
|
||||||
|
5. **mattermost-oidc image built** — latest mattermost-oidc image exists
|
||||||
|
6. **infra pins match published versions** — no stale pins
|
||||||
|
7. **Nightly gate green** — `NIGHTLY_STATUS` is not `failed`
|
||||||
|
|
||||||
|
## Quick Check Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check latest devx version
|
||||||
|
curl -sS https://git.oblachno.oblachno.fyi/api/v1/repos/oblachno-oss/devx/releases/latest | python3 -c "import json,sys; print(json.load(sys.stdin).get('tag_name','?'))"
|
||||||
|
|
||||||
|
# Check pinned devx version in each repo
|
||||||
|
for repo in grm sso-bridge infra; do
|
||||||
|
echo -n "$repo: "; grep 'devx @' /home/emo/dev/ideas/oblachno/$repo/pyproject.toml | grep -oP 'v[\d.]+'
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check latest sso-bridge image build
|
||||||
|
curl -sS -H "Authorization: token $DEVELOPER_GITEA_API_TOKEN" \
|
||||||
|
"https://git.oblachno.oblachno.fyi/api/v1/repos/oblachno/sso-bridge/actions/runs?per_page=5" \
|
||||||
|
| python3 -c "import json,sys; [print(r['id'],r['status'],r['conclusion']) for r in json.load(sys.stdin).get('workflow_runs',[]) if r.get('event')=='push']"
|
||||||
|
```
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# deployment-coordination
|
||||||
|
|
||||||
|
How grm releases propagate to infra. grm publishes a PyPI package and
|
||||||
|
auto-creates an infra dependency PR. Coordination ensures the PR is
|
||||||
|
merged before infra deploys.
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
Invoke this skill when:
|
||||||
|
- Changes to grm affect infra deployments
|
||||||
|
- Preparing a grm release that infra depends on
|
||||||
|
- Verifying infra has bumped to the latest grm version
|
||||||
|
- Coordinating a multi-repo change that includes grm
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- grm repo at `/home/emo/dev/ideas/oblachno/grm`
|
||||||
|
- `.env` with `DEVELOPER_GITEA_API_TOKEN`
|
||||||
|
- See `dependency-graph` skill for the full ecosystem map
|
||||||
|
|
||||||
|
## What grm Produces
|
||||||
|
|
||||||
|
grm publishes a Python package to the Gitea PyPI registry. infra pins it:
|
||||||
|
```toml
|
||||||
|
"grm @ git+https://git.oblachno.oblachno.fyi/oblachno-oss/grm.git@vX.Y.Z"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Release Flow
|
||||||
|
|
||||||
|
1. PR merged to master
|
||||||
|
2. Post-merge workflow runs `devx.ci.release` — classifies changes
|
||||||
|
3. If user-facing changes: git-cliff bumps version, creates tag, pushes
|
||||||
|
4. `devx.ci.publish` builds and publishes to Gitea PyPI registry
|
||||||
|
5. `devx.ci.create_dependency_pr --repo oblachno/infra --package grm`
|
||||||
|
auto-creates an infra PR to bump the pinned grm version
|
||||||
|
|
||||||
|
## Downstream Consumer
|
||||||
|
|
||||||
|
| Repo | Pin location | Auto-bump? |
|
||||||
|
|------|-------------|------------|
|
||||||
|
| infra | `pyproject.toml` | Yes — auto PR created by post-merge |
|
||||||
|
|
||||||
|
## Coordinating a grm Change
|
||||||
|
|
||||||
|
1. **Merge grm PR** — wait for post-merge publish + dependency-PR creation
|
||||||
|
2. **Verify publish** — check the new tag:
|
||||||
|
```bash
|
||||||
|
curl -sS -H "Authorization: token $DEVELOPER_GITEA_API_TOKEN" \
|
||||||
|
https://git.oblachno.oblachno.fyi/api/v1/repos/oblachno-oss/grm/releases/latest \
|
||||||
|
| python3 -c "import json,sys; print(json.load(sys.stdin).get('tag_name','?'))"
|
||||||
|
```
|
||||||
|
3. **Find the auto-created infra PR** — check infra for open PRs with
|
||||||
|
`dependency` label or title containing `bump grm`
|
||||||
|
4. **Review and merge the infra dependency PR** — verify the version bump,
|
||||||
|
run `make pytest-cov` in infra, add `ready-to-merge`
|
||||||
|
5. **Verify infra staging deploy** — after infra merges, staging deploy
|
||||||
|
picks up the new grm version
|
||||||
|
|
||||||
|
## State Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Current grm version
|
||||||
|
grep '__version__' /home/emo/dev/ideas/oblachno/grm/src/grm/__init__.py
|
||||||
|
|
||||||
|
# What infra pins
|
||||||
|
grep 'grm @' /home/emo/dev/ideas/oblachno/infra/pyproject.toml | grep -oP 'v[\d.]+'
|
||||||
|
|
||||||
|
# Check for open infra dependency PRs
|
||||||
|
curl -sS -H "Authorization: token $DEVELOPER_GITEA_API_TOKEN" \
|
||||||
|
"https://git.oblachno.oblachno.fyi/api/v1/repos/oblachno/infra/pulls?state=open" \
|
||||||
|
| python3 -c "import json,sys; [print(p['number'],p['title']) for p in json.load(sys.stdin) if 'grm' in p.get('title','').lower()]"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Mistakes
|
||||||
|
|
||||||
|
- Merging the grm PR but ignoring the auto-created infra dependency PR
|
||||||
|
- Deploying infra before the dependency PR is merged — stale grm version
|
||||||
|
- Forgetting that grm also has an Ansible role used by infra at deploy time
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# skill-creation
|
||||||
|
|
||||||
|
How to create, validate, and maintain Devin skills. Skills must be
|
||||||
|
clear, succinct, and actionable — no AI slop.
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
Invoke this skill when:
|
||||||
|
- Creating a new skill
|
||||||
|
- Amending an existing skill
|
||||||
|
- Evaluating whether a skill is needed
|
||||||
|
- Reviewing a PR that adds or modifies skills
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Skill directory: `.devin/skills/<skill-name>/SKILL.md`
|
||||||
|
- Validator: `tests/test_skills.py` (infra) or reference to it
|
||||||
|
- Tests: `tests/unit/test_skills_validation.py` (infra)
|
||||||
|
|
||||||
|
## When to Create a Skill
|
||||||
|
|
||||||
|
Create a skill when:
|
||||||
|
- An agent struggles with a task repeatedly (branch hygiene, PR order)
|
||||||
|
- A workflow has non-obvious ordering constraints (deployment coordination)
|
||||||
|
- A task requires specific tool usage over raw commands (CI monitoring)
|
||||||
|
- Multiple agents need shared context (dependency graph)
|
||||||
|
|
||||||
|
Do NOT create a skill for:
|
||||||
|
- One-off tasks (use a spec instead)
|
||||||
|
- Tasks already covered by AGENTS.md
|
||||||
|
- Tasks that are obvious from the Makefile or README
|
||||||
|
- Tasks that change frequently (skills should be stable)
|
||||||
|
|
||||||
|
## Skill Structure
|
||||||
|
|
||||||
|
Every skill MUST have:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# <skill-name>
|
||||||
|
|
||||||
|
One-line description of what the skill does.
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
2-4 bullet points describing when to use this skill.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
What must exist before using the skill (venv, .env, tools).
|
||||||
|
|
||||||
|
## <Core Content>
|
||||||
|
|
||||||
|
The actual guidance. Keep it actionable.
|
||||||
|
|
||||||
|
## Verification (if applicable)
|
||||||
|
|
||||||
|
How to verify the skill's guidance works.
|
||||||
|
|
||||||
|
## Common Mistakes (if applicable)
|
||||||
|
|
||||||
|
What agents get wrong without this skill.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quality Standards
|
||||||
|
|
||||||
|
### Do
|
||||||
|
- **Be specific.** Reference exact make targets, file paths, commands.
|
||||||
|
- **Be concise.** Each section should be scannable in under 30 seconds.
|
||||||
|
- **Be actionable.** Every paragraph should tell the agent what to DO.
|
||||||
|
- **Use tables** for command reference, mappings, and comparisons.
|
||||||
|
- **Use code blocks** for commands the agent should run.
|
||||||
|
- **Link to other skills** when related (e.g., "See `dependency-graph` skill").
|
||||||
|
|
||||||
|
### Don't
|
||||||
|
- **No preamble.** Don't start with "This skill helps agents..." — just state what it does.
|
||||||
|
- **No filler.** Don't repeat information from AGENTS.md or other skills.
|
||||||
|
- **No vague advice.** "Be careful with branches" is useless. "Run `git branch --show-current` before every commit" is useful.
|
||||||
|
- **No AI slop.** Don't write "In this comprehensive guide, we will explore..." — just give the guidance.
|
||||||
|
- **No redundant sections.** If "Common Mistakes" would repeat "When to Invoke", skip it.
|
||||||
|
- **No marketing.** Don't describe the skill as "powerful" or "comprehensive".
|
||||||
|
|
||||||
|
## Scope Rules
|
||||||
|
|
||||||
|
- **One skill per concern.** Don't mix branch hygiene with CI monitoring.
|
||||||
|
- **Project-specific, not generic.** Skills reference this repo's make targets, file paths, and conventions — not abstract advice.
|
||||||
|
- **Shared skills must be identical across repos.** Use `SHARED_SKILLS` in the validator to enforce this.
|
||||||
|
- **Per-repo skills must reflect that repo's reality.** Don't copy infra-specific targets to sso-bridge.
|
||||||
|
|
||||||
|
## Automated Validation
|
||||||
|
|
||||||
|
Every skill must pass the validator (`tests/test_skills.py`). The validator checks:
|
||||||
|
|
||||||
|
1. **Structure** — H1 title, "When to Invoke" section, "Prerequisites" section
|
||||||
|
2. **Commands** — referenced `make <target>` commands exist in Makefile or devx.mak
|
||||||
|
3. **Paths** — referenced file paths exist in the repo
|
||||||
|
4. **Shared skills** — identical content across repos (SHA-256 comparison)
|
||||||
|
5. **No drift** — no references to nonexistent commands or files
|
||||||
|
|
||||||
|
Run the validator:
|
||||||
|
```bash
|
||||||
|
python3 tests/test_skills.py --repo infra --repo sso-bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
## Effectiveness Evaluation
|
||||||
|
|
||||||
|
### Static Checks (automated, CI)
|
||||||
|
|
||||||
|
The validator runs in CI as part of `make pytest-cov`. A failing skill
|
||||||
|
test blocks the PR. This catches:
|
||||||
|
- Missing sections
|
||||||
|
- Invalid commands
|
||||||
|
- Broken file references
|
||||||
|
- Cross-repo drift
|
||||||
|
|
||||||
|
### Runtime Metrics (manual, periodic)
|
||||||
|
|
||||||
|
Track these signals to evaluate skill effectiveness:
|
||||||
|
- **Skill invocation frequency** — how often agents invoke the skill
|
||||||
|
- **Success rate when invoked** — did the skill prevent the mistake it targets?
|
||||||
|
- **Feedback issues** — agents create Gitea issues with `feedback` label when a skill is unclear or wrong
|
||||||
|
- **Mistake recurrence** — if agents still make the mistake the skill targets, the skill needs improvement
|
||||||
|
|
||||||
|
### Retrospective Review
|
||||||
|
|
||||||
|
Periodically (monthly or after major incidents) review skills:
|
||||||
|
1. List all skills and their last-modified dates
|
||||||
|
2. Check for feedback issues tagged `skill-improvement`
|
||||||
|
3. Verify referenced commands still exist (run validator)
|
||||||
|
4. Remove skills that are no longer relevant
|
||||||
|
5. Update skills where mistakes still recur
|
||||||
|
6. Document lessons in this skill's "Common Mistakes" section
|
||||||
|
|
||||||
|
## Creating a New Skill — Checklist
|
||||||
|
|
||||||
|
- [ ] Identify the repeated struggle or non-obvious workflow
|
||||||
|
- [ ] Check no existing skill covers it
|
||||||
|
- [ ] Write the skill following the structure above
|
||||||
|
- [ ] Run `python3 tests/test_skills.py` — must pass
|
||||||
|
- [ ] Run `make pytest-cov` — must pass with 100% coverage
|
||||||
|
- [ ] If shared across repos, copy identical content to each repo
|
||||||
|
- [ ] Add the skill to `SHARED_SKILLS` in the validator if shared
|
||||||
|
- [ ] Create PR, verify CI passes, merge
|
||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.23.1] - 2026-09-15
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Restrict docker-prune to exited containers
|
||||||
|
|
||||||
## [0.23.0] - 2026-08-28
|
## [0.23.0] - 2026-08-28
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ Each runner runs in an isolated **rootless Docker** environment under a dedicate
|
|||||||
|
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/src/branch/master/LICENSE)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/src/branch/master/LICENSE)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/wiki)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/wiki)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/releases)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/releases)
|
||||||
[](https://www.python.org/downloads/)
|
[](https://www.python.org/downloads/)
|
||||||
|
|
||||||
## Why GRM?
|
## Why GRM?
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
that:
|
that:
|
||||||
- "'Type=oneshot' in prune_service.content | b64decode"
|
- "'Type=oneshot' in prune_service.content | b64decode"
|
||||||
- "'docker rm -f' in prune_service.content | b64decode"
|
- "'docker rm -f' in prune_service.content | b64decode"
|
||||||
|
- "'status=exited' in prune_service.content | b64decode"
|
||||||
- "'GITEA-ACTIONS-TASK' in prune_service.content | b64decode"
|
- "'GITEA-ACTIONS-TASK' in prune_service.content | b64decode"
|
||||||
- "'docker system prune -af' in prune_service.content | b64decode"
|
- "'docker system prune -af' in prune_service.content | b64decode"
|
||||||
- "'docker network prune' in prune_service.content | b64decode"
|
- "'docker network prune' in prune_service.content | b64decode"
|
||||||
|
|||||||
@@ -5,16 +5,18 @@ Description=Docker prune for Gitea runner resources
|
|||||||
Type=oneshot
|
Type=oneshot
|
||||||
Environment=DOCKER_HOST=unix:///run/user/{{ gitea_runner_uid }}/docker.sock
|
Environment=DOCKER_HOST=unix:///run/user/{{ gitea_runner_uid }}/docker.sock
|
||||||
Environment=XDG_RUNTIME_DIR=/run/user/{{ gitea_runner_uid }}
|
Environment=XDG_RUNTIME_DIR=/run/user/{{ gitea_runner_uid }}
|
||||||
# Force-remove stale containers (including running ones) left behind by failed
|
# Force-remove stale *stopped* containers left behind by failed molecule tests.
|
||||||
# molecule tests. "docker container prune -f" only removes stopped containers,
|
# Implements: REQ-1 (GRM-166) — only containers with status=exited are
|
||||||
# so running containers from crashed/interrupted CI jobs accumulate indefinitely,
|
# eligible. RunningFor measures creation time, so a stale molecule instance
|
||||||
# consuming disk and memory. We stop+rm everything first, then prune the rest.
|
# (e.g. ubuntu-2604) that a new run restarts still looks ">1h old"; removing
|
||||||
|
# running containers kills active converges with "No such container"
|
||||||
|
# (infra nightly run 5710). Running leftovers are instead reused or destroyed
|
||||||
|
# by the next molecule create/destroy cycle.
|
||||||
# Exclude CI job containers (name starts with GITEA-ACTIONS-TASK) — removing
|
# Exclude CI job containers (name starts with GITEA-ACTIONS-TASK) — removing
|
||||||
# them kills the active CI job and causes "RWLayer is unexpectedly nil" errors.
|
# them kills the active CI job and causes "RWLayer is unexpectedly nil" errors.
|
||||||
# Only remove containers older than 1 hour (grep for "hour/day/week/month/year
|
# Only remove containers older than 1 hour (grep for "hour/day/week/month/year
|
||||||
# ago" in RunningFor) to avoid killing molecule test containers that CI jobs
|
# ago" in RunningFor) to avoid removing containers a job just created.
|
||||||
# are actively using.
|
ExecStart=/bin/sh -c 'docker ps -a --filter "status=exited" --format "{% raw %}{{.ID}} {{.Names}} {{.RunningFor}}{% endraw %}" 2>/dev/null | grep -v "GITEA-ACTIONS-TASK" | grep -E "(hour|day|week|month|year)s? ago" | awk "{print $1}" | xargs -r docker rm -f 2>/dev/null || true'
|
||||||
ExecStart=/bin/sh -c 'docker ps -a --format "{% raw %}{{.ID}} {{.Names}} {{.RunningFor}}{% endraw %}" 2>/dev/null | grep -v "GITEA-ACTIONS-TASK" | grep -E "(hour|day|week|month|year)s? ago" | awk "{print $1}" | xargs -r docker rm -f 2>/dev/null || true'
|
|
||||||
ExecStart=/usr/bin/docker system prune -af --filter "until={{ gitea_runner_prune_until }}" --volumes
|
ExecStart=/usr/bin/docker system prune -af --filter "until={{ gitea_runner_prune_until }}" --volumes
|
||||||
# Prune networks older than the prune-until threshold to avoid removing
|
# Prune networks older than the prune-until threshold to avoid removing
|
||||||
# networks that molecule tests are actively creating (e.g. 'traefik' network
|
# networks that molecule tests are actively creating (e.g. 'traefik' network
|
||||||
|
|||||||
+6
-6
@@ -8,12 +8,12 @@ Each runner runs in an isolated **rootless Docker** environment under a dedicate
|
|||||||
|
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/src/branch/master/LICENSE)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/src/branch/master/LICENSE)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/wiki)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/wiki)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/actions)
|
||||||
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/releases)
|
[](https://git.oblachno.oblachno.fyi/oblachno-oss/grm/releases)
|
||||||
[](https://www.python.org/downloads/)
|
[](https://www.python.org/downloads/)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# GRM-166: Fix docker-prune killing running molecule containers
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
`docker-prune.service` force-removes containers older than 1h by
|
||||||
|
**creation** time (`RunningFor`). Molecule instance containers
|
||||||
|
(`ubuntu-2604` etc.) run on the runner's shared rootless daemon and are
|
||||||
|
not name-excluded (only `GITEA-ACTIONS-TASK` jobs are). A stale molecule
|
||||||
|
container left by a crashed run is *restarted/reused* by the next run's
|
||||||
|
create phase — it then shows `RunningFor` >1h and gets `docker rm -f`'d
|
||||||
|
mid-converge: `No such container: ubuntu-2604`. Observed on infra nightly
|
||||||
|
run 5710 across multiple runners (incl. a 32 GB host), causing
|
||||||
|
shard failures.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
REQ-1: Change the container cleanup `ExecStart` in
|
||||||
|
`ansible/roles/gitea_runner/templates/docker-prune.service.j2` to only
|
||||||
|
target containers with `status=exited` (add
|
||||||
|
`--filter "status=exited"`). Running containers — including stale
|
||||||
|
molecule instances adopted by an active run — are never force-removed.
|
||||||
|
REQ-2: Update the template comment to document the race and why only
|
||||||
|
stopped containers are removed.
|
||||||
|
REQ-3: Extend the `template-content` molecule verify assertions to
|
||||||
|
require the `status=exited` filter in the rendered unit.
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
- `make molecule` (template-content scenario) verifies the rendered unit.
|
||||||
|
- `make pytest-cov` and `make lint-all` pass.
|
||||||
|
|
||||||
|
## Deploy Plan
|
||||||
|
- Merge to master → package publishes; runner hosts pick up the role on
|
||||||
|
their next grm install/upgrade cycle (or manual re-run of the role on
|
||||||
|
affected runners).
|
||||||
|
- Until then, nightly molecule reruns remain exposed to the race —
|
||||||
|
mitigated by the fact that swept daemons have no stale containers left.
|
||||||
|
|
||||||
|
## Rollback Plan
|
||||||
|
- Revert the merge commit. Running stale leftovers would then again be
|
||||||
|
force-removed (the pre-existing risky behaviour).
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [x] REQ-1: prune rm step filtered to `status=exited`
|
||||||
|
- [x] REQ-2: comment documents the creation-time vs running race
|
||||||
|
- [x] REQ-3: template-content verify asserts the exited filter
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# GRM-173: Add dependency-graph, deployment-coordination, and skill-creation skills
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
Agents working across the oblachno ecosystem lack shared, written context
|
||||||
|
for three recurring struggles: (1) knowing which repo produces what and
|
||||||
|
the correct order for cross-repo changes, (2) coordinating grm releases
|
||||||
|
with the downstream infra dependency PR, and (3) creating and validating
|
||||||
|
new Devin skills consistently. Without these skills, agents repeatedly
|
||||||
|
make mistakes such as deploying infra before the grm dependency PR is
|
||||||
|
merged, or writing skills that fail the validator.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
Add three skill files under `.devin/skills/`. Two are shared skills
|
||||||
|
(`dependency-graph`, `skill-creation`) that must be identical across
|
||||||
|
repos; one is grm-specific (`deployment-coordination`). All three
|
||||||
|
follow the standard skill structure (H1 title, When to Invoke,
|
||||||
|
Prerequisites, core content) and reference real make targets, file
|
||||||
|
paths, and API endpoints.
|
||||||
|
|
||||||
|
REQ-1: Add `.devin/skills/dependency-graph/SKILL.md` — shared skill mapping the oblachno ecosystem (repos, produces/consumers, dependency chain, correct change order, state verification)
|
||||||
|
REQ-2: Add `.devin/skills/deployment-coordination/SKILL.md` — grm-specific skill covering release flow, downstream consumer, coordinating a grm change, and common mistakes
|
||||||
|
REQ-3: Add `.devin/skills/skill-creation/SKILL.md` — shared skill for creating, validating, and maintaining skills (structure, quality standards, scope rules, automated validation, checklist)
|
||||||
|
|
||||||
|
## Files Affected
|
||||||
|
- `.devin/skills/dependency-graph/SKILL.md` (new)
|
||||||
|
- `.devin/skills/deployment-coordination/SKILL.md` (new)
|
||||||
|
- `.devin/skills/skill-creation/SKILL.md` (new)
|
||||||
|
- `docs/specs/GRM-173.md` (new)
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
- Verify all three SKILL.md files follow the required structure (H1, When to Invoke, Prerequisites)
|
||||||
|
- Verify referenced make targets and file paths are accurate
|
||||||
|
- Run `make pytest-cov` to confirm no test regressions (skills are docs-only, no code changes)
|
||||||
|
- Confirm shared skills (`dependency-graph`, `skill-creation`) are ready for cross-repo sync
|
||||||
|
|
||||||
|
## Deploy Plan
|
||||||
|
- Merge to master via auto-merge workflow
|
||||||
|
- No runtime changes; documentation-only (`.devin/**` is infrastructure path, no release triggered)
|
||||||
|
|
||||||
|
## Rollback Plan
|
||||||
|
- Revert the merge commit; skill files are removed, no functional impact
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [x] REQ-1: `.devin/skills/dependency-graph/SKILL.md` exists with ecosystem map, dependency chain, correct change order, and state verification sections
|
||||||
|
- [x] REQ-2: `.devin/skills/deployment-coordination/SKILL.md` exists with release flow, downstream consumer table, coordination steps, and common mistakes
|
||||||
|
- [x] REQ-3: `.devin/skills/skill-creation/SKILL.md` exists with skill structure template, quality standards, scope rules, automated validation, and creation checklist
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
"""Gitea Runner Manager — lean CLI for managing Gitea Actions runners."""
|
"""Gitea Runner Manager — lean CLI for managing Gitea Actions runners."""
|
||||||
|
|
||||||
__version__ = "0.23.0"
|
__version__ = "0.23.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user