Files
cleveragents-core/robot/tdd_quality_gate.robot
T
CoreRasurae e8d2f76466
CI / push-validation (pull_request) Successful in 45s
CI / helm (pull_request) Successful in 57s
CI / build (pull_request) Successful in 1m8s
CI / lint (pull_request) Successful in 1m31s
CI / tdd_quality_gate (pull_request) Failing after 1m26s
CI / quality (pull_request) Successful in 1m30s
CI / typecheck (pull_request) Successful in 1m43s
CI / security (pull_request) Successful in 1m42s
CI / e2e_tests (pull_request) Failing after 4m10s
CI / integration_tests (pull_request) Successful in 5m2s
CI / unit_tests (pull_request) Successful in 6m6s
CI / docker (pull_request) Successful in 1m32s
CI / coverage (pull_request) Successful in 12m12s
CI / status-check (push) Blocked by required conditions
CI / status-check (pull_request) Failing after 3s
CI / tdd_quality_gate (push) Has been skipped
CI / benchmark-regression (push) Failing after 1m8s
CI / build (push) Successful in 1m2s
CI / lint (push) Successful in 1m16s
CI / helm (push) Successful in 45s
CI / push-validation (push) Successful in 45s
CI / quality (push) Successful in 1m37s
CI / typecheck (push) Successful in 2m1s
CI / security (push) Successful in 2m1s
CI / integration_tests (push) Successful in 3m34s
CI / unit_tests (push) Successful in 5m14s
CI / docker (push) Successful in 1m37s
CI / coverage (push) Failing after 19m17s
CI / benchmark-publish (push) Successful in 1h20m43s
CI / e2e_tests (push) Successful in 4m13s
feat(ci): implement TDD bug tag quality gate for bug fix PRs
Add an automated quality gate that enforces TDD bug fix workflow rules
on pull requests. The gate parses PR descriptions for bug-closing
keywords (Closes/Fixes/Resolves #N, ISSUES CLOSED: #N), searches the
codebase for corresponding TDD tests tagged @tdd_bug_N, and verifies
that @tdd_expected_fail tags have been removed.

Key components:
- scripts/tdd_quality_gate.py: Main quality gate script with PR
  description parsing, TDD test discovery, and tag removal verification.
  All public functions validate arguments fail-fast and are statically
  typed.
- noxfile.py: New tdd_quality_gate session that reads PR_DESCRIPTION
  from the environment and runs the quality gate script.
- .forgejo/workflows/ci.yml: New tdd_quality_gate CI job that runs
  only on pull_request events, passing the PR body as PR_DESCRIPTION.
- features/tdd_quality_gate.feature: 46 Behave scenarios covering PR
  parsing, TDD test search, tag removal verification, full gate logic,
  robot diff handling, edge cases, argument validation, bool guards,
  co-located bug false-positive guard, and main() CLI entry point.
- features/steps/tdd_quality_gate_steps.py: Step definitions for all
  Behave scenarios using temporary directories for isolation.
- robot/tdd_quality_gate.robot: 15 Robot Framework integration tests
  exercising the gate end-to-end via a helper subprocess.
- robot/helper_tdd_quality_gate.py: Helper script for Robot tests with
  sentinel-based sub-commands.

Review-round fixes applied:
- check_expected_fail_removed now uses _contains_tag_token for
  word-boundary matching (avoids false positives on partial tag names)
- Diff expected-fail removal detection tracks flags at file level
  instead of per-hunk (fixes false negatives when tags span hunks)
- parse_bug_refs filters out issue number zero
- Redundant double error reporting eliminated (file-level check
  short-circuits the diff-level check)
- run_quality_gate returns (errors, bug_refs) tuple to avoid
  redundant re-parsing in main()
- Regex compilation cached via functools.lru_cache
- Nox session no longer installs the full project (stdlib only)
- CI checkout uses fetch-depth: 0 for reliable merge-base resolution

Review-round 2 fixes applied:
- _diff_has_expected_fail_removal_for_bug now requires the removed
  line to contain both the expected-fail tag and the specific bug tag
  (fixes false positives when two bugs share the same test file)
- check_expected_fail_removed error messages use the correct tag
  prefix per file type (@tdd_bug_N for .feature, tdd_bug_N for .robot)
- bool values rejected by bug-number validation guards in
  find_tdd_tests, check_expected_fail_removed, and
  _diff_has_expected_fail_removal_for_bug
- File-read error handling catches UnicodeDecodeError alongside OSError
  (root-safe unreadable-file handling via invalid-UTF-8 test fixture)
- Temp directory cleanup added to after_scenario hook in environment.py
- 8 new Behave scenarios: bool type guards (2), co-located bug
  false-positive regression (1), run_quality_gate argument validation
  (3), and main() CLI entry point exit codes (2)

Review-round 3 fixes applied:
- Synthetic PR diff helper (_default_pr_diff_for_bug_refs) now
  auto-detects .robot vs .feature file type from the temp search
  tree and generates the matching diff format (fixes under-tested
  robot-format diff code path in multi-bug integration scenarios)
- check_expected_fail_removed test step now filters files by bug
  tag via find_tdd_tests before checking (matches production path
  in run_quality_gate)
- after_scenario temp directory cleanup no longer sets
  context.temp_dir = None (fixes cleanup conflict with
  cli_init_yes_flag_steps.py cleanup functions that run after hooks)
- 2 new Behave scenarios: multi-line PR description parsing, and
  non-string pr_diff type guard for run_quality_gate

ISSUES CLOSED: #629
2026-05-12 00:22:49 +01:00

150 lines
7.0 KiB
Plaintext

*** Settings ***
Documentation Integration tests for the TDD quality gate script.
...
... Exercises ``scripts/tdd_quality_gate.py`` end-to-end by
... invoking it as a subprocess with various PR_DESCRIPTION
... values and temporary file trees, then verifying exit codes
... and output messages.
...
... See CONTRIBUTING.md > Bug Fix Workflow for the full
... specification.
Resource ${CURDIR}/common.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${HELPER} ${CURDIR}/helper_tdd_quality_gate.py
*** Test Cases ***
# ===========================================================================
# PR description parsing
# ===========================================================================
Parse Single Fixes Reference
[Documentation] Verify the script extracts a single Fixes #N reference
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} parse_fixes_single
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} parse-fixes-single-ok
Parse Multiple Mixed References
[Documentation] Verify the script extracts multiple closing keywords
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} parse_mixed_refs
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} parse-mixed-refs-ok
Parse Issues Closed Block
[Documentation] Verify the script extracts ISSUES CLOSED: #N references
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} parse_issues_closed
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} parse-issues-closed-ok
Parse Non Closing Words
[Documentation] Verify parser ignores embedded keyword substrings
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} parse_non_closing_words
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} parse-non-closing-words-ok
No Bug References Passes Trivially
[Documentation] Verify the quality gate passes when no bug refs in PR
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} no_bug_refs_pass
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} no-bug-refs-pass-ok
# ===========================================================================
# TDD test search and tag verification
# ===========================================================================
Find TDD Test In Feature File
[Documentation] Verify the script finds @tdd_bug_N in .feature files
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} find_feature_test
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} find-feature-test-ok
Find TDD Test In Robot File
[Documentation] Verify the script finds tdd_bug_N in .robot files
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} find_robot_test
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} find-robot-test-ok
Find TDD Test Uses Exact Tag Match
[Documentation] Verify partial tags are not matched as exact bug tags
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} find_exact_tag_match
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} find-exact-tag-match-ok
No TDD Test Found Fails Gate
[Documentation] Verify the gate fails when no TDD test exists
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} no_tdd_test_fails
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} no-tdd-test-fails-ok
Expected Fail Tag Still Present Fails Gate
[Documentation] Verify the gate fails when @tdd_expected_fail is still present
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} expected_fail_present
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} expected-fail-present-ok
Expected Fail Tag Removed Passes Gate
[Documentation] Verify the gate passes when @tdd_expected_fail is removed
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} expected_fail_removed
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} expected-fail-removed-ok
# ===========================================================================
# Full quality gate integration
# ===========================================================================
Full Gate Multiple Bugs Mixed Results
[Documentation] Verify the gate handles multiple bugs with mixed outcomes
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} multi_bug_mixed
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} multi-bug-mixed-ok
Full Gate All Clean Passes
[Documentation] Verify the gate passes when all referenced bugs have clean tests
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} all_clean_passes
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} all-clean-passes-ok
TDD Tests In Both Behave And Robot
[Documentation] Verify the gate checks tests in both .feature and .robot files
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} both_behave_and_robot
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} both-behave-and-robot-ok
Diff Removal Is Required
[Documentation] Verify the gate fails when PR diff has no expected-fail removal
[Tags] ci quality tdd
${result}= Run Process ${PYTHON} ${HELPER} diff_removal_required
... cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
Should Contain ${result.stdout} diff-removal-required-ok