Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5da7791
feat(ci): run unit-tests in parallel to speed them up
bshaffer Jul 29, 2026
0d9eb53
chore(ci): reduce unit-test output due to log truncation
bshaffer Jul 29, 2026
6a14237
chore(ci): rename conformance tests for clarity
bshaffer Jul 29, 2026
740552b
chore: run all ci tests
bshaffer Jul 29, 2026
3d37a2c
fix(ci): failing unit-tests
bshaffer Jul 29, 2026
24763d2
feat(ci): add matrix sharding
bshaffer Jul 29, 2026
0c5f19a
fix bash syntax error, better job names
bshaffer Jul 29, 2026
5b0a4a4
reduce fetch-depth for github actions runs, remove concurrency
bshaffer Jul 29, 2026
37e6bcf
remove c8 text output
bshaffer Jul 29, 2026
dd49119
feat: add conditional sharding using DRY_RUN_SHARDS envvar
bshaffer Jul 29, 2026
90754d4
fix(ci): common and pack-and-play tests
bshaffer Jul 29, 2026
e42dd27
Revert "remove c8 text output" - we will handle this in a future PR
bshaffer Jul 29, 2026
f12544e
add parent job for unit test shards (by node version), remove firesto…
bshaffer Jul 29, 2026
9d358d3
add dummy shards and extend test timeout for windows
bshaffer Jul 30, 2026
127374f
improve bigtable unit-test performance
bshaffer Jul 30, 2026
9ebd7db
increase timeout to 10 minutes for windows tests
bshaffer Jul 30, 2026
ce4850e
fix bigtable-system-tests
bshaffer Jul 30, 2026
cb703c9
skip pack-n-play tests on windows
bshaffer Jul 30, 2026
da39ebe
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Jul 30, 2026
d01121e
suggestions from gemini review
bshaffer Jul 30, 2026
b4d53f1
address another round of gemini code review
bshaffer Jul 30, 2026
4063b52
chore: pin actions/github-script to v8 SHA
bshaffer Jul 30, 2026
04f1fb0
add --strict to run_conditional_tests.sh
bshaffer Jul 31, 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
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
pull_request:
paths:
- 'handwritten/bigtable/**'
name: conformance
name: bigtable-conformance
jobs:
conformance:
runs-on: ubuntu-latest
Expand All @@ -36,16 +36,16 @@
matrix:
node: [ 18, 20 ]
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

Check warning on line 39 in .github/workflows/bigtable-conformance.yaml

View workflow job for this annotation

GitHub Actions / zizmor-output

ref-version-mismatch

bigtable-conformance.yaml:39: action's hash pin has mismatched or missing version comment: points to commit 11d5960a3267
with:
persist-credentials: false
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

Check warning on line 42 in .github/workflows/bigtable-conformance.yaml

View workflow job for this annotation

GitHub Actions / zizmor-output

ref-version-mismatch

bigtable-conformance.yaml:42: action's hash pin has mismatched or missing version comment: points to commit 11d5960a3267
with:
repository: googleapis/cloud-bigtable-clients-test
ref: main
path: handwritten/bigtable/cloud-bigtable-clients-test
persist-credentials: false
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6

Check warning on line 48 in .github/workflows/bigtable-conformance.yaml

View workflow job for this annotation

GitHub Actions / zizmor-output

ref-version-mismatch

bigtable-conformance.yaml:48: action's hash pin has mismatched or missing version comment: points to commit 249970729cb0
with:
node-version: ${{ matrix.node }}
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
Expand Down
65 changes: 62 additions & 3 deletions .github/workflows/presubmit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,37 @@ on:
pull_request:
name: presubmit
jobs:
setup:
runs-on: ubuntu-latest
outputs:
shard-matrix: ${{ steps.set-matrix.outputs.shard_matrix }}
shard-total: ${{ steps.set-matrix.outputs.shard_total }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 2
persist-credentials: false
- name: Calculate Matrix
id: set-matrix
run: |
export DRY_RUN_SHARDS=true
export BUILD_TYPE=presubmit
export TEST_TYPE=units
export GIT_DIFF_ARG=HEAD^1
bash ci/run_conditional_tests.sh --strict
units:
needs: setup
name: units (Node ${{ matrix.node-version }}, Shard ${{ matrix.shard-index }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [22, 24, 26]
shard-index: ${{ fromJSON(needs.setup.outputs.shard-matrix) }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 300
fetch-depth: 2
persist-credentials: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
Expand All @@ -23,18 +45,21 @@ jobs:
with:
version: ^10.0.0
- run: node --version
- run: ci/run_conditional_tests.sh
- run: ci/run_conditional_tests.sh --strict
name: Run unit tests
env:
BUILD_TYPE: presubmit
TEST_TYPE: units
SHARD_TOTAL: ${{ needs.setup.outputs.shard-total }}
SHARD_INDEX: ${{ matrix.shard-index }}
GIT_DIFF_ARG: HEAD^1
lint:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 300
fetch-depth: 2
persist-credentials: false
- name: Use Node.js 24
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
Expand All @@ -43,3 +68,37 @@ jobs:
- run: npm install
- run: npm run lint
name: Run monorepo linter

# Dummy jobs to satisfy branch protection requirements for each node version
units-status:
name: units (${{ matrix.node-version }})
needs: units
runs-on: ubuntu-latest
if: always()
strategy:
fail-fast: false
matrix:
node-version: [22, 24, 26]
steps:
- name: Check shard status
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId,
});
const nodeVersion = '${{ matrix.node-version }}';
const shardJobs = jobs.filter(j => j.name.includes(`units (Node ${nodeVersion},`));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we reuse test_dirs from setup?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with this way because:

  • Computing test_dirs with git diff takes ~1 second. Passing it via GitHub Actions adds ~5-10 seconds of network transfer and disk I/O per shard.
  • Because we have to calculate on both Windows vs. Linux, this way allows each OS runner to apply platform-specific handling (e.g., path separators and windows_exempt_tests) natively without needing serialization/translation across platforms.
  • It allows ci/run_conditional_tests.sh to be executed standalone

if (shardJobs.length === 0) {
core.setFailed(`No shard jobs found for Node ${nodeVersion}`);
return;
}
const failed = shardJobs.filter(j => j.conclusion === 'failure' || j.conclusion === 'cancelled');
if (failed.length > 0) {
const failedLinks = failed.map(j => `- ${j.name}: ${j.html_url}`).join('\n');
core.setFailed(`${failed.length} shards failed for Node ${nodeVersion}:\n${failedLinks}`);
} else {
core.info(`All shards passed for Node ${nodeVersion}`);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
pull_request:
paths:
- 'handwritten/storage/**'
name: conformance
name: storage-conformance
jobs:
conformance-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

Check warning on line 18 in .github/workflows/storage-conformance.yaml

View workflow job for this annotation

GitHub Actions / zizmor-output

ref-version-mismatch

storage-conformance.yaml:18: action's hash pin has mismatched or missing version comment: points to commit 11d5960a3267
with:
persist-credentials: false
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6

Check warning on line 21 in .github/workflows/storage-conformance.yaml

View workflow job for this annotation

GitHub Actions / zizmor-output

ref-version-mismatch

storage-conformance.yaml:21: action's hash pin has mismatched or missing version comment: points to commit 249970729cb0
with:
node-version: 14
- run: node --version
Expand Down
63 changes: 61 additions & 2 deletions .github/workflows/windows-presubmit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,37 @@ on:
pull_request:
name: presubmit-windows
jobs:
setup:
runs-on: ubuntu-latest
outputs:
shard-matrix: ${{ steps.set-matrix.outputs.shard_matrix }}
shard-total: ${{ steps.set-matrix.outputs.shard_total }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 2
persist-credentials: false
- name: Calculate Matrix
id: set-matrix
run: |
export DRY_RUN_SHARDS=true
export BUILD_TYPE=presubmit
export TEST_TYPE=units
export GIT_DIFF_ARG=HEAD^1
bash ci/run_conditional_tests.sh --strict
units:
needs: setup
name: units (Node ${{ matrix.node-version }}, Shard ${{ matrix.shard-index }})
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
node-version: [22, 24, 26]
shard-index: ${{ fromJSON(needs.setup.outputs.shard-matrix) }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 300
fetch-depth: 2
persist-credentials: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
Expand All @@ -23,9 +45,46 @@ jobs:
with:
version: ^10.0.0
- run: node --version
- run: bash ci/run_conditional_tests.sh
- run: bash ci/run_conditional_tests.sh --strict
name: Run windows unit tests
shell: bash
env:
BUILD_TYPE: presubmit
TEST_TYPE: units
SHARD_TOTAL: ${{ needs.setup.outputs.shard-total }}
SHARD_INDEX: ${{ matrix.shard-index }}
GIT_DIFF_ARG: HEAD^1

# Dummy jobs to satisfy branch protection requirements for each node version
units-status:
name: units (${{ matrix.node-version }})
needs: units
runs-on: ubuntu-latest
if: always()
strategy:
fail-fast: false
matrix:
node-version: [22, 24, 26]
steps:
- name: Check shard status
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId,
});
const nodeVersion = '${{ matrix.node-version }}';
const shardJobs = jobs.filter(j => j.name.includes(`units (Node ${nodeVersion},`));
if (shardJobs.length === 0) {
core.setFailed(`No shard jobs found for Node ${nodeVersion}`);
return;
}
const failed = shardJobs.filter(j => j.conclusion === 'failure' || j.conclusion === 'cancelled');
if (failed.length > 0) {
const failedLinks = failed.map(j => `- ${j.name}: ${j.html_url}`).join('\n');
core.setFailed(`${failed.length} shards failed for Node ${nodeVersion}:\n${failedLinks}`);
} else {
core.info(`All shards passed for Node ${nodeVersion}`);
}
134 changes: 96 additions & 38 deletions ci/run_conditional_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,50 @@ fi
test_script="${PROJECT_ROOT}/ci/run_single_test.sh"


if [ ${BUILD_TYPE} == "presubmit" ]; then
# For presubmit build, we want to know the difference from the
# common commit in origin/main.
GIT_DIFF_ARG="origin/main..."
for arg in "$@"; do
case "${arg}" in
--strict)
STRICT=true
;;
esac
done

# Then fetch enough history for finding the common commit.
git fetch origin main --deepen=300
if [[ "${STRICT}" == "true" || "${STRICT}" == "1" ]]; then
if [ -z "${GIT_DIFF_ARG}" ]; then
echo "Error: STRICT mode requires GIT_DIFF_ARG to be set." >&2
exit 1
fi
set +e
git diff --quiet ${GIT_DIFF_ARG}
diff_status=$?
set -e
if [[ ${diff_status} -ne 0 && ${diff_status} -ne 1 ]]; then
echo "Error: STRICT mode git diff ${GIT_DIFF_ARG} failed with exit code ${diff_status}." >&2
exit 1
fi
else
if [ -z "${GIT_DIFF_ARG}" ]; then
if [ "${BUILD_TYPE}" == "presubmit" ]; then
# For presubmit build, we want to know the difference from the
# common commit in origin/main.
GIT_DIFF_ARG="origin/main..."

elif [ ${BUILD_TYPE} == "continuous" ]; then
# For continuous build, we want to know the difference in the last
# commit. This assumes we use squash commit when merging PRs.
GIT_DIFF_ARG="HEAD~.."
# Then fetch enough history for finding the common commit.
git fetch origin main --deepen=300

# Then fetch one last commit for getting the diff.
git fetch origin main --deepen=1
elif [ "${BUILD_TYPE}" == "continuous" ]; then
# For continuous build, we want to know the difference in the last
# commit. This assumes we use squash commit when merging PRs.
GIT_DIFF_ARG="HEAD~.."

else
# Run everything.
GIT_DIFF_ARG=""
# Then fetch one last commit for getting the diff.
git fetch origin main --deepen=1

else
# Run everything.
GIT_DIFF_ARG=""
fi
fi
fi

# Then detect changes in the test scripts.
Expand All @@ -61,11 +86,11 @@ set -e
if [[ "${changed}" -eq 0 ]]; then
echo "no change detected in ci"
else
echo "skipping trigger of tests for now: tracking in #7540"
# echo "change detected in ci, we should test everything"
# echo "result of git diff ${GIT_DIFF_ARG} ci:"
# git diff ${GIT_DIFF_ARG} ci
# GIT_DIFF_ARG=""
# echo "skipping trigger of tests for now: tracking in #7540"
echo "change detected in ci, we should test everything"
echo "result of git diff ${GIT_DIFF_ARG} ci:"
git diff ${GIT_DIFF_ARG} ci
GIT_DIFF_ARG=""
Comment on lines +89 to +93

@bshaffer bshaffer Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As tests now take ~30 minutes (down from 2 hours), we can reenable this and close #7540.

Once we add PNPM workspaces and turbo caching, this number goes down to ~15!!

fi

# Now we have a fixed list, but we can change it to autodetect if
Expand All @@ -82,18 +107,21 @@ subdirs=(
)

RETVAL=0
# These following APIs need an explicit credential file to run properly (or oAuth2, which we don't support in this repo).
# These following APIs need an explicit credential file to run properly (or oAuth2, which we don't support in this repo).
# When we hit these packages, we will run the "samples with credentials" trigger, which contains the credentials as an env variable

tests_with_credentials="core/packages/google-auth-library-nodejs/ packages/google-analytics-admin/ packages/google-area120-tables/ packages/google-analytics-data/ packages/google-iam-credentials/ packages/google-apps-meet/ packages/google-chat/ packages/google-streetview-publish/ packages/google-cloud-developerconnect/"

# Some packages are only used by our bots and automation. These packages do not need to run on Windows and
# often employ platform specific code like file system interaction. Some packages may also fail
# on Windows due to incompatible npm scripts.
#
#
# Until these packages can be updated to be OS agnostic, we will skip them on Windows.
windows_exempt_tests="core/ core/packages/ core/dev-packages/ .github/scripts/fixtures/ .github/scripts/tests/ core/packages/gapic-node-processing/ core/packages/typeless-sample-bot/ handwritten/cloud-profiler/"

# Gather all test directories into an array
test_dirs=()

for subdir in ${subdirs[@]}; do
for d in `ls -d ${subdir}/*/`; do
if [ -s "ignore.json" ] && jq -e ".ignored[] | select(. == \"$d\")" ignore.json > /dev/null 2>&1; then
Expand All @@ -116,7 +144,7 @@ for subdir in ${subdirs[@]}; do
# System tests for packages are broken and blocking PRs.
# See https://github.com/googleapis/google-cloud-node/issues/7976.
#
# Per https://github.com/googleapis/google-cloud-node/issues/7921,
# Per https://github.com/googleapis/google-cloud-node/issues/7921,
# we are likely to permanently remove these tests in the near future.
if [[ "${subdir}" == "packages" && "${TEST_TYPE}" == "system" ]]; then
echo "Skipping ${TEST_TYPE} test for packages: ${d}"
Expand All @@ -126,7 +154,7 @@ for subdir in ${subdirs[@]}; do
# Sample tests for packages are broken/flaky and blocking PRs.
# See https://github.com/googleapis/google-cloud-node/issues/7976#issuecomment-4210458096.
#
# Per https://github.com/googleapis/google-cloud-node/issues/7921,
# Per https://github.com/googleapis/google-cloud-node/issues/7921,
# we are likely to permanently remove these tests in the near future.
if [[ "${subdir}" == "packages" && "${TEST_TYPE}" == "samples" ]]; then
echo "Skipping ${TEST_TYPE} test for packages: ${d}"
Expand Down Expand Up @@ -204,21 +232,51 @@ for subdir in ${subdirs[@]}; do
fi
fi
if [ "${should_test}" = true ]; then
echo "running test in ${d}"
pushd ${d}
# Temporarily allow failure.
set +e
${test_script}
ret=$?
set -e
if [ ${ret} -ne 0 ]; then
RETVAL=${ret}
# Since there are so many APIs, we should exit early if there's an error
exit ${RETVAL}
fi
popd
test_dirs+=("${d}")
fi
done
done
# If DRY_RUN_SHARDS is set, output dynamic matrix values to GitHub Actions and exit
if [[ "${DRY_RUN_SHARDS}" == "true" ]]; then
count=${#test_dirs[@]}
if [[ $count -gt 15 ]]; then
matrix="[0, 1, 2, 3, 4]"
total="5"
else
matrix="[0]"
total="1"
fi
if [[ -n "${GITHUB_OUTPUT}" ]]; then
echo "shard_matrix=${matrix}" >> "${GITHUB_OUTPUT}"
echo "shard_total=${total}" >> "${GITHUB_OUTPUT}"
else
echo "shard_matrix=${matrix}"
echo "shard_total=${total}"
fi
exit 0
fi

# If SHARD_TOTAL and SHARD_INDEX are provided, we will only run a subset of the tests.
for i in "${!test_dirs[@]}"; do
d="${test_dirs[$i]}"

if [[ -n "${SHARD_TOTAL}" && -n "${SHARD_INDEX}" ]]; then
if (( SHARD_TOTAL > 0 && i % SHARD_TOTAL != SHARD_INDEX )); then
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just keep an eye on whether there are differences between the shard durations (in case multiple "heavy" targets land in a single shard consistently.)

@bshaffer bshaffer Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've already seen this happen that Shard 0 is a little heavier, probably because of the bigtable and pack-n-play tests. If a big discrepancy emerges (right now, it seems like just a few minutes, so I am not sure it's a big concern), we could take the known longer tests and manually separate them? What are your thoughts on the best way to accomplish this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could take the known longer tests and manually separate them

This it what I'd do.

right now, it seems like just a few minutes, so I am not sure it's a big concern

+1

fi
fi

echo "running test in ${d}"
pushd "${d}" >/dev/null
# Temporarily allow failure.
set +e
"${test_script}"
ret=$?
set -e
if [ ${ret} -ne 0 ]; then
exit ${ret}
fi
popd >/dev/null
done

exit ${RETVAL}
exit 0
Loading
Loading