Conversation
…hy (#244) Document the governing motivation behind the branch, release, and versioning rules: pull-vs-push distribution grounds release restraint; dual-target branch sync enables the signed/linear/no-back-merge model; the 2-digit version carries human meaning while NBGV guarantees monotonic builds; contracts fix outcomes not implementations and favor reuse.
pyright strict on first-party code is the required baseline; mypy is allowed (required for HA platinum, useful for pydantic). Records default vs HA Python profiles; fixes the CODESTYLE-vs-AGENTS/catalog contradiction.
Both operational. Apply the registry corrections the audits found (aiopurpleair releaseTrigger -> publish-on-merge; drop stale HA cspell driftNote). Curated scientific symbols in the HA report preserved per maintainer instruction.
#247) Resolves the classification backlog (22 cataloged, 0 backlog). Adds the eda type and releaseTrigger none per maintainer decisions; non-conformant branch states flagged for correction.
…ewhere) (#248) One env.PLATFORMS computes the platform list; multi-arch only when publishing the main image, amd64 otherwise; QEMU gated on contains(env.PLATFORMS, 'arm64'). WORKFLOW.md Docker guarantees updated.
#249) Hub publisher -> dispatch-only single-branch; WORKFLOW.md contract rewritten to the symmetric single-branch model (matrix and IGNORE_GITHUB_REF retired).
Workflow YAML is declared LF in .editorconfig (Dependabot/Actions write LF), hub workflows converted, editorconfig-checker (EOL-only) added to the lint gate. git leaves endings alone; nothing renormalized. AGENTS.md updated.
…251) Three line-ending governance completions: - **AGENTS.md** — encode that non-executed pattern files stay CRLF: `.dockerignore`/`.gitignore` parsers strip a trailing CR, so only an interpreted Dockerfile is LF. (Corrects a misclassification from the fleet rollout where `.dockerignore` was wrongly LF-pinned.) - **`.editorconfig`** — pin `catalog/snippets/workflows/*.{yml,yaml}` to LF and convert the 11 snippets, so a copied snippet lands compliant with the workflow-YAML-LF rule. - **spec `recurring.eol`** — add the workflow-YAML LF pin to the assertion (#250 left it listing only the older pins). EOL-preserving; `git diff --ignore-cr-at-eol` shows only these three content changes plus the snippet conversions. ec, jq, validate.py, markdownlint, cspell all clean locally. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Promotes the accumulated governance and fleet-contract updates from develop to main, spanning the workflow/release contract, typing policy, audit report additions, registry/spec expansion, and line-ending enforcement.
Changes:
- Update the release/workflow contract to a symmetric single-branch publish model, and align repo workflows accordingly.
- Expand spec + registry to cover new repo classifications (
eda,releaseTrigger: none) and incorporate new audit reports. - Tighten governance around typing (pyright strict baseline; mypy permitted/required for HA) and add CI enforcement for
.editorconfig-defined line endings (workflow YAML pinned to LF).
Reviewed changes
Copilot reviewed 14 out of 25 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| WORKFLOW.md | Updates the CI/CD contract to the single-branch publish model and related guarantees. |
| spec/project-types.json | Extends project-type checks (HA + EDA) and updates workflow anchors/typing expectations. |
| reports/homeassistant-purpleair/audit.md | Adds an audit report for a Home Assistant integration repo. |
| reports/aiopurpleair/audit.md | Adds an audit report for a Python/PyPI repo. |
| registry/repos.schema.json | Extends schema to allow releaseTrigger: none. |
| registry/repos.json | Catalogs backlog repos; updates release triggers and drift notes. |
| cspell.json | Adds new allowed spelling (pydantic). |
| CODESTYLE.md | Replaces mypy ban with a strong-typing policy (pyright strict baseline; mypy allowed/required for HA). |
| catalog/snippets/workflows/run-periodic-codegen-pull-request.yml | Normalizes snippet formatting/EOL to match workflow YAML policy. |
| catalog/snippets/workflows/run-codegen-pull-request-task.yml | Normalizes snippet formatting/EOL to match workflow YAML policy. |
| catalog/snippets/workflows/publish-docker-readme-task.yml | Normalizes snippet formatting/EOL to match workflow YAML policy. |
| catalog/snippets/workflows/get-version-task.yml | Normalizes snippet formatting/EOL; retains NBGV invocation snippet. |
| catalog/snippets/workflows/check-upstream-version-task.yml | Normalizes snippet formatting/EOL; retains upstream-version tracker skeleton. |
| catalog/snippets/workflows/build-release-task.yml | Normalizes snippet formatting/EOL; retains orchestrator release-task shape. |
| catalog/snippets/workflows/build-pypilibrary-task.yml | Normalizes snippet formatting/EOL; retains PyPI build-only reusable workflow. |
| catalog/snippets/workflows/build-nugetlibrary-task.yml | Normalizes snippet formatting/EOL; retains NuGet build/publish reusable workflow. |
| catalog/snippets/workflows/build-executable-task.yml | Normalizes snippet formatting/EOL; retains executable build reusable workflow. |
| catalog/snippets/workflows/build-docker-task.yml | Implements branch-conditional Docker platforms (multi-arch main publish, amd64 otherwise). |
| catalog/snippets/workflows/build-datebadge-task.yml | Normalizes snippet formatting/EOL. |
| AGENTS.md | Adds Foundational Principles and extends line-ending governance for workflow YAML/pattern files. |
| .github/workflows/test-pull-request.yml | Adds editorconfig-checker CI step for line-ending validation. |
| .github/workflows/publish-release.yml | Updates publisher to dispatch-only single-branch publish for this source-only repo. |
| .github/workflows/merge-bot-pull-request.yml | Normalizes formatting/EOL; retains merge-bot behavior. |
| .editorconfig-checker.json | Configures editorconfig-checker to enforce EOL-only (disables other checks). |
| .editorconfig | Pins workflow YAML (and snippet workflow YAML) to LF. |
Comment on lines
+66
to
+73
| - name: Publish to NuGet.org step | ||
| if: ${{ inputs.push }} | ||
| run: | | ||
| set -euo pipefail | ||
| dotnet nuget push ${{ runner.temp }}/publish/*.nupkg \ | ||
| --source https://api.nuget.org/v3/index.json \ | ||
| --api-key ${{ secrets.NUGET_API_KEY }} \ | ||
| --skip-duplicate |
| The specific rules in this file implement a few governing principles. Read these first: they are the reason the branching, release, and versioning rules are shaped the way they are, and every rule below serves one of them. | ||
| - **Distribution respects the user: pull by default, push only where the channel forces it.** Docker images, GitHub Releases, and NuGet/PyPI packages are **pull** - the user decides when to consume them. A few channels are **push**: HACS surfaces a new release to every installed user as a pending update they did not go looking for, and a consumer that vendors from `main` picks up its current state. Because a release can reach users who did not ask for it, releasing is a deliberate act that marks a real functional change - never mechanical churn. This is the root of the two-phase default - merges do not publish, with `PUBLISH_ON_MERGE` as an explicit opt-in override - together with the no-op republish guarantee and maintainer-gated version bumps: a needless release spends the user's attention and, on a push channel, acts on their machine. |
| | branch-model | drift | pass | drift | both branches protected, live rulesets `enforcement: active`; develop allows only `squash` + `required_linear_history`, main allows only `merge` (`ruleset-{develop,main}.json`), required check `context: "Check pull request workflow status job"` matches the aggregator `name:` (`test-pull-request.yml:34`). Normalized diff: committed rulesets omit `required_reviewers: []` (live carries it) and top-level `bypass_actors` (live: `RepositoryRole 5 always` on both). Off-baseline filenames; extra live "Tag Rules" ruleset unrepresented - see Drift | | ||
| | repo-setup | pass | pass | pass | actions + dependabot stores both hold `CODEGEN_APP_CLIENT_ID`/`CODEGEN_APP_PRIVATE_KEY` (baseline merge-bot App, `merge-bot-pull-request.yml:45-46`) and `CODECOV_TOKEN` (codecov mechanism, used at `test-release-task.yml:204-207`); no forbidden `NUGET_API_KEY`/`PYPI_API_TOKEN`/`CODEGEN_APP_ID`; no publish secrets (github-release needs none). `CODECOV_TOKEN` in the dependabot store is beyond the mechanism's `stores: ["actions"]` but harmless | | ||
| | linter-parity | pass | pass | pass | one config each drives editor+CLI+CI, and CI runs each: markdownlint via `.markdownlint-cli2.jsonc` (`test-release-task.yml:108-110`), cspell via `cspell.json` `language: en-US` (`:113-119`), ruff via `.ruff.toml` (`:49-53`), pyright via `pyrightconfig.json` (`:91-95`), actionlint (`:121-122`), shellcheck (`:125-126`), plus mypy `--strict` (`:71-73`) | | ||
| | recurring-violations | drift | pass | drift | comments concise; spelling `en-US` (`cspell.json:3`); **EOL clean** - global `[*] end_of_line = crlf` default present (`.editorconfig:13`), LF pins for `*.sh`/`scripts/*` (`:29-33`) mirrored in `.gitattributes:12-13`, byte scan of all tracked files shows 68 CRLF / 6 correctly-LF (`scripts/*`, `repo-config/configure.sh`) / **0 mixed**. **Letter miss (charset):** em-dash (U+2014) and arrow (U+2192) pervade Python source comments/docstrings (`config_flow.py:120,136,...`, `coordinator.py:140`, `sensor.py`, `tests/*`) where ASCII equivalents (` - `, `->`) apply; docs are ASCII-clean; scientific symbols (µ, ³, ², §, ≤, ≥, ·, −) are within the carve-out. See Drift | |
| 1. **`publish-release.yml` blanket-deletes the whole run artifact set - the D5.5 anti-pattern.** `cleanup-artifacts` runs `gh api repos/.../actions/runs/${{ github.run_id }}/artifacts --jq '.artifacts[].id'` and DELETEs every id (`publish-release.yml:114-122`). WORKFLOW.md D5.5 states cleanup MUST NOT enumerate and delete the run's whole artifact set, precisely because it also destroys diagnostic/log artifacts and auto-emitted build-records. Harmless today (the pure-Python pipeline emits no build-records, and `purpleair-zip` already sets `retention-days: 1`, `build-release-task.yml:107`), but it is a letter violation of a MUST-NOT and would be destructive if a Docker/other target is added. Fix: delete `purpleair-zip` by exact name at its consumer (the release job) and rely on the retention backstop, dropping the blanket sweep. | ||
| 2. **Python ruff/pyright config off-canonical.** ruff lives in `.ruff.toml` and pyright in `pyrightconfig.json`; `pyproject.toml` holds only `[tool.pytest.ini_options]` (`pyproject.toml:1`) and `[tool.pylint]` (`:32`), no `[tool.ruff]`/`[tool.pyright]`. `python.config.placement` letter miss. Intent satisfied (both linters present and CI-run). This is an HA convention (mirrors `home-assistant/core`); see Spec Updates for the profile that would bless it. (driftNote (a) confirmed.) | ||
| 3. **Em-dash / arrow in Python source comments and docstrings.** U+2014 and U+2192 appear throughout `config_flow.py` (`:120,136,150,187,207,441,459,497,705`), `coordinator.py:140`, `diagnostics.py:43`, `sensor.py`, and `tests/components/purpleair/*` where ASCII equivalents (` - `, `->`) apply. Governance docs (README/HISTORY/AGENTS/CODESTYLE/WORKFLOW) are ASCII-clean, and scientific symbols (µ, ³, ², §, ≤, ≥, ·, −) are the allowed carve-out. A `recurring.charset` letter miss confined to code comments. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two-phase promotion of the accumulated governance work on
developtomain. Carries #244-#251:edatype andreleaseTrigger: noneAll commits were reviewed and CI-green on their individual develop PRs.