fix: resolve all 15 /code-review findings (workflow bugs, doc drift, test integrity, rename-safety)#36
Merged
Conversation
Single PR fixes every CONFIRMED + PLAUSIBLE finding from the extra-high- effort code-review on the post-/simplify range (ec7045d..HEAD). Workflow bugs (active failures) ------------------------------- 1. dependabot-auto-merge.yml: pre-create `manual-review` label via `gh label create --force` before adding it. Previously the workflow failed red on every Dependabot major bump (observed on PR #34) because the label didn't exist yet. 2. stale.yml: add `dependencies,manual-review` to `exempt-pr-labels` so Dependabot major-bump PRs aren't silently closed after 37 days. 5. dependabot-auto-merge.yml major-branch now calls `gh pr merge --disable-auto || true` before re-labeling. Without this, a Dependabot rebase that promoted a previously-classified minor into a major would keep the prior `--auto` enable and silently squash-merge. Doc drift (user-facing contradictions) -------------------------------------- 3. README.md + README.ko.md project-structure tree: drop the stale `tools/greet.py` line; relabel server.py from "+ inline tools + helpers" to "+ inline `greet` tool example". Replace README's "Modular (recommended for larger servers)" code block (which pointed at a deleted example file) with prose pointing at resources/server_info.py and prompts/code_review.py as the live `register(mcp)` exemplars. 4. CHANGELOG.md [Unreleased] reset to an empty courtesy stub. The previous bullets described attest-build-provenance v3.2.0, stale v10.2.0, ruff>=0.15<1, mypy>=2<3, pytest>=8<10, pytest-asyncio>=1<2, a `.python-version` file, and a SECURITY.md "feature set" framing — every one of those is now superseded by PRs #28-#34 + #27. The file's own header already declares GitHub Releases as canonical, so the courtesy stub now matches that contract. 6. server.py module docstring + tools-section comment: drop references to the deleted greet.py example; reference the live register(mcp) pattern in resources/ and prompts/. tools/__init__.py is now also deleted (the package was a dead public namespace shipping in the wheel after greet.py was removed). 11. setup.yml first-run bootstrap issue: rewrite the `Replace the example greet tool` checklist item to point at server.py inline (and mention modular split as an option), matching reality. 12. SECURITY.md adds a one-line WARNING above the branch-protection JSON that the hardcoded `test (3.11/3.12/3.13)` contexts MUST be updated in lockstep with any matrix change — otherwise required checks point at jobs that never report. 13. SECURITY.md prepends `gh auth refresh -s admin:repo,security_events` so copy-pasters who used the default `gh auth login` scopes don't hit opaque 404s on the vulnerability-alerts / automated-security-fixes PUTs. Production code correctness (rename-safety + entry-point testability) --------------------------------------------------------------------- 7+8. resources/server_info.py: replace the two hardcoded `"my-mcp-server"` literals with a module-level `PKG_NAME` derived from `__package__` (with underscores → hyphens). A clone that renames the package per setup.yml's first-run checklist now reports the correct dist name in `info://server/status` without a second hardcoded literal to remember. Test in tests/test_server_info.py is updated to compare `payload["name"]` against `mod.PKG_NAME` and `payload["version"]` against `importlib.metadata.version(mod.PKG_NAME)` — both sides resolve to the SAME source, so an uncommitted pyproject.toml version bump no longer makes the test fail for the wrong reason. 14. __main__.py: extract the try/except wrapper into `run() -> int` and guard the call site with `if __name__ == "__main__":`. Importing `my_mcp_server.__main__` (IDE auto-import, coverage discovery, etc.) no longer blocks on the server loop, and the KeyboardInterrupt / Exception arms are now testable. Test integrity -------------- 6. tests/test_server_info.py adds `test_read_pyproject_returns_none_when_no_pyproject_anywhere` exercising the OUTER `return None` (loop exhaustion at server_info.py:42) that the existing wheel-fallback tests bypassed via monkeypatch. Coverage on server_info.py jumps 96% → 100%. 9. tests/test_server_info.py::test_read_pyproject_returns_none_when_project_table_missing now installs a spy on `tomllib.load` and asserts EXACTLY ONE pyproject was read — so a future refactor that drops the inner `return None` and falls through to keep walking gets caught here (the spy would see >1 load) instead of silently passing because no other pyproject.toml is reachable on the way to /. 10. tests/test_server_info.py adds `test_pkg_name_derived_from_package` pinning the `PKG_NAME = __package__.split(".")[0].replace("_", "-")` contract — a refactor that re-hardcodes the literal would fail here. 15. tests/test_tools.py introduces a `_schema_constraint` helper that reads a JSON Schema keyword either at the top of a property OR inside an `anyOf` branch, so a future widening of the `greet` signature to `Annotated[str | None, Field(...)]` (where pydantic emits `anyOf`) fails with a clear schema-shape message instead of `KeyError`. 13. tests/test_main.py (new file, 3 tests): exercise the wrapper's clean return / KeyboardInterrupt / Exception arms. The Exception test also asserts the traceback is logged via `logging.exception` (silently exiting 1 without the log would make production debugging much harder). Coverage hygiene ---------------- 17. pyproject.toml `[tool.coverage.report]`: switch from `exclude_lines` (which appended to the default and matched nothing in src/) to `exclude_also` with patterns that actually have real or near-real matches (`if TYPE_CHECKING:`, `if __name__ == "__main__":`). The `pragma: no cover` and `raise NotImplementedError` patterns moved to coverage.py's built-in defaults. Verification ------------ - ruff / ruff format / mypy strict: all clean. - pytest: 26 passed (was 21; +3 main tests + 2 server_info tests, with test_falls_back tightened rather than added). - Coverage: 70.64% → 97.06% (was 84.69% after the last 2nd-pass session; __main__.py 0% → 100%, server_info.py 96% → 100%). Findings deferred from this PR ------------------------------ None — all 15 from the /code-review JSON output (CONFIRMED + PLAUSIBLE) are addressed. Findings REFUTED by verifiers (so no change required): - C-F1 (GITHUB_TOKEN read-only on Dependabot PRs): empirically false here because the workflow declares an explicit `permissions:` block. - C-F14 (cd.yml top-level permissions cap ci.yml): GitHub docs confirm reusable workflows use their own top-level permissions. - C-F15 (symlink resolution skips tmp_path): pytest's tmp_path on macOS already returns the canonical /private/var path.
2 tasks
heznpc
added a commit
that referenced
this pull request
May 28, 2026
… a git repository') (#37) PR #36 added `gh label create` + `gh pr merge --disable-auto` + `gh pr edit` to the major-update branch but the workflow has no `actions/checkout` step. Without a `.git` directory in the workdir, `gh` errors out with `fatal: not a git repository (or any of the parent directories): .git` before any subcommand runs. Observed on PR #35's auto-merge run (logged 2026-05-28T21:47:56.2681559Z). Two fixes: - Set `GH_REPO: ${{ github.repository }}` on the env block of BOTH steps (`gh` consults this env var to resolve the target repo when no git context is present). - Leaves the minor/patch branch with the same shielding even though its current single command (`gh pr merge --auto --squash`) already accepts a URL argument; defensive symmetry against future additions. No source code changes; workflow-only fix.
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 free
to 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.
Single PR addressing every CONFIRMED + PLAUSIBLE finding from the extra-high-effort
/code-reviewonec7045d..HEAD. Three REFUTED findings dropped.Workflow bugs (active failures, fix-first)
dependabot-auto-merge.ymlmanual-reviewlabel viagh label create --force. Previously failed red on every Dependabot major bump (PR #34 confirmed).stale.ymldependencies,manual-reviewtoexempt-pr-labels— Dependabot major-bump PRs no longer auto-closed after 37 days.dependabot-auto-merge.ymlgh pr merge --disable-autobefore re-labeling — a Dependabot rebase that re-classifies minor→major no longer keeps the prior--autoenable.Doc drift
README.md+README.ko.mdtools/greet.pyfrom structure trees; replace stale "Modular (recommended for larger servers)" code block with prose pointing atresources/server_info.pyandprompts/code_review.pyas the liveregister(mcp)exemplars.CHANGELOG.md[Unreleased]reset to a courtesy stub matching the file's own "GitHub Releases is canonical" framing. All bullets were historically false after PRs #28-#34 + #27.server.pydocstring + tools-section commentresources//prompts/; delete deadtools/__init__.py.setup.ymlfirst-run issuegreettool" checklist item to match reality (greet now lives inline inserver.py).SECURITY.mdtest (3.11/3.12/3.13)contexts MUST be updated in lockstep with matrix changes.SECURITY.mdgh auth refresh -s admin:repo,security_eventsso copy-pasters don't hit opaque 404s onvulnerability-alerts/automated-security-fixesPUTs.Production code (rename-safety + entry-point testability)
resources/server_info.py"my-mcp-server"literals withPKG_NAME = __package__.split(".")[0].replace("_", "-"). Clone renames per setup.yml now flow through to the wheel-install fallback.__main__.pyrun() -> intand guard the call site withif __name__ == "__main__":. Importingmy_mcp_server.__main__no longer blocks on the server loop, and the KeyboardInterrupt/Exception arms become testable.Test integrity
tests/test_server_info.pytest_read_pyproject_returns_none_when_no_pyproject_anywhereexercising the OUTERreturn None(loop exhaustion atserver_info.py:42) the previous wheel-fallback tests bypassed via monkeypatch.tests/test_server_info.pytest_read_pyproject_returns_none_when_project_table_missinginstalls a spy ontomllib.loadand asserts EXACTLY ONE pyproject was read — a future refactor that drops the innerreturn Noneand keeps walking now fails here instead of silently passing.tests/test_server_info.pytest_falls_back_to_importlib_metadata_when_pyproject_missingcompares both sides againstimportlib.metadata(same source). Uncommitted version bumps no longer cause misleading failures.tests/test_server_info.pytest_pkg_name_derived_from_packagepinning the rename-safety contract.tests/test_tools.py_schema_constrainthelper reads a JSON Schema keyword from top-of-property ORanyOfbranch — a future widening to `Annotated[strtests/test_main.py(NEW)run()'s clean / KeyboardInterrupt / Exception arms. Exception test also asserts traceback is logged.pyproject.tomlexclude_lines(which appended to defaults and matched nothing) toexclude_alsowith patterns that actually match (if TYPE_CHECKING:,if __name__ == "__main__":).Verification
Findings REFUTED (no change required)
permissions:block ondependabot-auto-merge.ymlgrants writes; PR chore(deps): bump the actions group across 1 directory with 3 updates #34's failure was themanual-reviewlabel, not the token./private/varpath.Test plan
--cov-fail-under=70(actual 97.06%)ruff check .+ruff format --check .+mypy src/all cleananalyze (python)+analyze (actions)green