Skip to content

fix(ci): enforce loud fail when package __version__ is missing#272

Merged
mvillmow merged 4 commits into
mainfrom
177-auto-impl
Jun 29, 2026
Merged

fix(ci): enforce loud fail when package __version__ is missing#272
mvillmow merged 4 commits into
mainfrom
177-auto-impl

Conversation

@mvillmow

@mvillmow mvillmow commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the silent failure anti-pattern in the deps-version-sync CI job. The check was passing when __version__ was absent from package __init__.py files, violating the repository's no-silent-failure principle.

Changes

  1. .github/workflows/_required.yml (lines 331-368): Replace the silent loop continuation with explicit error handling:

    • Uses AST parsing to find __version__ assignments (not substring matching)
    • Fails loudly with actionable error messages when __version__ is absent
    • Tracks confirmations to ensure at least one source verified the version
    • Handles both VERSION files and package __version__ declarations
  2. tests/test_version.py (new file): Adds two tests protecting the runtime contract:

    • test_package_version_matches_pyproject: Asserts telemachy.version equals pyproject.toml
    • test_package_exposes_dunder_version: Asserts the package exposes version

Verification

All existing tests pass (50 tests total, including 2 new version tests):

50 passed in 0.58s

The CI script now:

  • ✓ Passes on the real tree: "Version sync OK (1 source(s) confirmed)"
  • ✓ Fails loudly when __version__ is removed: "ERROR: src/telemachy/init.py has no top-level version assignment"
  • ✓ Contains no || true or continue-on-error: true suppressions

Related Issues

Fixes #177 (part of epic #92)

Closes #177

@mvillmow mvillmow left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

GO — correctly/completely fixes the silent-no-op version-sync gate (AST walk + loud fail). Minor nits: tab indentation in test_version.py vs project space style; dead confirmations==0 branch.

Comment thread tests/test_version.py Outdated
Comment thread .github/workflows/_required.yml Outdated
@mvillmow mvillmow enabled auto-merge (squash) June 20, 2026 15:36
mvillmow and others added 3 commits June 28, 2026 09:56
The deps-version-sync CI check at _required.yml:331-368 was silently
ineffective: when an __init__.py lacked __version__, the loop would skip
it without error, so the gate passed for the wrong reason (issue #177).

This change:
- Makes the AST check mandatory for all discovered src/**/__init__.py files
- Fails loudly with actionable error messages when __version__ is absent
- Uses a confirmations counter to ensure at least one source verified the
  version (VERSION file or package __version__)
- Adds tests/test_version.py to protect the runtime contract independently
  of CI YAML

The gate now enforces either (a) a VERSION file matching pyproject.toml, OR
(b) at least one src/**/__init__.py declaring __version__ matching
pyproject.toml. If neither holds, the job fails with a clear error.

Fixes #177 (epic #92)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Signed-off-by: mvillmow <4211002+mvillmow@users.noreply.github.com>
…ations guard

- tests/test_version.py: replace tab indentation with 4-space to match
  ruff indent-style = "space" (closes thread PRRT_kwDORoAqvc6K4lgF)
- _required.yml: remove unreachable `if confirmations == 0` block; the
  `if not init_files and not version_file.exists()` exit at lines 356-359
  already handles the empty-discovery case (closes thread PRRT_kwDORoAqvc6K4lgI)
- Apply ruff format across all affected source files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: mvillmow <4211002+mvillmow@users.noreply.github.com>
Identified 2 bugs discovered during implementation that fall within strict scope:

1. [safety] File handle leak at .github/workflows/_required.yml:362
   - open(init_file).read() never closes the file
   - Should use pathlib.Path(init_file).read_text() instead

2. [critical_bug] Unhandled exception at .github/workflows/_required.yml:368
   - ast.literal_eval(node.value) crashes if __version__ is non-literal
   - Should wrap in try/except with clear error message

Both are defects in core functionality discovered during implementation.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Signed-off-by: mvillmow <4211002+mvillmow@users.noreply.github.com>
GHSA-4xgf-cpjx-pc3j)

Signed-off-by: Micah Villmow <4211002+mvillmow@users.noreply.github.com>
@mvillmow mvillmow merged commit def36db into main Jun 29, 2026
14 of 15 checks passed
@mvillmow mvillmow deleted the 177-auto-impl branch June 29, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MAJOR] §12: version not __version__ — CI version sync check is silently ineffective

1 participant