Skip to content

Add areas.yaml validation to changelog checker (file integrity + entry prefix mapping)#4560

Closed
Copilot wants to merge 3 commits into
mainfrom
copilot/add-areas-yaml-validation
Closed

Add areas.yaml validation to changelog checker (file integrity + entry prefix mapping)#4560
Copilot wants to merge 3 commits into
mainfrom
copilot/add-areas-yaml-validation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 18, 2026

This change adds the missing changelogs/areas.yaml validation path for per-entry changelogs, while preserving back-compat for branches that do not have areas.yaml. It validates both the registry itself and entry filename area prefixes against that registry.

  • Checker behavior: validate areas.yaml content once per status run

    • Added AChangelogChangesChecker.check_areas_file() to enforce:
      • duplicate title detection (one error per duplicated title)
      • allowed charset for area keys and titles: [a-z0-9_\\-/]+
    • Errors are emitted in changelogs/areas.yaml context and include offending keys/titles.
  • Checker behavior: validate entry filename area prefix

    • check_entry_filename() now checks <area>__<slug>.rst area membership in areas.yaml when areas are configured.
    • Back-compat preserved: when areas.yaml is absent (areas map is empty), behavior remains the previous non-empty-area check only.
  • Wiring in base utils for optional areas registry

    • Added CHANGELOG_AREAS_PATH and ChangelogAreasDict.
    • Added AChangelogs.areas_path and cached AChangelogs.areas:
      • file missing => empty dict (no checker enforcement)
      • file present but parse/type invalid => ChangelogError
    • AChangelogCheck.changes_checker now receives both sections and areas.
  • Status aggregation integration

    • AChangelogStatus.errors now includes check_areas_file() output.
    • Areas-file checks run only for current changelog and only when areas are configured.
  • Interfaces/tests updated for new contract

    • Updated changelog interfaces for areas and checker areas-file validation hook.
    • Expanded unit coverage in:
      • py/envoy.base.utils/tests/test_abstract_project_changelogs.py
      • py/envoy.code.check/tests/test_abstract_changelog.py
      • py/envoy.code.check/tests/test_checker.py
# New checker behavior (when areas are configured)
area, slug = path.stem.split("__", 1)
if self.areas and area not in self.areas:
    return (
        f"{path}: Invalid area '{area}'. "
        "Valid areas come from changelogs/areas.yaml"
    )
Original prompt

Background

As part of the per-entry changelog migration (see envoy#45093 and the plan in toolshed#4499), envoy is introducing a new file changelogs/areas.yaml which is the canonical registry of "areas" (the filename prefix in per-entry changelog files like changelogs/current/<section>/<area>__<slug>.rst).

areas.yaml has the same shape as the existing changelogs/sections.yaml:

access_log:
  title: access_log
attributes:
  title: attributes
build:
  title: build
# ...

Right now nothing reads or validates this file. The parser in py/envoy.base.utils/envoy/base/utils/abstract/project/changelog.py::AChangelog.get_data_from_entries derives area from the filename stem and stuffs it straight into the entry dict, and AChangelogChangesChecker.check_entry_filename in py/envoy.code.check/envoy/code/check/abstract/changelog.py only checks that the area part is non-empty.

We want to add basic validation in the existing changelog checker (envoy.code.check) — keep the scope tight: just validate the file and the entry-prefix↔area mapping.

Scope (this PR)

Add validation to AChangelogChangesChecker in py/envoy.code.check/envoy/code/check/abstract/changelog.py. The validation should only fire when changelogs/areas.yaml is present (back-compat: release branches that don't have this file must not start failing). Detection: file exists, OR equivalently — since areas.yaml only makes sense alongside the per-entry layout — gate on the _entries_layout indicator already exposed on AChangelogs. Prefer file-present detection (areas_path.exists()) so that the check is independent of whether any entries have actually been written yet.

Three checks to add

  1. areas.yaml content — no duplicate titles

    • Each top-level key in areas.yaml has a title: field.
    • Two area keys MUST NOT share the same title.
    • On failure emit one error per duplicated title, e.g.:
      changelogs/areas.yaml: Duplicate title 'foo' used by areas: bar, baz
  2. areas.yaml content — valid title characters

    • Each title must match the regex ^[a-z0-9_\-/]+$ (lowercase ascii letters, digits, underscore, hyphen, forward slash). Anchored, non-empty.
    • On failure: changelogs/areas.yaml: Invalid title '<title>' for area '<key>' (must match [a-z0-9_\-/]+).
    • Apply the same character rule to the area key as well (the dict key, which is what filenames must match). One error per offending key.
  3. All entry filename area-prefixes must map to an area key in areas.yaml

    • For each changelogs/current/<section>/<area>__<slug>.rst file, after the existing non-empty-area check, look up area in the loaded areas.yaml mapping.
    • If not found, emit: <path>: Invalid area '<area>'. Valid areas come from changelogs/areas.yaml
    • This must integrate with the existing check_entry_filename flow (return error string, accumulated in check_entry_files).

Wiring

  • Add CHANGELOG_AREAS_PATH = "changelogs/areas.yaml" constant alongside the existing CHANGELOG_SECTIONS_PATH in py/envoy.base.utils/envoy/base/utils/abstract/project/changelog.py. Also add a ChangelogAreasDict typing entry parallel to ChangelogSectionsDict in py/envoy.base.utils/envoy/base/utils/typing.py (find where ChangelogSectionsDict lives — same shape: Dict[str, Dict[str, str]] with a title key).
  • Add an areas cached property and areas_path property on AChangelogs (parallel to sections / sections_path). Loading semantics:
    • If areas_path does NOT exist → return an empty dict (or None; pick whichever makes the downstream check cleanest — empty dict is fine and means "no validation registered"). Do NOT raise.
    • If it exists but fails to parse → raise ChangelogError (mirror the existing sections behaviour for ReaderError).
  • Pass areas into AChangelogChangesChecker.__init__ alongside sections (update AChangelogCheck.changes_checker cached_property in the same file to pass it through).
  • In AChangelogChangesChecker, store self.areas. Add the three checks above. The two areas.yaml content checks should run once per check session (not per-entry); add a method like check_areas_file(self) -> tuple[str, ...] that returns the title-uniqueness + title-charset + key-charset errors, and hook it into the existing entry-files error aggregation in AChangelogStatus.errors (it should only run when self.areas is non-empty, and probably only for the current version — same gating as check_entry_files).
  • Update check_entry_filename to look up area in self.areas when self.areas is truthy. When self.areas is empty (file absent), preserve current behaviour (just non-empty check).

Tests

Add tests in py/envoy.code.check/tests/test_abstract_changelog.py and py/envoy.base.utils/tests/test_abstract_project_changelogs.py covering:

  • ...

This pull request was created from Copilot chat.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 18, 2026

Deploy Preview for nifty-bassi-e26446 ready!

Name Link
🔨 Latest commit 7cdae79
🔍 Latest deploy log https://app.netlify.com/projects/nifty-bassi-e26446/deploys/6a0ad7a351300300084df132
😎 Deploy Preview https://deploy-preview-4560--nifty-bassi-e26446.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI changed the title [WIP] Add validation for areas.yaml in changelog migration Add areas.yaml validation to changelog checker (file integrity + entry prefix mapping) May 18, 2026
Copilot AI requested a review from phlax May 18, 2026 09:12
Copilot finished work on behalf of phlax May 18, 2026 09:12
@phlax phlax closed this May 18, 2026
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.

2 participants