Skip to content

Conversation

@miroslavpojer
Copy link
Collaborator

@miroslavpojer miroslavpojer commented Jan 14, 2026

Overview

This pull request introduces a structured integration testing approach, improves test organization, and refines the CI workflow to clearly separate unit and integration test execution. The goal is to increase confidence in end-to-end behavior while keeping fast feedback from unit tests.

Key outcomes:

  • End-to-end validation of the action via subprocess execution
  • Clear separation of unit vs. integration tests
  • More maintainable test layout and CI configuration

Testing infrastructure improvements

  • Added a dedicated integration test suite in tests/integration/test_local_run.py that executes main.py as a subprocess.
    This simulates real GitHub Action execution by passing inputs via environment variables and validates the full execution path.

  • Introduced tests/integration/dummy_github_repository.py, a dummy GitHubRepository implementation used by integration tests.
    This allows realistic behavior without real network calls or external dependencies.

  • Updated pyproject.toml to register a custom integration pytest marker, enabling explicit selection and separation of integration-style tests.

  • Reorganized existing unit tests and fixtures under tests/unit/ to clearly distinguish

CI workflow enhancements

  • Updated .github/workflows/test.yml to explicitly separate test execution:

    • Unit tests run with -m "not integration"
    • A dedicated integration-test job runs only integration tests
  • Adjusted the Pylint configuration in CI to ignore test files, reducing noise and keeping linting focused on production code.

This structure improves CI reliability, keeps unit test feedback fast, and ensures integration tests run in an environment closer to real usage.

Release Notes

  • Added end-to-end integration tests executing the action as a subprocess
  • Improved test structure and CI separation for unit and integration tests

Related

Closes #47

Summary by CodeRabbit

  • Chores
    • Updated Python version support to 3.13.
    • Restructured test infrastructure with separation of unit and integration tests.
    • Enhanced testing configuration for improved coverage.
    • Updated developer documentation for test execution.

✏️ Tip: You can customize this high-level summary in your review settings.

- Updated GitHub Actions workflow to ignore test files in Pylint analysis and added integration tests job.
- Modified pytest command to exclude integration tests from coverage checks.
- Added pytest markers for integration tests in pyproject.toml.
- Removed unused conftest.py file and consolidated logging setup tests.
- Created a dummy GitHub repository class for integration tests.
- Added unit tests for version validation and action checks.
- Cleaned up and organized test files into unit and integration directories.
- Removed obsolete test files related to version validation and action checks.
@miroslavpojer miroslavpojer self-assigned this Jan 14, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR implements integration testing infrastructure by separating unit and integration tests in the CI workflow, introducing pytest configuration with integration markers, establishing test fixtures for subprocess execution with mocked GitHub interactions, and extracting error constants for improved code reusability.

Changes

Cohort / File(s) Summary
CI/CD Workflow Configuration
.github/workflows/test.yml
Upgraded Python 3.11 → 3.13, added concurrency block for run cancellation, separated unit tests (with not integration filter) and integration tests into distinct jobs, removed PYTHONPATH setup
Project Configuration
pyproject.toml, .pylintrc
Added pytest configuration with integration marker definition, test paths, and recursion exclusions; extended pylint ignore list to include tests directory
Error Constants Extraction
version_tag_check/utils/constants.py, version_tag_check/version_tag_check_action.py
Created new constants module with ERROR_TAG_ALREADY_EXISTS and ERROR_TAG_DOES_NOT_EXIST; refactored action to import and use these constants instead of hardcoded strings
Integration Testing Framework
tests/integration/conftest.py, tests/integration/dummy_github_repository.py, tests/integration/test_local_run.py
Established integration test infrastructure: conftest fixture injects sitecustomize patch for subprocess mocking, dummy repository class returns deterministic tags, two test cases validate local subprocess execution with mocked GitHub interaction
Unit Test Enhancements
tests/unit/conftest.py, tests/unit/test_version_tag_check_action.py, tests/unit/test_version.py, tests/unit/test_version_validator.py
Added mock_logging_setup and mock_exit fixtures; refactored tests to use imported constants; minor spacing adjustments across test files
Documentation
DEVELOPER.md
Updated test running instructions to specify unit test path exclusion, documented new integration test location and subprocess execution pattern, adjusted coverage command to align with test separation

Sequence Diagram(s)

sequenceDiagram
    actor pytest as pytest Runner
    participant main as main.py<br/>(subprocess)
    participant sitecustomize as sitecustomize.py<br/>(patch module)
    participant action as VersionTagCheckAction
    participant dummy as DummyGitHubRepository

    pytest->>pytest: Create tmp_path & sitecustomize<br/>with patch logic
    pytest->>pytest: Set PYTHONPATH to include<br/>tmp_path & project_root
    pytest->>main: subprocess.run(main.py)<br/>with env (PYTHONPATH, GH_TOKEN, etc.)
    main->>sitecustomize: Auto-import sitecustomize.py<br/>at Python startup
    sitecustomize->>sitecustomize: Patch GitHubRepository<br/>with DummyGitHubRepository
    main->>action: Execute VersionTagCheckAction
    action->>dummy: Instantiate mocked repo<br/>(owner, repo, token)
    dummy->>dummy: get_all_tags()<br/>returns [v0.0.1, v0.0.2, v0.1.0]
    action->>action: Validate tag against<br/>dummy repository
    main->>pytest: Exit with code<br/>(0 for success, non-zero for error)
    pytest->>pytest: Assert exit code &<br/>stdout/stderr content
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #20: Updates DEVELOPER.md with developer guide; this PR further extends it with integration test documentation and test command guidance.

Suggested labels

enhancement

Suggested reviewers

  • Zejnilovic
  • benedeki
  • tmikula-dev

Poem

🐰 A framework for tests that run standalone,
With mocked repos and subprocesses in the lane,
Integration tales now spring to life,
Local validations, with less GitHub strife,
Hopping forward, one tag at a time! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main addition of integration tests for local execution, making the primary change clear and specific.
Description check ✅ Passed The PR description comprehensively covers the changes, includes release notes, and clearly references the related issue #47, matching the template requirements.
Linked Issues check ✅ Passed The PR successfully implements all coding objectives from issue #47: integration test runs locally and in CI, with proper separation and infrastructure in place.
Out of Scope Changes check ✅ Passed All changes are scoped to integration testing, test organization, CI workflow updates, and supporting infrastructure directly related to issue #47's objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
tests/integration/test_local_run.py (2)

21-49: Consider adding a timeout to prevent hanging tests.

The subprocess call works correctly, but lacks a timeout parameter. If the subprocess hangs (e.g., due to an unexpected prompt or deadlock), the test will block indefinitely.

💡 Suggested improvement
     result = subprocess.run(
         [sys.executable, str(PROJECT_ROOT / "main.py")],
         cwd=PROJECT_ROOT,
         env=env,
         capture_output=True,
         text=True,
+        timeout=30,  # Fail fast if subprocess hangs
     )

Note: The static analysis hint (S105) about hardcoded password for INPUT_GITHUB_TOKEN is a false positive—"fake-token" is intentional test data. Similarly, S603 about subprocess input is not a concern since all inputs are controlled test values.


52-76: Consider asserting the exact expected exit code.

The test correctly validates that the action fails when an existing tag is encountered, and properly uses the centralized ERROR_TAG_ALREADY_EXISTS constant. However, the exit code assertion could be more precise.

💡 Suggested improvement
-    assert result.returncode != 0
+    assert result.returncode == 1, f"Expected exit code 1, got {result.returncode}"

This makes the test more explicit about the expected behavior and aligns with the coding guideline that exit codes for existing failure scenarios should not change.


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c701ae and 69d4098.

📒 Files selected for processing (4)
  • tests/integration/test_local_run.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/utils/constants.py
  • version_tag_check/version_tag_check_action.py
🧰 Additional context used
📓 Path-based instructions (5)
version_tag_check/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

version_tag_check/**/*.py: Do not change existing error messages or log texts without a good reason, because tests check them
Add type hints for new public functions and classes
Use logging, not print, and keep logging wired through version_tag_check.utils.logging_config
Keep error messages stable; tests assert on exact strings

Files:

  • version_tag_check/utils/constants.py
  • version_tag_check/version_tag_check_action.py
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.py: Target Python 3.11 or later
Format with Black using pyproject.toml
Run mypy and prefer fixing types instead of ignoring errors

Files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
!(tests)/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run Pylint on tracked Python files, excluding tests/, and aim for score 9.5 or higher

Files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
tests/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

tests/**/*.py: Use pytest with tests located in tests/
Test behaviour: return values, raised errors, log messages, exit codes
Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests
Use pytest-cov and keep coverage at or above 80 percent

Files:

  • tests/unit/test_version_tag_check_action.py
  • tests/integration/test_local_run.py
version_tag_check/version_tag_check_action.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Route new behaviour that affects action inputs or outputs through VersionTagCheckAction

Files:

  • version_tag_check/version_tag_check_action.py
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Do not change existing error messages or log texts without a good reason, because tests check them

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Add type hints for new public functions and classes

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/version.py|version_tag_check/version_validator.py : Keep Version and NewVersionValidator free of I/O and environment access

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Keep error messages stable; tests assert on exact strings

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to main.py|version_tag_check/version_tag_check_action.py : Do not change exit codes for existing failure scenarios

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/version_tag_check_action.py : Route new behaviour that affects action inputs or outputs through VersionTagCheckAction

Applied to files:

  • version_tag_check/utils/constants.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/test_version.py|tests/test_version_validator.py|tests/test_version_tag_check_action.py : When touching version parsing or increment rules, extend tests in tests/test_version.py, tests/test_version_validator.py, tests/test_version_tag_check_action.py

Applied to files:

  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Use logging, not print, and keep logging wired through version_tag_check.utils.logging_config

Applied to files:

  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests

Applied to files:

  • tests/integration/test_local_run.py
🧬 Code graph analysis (1)
version_tag_check/version_tag_check_action.py (1)
version_tag_check/utils/gh_action.py (1)
  • set_action_failed (40-49)
🪛 Ruff (0.14.11)
tests/integration/test_local_run.py

33-33: Possible hardcoded password assigned to: "INPUT_GITHUB_TOKEN"

(S105)


41-41: subprocess call: check for execution of untrusted input

(S603)


62-62: Possible hardcoded password assigned to: "INPUT_GITHUB_TOKEN"

(S105)


67-67: subprocess call: check for execution of untrusted input

(S603)

🔇 Additional comments (6)
version_tag_check/utils/constants.py (1)

17-24: LGTM!

Well-structured constants module that centralizes error messages. This aligns with the coding guideline to keep error messages stable since tests assert on exact strings. Extracting these constants makes it easier to maintain consistency across production code and tests.

version_tag_check/version_tag_check_action.py (2)

24-24: LGTM!

The import of error constants from the centralized module is properly placed and follows the existing import organization.


73-80: LGTM!

Good refactoring to use centralized constants. The error messages and exit codes remain unchanged, preserving backward compatibility. Based on learnings, error messages should stay stable since tests assert on exact strings—this change centralizes them without altering their content.

tests/unit/test_version_tag_check_action.py (2)

22-22: LGTM!

Importing the error constants from the same source as production code ensures test assertions stay in sync with actual error messages.


136-137: LGTM!

Using the centralized constants for error message assertions is a good practice. This ensures tests remain valid if error messages are updated in the future—changes will only need to happen in one place. The inline comments now accurately describe each test scenario.

tests/integration/test_local_run.py (1)

1-18: LGTM!

The module docstring clearly explains the integration test strategy. Using sitecustomize.py to patch GitHubRepository in the subprocess is a clever approach that avoids real network calls while testing the actual wiring of main.py. Based on learnings, mocking GitHubRepository is the expected pattern for tests.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@miroslavpojer miroslavpojer requested a review from Copilot January 14, 2026 14:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces integration tests that execute the action as a subprocess, reorganizes the test structure to separate unit and integration tests, and updates the CI workflow accordingly.

Changes:

  • Added integration tests in tests/integration/ that run main.py as a subprocess with mocked repository behavior
  • Reorganized existing unit tests under tests/unit/ and registered a custom pytest marker for integration tests
  • Updated CI to run unit and integration tests separately, with Pylint now ignoring test files

Reviewed changes

Copilot reviewed 8 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/integration/test_local_run.py Implements integration tests that execute main.py via subprocess with environment-based inputs
tests/integration/dummy_github_repository.py Provides a test double for GitHubRepository used in integration tests
tests/unit/test_version.py Adds blank lines between test functions for formatting consistency
tests/unit/test_version_validator.py Adds a blank line before decorator for formatting consistency
tests/unit/conftest.py Adds blank lines between fixtures for formatting consistency
pyproject.toml Registers the "integration" pytest marker to enable test categorization
DEVELOPER.md Documents how to run unit and integration tests separately
.github/workflows/test.yml Separates unit and integration test execution in CI, removes unused PYTHONPATH setup

@miroslavpojer
Copy link
Collaborator Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Contributor

Copilot AI commented Jan 14, 2026

@miroslavpojer I've opened a new pull request, #49, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits January 14, 2026 14:49
Refactor integration tests: extract error constants and shared fixture
@miroslavpojer miroslavpojer requested a review from Copilot January 15, 2026 11:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 16 changed files in this pull request and generated 2 comments.

@miroslavpojer miroslavpojer requested a review from Copilot January 15, 2026 11:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 16 changed files in this pull request and generated 1 comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@DEVELOPER.md`:
- Line 237: Update the pytest invocation that currently uses "--ignore=tests" so
it doesn't exclude the test suite; replace the ignore with a narrower path like
"--ignore=tests/integration" (or remove the --ignore entirely) so tests/ are
collected; e.g., change the command string to use "--ignore=tests/integration
--cov=. tests/ --cov-fail-under=80 --cov-report=html".
♻️ Duplicate comments (1)
.github/workflows/test.yml (1)

107-107: Critical: pytest command is broken — it ignores the test directory it's supposed to run.

The command specifies tests/ as the test path but then adds --ignore=tests at the end, which will cause pytest to ignore all tests entirely. This will result in no tests being executed while the job still passes.

Based on the past review comment, the intent was to exclude integration tests from coverage. The correct fix should use --ignore=tests/integration to exclude only integration tests while still running unit tests.

🐛 Proposed fix
-        run: pytest --cov=. -v -m "not integration" tests/ --cov-fail-under=80 --ignore=tests
+        run: pytest --cov=. -v -m "not integration" --ignore=tests/integration tests/ --cov-fail-under=80
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 85db77a and 95d5e88.

📒 Files selected for processing (2)
  • .github/workflows/test.yml
  • DEVELOPER.md
🧰 Additional context used
📓 Path-based instructions (1)
!(tests)/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run Pylint on tracked Python files, excluding tests/, and aim for score 9.5 or higher

Files:

  • .github/workflows/test.yml
  • DEVELOPER.md
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to !(tests)/**/*.py : Run Pylint on tracked Python files, excluding tests/, and aim for score 9.5 or higher

Applied to files:

  • .github/workflows/test.yml
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Use pytest-cov and keep coverage at or above 80 percent

Applied to files:

  • .github/workflows/test.yml
  • DEVELOPER.md
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Use pytest with tests located in tests/

Applied to files:

  • DEVELOPER.md
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests

Applied to files:

  • DEVELOPER.md
🔇 Additional comments (5)
.github/workflows/test.yml (2)

47-47: LGTM!

The Pylint command now correctly excludes the tests/ directory, aligning with the coding guidelines that specify running Pylint on tracked Python files excluding tests.


109-133: LGTM!

The new integration-test job is well-structured with proper checkout, Python setup, and dependency installation. Running integration tests separately without coverage requirements is appropriate since these are end-to-end tests that validate subprocess execution rather than code coverage.

DEVELOPER.md (3)

9-9: LGTM!

Good addition of the navigation item for the new integration tests section.


195-199: LGTM!

Clear documentation update specifying that unit tests are under tests/unit/ with the appropriate command to run them.


206-227: LGTM!

Comprehensive documentation for the new integration testing capability. The section clearly explains:

  • Location of tests and the pytest marker used
  • How tests work (subprocess execution with patched GitHubRepository)
  • Environment variables used for inputs
  • Commands to run integration tests and exclude them

This aligns well with the learnings that GitHubRepository and environment variables should be mocked in tests.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Collaborator

@tmikula-dev tmikula-dev left a comment

Choose a reason for hiding this comment

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

Please react to the PR comments.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@version_tag_check/utils/contanst.py`:
- Around line 1-21: Rename the module contanst.py to constants.py and update the
three import statements that reference the old module name to import from
constants instead; inside the renamed module add explicit type annotations to
the module-level constants by changing ERROR_TAG_ALREADY_EXISTS and
ERROR_TAG_DOES_NOT_EXIST to have the str type (ERROR_TAG_ALREADY_EXISTS: str and
ERROR_TAG_DOES_NOT_EXIST: str) so other code importing these symbols uses the
correctly-typed constants.
🧹 Nitpick comments (1)
tests/integration/test_local_run.py (1)

41-47: Consider adding a timeout to subprocess calls.

If main.py hangs unexpectedly, these tests would block indefinitely. Adding a reasonable timeout prevents CI from stalling.

♻️ Suggested improvement
     result = subprocess.run(
         [sys.executable, str(PROJECT_ROOT / "main.py")],
         cwd=PROJECT_ROOT,
         env=env,
         capture_output=True,
         text=True,
+        timeout=30,
     )

Also applies to: 67-73

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95d5e88 and fa8d749.

📒 Files selected for processing (7)
  • .github/workflows/test.yml
  • .pylintrc
  • pyproject.toml
  • tests/integration/test_local_run.py
  • tests/unit/test_version_tag_check_action.py
  • version_tag_check/utils/contanst.py
  • version_tag_check/version_tag_check_action.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • pyproject.toml
  • tests/unit/test_version_tag_check_action.py
🧰 Additional context used
📓 Path-based instructions (5)
version_tag_check/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

version_tag_check/**/*.py: Do not change existing error messages or log texts without a good reason, because tests check them
Add type hints for new public functions and classes
Use logging, not print, and keep logging wired through version_tag_check.utils.logging_config
Keep error messages stable; tests assert on exact strings

Files:

  • version_tag_check/utils/contanst.py
  • version_tag_check/version_tag_check_action.py
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.py: Target Python 3.11 or later
Format with Black using pyproject.toml
Run mypy and prefer fixing types instead of ignoring errors

Files:

  • version_tag_check/utils/contanst.py
  • tests/integration/test_local_run.py
  • version_tag_check/version_tag_check_action.py
!(tests)/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run Pylint on tracked Python files, excluding tests/, and aim for score 9.5 or higher

Files:

  • version_tag_check/utils/contanst.py
  • .pylintrc
  • tests/integration/test_local_run.py
  • .github/workflows/test.yml
  • version_tag_check/version_tag_check_action.py
tests/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

tests/**/*.py: Use pytest with tests located in tests/
Test behaviour: return values, raised errors, log messages, exit codes
Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests
Use pytest-cov and keep coverage at or above 80 percent

Files:

  • tests/integration/test_local_run.py
version_tag_check/version_tag_check_action.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Route new behaviour that affects action inputs or outputs through VersionTagCheckAction

Files:

  • version_tag_check/version_tag_check_action.py
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Do not change existing error messages or log texts without a good reason, because tests check them

Applied to files:

  • version_tag_check/utils/contanst.py
  • tests/integration/test_local_run.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Keep error messages stable; tests assert on exact strings

Applied to files:

  • version_tag_check/utils/contanst.py
  • tests/integration/test_local_run.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/version.py|version_tag_check/version_validator.py : Keep Version and NewVersionValidator free of I/O and environment access

Applied to files:

  • version_tag_check/utils/contanst.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Add type hints for new public functions and classes

Applied to files:

  • version_tag_check/utils/contanst.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to main.py|version_tag_check/version_tag_check_action.py : Do not change exit codes for existing failure scenarios

Applied to files:

  • version_tag_check/utils/contanst.py
  • tests/integration/test_local_run.py
  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to !(tests)/**/*.py : Run Pylint on tracked Python files, excluding tests/, and aim for score 9.5 or higher

Applied to files:

  • .pylintrc
  • .github/workflows/test.yml
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/test_version.py|tests/test_version_validator.py|tests/test_version_tag_check_action.py : When touching version parsing or increment rules, extend tests in tests/test_version.py, tests/test_version_validator.py, tests/test_version_tag_check_action.py

Applied to files:

  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Mock GitHubRepository and environment variables; do not call the real GitHub API in unit tests

Applied to files:

  • tests/integration/test_local_run.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to tests/**/*.py : Use pytest-cov and keep coverage at or above 80 percent

Applied to files:

  • .github/workflows/test.yml
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to **/*.py : Run mypy and prefer fixing types instead of ignoring errors

Applied to files:

  • .github/workflows/test.yml
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to **/*.py : Target Python 3.11 or later

Applied to files:

  • .github/workflows/test.yml
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/version_tag_check_action.py : Route new behaviour that affects action inputs or outputs through VersionTagCheckAction

Applied to files:

  • version_tag_check/version_tag_check_action.py
📚 Learning: 2025-12-15T11:23:24.034Z
Learnt from: CR
Repo: AbsaOSS/version-tag-check PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-15T11:23:24.034Z
Learning: Applies to version_tag_check/**/*.py : Use logging, not print, and keep logging wired through version_tag_check.utils.logging_config

Applied to files:

  • version_tag_check/version_tag_check_action.py
🧬 Code graph analysis (2)
tests/integration/test_local_run.py (2)
tests/integration/conftest.py (1)
  • subprocess_env_with_mocked_github (13-43)
version_tag_check/version_tag_check_action.py (1)
  • run (53-91)
version_tag_check/version_tag_check_action.py (1)
version_tag_check/utils/gh_action.py (1)
  • set_action_failed (40-49)
🪛 Ruff (0.14.11)
tests/integration/test_local_run.py

33-33: Possible hardcoded password assigned to: "INPUT_GITHUB_TOKEN"

(S105)


41-41: subprocess call: check for execution of untrusted input

(S603)


62-62: Possible hardcoded password assigned to: "INPUT_GITHUB_TOKEN"

(S105)


67-67: subprocess call: check for execution of untrusted input

(S603)

🔇 Additional comments (9)
.pylintrc (1)

49-49: Redundant but harmless configuration.

Both ignore=CVS,tests (line 49) and ignore-paths=tests (line 117) exclude the tests directory. The ignore directive matches base names while ignore-paths matches path patterns. Having both provides belt-and-suspenders coverage, which is fine.

Also applies to: 117-117

version_tag_check/version_tag_check_action.py (2)

24-24: Good refactoring to use centralized constants.

The import references the contanst module (typo noted in separate comment). The actual error strings remain stable, which aligns with the coding guideline to keep error messages consistent for test assertions.


73-80: LGTM: Error handling uses centralized constants.

The tag existence checks now use ERROR_TAG_ALREADY_EXISTS and ERROR_TAG_DOES_NOT_EXIST constants instead of hardcoded strings. This improves maintainability while preserving the existing behavior and exit codes.

.github/workflows/test.yml (3)

24-26: Good addition of concurrency control.

The concurrency block prevents redundant workflow runs on the same PR, canceling in-progress runs when new commits are pushed.


110-111: Unit test configuration looks correct.

The pytest command properly excludes integration tests with -m "not integration" and maintains the 80% coverage threshold requirement.


113-137: Integration test job properly isolated.

The dedicated integration-test job runs only integration-marked tests from tests/integration/. No coverage collection here is appropriate since integration tests exercise end-to-end behavior rather than unit coverage.

tests/integration/test_local_run.py (3)

1-18: Good integration test structure.

The module docstring clearly explains the test approach and mocking strategy. The imports and PROJECT_ROOT setup are appropriate.


21-49: Test covers successful new version scenario.

The test properly:

  • Uses the @pytest.mark.integration marker
  • Leverages the subprocess_env_with_mocked_github fixture
  • Sets appropriate environment variables for action inputs
  • Validates exit code 0 with helpful assertion message

The INPUT_GITHUB_TOKEN = "fake-token" is intentionally a dummy value for testing (not a real credential), so the S105 static analysis warning is a false positive.


52-76: Test covers failure scenario for existing tag.

The test correctly:

  • Uses the existing tag v0.1.0 (present in DummyGitHubRepository)
  • Asserts non-zero exit code
  • Uses the centralized ERROR_TAG_ALREADY_EXISTS constant for output validation

This aligns with the coding guideline to use constants instead of hardcoded strings for test assertions.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@miroslavpojer miroslavpojer merged commit 4145e48 into master Jan 16, 2026
9 checks passed
@miroslavpojer miroslavpojer deleted the feature/add-integration-test-for-local-run branch January 16, 2026 14:09
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.

Implement local Integration test

3 participants