Skip to content
Draft

wip #16645

Show file tree
Hide file tree
Changes from all commits
Commits
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
194 changes: 194 additions & 0 deletions .github/workflows/experiment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
name: Next-Gen CI Pipeline

on:
pull_request:
branches: [ main, preview ]
# Native Merge Queue support for exhaustive batching
merge_group:
types: [checks_requested]

# Stop burning money on abandoned iterative commits
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
# ==========================================
# 1. DISCOVERY ENGINE (The Router)
# ==========================================
discover:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.changes.outputs.all_changed_files }}
# Expose the dynamic Python matrix to downstream jobs
python_versions: ${{ steps.set-python.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Detect Changed Packages
id: changes
uses: tj-actions/changed-files@v44
with:
files: packages/**
dir_names: true
dir_names_max_depth: 2
json: true
escape_json: false

- name: Determine Python Matrix (Risk-Tiering)
id: set-python
run: |
if [[ "${{ github.event_name }}" == "merge_group" ]]; then
echo "Merge Queue detected. Deploying exhaustive matrix."
echo 'matrix=["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]' >> $GITHUB_OUTPUT
else
echo "Pull Request detected. Deploying Min/Max Boundary matrix."
echo 'matrix=["3.9", "3.14"]' >> $GITHUB_OUTPUT
fi

# ==========================================
# 2. STATIC ANALYSIS (Grouped for Speed)
# ==========================================
static-checks:
needs: discover
if: ${{ needs.discover.outputs.packages != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.discover.outputs.packages) }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.14"
enable-cache: true
cache-dependency-glob: "${{ matrix.package }}/setup.py"

- name: Run Lint and MyPy
run: |
cd ${{ matrix.package }}
export NOX_DEFAULT_VENV_BACKEND=uv
uvx --with 'nox[uv]' nox -s lint mypy lint_setup_py

# ==========================================
# 3. DOCUMENTATION BUILD
# ==========================================
docs-build:
needs: discover
if: ${{ needs.discover.outputs.packages != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.discover.outputs.packages) }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.10"
enable-cache: true
cache-dependency-glob: "${{ matrix.package }}/setup.py"

- name: Build Docs and DocFX
run: |
cd ${{ matrix.package }}
export NOX_DEFAULT_VENV_BACKEND=uv
uvx --with 'nox[uv]' nox -s docs docfx

# ==========================================
# 4. UNIT TESTS (Dynamic 2D Matrix + Retries)
# ==========================================
unit-tests:
needs: discover
if: ${{ needs.discover.outputs.packages != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.discover.outputs.packages) }}
# Reads the array generated by the Discovery job
python: ${{ fromJSON(needs.discover.outputs.python_versions) }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python }}
enable-cache: true
cache-dependency-glob: "${{ matrix.package }}/setup.py"

- name: Execute Unit Tests (With Shock Absorbers)
run: |
cd ${{ matrix.package }}
export NOX_DEFAULT_VENV_BACKEND=uv

# 3-Attempt retry loop to mask legacy flaky tests
for i in 1 2 3; do
echo "Attempt $i of 3 for Python ${{ matrix.python }}..."
if uvx --with 'nox[uv]' nox -s unit-${{ matrix.python }}; then
echo "Tests passed successfully!"
exit 0
fi
echo "Tests failed. Waiting 5 seconds before retrying..."
sleep 5
done

echo "::error::Tests failed after 3 attempts. This is a hard failure."
exit 1

# ==========================================
# 5. SYSTEM TESTS
# ==========================================
system-tests:
needs: discover
if: ${{ needs.discover.outputs.packages != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.discover.outputs.packages) }}
python: ["3.11"]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python }}
enable-cache: true
cache-dependency-glob: "${{ matrix.package }}/setup.py"

- name: Execute System Tests
env:
RUN_SYSTEM_TESTS: "true"
run: |
cd ${{ matrix.package }}
export NOX_DEFAULT_VENV_BACKEND=uv
uvx --with 'nox[uv]' nox -s system-${{ matrix.python }}

# ==========================================
# 6. THE GATEKEEPER (Status Check Rollup)
# ==========================================
presubmit-passed:
if: always()
needs:
- discover
- static-checks
- docs-build
- unit-tests
- system-tests
runs-on: ubuntu-latest
steps:
- name: Evaluate Pipeline Status
run: |
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" || "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
echo "::error::One or more required CI jobs failed or were cancelled."
exit 1
fi

if [[ "${{ needs.discover.outputs.packages }}" == "[]" ]]; then
echo "No Python packages changed. Safely bypassing execution."
exit 0
fi

echo "All dynamically generated CI jobs completed successfully."
43 changes: 20 additions & 23 deletions .kokoro/system-single.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
#!/bin/bash
# Copyright 2022 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
#
# http://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.

# `-e` enables the script to automatically fail when a command fails
# `-o pipefail` sets the exit code to non-zero if any command fails,
# or zero if all commands in the pipeline exit successfully.
# Licensed under the Apache License, Version 2.0 (the "License"); ...
set -eo pipefail

pwd

# If NOX_SESSION is set, it only runs the specified session,
# otherwise run all the sessions.
NOX_SESSION_ARG=""

# IF NOX_FILE is set, it runs the specific nox file,
# otherwise it runs noxfile.py in the package directory.
NOX_FILE_ARG=""

[[ -z "${NOX_SESSION}" ]] || NOX_SESSION_ARG="-s ${NOX_SESSION}"

[[ -z "${NOX_FILE}" ]] || NOX_FILE_ARG="-f ${NOX_FILE}"

python3 -m nox ${NOX_SESSION_ARG} $NOX_FILE_ARG
# 3-Attempt retry loop to absorb GCP quota limits and network blips
for attempt in 1 2 3; do
echo "============================================"
echo "Execution attempt $attempt of 3..."
echo "============================================"

if uvx --with 'nox[uv]' nox ${NOX_SESSION_ARG} ${NOX_FILE_ARG}; then
echo "Tests passed successfully!"
exit 0
fi

if [[ $attempt -lt 3 ]]; then
echo "Tests failed. Backing off for 15 seconds to absorb quota limits..."
sleep 15
fi
done

echo "Tests failed after 3 attempts. Hard failure."
exit 1
Loading
Loading