Skip to content

fix(context): accept RepositoryEntry object form in .project/ reader (closes #385) - #386

Merged
mlieberman85 merged 1 commit into
darnitdevorg:mainfrom
mlieberman85:033-cncf-drift-repository-entry
Aug 23, 2026
Merged

fix(context): accept RepositoryEntry object form in .project/ reader (closes #385)#386
mlieberman85 merged 1 commit into
darnitdevorg:mainfrom
mlieberman85:033-cncf-drift-repository-entry

Conversation

@mlieberman85

Copy link
Copy Markdown
Contributor

Summary

CNCF .project/ types.go changed Project.Repositories from []string to []RepositoryEntry in cncf/automation@bd7fec94 (2026-08-21, "feat: add RepositoryEntry type with tags and primary fields"). Each repositories[*] item may now be either a plain string OR an object of shape {url, tags?, primary?}. Feature 030's nightly canary (test_upstream_spec_unchanged) correctly fired on the drift. Without a reader reconcile, a .project/project.yaml written in the new object form degrades silently -- the pre-fix reader stores each dict item verbatim so no downstream consumer can extract the URL.

Mirrors feature 030's _coerce_scalar_or_list collapse pattern:

  • New helper _coerce_repository_entry(value) -> str: returns the input for a scalar string, value['url'] for a mapping, and \"\" for anything else.
  • Reader maps every item through the coercer and filters out empty results so a malformed entry (missing url) does not silently expand into a stringified representation of the mapping.
  • ProjectConfig.repositories stays list[str]. Downstream consumers (dot_project_merger.py, dot_project_mapper.py) are unchanged.
  • tags and primary metadata is dropped at parse time. If a future control needs the metadata, we can promote the field to a structured RepositoryEntry dataclass in a later reconcile without a further reshape.

Per feature 030 Q3: bumps DOT_PROJECT_SPEC_VERSION 1.2.0 -> 1.3.0 in lock-step with the tracked-hash file (860df23... -> afa3d179...). Module docstring's reconciliation history is extended.

Closes #385.

Side note captured in #385

tests/darnit/parity/tier1/conftest.py:32's pytest_collection_modifyitems applies the integration marker to every collected item (not scoped to tier1/), which is why unrelated PRs (e.g., #384) got gated on this upstream canary. Worth constraining that hook to items under its own conftest scope; out of scope for this PR but tracked.

Test plan

  • pytest tests/darnit/context/test_dot_project.py::TestRepositoryEntryReshape -- 6 new tests pass (scalar-only, object-only, mixed, malformed-object dropped, empty-list, spec-version bump).
  • pytest tests/darnit/context/test_dot_project_upstream.py -- all 5 pass on the new hash (canary now green).
  • Full workspace pytest tests/ -- 2748 pass, 17 skip, 0 fail. No deselect needed.
  • ruff check on touched files -- clean.
  • python scripts/validate_sync.py --verbose -- PASS.

Backward compatibility: additive. Existing .project/project.yaml files with plain-string repositories items still parse to the same list[str] shape. New object-form files now also parse correctly. No downstream consumer's contract changes.

…loses darnitdevorg#385)

CNCF `.project/` types.go changed `Project.Repositories` from
`[]string` to `[]RepositoryEntry` in cncf/automation@bd7fec94
(2026-08-21, "feat: add RepositoryEntry type with tags and primary
fields"). Each `repositories[*]` item may now be either a plain string
OR an object of shape `{url, tags?, primary?}`. Feature 030's
nightly canary correctly fired on the drift; without a reader
reconcile, a `.project/project.yaml` written in the new object form
degrades silently (the pre-fix reader treats each dict item as a
whole-value string that no downstream consumer knows how to use).

Mirroring feature 030's collapse-to-scalar pattern for the
`StringOrSlice` reshape, add `_coerce_repository_entry(value) -> str`
that returns the input for a scalar string, `value['url']` for a
mapping, and `""` for anything else. Reader now maps every item
through the coercer and filters out empty results so a malformed
entry (missing `url`) does not silently expand into a stringified
representation of the mapping. `ProjectConfig.repositories` stays
`list[str]`; downstream consumers (`dot_project_merger.py`,
`dot_project_mapper.py`) are unchanged. `tags` and `primary`
metadata is dropped at parse time. If a future control needs the
metadata, we can promote the field to a structured RepositoryEntry
dataclass in a later reconcile without a further reshape.

Per feature 030 Q3: bump DOT_PROJECT_SPEC_VERSION 1.2.0 -> 1.3.0
in lock-step with the tracked-hash file (860df23... ->
afa3d179...). Module docstring's reconciliation history is
extended.

Tests:
- `TestRepositoryEntryReshape` (6 tests): scalar-only,
  object-only, mixed, malformed-object dropped, empty list,
  spec-version bump.
- `test_upstream_spec_unchanged` passes on the new hash.
- Full workspace: 2748 pass, 17 skip, 0 fail.

Side note recorded in darnitdevorg#385: `tests/darnit/parity/tier1/conftest.py`'s
`pytest_collection_modifyitems` applies `integration` to every
collected item (not scoped to tier1/), which is why unrelated PRs
(darnitdevorg#384) are gated on the upstream canary. Worth constraining the
hook to items under its own conftest scope; out of scope here.
@mlieberman85
mlieberman85 merged commit 409e026 into darnitdevorg:main Aug 23, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant