Compare commits

...
9 Commits
Author SHA1 Message Date
gitea-actions-bot 87d46226f6 chore: update badge URLs to commit 09be7662 [skip ci] 2026-09-05 14:18:15 +00:00
emil 4638e334b5 DEVX-167: docs: add dependency-graph, deployment-coordination, and skill-creation skills
Post-merge / detect-and-configure (push) Successful in 20s
Post-merge / release-and-maintain (push) Successful in 54s
Co-authored-by: emil User <emil.simeonov@tutanota.com>
2026-09-05 14:16:52 +00:00
gitea-actions-bot c6bd4e8f63 chore: update badge URLs to commit 27d2b933 [skip ci] 2026-08-26 18:12:15 +00:00
devx-ci-bot d47e3833bc release: v0.51.9 [skip ci] 2026-08-26 18:11:18 +00:00
emil c00e9e3d7b DEVX-166: fix: exclude docs/plans/* from PR size check
Post-merge / detect-and-configure (push) Successful in 13s
Post-merge / release-and-maintain (push) Successful in 1m25s
Co-authored-by: emil User <emil.simeonov@tutanota.com>
2026-08-26 18:10:34 +00:00
gitea-actions-bot 40e95bc96f chore: update badge URLs to commit ae0cb5b8 [skip ci] 2026-08-26 18:06:00 +00:00
devx-ci-bot 3aa9681404 release: v0.51.8 [skip ci] 2026-08-26 18:04:45 +00:00
emil e96f63cb40 DEVX-165: fix: accept deps: as valid conventional commit type
Post-merge / detect-and-configure (push) Successful in 14s
Post-merge / release-and-maintain (push) Successful in 1m46s
Co-authored-by: emil User <emil.simeonov@tutanota.com>
2026-08-26 18:03:57 +00:00
gitea-actions-bot 6d6c8cceec chore: update badge URLs to commit 2f14bdfd [skip ci] 2026-08-26 14:29:30 +00:00
18 changed files with 539 additions and 29 deletions
+135
View File
@@ -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,90 @@
# deployment-coordination
How devx releases propagate to downstream repos. devx is the base
package — all other repos pin it. A devx release must complete before
consumers can bump.
## When to Invoke
Invoke this skill when:
- Changes to devx affect downstream repos (grm, sso-bridge, infra)
- Preparing a devx release that other repos depend on
- Verifying downstream repos have bumped to the latest devx version
- Coordinating a multi-repo change that starts in devx
## Prerequisites
- devx repo at `/home/emo/dev/ideas/oblachno/devx`
- `.env` with `DEVELOPER_GITEA_API_TOKEN`
- See `dependency-graph` skill for the full ecosystem map
## What devx Produces
devx publishes a Python package to the Gitea PyPI registry. Downstream
repos pin it:
```toml
"devx @ git+https://git.oblachno.oblachno.fyi/oblachno-oss/devx.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. Downstream repos must bump their pinned devx version
## Downstream Consumers
| Repo | Pin location | Auto-bump? |
|------|-------------|------------|
| grm | `pyproject.toml` | No — manual |
| sso-bridge | `pyproject.toml` | No — manual |
| infra | `pyproject.toml` | No — manual |
devx does NOT auto-create dependency PRs in downstream repos. Bumping
is manual: create a PR in each downstream repo to update the pinned
version.
## Coordinating a devx Change
When a change to devx affects downstream repos:
1. **Merge devx PR** — wait for post-merge publish to complete
2. **Verify publish** — check the new tag exists:
```bash
curl -sS -H "Authorization: token $DEVELOPER_GITEA_API_TOKEN" \
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','?'))"
```
3. **Bump downstream repos** — for each repo (grm, sso-bridge, infra):
- Update `devx @ ...@vX.Y.Z` in `pyproject.toml`
- Run `make setup` to install the new version
- Run `make pytest-cov` to verify compatibility
- Create and merge a PR
4. **Verify infra deploys** — after infra bumps, verify staging deploy
picks up the new devx version
## State Verification
Before starting a devx change, verify current state:
```bash
# Current devx version
grep '__version__' /home/emo/dev/ideas/oblachno/devx/src/devx/__init__.py
# What each repo pins
for repo in grm sso-bridge infra; do
echo -n "$repo pins: "
grep 'devx @' /home/emo/dev/ideas/oblachno/$repo/pyproject.toml | grep -oP 'v[\d.]+'
done
```
If pins are inconsistent across repos, bump them to the latest published
version before starting new work.
## Common Mistakes
- Merging a devx PR and immediately merging downstream PRs without
waiting for the publish job to complete
- Forgetting to bump infra (it has the most complex deploy pipeline)
- Bumping only one downstream repo when the change affects all three
+142
View File
@@ -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
+12
View File
@@ -2,6 +2,18 @@
All notable changes to this project will be documented in this file.
## [0.51.9] - 2026-08-26
### Bug Fixes
- Exclude docs/plans/* from PR size check
## [0.51.8] - 2026-08-26
### Bug Fixes
- Accept deps: as valid conventional commit type
## [0.51.7] - 2026-08-26
### Bug Fixes
+9 -9
View File
@@ -16,12 +16,12 @@ quality badges.
[![CI](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions/workflows/ci.yml/badge.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/src/branch/master/LICENSE)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/python.svg)](https://www.python.org/downloads/)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/python.svg)](https://www.python.org/downloads/)
## Why devx?
@@ -87,7 +87,7 @@ extra index and list devx in your dependencies:
```toml
[project]
dependencies = [
"devx>=0.51.7",
"devx>=0.51.9",
]
[tool.pip]
@@ -101,8 +101,8 @@ pip install -e .
```
> **Note:** If your project requires a specific devx version, pin it in
> `dependencies` (for example, `"devx==0.51.7"`) or use a version constraint
> (for example, `"devx>=0.51.7,<0.52"`).
> `dependencies` (for example, `"devx==0.51.9"`) or use a version constraint
> (for example, `"devx>=0.51.9,<0.52"`).
### Optional extras
+8 -8
View File
@@ -12,12 +12,12 @@ project to be reusable across all oblachno-oss repositories.
[![CI](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions/workflows/ci.yml/badge.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/src/branch/master/LICENSE)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/f474ba2f81ea1a1c7e1d204f7b07652a55be2e67/python.svg)](https://www.python.org/downloads/)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/09be76620c0a26418c614fb26b7feec2a4f457d3/python.svg)](https://www.python.org/downloads/)
## Overview
@@ -74,14 +74,14 @@ Add devx to your `pyproject.toml` dependencies and configure the registry:
```toml
[project]
dependencies = [
"devx>=0.51.7",
"devx>=0.51.9",
]
[tool.pip]
extra-index-url = "https://git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple"
```
Pin a specific version if needed: `"devx==0.51.7"` or `"devx>=0.51.7,<0.52"`.
Pin a specific version if needed: `"devx==0.51.9"` or `"devx>=0.51.9,<0.52"`.
### Optional extras
+31
View File
@@ -0,0 +1,31 @@
# DEVX-165: Accept deps: as valid conventional commit type
## Problem
The commit validator rejects `deps:` as a conventional commit type, causing
post-merge CI failures on grm and sso-bridge repos where automated dependency
bump PRs use `deps: bump devx...` as the commit message.
## Approach
REQ-1: Add `deps` to `CONVENTIONAL_RE` in `src/devx/config.py`
REQ-2: Update the allowed types list in the error message in
`src/devx/ci/validate_commit_msg.py`
REQ-3: Add test coverage for `deps:` type in `tests/unit/test_config.py`
and `tests/unit/test_validate_commit_msg.py`
## Test Plan
- `make pytest-cov` passes with 100% coverage
- `make lint-all` passes
## Deploy Plan
- Merge to master → post-merge auto-publishes new devx version
- grm and sso-bridge bump devx version to pick up the fix
## Rollback Plan
- Revert the merge commit
## Acceptance Criteria
- [x] REQ-1: Add `deps` to `CONVENTIONAL_RE` in `src/devx/config.py`
- [x] REQ-2: Update the allowed types list in the error message in
`src/devx/ci/validate_commit_msg.py`
- [x] REQ-3: Add test coverage for `deps:` type in `tests/unit/test_config.py`
and `tests/unit/test_validate_commit_msg.py`
+27
View File
@@ -0,0 +1,27 @@
# DEVX-166: Exclude docs/plans/* from PR size check
## Problem
Planning docs in `docs/plans/` are legitimately large (700+ lines) but
fail the PR size check (max 500 lines). This blocks PRs that only add
planning documents.
## Approach
REQ-1: Add `docs/plans/*` to `DEFAULT_EXCLUDED_PATTERNS` in
`src/devx/ci/check_pr_size.py`
REQ-2: Add test coverage for the new exclusion pattern
## Test Plan
- `make pytest-cov` passes with 100% coverage
- `make lint-all` passes
## Deploy Plan
- Merge to master → post-merge auto-publishes new devx version
- Infra PR #1179 picks up the fix once devx is bumped
## Rollback Plan
- Revert the merge commit
## Acceptance Criteria
- [x] REQ-1: Add `docs/plans/*` to `DEFAULT_EXCLUDED_PATTERNS` in
`src/devx/ci/check_pr_size.py`
- [x] REQ-2: Add test coverage for the new exclusion pattern
+64
View File
@@ -0,0 +1,64 @@
# DEVX-167: Add dependency-graph, deployment-coordination, and skill-creation skills
## Problem
Agents working across the oblachno ecosystem lack shared, persistent
context for three recurring pain points:
1. **Cross-repo dependency ordering** — agents frequently merge
downstream PRs before the upstream publish job completes, or forget
to bump infra. There is no single reference for which repo produces
what and in what order changes must propagate.
2. **devx release coordination** — devx is the base package pinned by
grm, sso-bridge, and infra. Agents repeatedly merge devx PRs and
immediately merge downstream bumps without waiting for the PyPI
publish job, or bump only one consumer when a change affects all
three.
3. **Skill quality drift** — skills are created ad hoc with inconsistent
structure, vague advice, and no automated validation reference. New
skills miss required sections, reference nonexistent make targets,
and drift across repos.
## Approach
Add three SKILL.md files under `.devin/skills/`:
REQ-1: `dependency-graph` — shared skill mapping the oblachno ecosystem
(repos, what each produces, consumers, release triggers, correct
cross-repo change order, state verification checklist)
REQ-2: `deployment-coordination` — devx-specific skill covering the
devx release flow, downstream consumers, manual bump procedure, and
common mistakes when coordinating a devx change
REQ-3: `skill-creation` — shared skill defining skill structure,
quality standards, scope rules, automated validation reference, and a
creation 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/DEVX-167.md` (new)
## Test Plan
- Verify all three SKILL.md files follow the required structure (H1
title, When to Invoke, Prerequisites sections)
- Verify referenced make targets and file paths exist
- Run `make pytest-cov` — skill validation tests must pass
## Deploy Plan
- Merge to master; skills are consumed by agents immediately on next
invocation — no build or deploy step required
## Rollback Plan
- Revert the merge commit; remove the three skill directories
## Acceptance Criteria
- [x] REQ-1: dependency-graph skill exists with ecosystem map, repo
table, dependency chain, cross-repo change order, and state
verification checklist
- [x] REQ-2: deployment-coordination skill exists with devx release
flow, downstream consumer table, coordination steps, and common
mistakes
- [x] REQ-3: skill-creation skill exists with structure template,
quality standards, scope rules, validation reference, and
creation checklist
+2 -2
View File
@@ -48,12 +48,12 @@ Add devx to your `pyproject.toml`:
```toml
[project]
dependencies = [
"devx>=0.51.7",
"devx>=0.51.9",
]
[project.optional-dependencies]
dev = [
"devx>=0.51.7",
"devx>=0.51.9",
]
```
+1 -1
View File
@@ -6,4 +6,4 @@ create_dependency_pr, auto_merge, release, publish), developer tooling
molecule testing helpers for Ansible projects.
"""
__version__ = "0.51.7"
__version__ = "0.51.9"
+1
View File
@@ -36,6 +36,7 @@ DEFAULT_EXCLUDED_PATTERNS = [
"CHANGELOG.md",
"README.md",
"docs/index.md",
"docs/plans/*",
"*.svg",
"uv.lock",
"poetry.lock",
+1 -1
View File
@@ -118,7 +118,7 @@ def main(commit_msg_file: str | None, branch: str | None, from_git: bool) -> Non
" Expected: <type>: <description>\n"
" Got: {subject}\n"
" Allowed types: feat, fix, chore, docs, style, refactor,\n"
" perf, test, ci, build, revert, BREAKING CHANGE",
" perf, test, ci, build, deps, revert, BREAKING CHANGE",
subject=subject,
)
)
+1 -1
View File
@@ -93,4 +93,4 @@ RETRY_BACKOFF_BASE = 2 # seconds: 2, 4, 8
RETRY_STATUS_CODES = {429, 500, 502, 503, 504}
# Conventional commit regex — used by validate_commit_msg.py
CONVENTIONAL_RE = re.compile(r"^(feat|fix|chore|docs|style|refactor|perf|test|ci|build|revert)(\(.+\))?: .+")
CONVENTIONAL_RE = re.compile(r"^(feat|fix|chore|docs|style|refactor|perf|test|ci|build|revert|deps)(\(.+\))?: .+")
+7 -7
View File
@@ -2999,13 +2999,13 @@
"PR number for label check": "PR number for label check",
"Repo (owner/name) for label check": "Repo (owner/name) for label check"
},
"Oops! Commit message must follow conventional commit format.\n Expected: <type>: <description>\n Got: {subject}\n Allowed types: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE": {
"bg": "Опа! Съобщението за commit трябва да следва конвенционален формат.\n Очаква се: <type>: <description>\n Получено: {subject}\n Разрешени типове: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"de": "Ups! Commit-Nachricht muss dem konventionellen Commit-Format folgen.\n Erwartet: <type>: <description>\n Erhalten: {subject}\n Erlaubte Typen: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"en": "Oops! Commit message must follow conventional commit format.\n Expected: <type>: <description>\n Got: {subject}\n Allowed types: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"pl": "Ups! Wiadomość commit musi być w formacie conventional commit.\n Oczekiwano: <typ>: <opis>\n Otrzymano: {subject}\n Dozwolone typy: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"ru": "Ой! Сообщение коммита должно соответствовать формату conventional commit.\n Ожидается: <type>: <description>\n Получено: {subject}\n Допустимые типы: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"zh": "哎呀!提交消息必须遵循 conventional commit 格式。\n 预期格式: <type>: <description>\n 实际: {subject}\n 允许的类型: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, revert, BREAKING CHANGE",
"Oops! Commit message must follow conventional commit format.\n Expected: <type>: <description>\n Got: {subject}\n Allowed types: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE": {
"bg": "Опа! Съобщението за commit трябва да следва конвенционален формат.\n Очаква се: <type>: <description>\n Получено: {subject}\n Разрешени типове: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"de": "Ups! Commit-Nachricht muss dem konventionellen Commit-Format folgen.\n Erwartet: <type>: <description>\n Erhalten: {subject}\n Erlaubte Typen: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"en": "Oops! Commit message must follow conventional commit format.\n Expected: <type>: <description>\n Got: {subject}\n Allowed types: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"pl": "Ups! Wiadomość commit musi być w formacie conventional commit.\n Oczekiwano: <typ>: <opis>\n Otrzymano: {subject}\n Dozwolone typy: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"ru": "Ой! Сообщение коммита должно соответствовать формату conventional commit.\n Ожидается: <type>: <description>\n Получено: {subject}\n Допустимые типы: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"zh": "哎呀!提交消息必须遵循 conventional commit 格式。\n 预期格式: <type>: <description>\n 实际: {subject}\n 允许的类型: feat, fix, chore, docs, style, refactor,\n perf, test, ci, build, deps, revert, BREAKING CHANGE",
"PR number for label check": "PR number for label check",
"Repo (owner/name) for label check": "Repo (owner/name) for label check"
},
+6
View File
@@ -26,6 +26,12 @@ class TestIsExcluded:
def test_excludes_readme(self) -> None:
assert is_excluded("README.md", ["README.md"])
def test_excludes_plans_glob(self) -> None:
assert is_excluded("docs/plans/sso-bridge-full-extraction.md", ["docs/plans/*"])
def test_does_not_exclude_specs(self) -> None:
assert not is_excluded("docs/specs/DEVX-165.md", ["docs/plans/*"])
class TestCheckSize:
def test_under_limits_passes(self) -> None:
+1
View File
@@ -38,6 +38,7 @@ class TestConfigConstants:
def test_conventional_re(self) -> None:
assert CONVENTIONAL_RE.match("feat: add feature")
assert CONVENTIONAL_RE.match("fix(scope): bug fix")
assert CONVENTIONAL_RE.match("deps: bump devx from v0.50.2 to v0.51.0")
assert not CONVENTIONAL_RE.match("random message")
assert not CONVENTIONAL_RE.match("feat:")
assert not CONVENTIONAL_RE.match("BREAKING CHANGE: something")
+1
View File
@@ -30,6 +30,7 @@ class TestHelpers:
assert CONVENTIONAL_RE.match("test: add tests")
assert CONVENTIONAL_RE.match("ci: update workflow")
assert CONVENTIONAL_RE.match("build: update deps")
assert CONVENTIONAL_RE.match("deps: bump devx from v0.50.2 to v0.51.0")
assert CONVENTIONAL_RE.match("revert: undo change")
def test_conventional_re_allows_scope(self) -> None: