Run AWS test suites only on ready pull requests and related changes - #837
Conversation
Draft pull requests now run only the offline lint job. A ready pull request runs the PyAthena suite, and runs the SQLAlchemy compliance suites and the Spark tests only when their code, tests, dependencies, or the Test workflows change. The weekly schedule and manual dispatch still run every suite. Refs #834 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| # SQLAlchemy compliance suites and the Spark tests only when their code, | ||
| # tests, dependencies, or this workflow change. | ||
| changes: | ||
| if: >- |
There was a problem hiding this comment.
Self-review round one (implementation behavior): FINDINGS, repaired
- Perspective: behavior and failure paths of the workflow conditions, framework contracts (GitHub Actions
needs/ifon reusable-workflow jobs,pull_requestactivity types), and simplicity. - Base
2a107adf1f68713e7b7da2e334cc98ca543b7e7d, head99948ec7fd9ea8524c2b997fe9700562c27aa5a0(initial pass), repair checked at44fab0164369491f4171cb6f55f7509a8f40fb65. - Covered:
.github/workflows/test.yaml,.github/workflows/test-suite.yaml, the toxpassenvinpyproject.toml,docs/testing.md,AGENTS.md,.agents/skills/development-workflow/SKILL.md. - Checked:
- A Draft or fork PR skips
changes, so the threeneeds: changesjobs are skipped. Observed on the Draft run:lintpassed,changes/test/test-sqla/test-sqla-asyncskipped. ready_for_reviewhasdraft == false. Schedule and dispatch take the non-PR branch, which sets both outputs totrue.- A failing
gh apicall fails the step underbash -e. The dependent jobs are then skipped and the run is red, not silently green. - An empty
PYTEST_ADDOPTSis a no-op. With the ignores set,pytest --collect-only tests/pyathenacollects no Spark tests. - No branch protection requires these checks, so skipped jobs do not block merges.
- A Draft or fork PR skips
- Finding:
docs/testing.md:151said lint runs on every pull request.paths-ignoremeans docs/Markdown-only PRs do not run the Test workflow at all. Repaired in 44fab01 (this line and thelintjob comment at line 37). - Limit: the skip path for a non-dialect ready PR can only be observed after merge.
|
|
||
| ## GitHub Actions | ||
|
|
||
| The Test workflow runs for pull requests that change files other than `docs/` and Markdown. |
There was a problem hiding this comment.
Self-review round two (claims and operational behavior): FINDINGS, repaired
- Base
2a107adf1f68713e7b7da2e334cc98ca543b7e7d, head44fab0164369491f4171cb6f55f7509a8f40fb65. - Claims checked:
- The trigger table here matches the
changesfilter. Verified locally against sample file lists (dialect, compliance tests, Spark,uv.lock, workflow, docs workflow,tests/pyathena/sqlalchemy/). - Dispatch runs every suite, so the release procedure (dispatch on master) keeps full coverage.
gh pr ready --undois the command that returns a PR to Draft.- The cost figures in the PR body (65% of sampled queries from the compliance suites, about $20 Spark) come from the measurements recorded on Reduce the AWS cost of integration tests without reducing real-service coverage #834.
- The trigger table here matches the
- Finding: the PR body said lint previously ran only inside the AWS jobs. The Scripts workflow also runs
just lint(viajust scripts) for script, workflow, and dependency changes. PR body corrected. - Operator view: a Draft PR now makes no AWS calls. A ready non-dialect PR runs 5 jobs instead of 15. Weekly and pre-release runs still cover everything. A regression in a skipped suite surfaces at the next weekly or release run.
- Deferred: the smaller Python matrix for intermediate pushes (Reduce the AWS cost of integration tests without reducing real-service coverage #834 item 2), pending cost measurement.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| # ready_for_review starts the AWS jobs for a pull request leaving Draft; | ||
| # converted_to_draft starts a run without them, which cancels any | ||
| # in-progress run through the concurrency group. | ||
| types: [opened, synchronize, reopened, ready_for_review, converted_to_draft] |
There was a problem hiding this comment.
Independent review (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc2e-d2c6-7920-a11f-1a93c81fb383): FINDINGS. This was a static review: the reviewer was told not to edit, run tests, or access GitHub, and did none of these.
- Snapshot: detached worktree at head
44fab0164369491f4171cb6f55f7509a8f40fb65, base2a107adf1f68713e7b7da2e334cc98ca543b7e7d, literal diff supplied. No PR number, PR description, or prior findings were included in the prompt. - Covered: the diff, the changed workflow/process files,
justfile, the tox config, and the SQLAlchemy/Spark callers relevant to the path filters. - Finding 1 (
test.yaml:13at the reviewed head): the trigger list omittedconverted_to_draft. Returning a Ready PR to Draft while its AWS jobs ran started no new run, so the concurrency group did not cancel them. That contradicted the documented Draft behavior and the skill'sgh pr ready --undostep. Accepted and repaired in 7787388:converted_to_draftnow starts a run in whichchangesand the AWS jobs are skipped, and that run cancels the in-progress one.docs/testing.mdstates this. - Finding 2 (path filters, line 88 at this head): shared modules such as
pyathena/util.pytrigger neither the compliance suites nor the Spark tests, although those callers import them. Rejected as a deliberate trade-off, not a defect. Reduce the AWS cost of integration tests without reducing real-service coverage #834's agreed direction limits the compliance-suite trigger to the dialect, its tests, and dependencies, and relies on the weekly run and the pre-release dispatch (both run every suite) to catch regressions from other modules.docs/testing.mdlists exactly which paths trigger each suite.
There was a problem hiding this comment.
Repair self-review, both perspectives, for 7787388 (range 44fab0164369491f4171cb6f55f7509a8f40fb65..7787388be47f2fe656c628568567c513f7585edc): CLEAN
- Round one (behavior): a
converted_to_draftevent hasdraft == true, sochangesand the three AWS jobs are skipped and onlylintruns. The run shares therefs/pull/N/mergeconcurrency group, socancel-in-progresscancels an in-progress AWS run.paths-ignorestill applies, so docs-only PRs start no run, as before. actionlint passes. - Round two (claims and operations): the new
docs/testing.mdsentence (converting back to Draft cancels the AWS jobs) and the workflow comment match this behavior. The extra cost is one offlinelintjob per conversion to Draft. The skill'sgh pr ready --undostep now also stops any AWS jobs still running.
There was a problem hiding this comment.
Independent follow-up (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc33-0cbe-7793-9652-9b5bd11a373f), static review of 44fab01..7787388: FINDINGS
- Confirmed that the repair fixes finding 1:
converted_to_draftstarts a run in whichchangesand the AWS jobs are skipped, and the shared concurrency group cancels the in-flight run. - New finding:
paths-ignorealso applies toconverted_to_draft. If a Ready PR reverts its code while AWS jobs run, it is left changing only Markdown, and neither the revert nor the conversion to Draft starts a run. The unconditional claim that converting to Draft cancels the jobs indocs/testing.mdwas therefore too broad. Accepted; wording repaired in 1ec4635 (7787388..1ec4635): the docs sentence is now scoped to the pull requests the workflow runs for, and the workflow comment notes thatpaths-ignoreapplies. Behavior is unchanged. For a docs-only PR, the in-flight jobs finish normally and the docs-only state needs no AWS coverage. - Repair self-review, both perspectives: CLEAN. actionlint and
just docs lintpass. The sentence now follows the section's scope (docs/testing.md:151). No other prose claims unconditional cancellation.
There was a problem hiding this comment.
Independent follow-up 2 (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc35-0bd0-7522-82f0-064c7f046913), static review of 7787388..1ec4635: FINDINGS
- Confirmed that the paths-ignore wording repair resolves the previous finding.
- New finding:
docs/testing.md:163("these pull requests") still included external forks from line 152. For a fork PR, marking it Ready starts no AWS jobs, becausechangesrequires the head repository to match. Accepted; wording repaired in 46d3c52 (1ec4635..46d3c52): the table row and the sentence now say "a pull request from a branch of this repository". Behavior is unchanged. - Repair self-review, both perspectives: CLEAN.
just docs lintpasses. The fork policy paragraph that follows (line 170) is unchanged and consistent with the new wording.
There was a problem hiding this comment.
Independent follow-up 3 (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc37-16c6-74e1-b7cd-f63b1170cee1), static review of 1ec4635..46d3c52 plus a full pass over the GitHub Actions section: FINDINGS
- Confirmed that the fork-scoping repair matches the repository check in
test.yaml. - Finding: rewording for forks dropped the docs-only scope, so the Draft-cancellation claim at
docs/testing.md:163was unconditional again, which regresses follow-up 1. Accepted; repaired in 2c3588b (46d3c52..2c3588b): the sentence now covers a pull request from a branch of this repository that still changes files other thandocs/and Markdown. Behavior is unchanged. - Repair self-review, both perspectives: CLEAN.
just docs lintpasses. The sentence now states both conditions thatpaths-ignoreand thechangesjob impose.
There was a problem hiding this comment.
Independent follow-up 4 (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc39-9c42-7210-b055-5a49c602d347), static review of 46d3c52..2c3588b plus a final pass over the GitHub Actions section of docs/testing.md against test.yaml and test-suite.yaml: CLEAN. The reviewer confirmed that the cancellation sentence is now limited to same-repository PRs that still change files outside docs/ and Markdown, and that the remaining claims in the section match the workflow definitions. Independent review is complete for head 2c3588ba2ceacd15737a4f60af4a508ee66c246e.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a skip-sqla input to the reusable test suite, like skip-spark, and count the PyAthena suite's SQLAlchemy test directories as related files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| description: Skip the Spark tests of the PyAthena suite | ||
| type: boolean | ||
| default: false | ||
| skip-sqla: |
There was a problem hiding this comment.
Self-review, both rounds, of the skip-sqla change requested by the maintainer (2c3588ba2ceacd15737a4f60af4a508ee66c246e..87aacabba94436acb6d30a39a2aae044ae5ac879): CLEAN
- Round one (behavior):
PYTEST_ADDOPTSis a folded scalar that joins the two conditional ignore groups. With both inputs false it is whitespace only, which pytest treats as no options (checked withPYTEST_ADDOPTS=' ': 1,889 tests collected).- With both inputs true, 1,297 tests are collected and none come from
tests/pyathena/(aio/)spark/ortests/pyathena/(aio/)sqlalchemy/. Neither directory has aconftest.py, so ignoring them removes no shared fixtures. skip-sqlareuses thesqlaoutput, which now also matchestests/pyathena/(aio/)sqlalchemy/: editing those tests runs them, and also runs the compliance suites. This keeps a single SQLAlchemy trigger, as for Spark.- Only the
test(pyathena) job receivesskip-sqla; the compliance jobs keep their job-levelif. actionlint andjust scriptspass.
- Round two (claims and operations):
docs/testing.mdnow names the "SQLAlchemy tests" column and lists both parts and all trigger paths. It states that the PyAthena suite runs without the skipped directories.just docs lintpasses.- Operator effect: a ready PR that touches neither area now runs 1,297 of the PyAthena suite's 1,889 tests. Dialect regressions caused by core modules (cursor, formatter, converter) are then caught by the weekly or pre-release run, the same trade-off already accepted for Spark and the compliance suites.
- The PR body was updated to describe both inputs and the observed Ready/Draft runs.
There was a problem hiding this comment.
Independent follow-up (relayed): Codex, via the Claude Code codex:codex-rescue agent (Codex thread 01a0dc58-a3ed-7892-ad0b-91b3546dc52a), static review of 2c3588b..87aacab: CLEAN.
The reviewer checked:
- the folded scalar and boolean expressions (the ignore groups are space-separated, and empty groups leave only harmless whitespace);
PYTEST_ADDOPTSpropagation through the toxpassenvinto the pytest command;- the filter regexes;
- that no test outside the ignored directories imports fixtures or setup from them;
- that
docs/testing.mdmatches the workflow.
No builds or tests were run. Independent review is complete for head 87aacabba94436acb6d30a39a2aae044ae5ac879.
WHAT
Changes when the Test workflow runs the AWS suites:
test.yamllintjob runsjust lintoffline for every Test run, including Draft and fork pull requests. Until now, most pull requests ran lint only inside the AWS jobs; the Scripts workflow runs it only for script, workflow, and dependency changes.changesjob lists the pull request's files through the GitHub API and decides whether the SQLAlchemy tests and the Spark tests run. The SQLAlchemy tests are the compliance suites plus the PyAthena suite'stests/pyathena/(aio/)sqlalchemy/; the Spark tests are itstests/pyathena/(aio/)spark/. It is skipped for Draft and fork pull requests, so the AWS jobs that need it are skipped too.ready_for_reviewstarts the AWS jobs when a pull request leaves Draft.converted_to_draftstarts a run without them, which cancels a run still in progress through the concurrency group.pyproject.toml,uv.lock,justfile, and the Test workflows. SQLAlchemy tests:pyathena/(aio/)sqlalchemy/,tests/sqlalchemy/,tests/pyathena/(aio/)sqlalchemy/,setup.cfg. Spark tests:pyathena/(aio/)spark/,tests/pyathena/(aio/)spark/.test-suite.yaml: newskip-sparkandskip-sqlainputs, which add--ignoreoptions for the PyAthena suite's Spark and SQLAlchemy test directories toPYTEST_ADDOPTS.pyproject.tomlpassesPYTEST_ADDOPTSthrough tox.docs/testing.md,AGENTS.md, and thedevelopment-workflowskill describe the new flow: reviews happen in Draft,gh pr readystarts AWS CI, and a failed AWS job returns the PR to Draft.gh workflow run test.yaml --ref <branch>gives AWS results while the PR is still Draft.Unchanged:
paths-ignore, the concurrency group, the fork guard intest-suite.yaml, and the release procedure, since dispatching on master runs every suite.Deferred from #834: a smaller Python matrix for intermediate pushes (item 2). It will be revisited after measuring the effect of this change.
WHY
Refs #834. The test account cost about $143 in September. The cost scales with the number of Athena queries, and each Test run started 15 jobs, including runs for Draft pull requests. In a sample of 10,000 CI queries, 65% came from the compliance suites, and Spark cost about $20. Regressions in suites skipped on a pull request are caught by the weekly run and by the dispatch before a release.
TEST
Tested commit: 87aacab
just scripts(includesjust lint, actionlint, shellcheck, andscripts/tests): passed, 108 tests.mypy .on Python 3.12, thelintjob's interpreter, passed (run on 99948ec; later commits do not change Python code).just docs lintandmarkdownlint-cli2 '.agents/skills/**/*.md' AGENTS.md: 0 errors.pytest --collect-only tests/pyathenawith the Spark and SQLAlchemy ignores inPYTEST_ADDOPTS: 1,297 tests, none under the ignored directories. Without them: 1,889 tests.changesfilter locally on sample file lists:pyathena/cursor.py,tests/pyathena/test_cursor.py, and.github/workflows/docs.yaml→ neitherpyathena/(aio/)sqlalchemy/base.py,tests/sqlalchemy/test_suite.py,tests/pyathena/(aio/)sqlalchemy/test_base.py, andsetup.cfg→ SQLAlchemy onlypyathena/spark/cursor.pyandtests/pyathena/aio/spark/test_cursor.py→ Spark onlyuv.lockand.github/workflows/test-suite.yaml→ bothObserved on this pull request (at 2c3588b):
lintran;changesand the AWS jobs were skipped.changessucceeded and all 15 AWS jobs started, because the PR changes the Test workflows.lintonly) cancelled those AWS jobs.🤖 Generated with Claude Code