-
Notifications
You must be signed in to change notification settings - Fork 1.7k
test(monorepo): adds adhoc package selection for CI system tests #17931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
chalmerlowe
wants to merge
41
commits into
main
Choose a base branch
from
feat/adhoc-package-selection
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+222
−3
Draft
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
b23b281
feat: implement ad-hoc package selection for CI/CD
chalmerlowe e8baccc
docs: add comment explaining inline python usage in system.sh
chalmerlowe 85d0855
docs: tweak comment explaining inline python usage
chalmerlowe 56576b9
fix: make grep commands safe and quote variables in adhoc_test_runner.sh
chalmerlowe 43800e2
fix: add auth token to curl and harden inline python in system.sh
chalmerlowe 69bb3ce
Apply suggestion from @chalmerlowe
chalmerlowe 22cc3fb
fix: harden ad-hoc integration in system.sh against silent failures
chalmerlowe cfe4106
chore: add experimental comment to trigger kokoro
chalmerlowe a8b1c61
chore: replace heavy packages (bigquery, bigtable) with lighter ones …
chalmerlowe cbe0b14
chore: inject intentional failure in google-resumable-media to test a…
chalmerlowe 2e2f861
chore: break setup.py in google-resumable-media to guarantee failure
chalmerlowe c007410
chore: dump logs for passed packages in system.sh for debugging
chalmerlowe 6db8c21
chore: add debug echoes and robustify log dumping in system.sh
chalmerlowe 86a47f8
fix: simplify argument passing to bash -c in xargs to avoid positiona…
chalmerlowe f5b0026
chore: replace heavy-handed setup.py breakage with a dummy failing test
chalmerlowe e5b4ddb
fix: remove unused pytest import to satisfy linter
chalmerlowe d43fcdd
feat: use associative arrays for package deduplication (matches desig…
chalmerlowe 2b1ce74
docs: clarify experimental comments in dummy test and speech client
chalmerlowe c61d727
chore: add debug echoes and robustify xargs in system.sh
chalmerlowe e10353e
fix: resolve lint errors and harden array handling in system.sh
chalmerlowe c2fa46b
Update .kokoro/system.sh
chalmerlowe 26cc68b
chore(ci): add copyright and improve error handling for adhoc tests
chalmerlowe 21c8cd9
chore(ci): clarify precondition in adhoc test runner
chalmerlowe d10e510
chore: remove temporary testing artifacts and apply hardening suggest…
chalmerlowe 1a70dac
docs: update README.md with detailed use cases and usage instructions
chalmerlowe 0d4231c
chore(ci): remove token logic from ad-hoc label checker
chalmerlowe c55dfc6
chore(ci): add rate limit debugging to ad-hoc checker
chalmerlowe fa5a346
chore(ci): trigger ad-hoc rate limit check (iteration 1)
chalmerlowe df878c8
chore(ci): trigger ad-hoc rate limit check (iteration 2)
chalmerlowe b06d0f3
chore(ci): trigger ad-hoc rate limit check (iteration 3)
chalmerlowe 5a06c08
chore(ci): trigger ad-hoc rate limit check (iteration 4)
chalmerlowe 55e4d8d
chore(ci): trigger ad-hoc rate limit check (iteration 5)
chalmerlowe 78256a5
chore(ci): trigger ad-hoc rate limit check (iteration 6)
chalmerlowe 2b7a282
chore(ci): trigger ad-hoc rate limit check (iteration 7)
chalmerlowe 50de366
chore(ci): trigger ad-hoc rate limit check (iteration 8)
chalmerlowe 6b03144
chore(ci): trigger ad-hoc rate limit check (iteration 9)
chalmerlowe 032f2d0
remove duplicate comment.
chalmerlowe 47076b5
chore(ci): armor ad-hoc checker to fail open safely
chalmerlowe 77dc5b5
refactor(ci): extract ad-hoc logic to external hook script
chalmerlowe 4b9c4e0
revise log statement
chalmerlowe 2e8e03d
revise log statement
chalmerlowe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| handwritten: google-cloud-translate | ||
| handwritten: google-cloud-logging | ||
| core: google-api-core | ||
| core: google-cloud-core |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package: google-cloud-logging | ||
| package: google-cloud-dns | ||
| group: handwritten |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Ad-Hoc Package Testing | ||
|
|
||
| ## Overview | ||
| Ad-hoc package testing allows you to run CI tests for a specific subset of packages or predefined package groups without the need for intrusive and/or temporary mods to the package code to trigger a CI job run. Key use cases include: | ||
|
|
||
| * **Downstream Dependency Smoke Tests:** If you update a core library (like `google-api-core`), the diff detector only sees the core library. Ad-hoc lets you explicitly include major downstream consumers (like `storage`) to verify compatibility. | ||
| * **Debugging specific package failures:** If you want to look at just one OR two failing packages out of a larger group of failing packages, it can be helpful to run them in isolation in a separate PR (so that your prospective changes don't have to wait on all the other packages). This allows you to easily flag which packages you want to investigate by potentially starting with a baseline test with no changes (i.e. does this fail due to an externality OR due to a change in the code)? | ||
| * **Testing CI infrastructure updates:** If you are changing `.kokoro/system.sh` or root scripts, the standard diff detector won't trigger tests because no package folders changed. Ad-hoc allows you to test your CI scripts using a single lightweight package without polluting package code with dummy comments. | ||
|
|
||
| ## How It Works | ||
| The ad-hoc testing system reads configuration files in the `ci/adhoc/` directory to determine which packages to test. It is triggered via the `test:adhoc` GitHub label on Pull Requests. | ||
|
|
||
| When triggered, the ad-hoc selected packages are **merged** with any packages automatically detected by the CI system (e.g., packages modified in the current PR). The final combined list is automatically deduplicated, ensuring each package is tested only once. | ||
|
|
||
| ## Configuration Files | ||
|
|
||
| These files are located in the `ci/adhoc/` directory. | ||
|
|
||
| ### 1. `.standalone_package_list.txt` | ||
| This file lists the specific packages or groups you want to test. | ||
|
|
||
| * **To test an individual package:** Add a line starting with `package: ` (be sure to include the colon and space) followed by the package directory name. | ||
| * *Example:* `package: google-cloud-dns` | ||
| * **To test a group of packages:** Add a line starting with `group: ` (be sure to include the colon and space) followed by the group name. NOTE: groups are defined in the file: `.package_groups.txt` | ||
| * *Example:* `group: handwritten` | ||
|
|
||
| ### 2. `.package_groups.txt` | ||
| This file defines groups of commonly tested packages for convenience of the team. Groups such as all handwritten, all core, all hybrids, most widely used, etc. can be defined here. | ||
|
|
||
| * **Format:** Each package in a group should be on its own line, prefixed by the group name, colon, and a space. | ||
| * *Example:* | ||
| ```text | ||
| handwritten: google-cloud-translate | ||
| handwritten: google-cloud-logging | ||
| core: google-api-core | ||
| ``` | ||
|
|
||
| #### 💡 Pro Tip | ||
| You can mix packages and groups in `.standalone_package_list.txt`. The system will automatically expand groups and deduplicate the list! | ||
|
|
||
| ## Usage | ||
|
|
||
| 1. **Edit Configuration:** Open `ci/adhoc/.standalone_package_list.txt` and add the packages or groups you want to test. | ||
| 2. **Trigger Tests:** | ||
| * **New PR:** Commit the changes and open a Pull Request form. | ||
| * **Activate Label:** Add the `test:adhoc` label to your PR form in the GitHub UI. If you miss this step, simply applying the label won't magically launch the tests the way `kokoro-force-run` does. The label is only checked when a commit is detected. | ||
| * **Existing PR:** Commit and push the changes to your branch. If the label is already present, pushing a new commit will trigger the tests. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| #!/bin/bash | ||
| # Copyright 2026 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # Script to determine ad-hoc packages to test. | ||
| # This script is intended to be sourced from main test scripts. | ||
| # | ||
| # Precondition: This script assumes it is sourced from the project root (as set by system.sh). | ||
|
|
||
|
chalmerlowe marked this conversation as resolved.
|
||
| ADHOC_DIR="ci/adhoc" | ||
| STANDALONE_LIST="${ADHOC_DIR}/.standalone_package_list.txt" | ||
| GROUPS_FILE="${ADHOC_DIR}/.package_groups.txt" | ||
|
|
||
| if [[ ! -f "$STANDALONE_LIST" ]]; then | ||
| echo "Warning: $STANDALONE_LIST not found." | ||
| return 0 2>/dev/null || exit 0 | ||
| fi | ||
|
|
||
| if [[ ! -f "$GROUPS_FILE" ]]; then | ||
| echo "Warning: $GROUPS_FILE not found." | ||
| return 0 2>/dev/null || exit 0 | ||
| fi | ||
|
|
||
| # Grab individual packages | ||
| adhoc_packages=$(grep "^package:" "$STANDALONE_LIST" | cut -d':' -f2 | tr -d '\r' | xargs || true) | ||
|
|
||
| # Grab requested groups | ||
| requested_groups=$(grep "^group:" "$STANDALONE_LIST" | cut -d':' -f2 | tr -d '\r' | xargs || true) | ||
|
|
||
| # Expand groups | ||
| for group in $requested_groups; do | ||
| group_pkgs=$(grep "^$group:" "$GROUPS_FILE" | cut -d':' -f2 | tr -d '\r' | xargs || true) | ||
| adhoc_packages="$adhoc_packages $group_pkgs" | ||
| done | ||
|
|
||
| # Convert to unique list (deduplicate our adhoc packages) | ||
| ADHOC_PACKAGES=$(echo "$adhoc_packages" | tr ' ' '\n' | sort -u | xargs) | ||
|
|
||
| export ADHOC_PACKAGES | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| #!/bin/bash | ||
| # Copyright 2026 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # ci/adhoc/setup_adhoc.sh | ||
| # This script is sourced by system.sh to check for ad-hoc status and update PACKAGES_TO_TEST. | ||
| # It fails open and is isolated to minimize impact on production. | ||
|
|
||
| TRIGGER_ADHOC="false" | ||
|
|
||
| echo "Checking for adhoc test label on PR #${KOKORO_GITHUB_PULL_REQUEST_NUMBER}..." | ||
| # Simple, unauthenticated call to check labels (capturing headers for rate limit debugging) | ||
| CURL_OUTPUT=$(curl -s -i -H "User-Agent: Kokoro-AdHoc-Checker" "https://api.github.com/repos/googleapis/google-cloud-python/issues/${KOKORO_GITHUB_PULL_REQUEST_NUMBER}/labels" || true) | ||
|
|
||
| # Separate headers and body | ||
| # Using awk to find the blank line separating headers from body | ||
| HEADERS=$(echo "$CURL_OUTPUT" | awk 'BEGIN{RS="\r\n\r\n"} NR==1' || true) | ||
| LABELS_JSON=$(echo "$CURL_OUTPUT" | awk 'BEGIN{RS="\r\n\r\n"} NR==2' || true) | ||
|
|
||
| # --- DEBUGGING: Extract and print Rate Limit Headers --- | ||
| echo "---------------------------------------------------------------" | ||
| echo "DEBUG: GitHub API Rate Limit Status:" | ||
| echo "$HEADERS" | grep -i "^x-ratelimit-limit:" | tr -d '\r' || true | ||
| echo "$HEADERS" | grep -i "^x-ratelimit-remaining:" | tr -d '\r' || true | ||
| echo "$HEADERS" | grep -i "^x-ratelimit-used:" | tr -d '\r' || true | ||
|
|
||
| # Convert reset time to human-readable if date is available, otherwise show raw | ||
| RESET_EPOCH=$(echo "$HEADERS" | grep -i "^x-ratelimit-reset:" | awk '{print $2}' | tr -d '\r' || true) | ||
| if [[ -n "$RESET_EPOCH" ]]; then | ||
| if date -d "@$RESET_EPOCH" >/dev/null 2>&1; then | ||
| RESET_HUMAN=$(date -d "@$RESET_EPOCH" "+%Y-%m-%d %H:%M:%S UTC") | ||
| echo "x-ratelimit-reset: $RESET_HUMAN ($RESET_EPOCH)" | ||
| else | ||
| echo "x-ratelimit-reset: $RESET_EPOCH" | ||
| fi | ||
| fi | ||
| echo "---------------------------------------------------------------" | ||
|
|
||
| if [[ -z "$LABELS_JSON" ]] || [[ "$HEADERS" == *"HTTP/1.1 4"* ]] || [[ "$HEADERS" == *"HTTP/1.1 5"* ]]; then | ||
| echo "===============================================================" | ||
| echo "WARNING: Failed to fetch labels or received error from GitHub API!" | ||
| echo "Ad-hoc tests will NOT be triggered." | ||
| echo "===============================================================" | ||
| else | ||
| # Use jq to parse github labels (works as long as jq is available in python-multi image). | ||
| IS_ADHOC=$(echo "$LABELS_JSON" | jq -r 'if type == "array" then any(.name == "test:adhoc") else false end' 2>/dev/null || echo "false") | ||
|
|
||
| if [[ "$IS_ADHOC" == "true" ]]; then | ||
| TRIGGER_ADHOC="true" | ||
| echo "Adhoc test label 'test:adhoc' found!" | ||
| else | ||
| if [[ "$LABELS_JSON" != "["* ]]; then | ||
| API_ERR_MSG=$(echo "$LABELS_JSON" | jq -r '.message // "Unknown error"' 2>/dev/null || echo "Unknown error") | ||
| echo "===============================================================" | ||
| echo "WARNING: Failed to fetch PR labels from GitHub API!" | ||
| echo "Error Message: $API_ERR_MSG" | ||
| echo "This might be due to API Rate Limiting." | ||
| echo "Ad-hoc tests will NOT be triggered." | ||
| echo "===============================================================" | ||
| else | ||
| echo "Adhoc test label 'test:adhoc' not found." | ||
| fi | ||
| fi | ||
| fi | ||
|
|
||
| if [[ "$TRIGGER_ADHOC" == "true" ]]; then | ||
| echo "Running ad-hoc package selection..." | ||
| # Ensure the runner script exists before sourcing | ||
| if [[ -f "ci/adhoc/adhoc_test_runner.sh" ]]; then | ||
| source ci/adhoc/adhoc_test_runner.sh | ||
|
|
||
| echo "Deduplicating packages..." | ||
| # Deduplication using Associative Arrays (Requires Bash 4+) | ||
| declare -A unique_packages | ||
| for pkg in "${PACKAGES_TO_TEST[@]}"; do | ||
| [[ -n "$pkg" ]] && unique_packages["$pkg"]=1 | ||
| done | ||
| for pkg in $ADHOC_PACKAGES; do | ||
| [[ -n "$pkg" ]] && unique_packages["$pkg"]=1 | ||
| done | ||
|
|
||
| PACKAGES_TO_TEST=("${!unique_packages[@]}") | ||
|
|
||
| echo "Combined packages to test: ${PACKAGES_TO_TEST[*]}" | ||
| else | ||
| echo "===============================================================" | ||
| echo "WARNING: ci/adhoc/adhoc_test_runner.sh not found!" | ||
| echo "Ad-hoc packages will NOT be added." | ||
| echo "===============================================================" | ||
| fi | ||
| fi |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.