Skip to content

feat: support default-status-checks at repository level#1112

Merged
myakove merged 2 commits into
mainfrom
feat/issue-1111-repo-level-status-checks
Jun 16, 2026
Merged

feat: support default-status-checks at repository level#1112
myakove merged 2 commits into
mainfrom
feat/issue-1111-repo-level-status-checks

Conversation

@rnetser

@rnetser rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Problem

default-status-checks was only accepted at the global config level. Different repos need different external CI checks required for can-be-merged, but there was no way to configure this per-repo.

Solution

The runtime code (Config.get_value()) already resolves per-repo → global config, so per-repo default-status-checks already worked at runtime. Only the YAML schema was missing the property at the per-repo level, causing schema validation to reject it.

Changes

  • webhook_server/config/schema.yaml — added default-status-checks to per-repo properties
  • examples/config.yaml — added per-repo usage example
  • webhook_server/tests/test_config_schema.py — added test validating schema acceptance and runtime resolution via Config() constructor
  • docs/repository-overrides.md — added row to overrides table

Config example

repositories:
  my-repo:
    name: my-org/my-repo
    default-status-checks:
      - "WIP"
      - "can-be-merged"
      - "ci/my-external-check"

Closes #1111

Assisted-by: Claude noreply@anthropic.com

@qodo-code-review

qodo-code-review Bot commented Jun 14, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used

Grey Divider


Action required

1. Missing precedence tests for checks ✓ Resolved 📎 Requirement gap ☼ Reliability
Description
The added test only validates that Config.get_value("default-status-checks") returns a repo-level
list, but it does not test global-only behavior or precedence when both global and repo-level
default-status-checks are set. This leaves the required precedence/merge semantics untested and
risks regressions in required status check computation.
Code

webhook_server/tests/test_config_schema.py[R277-299]

+    def test_per_repo_default_status_checks(
+        self, valid_minimal_config: dict[str, Any], monkeypatch: pytest.MonkeyPatch
+    ) -> None:
+        """Test that default-status-checks is accepted at per-repo level and resolved at runtime."""
+        config = valid_minimal_config.copy()
+        config["repositories"] = {
+            "repo1": {
+                "name": "org/repo1",
+                "default-status-checks": ["WIP", "can-be-merged", "ci/my-external-check"],
+            },
+        }
+
+        temp_dir = self.create_temp_config_dir_and_data(config)
+
+        try:
+            monkeypatch.setenv("WEBHOOK_SERVER_DATA_DIR", temp_dir)
+
+            repo_config = Config(repository="repo1")
+            assert repo_config.get_value("default-status-checks") == [
+                "WIP",
+                "can-be-merged",
+                "ci/my-external-check",
+            ]
Evidence
PR Compliance ID 4 requires tests that cover global-only behavior, repo-level overrides, and
precedence over global configuration. The added test configures only repo-level
default-status-checks and asserts get_value for that repo, without any scenario where global and
repo-level values coexist or where required status checks are computed/validated.

Automated tests cover repo-level default-status-checks behavior
webhook_server/tests/test_config_schema.py[277-299]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new test for per-repo `default-status-checks` does not cover the required behaviors: (1) global-only defaults still work, (2) repo-level values override global values when both are present, and (3) the computed required status checks reflect this precedence.

## Issue Context
Compliance requires automated coverage for repo-level overrides and precedence over global configuration for required status checks.

## Fix Focus Areas
- webhook_server/tests/test_config_schema.py[277-302]
- webhook_server/tests/test_github_repository_settings.py[444-505]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Schema test not enforced 🐞 Bug ⚙ Maintainability
Description
test_per_repo_default_status_checks asserts Config.get_value() behavior but never checks that
webhook_server/config/schema.yaml actually allows repositories.*.default-status-checks;
Config.__init__() does not perform schema validation, so this test can pass even if the schema
regresses. This weakens CI coverage for the main purpose of the PR (schema acceptance at repo
level).
Code

webhook_server/tests/test_config_schema.py[R277-301]

+    def test_per_repo_default_status_checks(
+        self, valid_minimal_config: dict[str, Any], monkeypatch: pytest.MonkeyPatch
+    ) -> None:
+        """Test that default-status-checks is accepted at per-repo level and resolved at runtime."""
+        config = valid_minimal_config.copy()
+        config["repositories"] = {
+            "repo1": {
+                "name": "org/repo1",
+                "default-status-checks": ["WIP", "can-be-merged", "ci/my-external-check"],
+            },
+        }
+
+        temp_dir = self.create_temp_config_dir_and_data(config)
+
+        try:
+            monkeypatch.setenv("WEBHOOK_SERVER_DATA_DIR", temp_dir)
+
+            repo_config = Config(repository="repo1")
+            assert repo_config.get_value("default-status-checks") == [
+                "WIP",
+                "can-be-merged",
+                "ci/my-external-check",
+            ]
+        finally:
+            shutil.rmtree(temp_dir)
Evidence
The added test only instantiates Config and checks get_value(), while Config.__init__()
performs only file existence/repositories presence/label validation and does not load or validate
schema.yaml.

webhook_server/tests/test_config_schema.py[277-301]
webhook_server/libs/config.py[13-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`test_per_repo_default_status_checks` is intended to confirm that per-repo `default-status-checks` is schema-accepted, but it only checks runtime resolution via `Config.get_value()`.

## Issue Context
`Config` does not validate against `schema.yaml`, so the test does not fail if the schema is missing the new property.

## Fix Focus Areas
- webhook_server/tests/test_config_schema.py[277-301]
- webhook_server/config/schema.yaml[315-340]

## Suggested fix
Add a schema assertion similar to existing schema-focused tests in this file, e.g. load `schema.yaml` and assert:
- `"default-status-checks" in schema["properties"]["repositories"]["additionalProperties"]["properties"]`
Optionally also assert its type is `array` with `items.type: string`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Validator skips repo list ✓ Resolved 🐞 Bug ☼ Reliability
Description
The repo-level schema now allows default-status-checks, but the docs-recommended validator script
(webhook_server/tests/test_schema_validator.py) does not type-check this field under repositories,
so invalid types can pass "validation". If default-status-checks is mis-typed (e.g., string),
runtime code will later crash when it assumes a list and performs list concatenation in repository
bootstrap.
Code

webhook_server/config/schema.yaml[R336-340]

+        default-status-checks:
+          type: array
+          items:
+            type: string
+          description: Override global default-status-checks for this repository
Evidence
Schema now documents per-repo default-status-checks, but the validator’s per-repo array_fields
list omits it, while runtime bootstrap assumes the value is a list and concatenates it with another
list. The troubleshooting docs recommend this validator as the way to validate configs before
restart, making the gap user-impacting.

webhook_server/config/schema.yaml[315-340]
webhook_server/tests/test_schema_validator.py[146-198]
webhook_server/utils/github_repository_settings.py[290-294]
docs/troubleshooting.md[3-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`default-status-checks` is now a supported per-repo config field, but `webhook_server/tests/test_schema_validator.py` doesn’t validate it at the repository level.

## Issue Context
Docs instruct users to validate configs using this script; if a user sets `repositories.<repo>.default-status-checks` to a non-list, the validator will not catch it, and bootstrap can crash when constructing the required checks list.

## Fix Focus Areas
- webhook_server/tests/test_schema_validator.py[146-198]
- webhook_server/utils/github_repository_settings.py[290-294]
- docs/troubleshooting.md[5-8]

## Suggested fix
1) Add `"default-status-checks"` to the repository-level `array_fields` in `ConfigValidator._validate_single_repository`.
2) Optionally validate that all items are strings.
3) Add/extend a test (could be in `test_schema_validator.py` or another pytest file) that fails when `default-status-checks` is not a list at repo level.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@myakove-bot

Copy link
Copy Markdown
Collaborator

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Pre-commit Checks: pre-commit runs automatically if .pre-commit-config.yaml exists
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message
  • /security-override - Set security check runs to pass (maintainers only)
  • /security-override cancel - Re-run security checks

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest python-module-install - Test Python package installation
  • /retest pre-commit - Run pre-commit hooks and checks
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3
  • /cherry-pick-retry <branch> - Retry a failed cherry-pick (merged PRs only)

Branch Management

  • /rebase - Rebase this PR branch onto its base branch

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. LGTM Count: Minimum 1 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  5. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • myakove
  • rnetser

Reviewers:

  • myakove
  • rnetser
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6[1m])
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])
  • Test Oracle: Triggers: approved (claude/claude-opus-4-6[1m]); /test-oracle can be used anytime
Security Checks
  • Suspicious Path Detection: Monitors paths: .claude/, .vscode/, .cursor/, .devcontainer/, .pi/, .github/workflows/, .github/actions/
  • Committer Identity Check: Verifies last committer matches PR author
  • Mandatory: Security checks block merge (use /security-override to bypass — maintainers only)

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Enable per-repository default-status-checks override via config schema
✨ Enhancement 🧪 Tests 📝 Documentation 🕐 10-20 Minutes

Grey Divider

Walkthroughs

Description
• Allow default-status-checks under per-repository config by extending YAML schema.
• Add example repo-level override configuration for external CI required checks.
• Validate schema acceptance and runtime resolution with a dedicated Config-based test.
Diagram
graph TD
  A["docs/repository-overrides.md"] --> B["examples/config.yaml"] --> C["webhook_server/config/schema.yaml"] --> D["webhook_server/tests/test_config_schema.py"] --> E["Config(repository=repo)"] --> F["get_value(default-status-checks)"] --> G["Merge gate checks"]
Loading
High-Level Assessment

The chosen approach is optimal: runtime already supported per-repo overrides, so extending the schema (plus adding an example, documentation, and a focused regression test) fixes the real blocker without introducing new configuration semantics. A deeper schema refactor (e.g., factoring common property definitions via $defs/$ref) was considered but would add churn without improving the behavior needed for this issue.

Grey Divider

File Changes

Enhancement (1)
schema.yaml Allow default-status-checks in per-repository schema properties +5/-0

Allow default-status-checks in per-repository schema properties

• Updates the YAML schema to accept 'default-status-checks' under each repository entry as an array of strings, enabling schema validation for repo-level overrides.

webhook_server/config/schema.yaml


Tests (1)
test_config_schema.py Test schema acceptance and runtime resolution of per-repo default-status-checks +26/-0

Test schema acceptance and runtime resolution of per-repo default-status-checks

• Adds a regression test that writes a config with a repo-level 'default-status-checks', constructs 'Config(repository=...)', and asserts 'get_value()' returns the per-repo list.

webhook_server/tests/test_config_schema.py


Documentation (2)
repository-overrides.md Document per-repo override support for default-status-checks +1/-0

Document per-repo override support for default-status-checks

• Adds 'default-status-checks' to the repository override table, clarifying that it can be set per-repository to override the global value.

docs/repository-overrides.md


config.yaml Add per-repo default-status-checks example configuration +4/-0

Add per-repo default-status-checks example configuration

• Extends the sample repository configuration to demonstrate overriding 'default-status-checks' for a specific repo, including external CI check names.

examples/config.yaml


Grey Divider

Qodo Logo

Comment thread webhook_server/tests/test_config_schema.py
Comment thread webhook_server/tests/test_config_schema.py
Comment thread webhook_server/config/schema.yaml
@qodo-code-review

qodo-code-review Bot commented Jun 14, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 5336771

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo requirement gap) — Missing precedence tests for checks

Addressed: Fixed — added test_per_repo_default_status_checks_falls_back_to_global (global-only) and test_per_repo_default_status_checks_overrides_global (repo overrides global, asserts global-check not in result).

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Fixed — added test_schema_allows_per_repo_default_status_checks that loads schema.yaml directly and asserts default-status-checks exists in per-repo properties with correct type (array of strings).

webhook_server/config/schema.yaml:336 (qodo bug) — Validator skips repo list

Addressed: Fixed — added default-status-checks to the array_fields list in ConfigValidator._validate_single_repository. Invalid types (e.g., string) are now caught by the validator.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Already addressed in previous commit — added test_schema_allows_per_repo_default_status_checks which loads schema.yaml directly and asserts the property exists with correct type.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Already addressed — test_schema_allows_per_repo_default_status_checks loads schema.yaml directly and asserts the property exists. See commit 5336771.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Already addressed in commit 5336771 — test_schema_allows_per_repo_default_status_checks loads schema.yaml directly.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Addressed in commit 5336771 — see test_schema_allows_per_repo_default_status_checks.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Addressed — see test_schema_allows_per_repo_default_status_checks in commit 5336771.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Addressed: Addressed in commit 5336771.

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

/build-and-push-container

@myakove-bot

Copy link
Copy Markdown
Collaborator

New container for ghcr.io/myk-org/github-webhook-server:pr-1112 published

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

/verified

@rnetser

rnetser commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review re-review

@rnetser

rnetser commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@rnetser

rnetser commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review re-review

rnetser added 2 commits June 16, 2026 14:07
Config.get_value() already resolves per-repo → global config, so
the runtime code already supported per-repo default-status-checks.
Only the YAML schema was missing the property at the per-repo level,
causing schema validation to reject it.

Add default-status-checks to the per-repo properties in the schema,
add a per-repo example in examples/config.yaml, add a schema
validation test that exercises Config() constructor and get_value()
resolution, and document the override in repository-overrides.md.

Closes #1111

Signed-off-by: rnetser <rnetser@redhat.com>
Assisted-by: Claude <noreply@anthropic.com>
…-status-checks

Addresses Qodo review findings — adds global fallback, repo-override
precedence, and direct schema assertion tests. Also adds
default-status-checks to validator array_fields.

Signed-off-by: rnetser <rnetser@redhat.com>
Assisted-by: Claude <noreply@anthropic.com>
@rnetser rnetser force-pushed the feat/issue-1111-repo-level-status-checks branch from 5336771 to 9985cf5 Compare June 16, 2026 11:08
@qodo-code-review

qodo-code-review Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 9985cf5

@myakove-bot

Copy link
Copy Markdown
Collaborator

Clean rebase detected — no code changes compared to previous head (5336771).
The following labels were preserved: verified, commented-rnetser.

@rnetser

rnetser commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/tests/test_config_schema.py:277 (qodo bug) — Schema test not enforced

Skipped: Already addressed — test_schema_allows_per_repo_default_status_checks (line 344) directly loads schema.yaml and asserts default-status-checks exists in repositories.additionalProperties.properties with type array and items.type string. This is the dedicated schema regression test.

@myakove myakove merged commit 993f795 into main Jun 16, 2026
9 of 10 checks passed
@myakove myakove deleted the feat/issue-1111-repo-level-status-checks branch June 16, 2026 11:54
@myakove-bot

Copy link
Copy Markdown
Collaborator

Successfully removed PR tag: ghcr.io/myk-org/github-webhook-server:pr-1112.

@myakove-bot

Copy link
Copy Markdown
Collaborator

New container for ghcr.io/myk-org/github-webhook-server:latest published

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.

feat: support default-status-checks at repository level

3 participants