Skip to content
Merged
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
133 changes: 133 additions & 0 deletions .github/scripts/detect_changed_packages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
"""Detect which packages have changed in a PR or push to main."""

import json
import os
import subprocess
import sys
from pathlib import Path


def get_all_packages() -> list[str]:
"""Get all packages in the monorepo."""
packages_dir = Path("packages")
packages = []

for item in packages_dir.iterdir():
if item.is_dir() and (item / "pyproject.toml").exists():
packages.append(item.name)

return sorted(packages)


def get_changed_packages(base_sha: str, head_sha: str) -> list[str]:
"""Get packages that have changed between two commits."""
try:
# Get changed files
result = subprocess.run(
["git", "diff", "--name-only", f"{base_sha}...{head_sha}"],
capture_output=True,
text=True,
check=True,
)

changed_files = result.stdout.strip().split("\n")

# Extract package names from paths like "packages/uipath-llamaindex/..."
changed_packages = set()
for file_path in changed_files:
if file_path.startswith("packages/"):
parts = file_path.split("/")
if len(parts) >= 2:
package_name = parts[1]
# Verify it's a real package
if (Path("packages") / package_name / "pyproject.toml").exists():
changed_packages.add(package_name)

return sorted(changed_packages)

except subprocess.CalledProcessError as e:
print(f"Error running git diff: {e}", file=sys.stderr)
return []


def get_changed_packages_auto() -> list[str]:
"""Auto-detect changed packages using git."""
try:
# Try to detect changes against origin/main
result = subprocess.run(
["git", "diff", "--name-only", "origin/main...HEAD"],
capture_output=True,
text=True,
check=True,
)

changed_files = result.stdout.strip().split("\n")

# Extract package names
changed_packages = set()
for file_path in changed_files:
if file_path.startswith("packages/"):
parts = file_path.split("/")
if len(parts) >= 2:
package_name = parts[1]
if (Path("packages") / package_name / "pyproject.toml").exists():
changed_packages.add(package_name)

return sorted(changed_packages)

except (subprocess.CalledProcessError, Exception) as e:
print(f"Warning: Could not auto-detect changes: {e}", file=sys.stderr)
return []


def main():
"""Main entry point."""
event_name = os.getenv("GITHUB_EVENT_NAME", "")
base_sha = os.getenv("BASE_SHA", "")
head_sha = os.getenv("HEAD_SHA", "")

# On push to main, test all packages
if event_name == "push":
packages = get_all_packages()
print(f"Push to main - testing all {len(packages)} packages:")
for pkg in packages:
print(f" - {pkg}")

# On PR with explicit SHAs, detect changed packages
elif event_name == "pull_request" and base_sha and head_sha:
packages = get_changed_packages(base_sha, head_sha)
print(f"Pull request - detected {len(packages)} changed package(s):")
for pkg in packages:
print(f" - {pkg}")

# workflow_call or missing context - try auto-detection
else:
print(f"Event: {event_name or 'workflow_call'} - attempting auto-detection")
packages = get_changed_packages_auto()

if packages:
print(f"Auto-detected {len(packages)} changed package(s):")
for pkg in packages:
print(f" - {pkg}")
else:
# Fallback: test all packages
print("Could not detect changes - testing all packages")
packages = get_all_packages()
for pkg in packages:
print(f" - {pkg}")

# Output as JSON for GitHub Actions
packages_json = json.dumps(packages)
print(f"\nPackages JSON: {packages_json}")

# Write to GitHub output
github_output = os.getenv("GITHUB_OUTPUT")
if github_output:
with open(github_output, "a") as f:
f.write(f"packages={packages_json}\n")
f.write(f"count={len(packages)}\n")


if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
uses: ./.github/workflows/commitlint.yml

lint:
uses: ./.github/workflows/lint.yml
uses: ./.github/workflows/lint-packages.yml

test:
uses: ./.github/workflows/test.yml
uses: ./.github/workflows/test-packages.yml
37 changes: 0 additions & 37 deletions .github/workflows/discover-packages.yml

This file was deleted.

47 changes: 0 additions & 47 deletions .github/workflows/discover-testcases.yml

This file was deleted.

73 changes: 71 additions & 2 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,89 @@ name: Integration testing
on:
push:
branches: [ main, develop ]
paths:
- 'packages/**'
- '.github/workflows/integration_tests.yml'
- '.github/scripts/detect_changed_packages.py'
pull_request:
branches: [ main ]
paths:
- 'packages/**'
- '.github/workflows/integration_tests.yml'
- '.github/scripts/detect_changed_packages.py'

permissions:
contents: read
pull-requests: write
actions: read

jobs:
detect-changed-packages:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.detect.outputs.packages }}
count: ${{ steps.detect.outputs.count }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Detect changed packages
id: detect
run: |
python .github/scripts/detect_changed_packages.py

discover-testcases:
uses: ./.github/workflows/discover-testcases.yml
needs: detect-changed-packages
if: needs.detect-changed-packages.outputs.count > 0
runs-on: ubuntu-latest
outputs:
testcases: ${{ steps.discover.outputs.testcases }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Discover testcases for changed packages
id: discover
run: |
# Get list of packages to check
PACKAGES='${{ needs.detect-changed-packages.outputs.packages }}'

# Find all testcases in changed packages only
testcases_array="[]"

for package_name in $(echo "$PACKAGES" | jq -r '.[]'); do
testcases_dir="packages/$package_name/testcases"

if [ -d "$testcases_dir" ]; then
echo "Discovering testcases in $package_name"

# Find all testcase folders in this package
for testcase_dir in "$testcases_dir"/*; do
if [ -d "$testcase_dir" ]; then
testcase_name=$(basename "$testcase_dir")
# Skip 'common' directory if it exists
if [ "$testcase_name" != "common" ]; then
echo " Found: $testcase_name"
testcases_array=$(echo "$testcases_array" | jq -c ". += [{\"package\": \"$package_name\", \"testcase\": \"$testcase_name\"}]")
fi
fi
done
fi
done

echo "Testcases matrix: $testcases_array"
echo "testcases=$testcases_array" >> $GITHUB_OUTPUT

integration-tests:
needs: [discover-testcases]
needs: [detect-changed-packages, discover-testcases]
if: needs.discover-testcases.outputs.testcases != '[]'
runs-on: ubuntu-latest
timeout-minutes: 10
container:
Expand Down
40 changes: 32 additions & 8 deletions .github/workflows/lint-custom-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,50 @@ on:
workflow_call:
pull_request:
types: [opened, synchronize, labeled, unlabeled]
paths:
- 'packages/**'
- '.github/workflows/lint-custom-version.yml'
- '.github/scripts/detect_changed_packages.py'

permissions:
contents: read
pull-requests: read

jobs:
discover-packages:
detect-changed-packages:
if: contains(github.event.pull_request.labels.*.name, 'test-core-dev-version')
uses: ./.github/workflows/discover-packages.yml
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.detect.outputs.packages }}
count: ${{ steps.detect.outputs.count }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Detect changed packages
id: detect
run: |
python .github/scripts/detect_changed_packages.py

lint-with-custom-version:
name: Lint ${{ matrix.package }} - Custom Version
needs: [discover-packages]
needs: detect-changed-packages
if: contains(github.event.pull_request.labels.*.name, 'test-core-dev-version') && needs.detect-changed-packages.outputs.count > 0
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'test-core-dev-version')
defaults:
run:
working-directory: packages/${{ matrix.package }}
strategy:
fail-fast: false
matrix:
package: ${{ fromJson(needs.discover-packages.outputs.packages) }}
permissions:
contents: read
pull-requests: read
package: ${{ fromJson(needs.detect-changed-packages.outputs.packages) }}

steps:
- name: Checkout
Expand Down
Loading