diff --git a/.asf.yaml b/.asf.yaml index 4ba611817a..f2d710ec8e 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -36,13 +36,44 @@ github: protected_branches: main: required_status_checks: - # strict means "Require branches to be up to date before merging". - strict: true + contexts: + # Repository policy and security checks. + - Analyze Actions + - Run zizmor 🌈 + - asf-allowlist-check + - rat + + # Documentation checks. + - docs + - markdown-link-check + + # Python workflow gates. + - python-ci-required + - python-integration-required required_pull_request_reviews: required_approving_review_count: 1 required_linear_history: true + rulesets: + - name: Merge Queue + target: branch + enforcement: active + conditions: + ref_name: + include: + - "~DEFAULT_BRANCH" + exclude: [] + rules: + - type: merge_queue + parameters: + check_response_timeout_minutes: 90 + grouping_strategy: ALLGREEN + max_entries_to_build: 1 + max_entries_to_merge: 1 + merge_method: SQUASH + min_entries_to_merge: 1 + min_entries_to_merge_wait_minutes: 0 pull_requests: # allow pull requests to merge automatically once all requirements are met allow_auto_merge: true diff --git a/.github/workflows/asf-allowlist-check.yml b/.github/workflows/asf-allowlist-check.yml index 3844789995..89053c77ee 100644 --- a/.github/workflows/asf-allowlist-check.yml +++ b/.github/workflows/asf-allowlist-check.yml @@ -25,6 +25,7 @@ name: "ASF Allowlist Check" on: pull_request: + merge_group: push: branches: - main diff --git a/.github/workflows/check-md-link.yml b/.github/workflows/check-md-link.yml index 6ea7eaa3b6..3e7bd88a11 100644 --- a/.github/workflows/check-md-link.yml +++ b/.github/workflows/check-md-link.yml @@ -27,9 +27,7 @@ on: branches: - 'main' pull_request: - paths: - - '.github/workflows/check-md-link.yml' - - 'mkdocs/**' + merge_group: workflow_dispatch: permissions: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b113d4bed8..e5e6b68bc1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,6 +24,7 @@ on: branches: [ "main" ] pull_request: branches: [ "main" ] + merge_group: schedule: - cron: '16 4 * * 1' diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index 3082656c7e..b5bf11b8ad 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -18,7 +18,9 @@ # name: "Run License Check" -on: pull_request +on: + pull_request: + merge_group: permissions: contents: read diff --git a/.github/workflows/python-ci-docs.yml b/.github/workflows/python-ci-docs.yml index 83f97135e3..bbf718d132 100644 --- a/.github/workflows/python-ci-docs.yml +++ b/.github/workflows/python-ci-docs.yml @@ -24,6 +24,7 @@ on: branches: - 'main' pull_request: + merge_group: permissions: contents: read diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 8ab526097f..4d3cebbbe2 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -24,19 +24,7 @@ on: branches: - 'main' pull_request: - paths: - - '**' # Include all files and directories in the repository by default. - - '!.github/workflows/**' # Exclude all workflow files - - '.github/workflows/python-ci.yml' # except the current file. - - '!.github/ISSUE_TEMPLATE/**' # Exclude files and directories that don't impact tests or code like templates, metadata, and documentation. - - '!.gitignore' - - '!.asf.yml' - - '!mkdocs/**' - - '!.gitattributes' - - '!README.md' - - '!CONTRIBUTING.md' - - '!LICENSE' - - '!NOTICE' + merge_group: permissions: contents: read @@ -127,3 +115,17 @@ jobs: run: uv sync --directory . --only-group dev --no-install-project - name: Mirror wheel CIBW_TEST_COMMAND run: uv run --directory . pytest tests/avro/test_decoder.py + + python-ci-required: + if: ${{ always() }} + needs: [lint-and-unit-test, windows-unit-test, cibw-dev-env-smoke-test] + runs-on: ubuntu-latest + steps: + - name: Verify Python CI jobs succeeded + env: + RESULTS: ${{ join(needs.*.result, ' ') }} + run: | + read -ra results <<< "$RESULTS" + for result in "${results[@]}"; do + test "$result" = "success" + done diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index 8c7337d1d3..55e52bbb20 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -24,13 +24,7 @@ on: branches: - 'main' pull_request: - paths: # Only run integration tests when Python (or the code they exercise) changes. - - '**/*.py' - - 'pyproject.toml' - - 'uv.lock' - - 'Makefile' - - 'dev/**' # docker-compose files and fixtures used by the integration suites. - - '.github/workflows/python-integration.yml' # this file itself. + merge_group: permissions: contents: read @@ -183,3 +177,17 @@ jobs: merge-multiple: true - name: Generate coverage report (75%) # Coverage threshold should only increase over time — never decrease it! run: COVERAGE_FAIL_UNDER=75 make coverage-report + + python-integration-required: + if: ${{ always() }} + needs: [integration-test, integration-test-s3, integration-test-adls, integration-test-gcs, integration-coverage-report] + runs-on: ubuntu-latest + steps: + - name: Verify Python integration jobs succeeded + env: + RESULTS: ${{ join(needs.*.result, ' ') }} + run: | + read -ra results <<< "$RESULTS" + for result in "${results[@]}"; do + test "$result" = "success" + done diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index eea0bd0983..6daaf43234 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -24,6 +24,7 @@ on: branches: ["main"] pull_request: branches: ["**"] + merge_group: permissions: {} diff --git a/AGENTS.md b/AGENTS.md index 1f7b18a544..d30e31bd63 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,6 +62,13 @@ lives under `pyiceberg/`, organized by concern rather than by engine: - Use existing test fixtures when possible. - We have a strong bias towards integration testing over mocks. Mocks should be avoided whenever possible and should only be used if similar, existing tests are using mocks. +### Required CI and Merge Queue + +- Keep the `required_status_checks.contexts` list in `.asf.yaml` synchronized whenever a required job/check is added, renamed, or removed. Each entry is a job/check context name, not a workflow filename. +- Verify that every required context reports for both `pull_request` and `merge_group`. Its producer workflow must run on both events. +- When a workflow uses an aggregate required job, such as `python-ci-required`, keep `if: always()` and its `needs` list in sync with every job whose result should block merging. +- Do not use `pull_request` path filters in workflows that produce required contexts. A skipped workflow does not report its required context, which blocks pull requests and causes Merge Queue entries to time out. + ## Commands - **Install / set up dev env:** `make install` (installs `uv`, syncs all extras, builds Cython, installs pre-commit hooks)