Skip to content

ci: fix the lint findings that stop CI before any test runs - #122

Open
nk0952 wants to merge 1 commit into
embeddedos-org:masterfrom
nk0952:ci-unblock-lint-gate
Open

ci: fix the lint findings that stop CI before any test runs#122
nk0952 wants to merge 1 commit into
embeddedos-org:masterfrom
nk0952:ci-unblock-lint-gate

Conversation

@nk0952

@nk0952 nk0952 commented Sep 10, 2026

Copy link
Copy Markdown

Summary

CI on master is red, and it fails at the Lint (ruff) step in all nine matrix legs. Everything after that step - yamllint, mypy, Run test suite - is skipped. So the red X isn't a failing test being reported; CI hasn't got as far as running one.

That has been hiding a real regression. python -m pytest tests/ fails 9 tests in tests/unit/test_index_sync.py on master right now, and CI has never mentioned it.

This clears the lint and type findings sitting between the workflow and its own test step.

Type of Change

  • ci - CI/CD pipeline changes

Changes

ruff check . reports four findings on master, all in test files:

  • tests/ebuild/test_build_dir_resolution.py:31 - F811, import shutil appears twice
  • tests/unit/test_ci_gate.py:214,215 - E402, two imports sitting below module-level code
  • tests/ebuild/test_package_recipe.py:117 - W292, no newline at end of file

Fixing those gets the job as far as Type check (mypy), which then fails on ebuild/plugins/__init__.py:46:

error: Argument 2 to "get" of "Deprecated" has incompatible type "list[Never]"; expected "EntryPoints"  [arg-type]
note: Error code "arg-type" not covered by "type: ignore[attr-defined]" comment

The # type: ignore there names the wrong error code, so it was never silencing anything. I spelled out the pre-3.10 entry_points() mapping shape with cast rather than widening the ignore. That branch only runs on Python 3.8/3.9, which the matrix doesn't cover, so behaviour is unchanged either way.

Testing

Python 3.11.15, pip install -e ".[dev]", ruff 0.16.6. I ran each CI step by hand with the same flags ci.yml uses:

step master this branch + #119
ruff check . 4 errors pass pass
yamllint . pass pass pass
mypy ... 2 errors 1 error pass (107 files)
pytest tests/ 9 failed, 669 passed 9 failed, 669 passed 678 passed, 0 failed
  • All existing tests pass - 669 before, 669 after, no expectations changed
  • Manual testing performed - each workflow step run individually

Nothing outside the cast touches a shipped code path.

Related Issues

The 9 remaining failures are test_index_sync.py, which open PR #119 fixes. I've left those alone rather than duplicate that work - landing both gives a green gate, which is the last column above.

Additional Notes

Two things I noticed but didn't fold in, since they look like maintainer calls:

  1. ci.yml installs its linters unpinned. A new ruff release can turn the gate red with no change to this repo, which may well be how this arrived. Pinning them, or moving them into the dev extra in pyproject.toml, would make the gate reproducible.
  2. .coveragerc sets fail_under = 100 against a suite measuring ~24%, and ci.yml works around it with --cov-fail-under=0 plus a comment calling it a maintainer decision. Probably worth settling in one place.

Every leg of the CI matrix on master fails at the "Lint (ruff)" step
(run #455, all nine legs), so yamllint, mypy and the test suite never
run. The red X on master is not a failing test being reported -- CI has
not got as far as running one in a long time.

That is not academic. `python -m pytest tests/` fails 9 tests in
tests/unit/test_index_sync.py on master today, and CI has never said so.

ruff reports four findings, all in test files:

  tests/ebuild/test_build_dir_resolution.py:31  F811  import shutil twice
  tests/unit/test_ci_gate.py:214,215            E402  imports below code
  tests/ebuild/test_package_recipe.py:117       W292  no newline at EOF

With those fixed the job gets as far as mypy, which fails on
ebuild/plugins/__init__.py:46. The `# type: ignore[attr-defined]` there
names the wrong error code, so it was never silencing the arg-type error
the same line raises. I spelled out the pre-3.10 entry_points() mapping
shape with cast instead of widening the ignore. That branch only runs on
Python 3.8/3.9, which the matrix does not cover, so runtime behaviour is
unchanged either way.

The 9 index-sync failures that remain are PR embeddedos-org#119's, and I have not
duplicated it. With both applied the suite is 678 passed, 0 failed.

Checked on Python 3.11.15 with ruff 0.16.6, running each CI step by
hand: ruff and yamllint clean, mypy down from 2 errors to 1, pytest
unchanged at 669 passed with no test expectations touched.

Signed-off-by: Nitesh Kumar <nk0952@gmail.com>
Kartikey1306 added a commit to Kartikey1306/ebuild that referenced this pull request Sep 11, 2026
…/3.11, yamllint on Windows

Both surfaced on this branch's first CI run, once ruff let the job get past
its first step.

- ebuild/plugins/__init__.py: on Python 3.10 and 3.11 the stubs type
  entry_points() as the deprecated mapping, and its .get() wants an
  EntryPoints default, so mypy fails with arg-type. The line carried a
  '# type: ignore[attr-defined]' -- the wrong error code, so it suppressed
  nothing. Spelled out with a cast, byte-identical to embeddedos-org#122's hunk (54605f0).

- .yamllint.yml: the Windows runners check out with core.autocrlf=true, so
  every YAML file arrives as CRLF and the default new-lines: unix rule
  rejected every line. The step was added on 09-03 and had never passed on
  that leg. new-lines: platform accepts the checkout's own convention.

@srpatcha srpatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — ebuild#122 "ci: fix the lint findings that stop CI before any test runs"

head: 6958986 author: nk0952 ci: none reported

Verdict: Correct diagnosis and a minimal, behaviour-preserving fix. I reproduced both halves of the claim locally: ruff check . on origin/master (76970c9) reports exactly the 4 errors named in the body, and the same command on this head reports All checks passed!. Conforms to §5.1 — no dependency direction is touched. The one thing that matters before merge is that #132 already contains this same lint change, with green CI.

Findings

# Severity File:line Finding Recommended fix
1 Medium tests/unit/test_ci_gate.py, tests/ebuild/test_build_dir_resolution.py, tests/ebuild/test_package_recipe.py Duplicate work: open PR #132 ("fix: repair master — lint, a dropped method, vendored drift, scorecard") carries byte-identical changes to all three of these test files plus the same ebuild/plugins/__init__.py rewrite, and #132 has 30 green checks against it while this branch has none. Whichever lands second will be a conflict or an empty diff. Coordinate with #132 rather than both landing. Either close this in favour of #132, or split #132 down to its non-lint parts (recipe to_dict, .gitattributes, scorecard) and land this one first as the narrow CI unblock. Decide before either merges; do not merge both.
2 Low pyproject.toml:10 vs .github/workflows/ci.yml:31 The PR body is right that the pre-3.10 entry_points() branch is untested, but the reason is a gap, not a design: requires-python = ">=3.8" while the CI matrix is ["3.10","3.11","3.12"]. Python 3.8/3.9 are declared supported and never built, so the branch this PR is editing cannot be exercised by any check. Out of scope for this PR. Either raise requires-python to >=3.10 and delete the hasattr(entry_points, "select") fallback entirely as dead code, or add a 3.9 leg to the matrix. Worth a separate issue.
3 Low ebuild/plugins/__init__.py:46 cast(Mapping[str, Any], ...) silences mypy but keeps eps typed as the union of two unrelated shapes, so the for ep in eps loop below is still unchecked. Functionally fine — cast is a runtime no-op, so the claim "behaviour is unchanged either way" holds. Acceptable as-is. If the 3.8/3.9 floor is dropped per finding 2 this disappears with the branch.

Architecture conformance

Conforms. Master design §21 places ebuild in Tier 1 — Foundation, and every touched file is inside that repo: three test modules and one plugin-discovery module. §5.1 is not engaged — no new import, link or manifest entry crosses a tier, and importlib.metadata is stdlib. The ebuild/plugins/__init__.py change adds typing imports only, so eBuild remains a build-time control plane and not a runtime dependency (§5.1, §9).

Against .github/STANDARDS.md: the commit is Conventional-Commits shaped (ci:), which the standards file requires.

The two items the author raised but did not fold in are both real and both correctly left to a maintainer:

  • ci.yml:55 installs mypy ruff yamllint unpinned, so a linter release can redden the gate with no repo change. That is a plausible origin for the current breakage and is a reproducibility defect in the gate itself.
  • .coveragerc fail_under = 100 against a ~24% suite, worked around by --cov-fail-under=0 at ci.yml:88. A gate that is disabled at every call site is not a gate. Neither is this PR's to fix.

Proposed changes

  1. Resolve the overlap with #132 first — that is the only blocking item. #132 is the larger change and already green; if it lands, this PR becomes empty.
  2. If this one is preferred as the narrow unblock, no diff changes are needed. It is mergeable as written.
  3. Separately (not in this PR): pin the linter versions in ci.yml or move them into the dev extra, and open an issue for the requires-python >= 3.8 / CI-floor-3.10 mismatch.

Not checked

  • mypy — NOT RUN. mypy is not installed on this host. The claim that master has 2 mypy errors and this branch has 1 is unverified; I confirmed only that the # type: ignore[attr-defined] comment on master names a code that would not cover an arg-type error, which makes the author's account consistent.
  • yamllint — NOT RUN. Not installed. No YAML is touched by this diff, so the risk is nil.
  • pytest — NOT RUN. pytest is not importable on this host and the local ebuild clone has a dirty working tree, so it was left untouched per the rules of engagement. The claims "669 passed before and after" and "9 failures in tests/unit/test_index_sync.py remain" are unverified. The 9 failures are attributed to #119; I did not confirm that attribution.
  • CI — no checks reported on ci-unblock-lint-gate. GitHub shows no check runs at all for this branch, so there is no evidence from CI either way. This is not a CI failure; it is an absence of CI, and it means the branch's own claim of being green after merge rests entirely on the author's local runs.
  • I did not verify the + #119 column of the body's table; I did not check out or merge #119.

Verified locally: ruff 0.16.5, ruff check . against git archive exports of origin/master (4 errors: F811 at tests/ebuild/test_build_dir_resolution.py:31, E402 at tests/unit/test_ci_gate.py:214 and :215, W292 at tests/ebuild/test_package_recipe.py:117) and of this head (All checks passed!). The repo's CI pins no ruff version, so a different ruff release may not agree.


Automated architecture review of 69589862398d — scheduled, model claude-opus-5, checked against the EmbeddedOS Master Design v2.0. Advisory only: this reviewer never approves, requests changes, or merges. Reply here to discuss or push back — a wrong finding is a bug worth reporting.

@srpatcha srpatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is the smallest change that fixes the lint findings, and the description matches the diff exactly. I reproduced it locally: ruff check . goes from 4 findings on master to clean, mypy drops the plugins/__init__.py:46 arg-type error (the cast is the honest fix rather than widening the ignore), and the test count is unchanged with the nine test_index_sync failures remaining, as you noted.

For the maintainers' benefit: the four hunks are byte-identical to the corresponding ones in #132, which additionally restores PackageRecipe.to_dict() and fixes the vendor-drift guard. Either order works — whichever merges second will apply cleanly as a no-op. #127 carries a different version of two of these files and will conflict.

Approving.

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