From fcb75ee0ebb5778a1f4e7fa66e1dbd62d465c163 Mon Sep 17 00:00:00 2001 From: laughingman7743 Date: Wed, 30 Sep 2026 15:12:04 +0900 Subject: [PATCH 1/4] ci: run SQLAlchemy and Spark tests when shared core modules change The changes job selected the SQLAlchemy and Spark suites only from their own package and test paths, so a ready pull request that changed only a top-level module both import (such as pyathena/util.py or pyathena/common.py) or a shared test fixture skipped them. Treat the top-level modules of pyathena and pyathena.aio, and the shared test fixtures (tests/__init__.py, tests/pyathena/{conftest,tables,util}.py, tests/pyathena/aio/conftest.py, tests/resources/), as shared by both suites. Changes limited to the result-set or filesystem packages still skip them. Closes #896 Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d7abd731e..9e78d1433 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -68,9 +68,10 @@ jobs: # requests run none. A ready pull request always runs the PyAthena suite; it # runs the SQLAlchemy tests (the compliance suites and the PyAthena suite's # SQLAlchemy tests) and the Spark tests only when their code, tests, - # dependencies, or this workflow change. Pull requests and the schedule test - # the newest Python version; a dispatch tests the requested versions or - # every version, and the Release workflow every version. + # dependencies, this workflow, the top-level modules of pyathena and + # pyathena.aio, or the shared test fixtures change. Pull requests and the + # schedule test the newest Python version; a dispatch tests the requested + # versions or every version, and the Release workflow every version. changes: if: >- github.event_name != 'pull_request' || @@ -123,8 +124,11 @@ jobs: files=$(gh api "repos/$REPO/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename') printf 'Changed files:\n%s\n' "$files" shared='^(\.github/workflows/test(-suite)?\.yaml|justfile|pyproject\.toml|uv\.lock)$' - sqla="$shared|^pyathena/(aio/)?sqlalchemy/|^tests/sqlalchemy/|^tests/pyathena/(aio/)?sqlalchemy/|^setup\.cfg$" - spark="$shared|^pyathena/(aio/)?spark/|^tests/pyathena/(aio/)?spark/" + # The top-level modules and the shared test fixtures, which both the + # SQLAlchemy and the Spark code and tests import. + core='^pyathena/(aio/)?[^/]+\.py$|^tests/(__init__|pyathena/(conftest|tables|util)|pyathena/aio/conftest)\.py$|^tests/resources/' + sqla="$shared|$core|^pyathena/(aio/)?sqlalchemy/|^tests/sqlalchemy/|^tests/pyathena/(aio/)?sqlalchemy/|^setup\.cfg$" + spark="$shared|$core|^pyathena/(aio/)?spark/|^tests/pyathena/(aio/)?spark/" if grep -qE "$sqla" <<< "$files"; then echo "sqla=true" >> "$GITHUB_OUTPUT" else From 3deba1dd43a172a3b394fe66510445dc167c849d Mon Sep 17 00:00:00 2001 From: laughingman7743 Date: Wed, 30 Sep 2026 15:16:00 +0900 Subject: [PATCH 2/4] ci: describe the shared core paths by how the suites load them Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9e78d1433..b1f6e46fb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -124,8 +124,8 @@ jobs: files=$(gh api "repos/$REPO/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename') printf 'Changed files:\n%s\n' "$files" shared='^(\.github/workflows/test(-suite)?\.yaml|justfile|pyproject\.toml|uv\.lock)$' - # The top-level modules and the shared test fixtures, which both the - # SQLAlchemy and the Spark code and tests import. + # The SQLAlchemy and Spark packages load the top-level modules, + # directly or transitively, and their tests use the shared fixtures. core='^pyathena/(aio/)?[^/]+\.py$|^tests/(__init__|pyathena/(conftest|tables|util)|pyathena/aio/conftest)\.py$|^tests/resources/' sqla="$shared|$core|^pyathena/(aio/)?sqlalchemy/|^tests/sqlalchemy/|^tests/pyathena/(aio/)?sqlalchemy/|^setup\.cfg$" spark="$shared|$core|^pyathena/(aio/)?spark/|^tests/pyathena/(aio/)?spark/" From 020dc45b7842155239b43f4905b23690d0e38ae6 Mon Sep 17 00:00:00 2001 From: laughingman7743 Date: Wed, 30 Sep 2026 15:22:08 +0900 Subject: [PATCH 3/4] ci: include the test package initializers in the shared core paths Python loads tests/pyathena/__init__.py and tests/pyathena/aio/__init__.py when importing the SQLAlchemy and Spark tests. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b1f6e46fb..e7decb31d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -126,7 +126,7 @@ jobs: shared='^(\.github/workflows/test(-suite)?\.yaml|justfile|pyproject\.toml|uv\.lock)$' # The SQLAlchemy and Spark packages load the top-level modules, # directly or transitively, and their tests use the shared fixtures. - core='^pyathena/(aio/)?[^/]+\.py$|^tests/(__init__|pyathena/(conftest|tables|util)|pyathena/aio/conftest)\.py$|^tests/resources/' + core='^pyathena/(aio/)?[^/]+\.py$|^tests/(pyathena/(aio/)?)?(__init__|conftest)\.py$|^tests/pyathena/(tables|util)\.py$|^tests/resources/' sqla="$shared|$core|^pyathena/(aio/)?sqlalchemy/|^tests/sqlalchemy/|^tests/pyathena/(aio/)?sqlalchemy/|^setup\.cfg$" spark="$shared|$core|^pyathena/(aio/)?spark/|^tests/pyathena/(aio/)?spark/" if grep -qE "$sqla" <<< "$files"; then From 7439d76ea0e9b78797eca35bb82cff109f39e678 Mon Sep 17 00:00:00 2001 From: laughingman7743 Date: Thu, 1 Oct 2026 09:02:05 +0900 Subject: [PATCH 4/4] ci: select the SQLAlchemy and Spark tests with dorny/paths-filter Replace the grep over the pull request files API with dorny/paths-filter v4.0.3, which reads the same API, so the path lists are YAML globs instead of long regular expressions. The selection is unchanged for every tracked file; a renamed file now also matches by its previous path. Events other than pull_request still run every suite, and the Python version selection stays in its own step. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test.yaml | 76 +++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e7decb31d..3bf426e80 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -81,16 +81,53 @@ jobs: permissions: pull-requests: read outputs: - sqla: ${{ steps.filter.outputs.sqla }} - spark: ${{ steps.filter.outputs.spark }} - python-versions: ${{ steps.filter.outputs.python-versions }} + sqla: ${{ github.event_name != 'pull_request' || steps.paths.outputs.sqla == 'true' }} + spark: ${{ github.event_name != 'pull_request' || steps.paths.outputs.spark == 'true' }} + python-versions: ${{ steps.versions.outputs.python-versions }} steps: - - id: filter + - id: paths + if: github.event_name == 'pull_request' + uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 + with: + filters: | + shared: &shared + - .github/workflows/test.yaml + - .github/workflows/test-suite.yaml + - justfile + - pyproject.toml + - uv.lock + # The SQLAlchemy and Spark packages load the top-level modules, + # directly or transitively, and their tests use the shared fixtures. + core: &core + - pyathena/*.py + - pyathena/aio/*.py + - tests/__init__.py + - tests/pyathena/__init__.py + - tests/pyathena/conftest.py + - tests/pyathena/tables.py + - tests/pyathena/util.py + - tests/pyathena/aio/__init__.py + - tests/pyathena/aio/conftest.py + - tests/resources/** + sqla: + - *shared + - *core + - setup.cfg + - pyathena/sqlalchemy/** + - pyathena/aio/sqlalchemy/** + - tests/sqlalchemy/** + - tests/pyathena/sqlalchemy/** + - tests/pyathena/aio/sqlalchemy/** + spark: + - *shared + - *core + - pyathena/spark/** + - pyathena/aio/spark/** + - tests/pyathena/spark/** + - tests/pyathena/aio/spark/** + - id: versions env: - GH_TOKEN: ${{ github.token }} EVENT_NAME: ${{ github.event_name }} - REPO: ${{ github.repository }} - PR_NUMBER: ${{ github.event.pull_request.number }} REQUESTED_VERSIONS: ${{ inputs.python-versions }} # Every supported version, oldest first; keep in sync with the # pyproject.toml classifiers. @@ -114,31 +151,6 @@ jobs: ;; esac echo "python-versions=$versions" >> "$GITHUB_OUTPUT" - if [[ "$EVENT_NAME" != "pull_request" ]]; then - { - echo "sqla=true" - echo "spark=true" - } >> "$GITHUB_OUTPUT" - exit 0 - fi - files=$(gh api "repos/$REPO/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename') - printf 'Changed files:\n%s\n' "$files" - shared='^(\.github/workflows/test(-suite)?\.yaml|justfile|pyproject\.toml|uv\.lock)$' - # The SQLAlchemy and Spark packages load the top-level modules, - # directly or transitively, and their tests use the shared fixtures. - core='^pyathena/(aio/)?[^/]+\.py$|^tests/(pyathena/(aio/)?)?(__init__|conftest)\.py$|^tests/pyathena/(tables|util)\.py$|^tests/resources/' - sqla="$shared|$core|^pyathena/(aio/)?sqlalchemy/|^tests/sqlalchemy/|^tests/pyathena/(aio/)?sqlalchemy/|^setup\.cfg$" - spark="$shared|$core|^pyathena/(aio/)?spark/|^tests/pyathena/(aio/)?spark/" - if grep -qE "$sqla" <<< "$files"; then - echo "sqla=true" >> "$GITHUB_OUTPUT" - else - echo "sqla=false" >> "$GITHUB_OUTPUT" - fi - if grep -qE "$spark" <<< "$files"; then - echo "spark=true" >> "$GITHUB_OUTPUT" - else - echo "spark=false" >> "$GITHUB_OUTPUT" - fi # The three suites create their own schemas and tables, so they run in # parallel; each is still a separate job for "Re-run failed jobs".