Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
01d4753
added unit test sharding
daniel-sanche Jun 12, 2026
a7502d4
run system tests concurrently
daniel-sanche Jun 12, 2026
9ad0f0c
added changes to many packages for testing
daniel-sanche Jun 12, 2026
02c7653
added sharding test file
daniel-sanche Jun 12, 2026
3c8d057
added unit-complete to gather all shards
daniel-sanche Jun 12, 2026
73ab091
changed shard params
daniel-sanche Jun 12, 2026
74f1ef7
fixed tests
daniel-sanche Jun 12, 2026
a450254
fix coverage
daniel-sanche Jun 12, 2026
af4d10c
fix system tests
daniel-sanche Jun 12, 2026
15916df
split out system test logs
daniel-sanche Jun 12, 2026
49cac0f
attempt fix for lint
daniel-sanche Jun 12, 2026
d8dd522
update system tests to show logs for each target
daniel-sanche Jun 12, 2026
de74a68
update sharding logic
daniel-sanche Jun 12, 2026
46d1583
fixed lint/mypy runs
daniel-sanche Jun 12, 2026
6e3531d
removed sqlalchemy-spanner from touched packages
daniel-sanche Jun 12, 2026
e6167bd
system tests print all logs in main build log
daniel-sanche Jun 12, 2026
fd5792d
removed many SHARD_TEST files
daniel-sanche Jun 12, 2026
8b825d5
updated lint and mypy logic
daniel-sanche Jun 12, 2026
32968a9
add shard descriptions
daniel-sanche Jun 12, 2026
ff1274f
remove global run on ci/ change
daniel-sanche Jun 12, 2026
c49b06d
attempt cover fix
daniel-sanche Jun 12, 2026
1cd8c1f
attempt fix for cover
daniel-sanche Jun 12, 2026
a0f5c9a
allow hidden files for cover
daniel-sanche Jun 12, 2026
71f444a
fail fast
daniel-sanche Jun 12, 2026
cf1a1f1
use individual coverage checks
daniel-sanche Jun 12, 2026
b00967f
loosen firestore coverage requirement
daniel-sanche Jun 12, 2026
7bb323c
activated more packages
daniel-sanche Jun 12, 2026
3633089
10 packages total
daniel-sanche Jun 13, 2026
980d8eb
change default for coverage percent
daniel-sanche Jun 13, 2026
a5cc497
activated 11th package (enable sharding)
daniel-sanche Jun 13, 2026
b36b559
fixed typo
daniel-sanche Jun 13, 2026
c3cf49e
change shard logic
daniel-sanche Jun 13, 2026
acdfb18
iterating on shard logic
daniel-sanche Jun 13, 2026
9c80a51
rename tests
daniel-sanche Jun 13, 2026
cf554ca
add label to number in shard
daniel-sanche Jun 13, 2026
886d6d9
unit tests fail if initialize fails
daniel-sanche Jun 13, 2026
83ca04a
added known-bad package
daniel-sanche Jun 13, 2026
ae05642
added summary to cover step
daniel-sanche Jun 13, 2026
7b565a4
added no-fail .coveragerc to sqlalchemy-spanner
daniel-sanche Jun 13, 2026
72503de
Merge branch 'main' into ci_sharding
daniel-sanche Jun 18, 2026
e34b654
reverted systen test changes
daniel-sanche Jun 19, 2026
6c1be8b
added github tag to test all packages
daniel-sanche Jul 6, 2026
8fb68d3
re-run when label added
daniel-sanche Jul 6, 2026
fb90860
don't trigger on label changes
daniel-sanche Jul 6, 2026
6123e7a
revered unrelated changes
daniel-sanche Jul 6, 2026
c99a693
increased shard count
daniel-sanche Jul 6, 2026
ee7cabc
isolate specific packages
daniel-sanche Jul 6, 2026
40d31e3
isolated shards should be included in max_shard count
daniel-sanche Jul 6, 2026
89e5499
changed shard names
daniel-sanche Jul 6, 2026
a1fab95
use pacakge weights instead of isolation
daniel-sanche Jul 6, 2026
92626bd
parallelize final cover check
daniel-sanche Jul 6, 2026
8c4d2dd
resolve merge conflict
daniel-sanche Jul 6, 2026
7ccca59
Merge branch 'main' into ci_sharding
daniel-sanche Jul 6, 2026
2e9bafc
added additional weights
daniel-sanche Jul 6, 2026
f14d489
pack shards alphabetically
daniel-sanche Jul 6, 2026
e4495b8
fixed typo
daniel-sanche Jul 6, 2026
80f0061
avoid combining all coverage files
daniel-sanche Jul 6, 2026
964e142
optimized coverage step
daniel-sanche Jul 7, 2026
b4733da
fix coverage files
daniel-sanche Jul 7, 2026
8ea10ec
change MAX_JOBS
daniel-sanche Jul 7, 2026
bdc977a
end early if fail_under = 0
daniel-sanche Jul 7, 2026
5cb0e26
added pip cache
daniel-sanche Jul 7, 2026
deaabe7
fixing bug in coverage search
daniel-sanche Jul 7, 2026
b20bb1a
enable test against ces
daniel-sanche Jul 7, 2026
15421a7
removed empty file
daniel-sanche Jul 7, 2026
b4f9d9d
updated find call
daniel-sanche Jul 7, 2026
b9f750d
combine coverage in shards
daniel-sanche Jul 7, 2026
073dc07
Revert "combine coverage in shards"
daniel-sanche Jul 7, 2026
da2f41e
use RAM disk for coverage results
daniel-sanche Jul 7, 2026
e611fe7
made max shards configurable
daniel-sanche Jul 7, 2026
e453d2c
added test files
daniel-sanche Jul 7, 2026
45b5e68
define package weights in yaml
daniel-sanche Jul 7, 2026
fa06713
added fast path for coverage check
daniel-sanche Jul 7, 2026
cd33370
undo fast-path optimization
daniel-sanche Jul 7, 2026
5bfe2d1
only upload coverage for first and last supported version
daniel-sanche Jul 7, 2026
6c0566f
use 3.10 as lower bound
daniel-sanche Jul 7, 2026
e1bedf1
avoid going over max_shards
daniel-sanche Jul 7, 2026
60a3e74
fixed coverage condition
daniel-sanche Jul 7, 2026
a4566cf
use all runtimes in coverage
daniel-sanche Jul 7, 2026
010e1ad
remove empty files
daniel-sanche Jul 7, 2026
e35ea34
removed duplication
daniel-sanche Jul 7, 2026
d04104d
cleaned up conditional tests
daniel-sanche Jul 7, 2026
cf3de20
added back subdirs
daniel-sanche Jul 7, 2026
f1eb3a4
added comments to sharding script
daniel-sanche Jul 7, 2026
c70613a
moved script out of yaml
daniel-sanche Jul 7, 2026
eaf75e9
print only count for successes
daniel-sanche Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 94 additions & 83 deletions .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,68 @@ permissions:
contents: read

jobs:
initialize:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
is_full_run: ${{ steps.check-label.outputs.is_full_run }}
env:
MAX_SHARDS: 20
# Define weights for long-running unit tests to balance shard execution time
# Each weight is roughly 1 minute of expected execution time
# Default for unset packages is 1
PACKAGE_WEIGHTS: |
bigframes: 6
google-ai-generativelanguage: 4
google-auth: 5
google-cloud-compute: 12
google-cloud-compute-v1beta: 12
google-cloud-dialogflow: 6
google-cloud-dialogflow-cx: 6
google-cloud-discoveryengine: 8
google-cloud-retail: 5
google-shopping-merchant-accounts: 4
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for unit_test:all_packages label
id: check-label
run: |
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'unit_test:all_packages') }}" == "true" ]]; then
echo "is_full_run=true" >> $GITHUB_OUTPUT
else
echo "is_full_run=false" >> $GITHUB_OUTPUT
fi
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Get package shards
id: set-matrix
env:
BUILD_TYPE: presubmit
TARGET_BRANCH: ${{ github.base_ref || github.event.merge_group.base_ref }}
TEST_ALL_PACKAGES: ${{ steps.check-label.outputs.is_full_run }}
MAX_SHARDS: ${{ env.MAX_SHARDS }}
PACKAGE_WEIGHTS: ${{ env.PACKAGE_WEIGHTS }}
run: |
if [ -n "$TARGET_BRANCH" ]; then
git fetch origin "$TARGET_BRANCH" --deepen=200 || true
fi
echo "matrix=$(python3 ci/get_package_shards.py)" >> $GITHUB_OUTPUT

unit:
needs: initialize
if: needs.initialize.outputs.matrix != '[]' && needs.initialize.outputs.matrix != ''
runs-on: ubuntu-22.04
strategy:
fail-fast: true
matrix:
python: ['3.9', '3.10', "3.11", "3.12", "3.13", "3.14"]
package_shard: ${{ fromJson(needs.initialize.outputs.matrix) }}
name: ${{ matrix.package_shard.is_sharded && format('unit ({0}, {1})', matrix.python, matrix.package_shard.name) || format('unit ({0})', matrix.python) }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
Expand All @@ -32,30 +88,51 @@ jobs:
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: ${{ matrix.python }}
cache: 'pip'
- name: Install nox
run: |
python -m pip install --upgrade setuptools pip wheel
python -m pip install nox
- name: Run unit tests
- name: Run unit tests for ${{ matrix.package_shard.description }}
env:
COVERAGE_FILE: ${{ github.workspace }}/.coverage-${{ matrix.python }}
BUILD_TYPE: presubmit
TARGET_BRANCH: ${{ github.base_ref || github.event.merge_group.base_ref }}
TEST_TYPE: unit
PY_VERSION: ${{ matrix.python }}
PACKAGE_LIST: ${{ matrix.package_shard.packages }}
run: |
ci/run_conditional_tests.sh
- name: Upload coverage results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: coverage-artifact-${{ matrix.python }}
path: .coverage-${{ matrix.python }}
name: coverage-artifact-${{ matrix.python }}-${{ matrix.package_shard.index }}
path: .coverage.${{ matrix.python }}.*
include-hidden-files: true

all-tests:
needs: [initialize, unit]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check unit test results
run: |
# 1. Check initialize job
if [[ "${{ needs.initialize.result }}" != "success" ]]; then
echo "Error: The initialize job status was: ${{ needs.initialize.result }}"
exit 1
fi
# 2. Check unit test shards
if [[ "${{ needs.unit.result }}" != "success" && "${{ needs.unit.result }}" != "skipped" ]]; then
echo "Unit tests failed"
exit 1
fi
echo "All unit tests passed or were skipped"

cover:
runs-on: ubuntu-latest
needs:
- unit
- initialize
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
Expand All @@ -71,10 +148,16 @@ jobs:
python-version: "3.10"
- name: Set number of files changes in packages directory
id: packages
env:
TEST_ALL_PACKAGES: ${{ needs.initialize.outputs.is_full_run }}
run: |
git diff HEAD~1 -- packages > /dev/null
num_files_changed=$(git diff HEAD~1 -- packages | wc -l | tr -d ' ')
echo "num_files_changed=${num_files_changed}" >> "$GITHUB_OUTPUT"
if [[ "${TEST_ALL_PACKAGES}" == "true" ]]; then
echo "num_files_changed=1" >> "$GITHUB_OUTPUT"
else
git diff HEAD~1 -- packages > /dev/null
num_files_changed=$(git diff HEAD~1 -- packages | wc -l | tr -d ' ')
echo "num_files_changed=${num_files_changed}" >> "$GITHUB_OUTPUT"
fi
- name: Install coverage
if: ${{ steps.packages.outputs.num_files_changed > 0 }}
run: |
Expand All @@ -84,86 +167,14 @@ jobs:
if: ${{ steps.packages.outputs.num_files_changed > 0 }}
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
with:
path: .coverage-results/
path: /dev/shm/.coverage-results/
merge-multiple: true
- name: Report coverage results
if: ${{ steps.packages.outputs.num_files_changed > 0 }}
env:
# TODO: default to 100% coverage after next gapic-generator release
# https://github.com/googleapis/google-cloud-python/issues/17459
DEFAULT_FAIL_UNDER: 99
TEST_ALL_PACKAGES: ${{ needs.initialize.outputs.is_full_run }}
run: |
if [ -d .coverage-results ]; then
# Unzip any zipped coverage results
find .coverage-results -type f -name '*.zip' -exec unzip -o {} \;

# Find all coverage files and combine them.
# We find files starting with .coverage (excluding .coveragerc files and templates)
coverage_files=$(find .coverage-results . -type f -name '.coverage*' ! -name '.coveragerc*')
if [ -n "${coverage_files}" ]; then
coverage combine ${coverage_files}
else
echo "Error: No coverage files found to combine."
exit 1
fi

# Find all modified packages
modified_packages=$(git diff --name-only HEAD~1 -- packages | cut -d/ -f1,2 | sort -u)

failed_packages=()
passed_packages=()

for pkg in ${modified_packages}; do
if [ -d "${pkg}" ]; then
echo "============================================================"
echo "Evaluating coverage for package: ${pkg}"
echo "============================================================"

set +e
pushd "${pkg}" > /dev/null
if [ -f ".coveragerc" ]; then
echo "Using package-specific configuration: ${pkg}/.coveragerc"
# If fail_under is specified in the package-specific .coveragerc, coverage report
# will automatically enforce it. Otherwise, we enforce the default.
if grep -q "fail_under" ".coveragerc"; then
COVERAGE_FILE=../../.coverage coverage report --include="$PWD/**"
else
echo "No fail_under specified in ${pkg}/.coveragerc, enforcing default"
COVERAGE_FILE=../../.coverage coverage report --include="$PWD/**" --fail-under="${DEFAULT_FAIL_UNDER}"
fi
else
echo "No .coveragerc found for ${pkg}, enforcing default"
COVERAGE_FILE=../../.coverage coverage report --include="$PWD/**" --fail-under="${DEFAULT_FAIL_UNDER}"
fi
status=$?
popd > /dev/null
set -e

if [ ${status} -ne 0 ]; then
failed_packages+=("${pkg}")
else
passed_packages+=("${pkg}")
fi
fi
done

echo "============================================================"
echo "Coverage Evaluation Summary"
echo "============================================================"
if [ ${#passed_packages[@]} -gt 0 ]; then
echo "Passed packages:"
for pkg in "${passed_packages[@]}"; do
echo " - ${pkg}"
done
fi
if [ ${#failed_packages[@]} -gt 0 ]; then
echo "Failed packages:"
for pkg in "${failed_packages[@]}"; do
echo " - ${pkg}"
done
exit 1
fi
else
echo "Error: No coverage results were downloaded from the unit test jobs."
echo "This usually means the unit tests did not run or failed to upload their coverage files."
exit 1
fi
ci/report_coverage.sh
Loading
Loading