Skip to content

Commit 5ea0ef9

Browse files
committed
feat: add uipath-core and platform
1 parent a2aaf1b commit 5ea0ef9

784 files changed

Lines changed: 60414 additions & 232 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/labeler.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
test:uipath-langchain:
2+
- changed-files:
3+
- any-glob-to-any-file: ['packages/uipath/src/**/*.py']
4+
- changed-files:
5+
- any-glob-to-any-file: ['packages/uipath-platform/src/**/*.py']
6+
- changed-files:
7+
- any-glob-to-any-file: ['packages/uipath-core/src/**/*.py']
8+
19
test:uipath-llamaindex:
210
- changed-files:
3-
- any-glob-to-any-file: ['src/**/*.py']
11+
- any-glob-to-any-file: ['packages/uipath/src/**/*.py']
412

5-
test:uipath-langchain:
13+
test:uipath-runtime:
614
- changed-files:
7-
- any-glob-to-any-file: ['src/**/*.py']
15+
- any-glob-to-any-file: ['packages/uipath-core/src/**/*.py']
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#!/usr/bin/env python3
2+
"""Detect which packages have changed in a PR or push to main.
3+
4+
Includes dependency-aware propagation: when a package changes, all
5+
downstream dependents are also included in the test list.
6+
"""
7+
8+
import json
9+
import os
10+
import subprocess
11+
import sys
12+
from pathlib import Path
13+
14+
# Internal dependency graph: package -> packages that depend on it.
15+
# When a package changes, its dependents' tests also run.
16+
# Add new entries here as packages are added to the monorepo.
17+
# External dependents (uipath-langchain, uipath-runtime, etc.) are
18+
# handled separately via labeler.yml auto-labels.
19+
DEPENDENTS: dict[str, list[str]] = {
20+
"uipath-core": ["uipath-platform", "uipath"],
21+
"uipath-platform": ["uipath"],
22+
}
23+
24+
25+
def expand_with_dependents(changed: list[str], all_packages: list[str]) -> list[str]:
26+
"""Expand changed package list to include downstream dependents."""
27+
expanded = set(changed)
28+
for pkg in changed:
29+
for dep in DEPENDENTS.get(pkg, []):
30+
if dep in all_packages:
31+
expanded.add(dep)
32+
return sorted(expanded)
33+
34+
35+
def get_all_packages() -> list[str]:
36+
"""Get all packages in the monorepo."""
37+
packages_dir = Path("packages")
38+
packages = []
39+
40+
for item in packages_dir.iterdir():
41+
if item.is_dir() and (item / "pyproject.toml").exists():
42+
packages.append(item.name)
43+
44+
return sorted(packages)
45+
46+
47+
def get_changed_packages(base_sha: str, head_sha: str) -> list[str]:
48+
"""Get packages that have changed between two commits."""
49+
try:
50+
# Get changed files
51+
result = subprocess.run(
52+
["git", "diff", "--name-only", f"{base_sha}...{head_sha}"],
53+
capture_output=True,
54+
text=True,
55+
check=True,
56+
)
57+
58+
changed_files = result.stdout.strip().split("\n")
59+
60+
# Extract package names from paths like "packages/uipath-llamaindex/..."
61+
changed_packages = set()
62+
for file_path in changed_files:
63+
if file_path.startswith("packages/"):
64+
parts = file_path.split("/")
65+
if len(parts) >= 2:
66+
package_name = parts[1]
67+
# Verify it's a real package
68+
if (Path("packages") / package_name / "pyproject.toml").exists():
69+
changed_packages.add(package_name)
70+
71+
return sorted(changed_packages)
72+
73+
except subprocess.CalledProcessError as e:
74+
print(f"Error running git diff: {e}", file=sys.stderr)
75+
return []
76+
77+
78+
def get_changed_packages_auto() -> list[str]:
79+
"""Auto-detect changed packages using git."""
80+
try:
81+
# Try to detect changes against origin/main
82+
result = subprocess.run(
83+
["git", "diff", "--name-only", "origin/main...HEAD"],
84+
capture_output=True,
85+
text=True,
86+
check=True,
87+
)
88+
89+
changed_files = result.stdout.strip().split("\n")
90+
91+
# Extract package names
92+
changed_packages = set()
93+
for file_path in changed_files:
94+
if file_path.startswith("packages/"):
95+
parts = file_path.split("/")
96+
if len(parts) >= 2:
97+
package_name = parts[1]
98+
if (Path("packages") / package_name / "pyproject.toml").exists():
99+
changed_packages.add(package_name)
100+
101+
return sorted(changed_packages)
102+
103+
except (subprocess.CalledProcessError, Exception) as e:
104+
print(f"Warning: Could not auto-detect changes: {e}", file=sys.stderr)
105+
return []
106+
107+
108+
def main():
109+
"""Main entry point."""
110+
event_name = os.getenv("GITHUB_EVENT_NAME", "")
111+
base_sha = os.getenv("BASE_SHA", "")
112+
head_sha = os.getenv("HEAD_SHA", "")
113+
114+
all_packages = get_all_packages()
115+
116+
# If we have explicit SHAs (from PR or push), detect changed packages
117+
if base_sha and head_sha:
118+
packages = get_changed_packages(base_sha, head_sha)
119+
event_type = "pull request" if event_name == "pull_request" else "push"
120+
print(f"{event_type.capitalize()} - detected {len(packages)} directly changed package(s):")
121+
for pkg in packages:
122+
print(f" - {pkg}")
123+
124+
# workflow_call or missing context - try auto-detection
125+
else:
126+
print(f"Event: {event_name or 'workflow_call'} - attempting auto-detection")
127+
packages = get_changed_packages_auto()
128+
129+
if packages:
130+
print(f"Auto-detected {len(packages)} directly changed package(s):")
131+
for pkg in packages:
132+
print(f" - {pkg}")
133+
else:
134+
# Fallback: test all packages
135+
print("Could not detect changes - testing all packages")
136+
packages = all_packages
137+
for pkg in packages:
138+
print(f" - {pkg}")
139+
140+
# Expand with downstream dependents
141+
expanded = expand_with_dependents(packages, all_packages)
142+
added = sorted(set(expanded) - set(packages))
143+
if added:
144+
print(f"\nAdded {len(added)} dependent package(s):")
145+
for pkg in added:
146+
print(f" - {pkg}")
147+
packages = expanded
148+
149+
# Output as JSON for GitHub Actions
150+
packages_json = json.dumps(packages)
151+
print(f"\nPackages JSON: {packages_json}")
152+
153+
# Write to GitHub output
154+
github_output = os.getenv("GITHUB_OUTPUT")
155+
if github_output:
156+
with open(github_output, "a") as f:
157+
f.write(f"packages={packages_json}\n")
158+
f.write(f"count={len(packages)}\n")
159+
160+
161+
if __name__ == "__main__":
162+
main()

.github/workflows/cd.yml

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,51 @@ on:
66
branches:
77
- main
88
paths:
9-
- pyproject.toml
9+
- 'packages/*/pyproject.toml'
10+
- '!packages/*/samples/**/pyproject.toml'
11+
- '!packages/*/testcases/**/pyproject.toml'
12+
13+
permissions:
14+
contents: read
15+
pull-requests: read
1016

1117
jobs:
12-
lint:
13-
uses: ./.github/workflows/lint.yml
18+
detect-changed-packages:
19+
runs-on: ubuntu-latest
20+
outputs:
21+
packages: ${{ steps.detect.outputs.packages }}
22+
count: ${{ steps.detect.outputs.count }}
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
1428

15-
test:
16-
uses: ./.github/workflows/test.yml
29+
- name: Setup Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: '3.11'
33+
34+
- name: Detect changed packages
35+
id: detect
36+
env:
37+
GITHUB_EVENT_NAME: ${{ github.event_name }}
38+
BASE_SHA: ${{ github.event.before }}
39+
HEAD_SHA: ${{ github.event.after }}
40+
run: python .github/scripts/detect_changed_packages.py
1741

1842
build:
19-
name: Build
43+
name: Build ${{ matrix.package }}
44+
needs: detect-changed-packages
45+
if: needs.detect-changed-packages.outputs.count > 0 && github.repository == 'UiPath/uipath-python'
2046
runs-on: ubuntu-latest
21-
22-
needs:
23-
- lint
24-
- test
25-
26-
if: ${{ github.repository == 'UiPath/uipath-python' }}
47+
defaults:
48+
run:
49+
working-directory: packages/${{ matrix.package }}
50+
strategy:
51+
fail-fast: false
52+
matrix:
53+
package: ${{ fromJson(needs.detect-changed-packages.outputs.packages) }}
2754
permissions:
2855
contents: read
2956
actions: write
@@ -40,15 +67,17 @@ jobs:
4067
- name: Setup Python
4168
uses: actions/setup-python@v5
4269
with:
43-
python-version-file: ".python-version"
70+
python-version-file: "packages/${{ matrix.package }}/.python-version"
4471

4572
- name: Install dependencies
4673
run: uv sync --all-extras
4774

4875
- name: Update AGENTS.md
76+
if: matrix.package == 'uipath'
4977
run: uv run python scripts/update_agents_md.py
5078

5179
- name: Replace connection string placeholder
80+
if: matrix.package == 'uipath'
5281
run: |
5382
originalfile="src/uipath/telemetry/_constants.py"
5483
tmpfile=$(mktemp)
@@ -60,21 +89,23 @@ jobs:
6089
CONNECTION_STRING: ${{ secrets.APPLICATIONINSIGHTS_CONNECTION_STRING }}
6190

6291
- name: Build
63-
run: uv build
92+
run: uv build --no-sources --package ${{ matrix.package }}
6493

6594
- name: Upload artifacts
6695
uses: actions/upload-artifact@v4
6796
with:
68-
name: release-dists
69-
path: dist/
97+
name: release-dists-${{ matrix.package }}
98+
path: packages/${{ matrix.package }}/dist/
7099

71100
pypi-publish:
72-
name: Upload release to PyPI
101+
name: Upload ${{ matrix.package }} to PyPI
102+
needs: [detect-changed-packages, build]
73103
runs-on: ubuntu-latest
74104
environment: pypi
75-
76-
needs:
77-
- build
105+
strategy:
106+
fail-fast: false
107+
matrix:
108+
package: ${{ fromJson(needs.detect-changed-packages.outputs.packages) }}
78109
permissions:
79110
contents: read
80111
id-token: write
@@ -83,7 +114,7 @@ jobs:
83114
- name: Retrieve release distributions
84115
uses: actions/download-artifact@v4
85116
with:
86-
name: release-dists
117+
name: release-dists-${{ matrix.package }}
87118
path: dist/
88119

89120
- name: Publish package distributions to PyPI

.github/workflows/ci.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@ on:
55
branches:
66
- main
77
paths-ignore:
8-
- pyproject.toml
8+
- packages/*/pyproject.toml
9+
- '!packages/*/samples/**/pyproject.toml'
10+
- '!packages/*/testcases/**/pyproject.toml'
911
pull_request:
1012
branches:
1113
- main
1214

15+
permissions:
16+
contents: read
17+
1318
jobs:
1419
commit-lint:
1520
if: ${{ github.event_name == 'pull_request' }}
1621
uses: ./.github/workflows/commitlint.yml
1722

1823
lint:
19-
uses: ./.github/workflows/lint.yml
24+
uses: ./.github/workflows/lint-packages.yml
2025

2126
test:
22-
uses: ./.github/workflows/test.yml
27+
uses: ./.github/workflows/test-packages.yml

.github/workflows/integration_tests.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Integration testing
1+
name: uipath - Integration Tests
22

33
on:
44
push:
@@ -22,6 +22,7 @@ jobs:
2222

2323
- name: Discover testcases
2424
id: discover
25+
working-directory: packages/uipath
2526
run: |
2627
# Find all testcase folders (excluding common folders like README, etc.)
2728
testcase_dirs=$(find testcases -maxdepth 1 -type d -name "*-*" | sed 's|testcases/||' | sort)
@@ -54,6 +55,7 @@ jobs:
5455
uses: actions/checkout@v4
5556

5657
- name: Install dependencies
58+
working-directory: packages/uipath
5759
run: uv sync
5860

5961
- name: Run testcase
@@ -68,7 +70,7 @@ jobs:
6870
TELEMETRY_CONNECTION_STRING: ${{ secrets.APPLICATIONINSIGHTS_CONNECTION_STRING }}
6971
APP_INSIGHTS_APP_ID: ${{ secrets.APP_INSIGHTS_APP_ID }}
7072
APP_INSIGHTS_API_KEY: ${{ secrets.APP_INSIGHTS_API_KEY }}
71-
working-directory: testcases/${{ matrix.testcase }}
73+
working-directory: packages/uipath/testcases/${{ matrix.testcase }}
7274
run: |
7375
# If any errors occur execution will stop with exit code
7476
set -e

0 commit comments

Comments
 (0)