diff --git a/.github/workflows/nightly-version-bump.yml b/.github/workflows/nightly-version-bump.yml new file mode 100644 index 0000000..629875c --- /dev/null +++ b/.github/workflows/nightly-version-bump.yml @@ -0,0 +1,45 @@ +name: Nightly SDK Version Bump + +permissions: + contents: write + pull-requests: write + +on: + schedule: + - cron: "0 3 * * *" # 03:00 UTC every night + workflow_dispatch: {} + +jobs: + bump: + name: Update SDK versions and create PR + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install Python dependencies for script + run: pip install requests + + - name: Run update_versions.py + run: python scripts/update_versions.py + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: bump kernel sdk versions to latest" + title: "chore: nightly SDK version bump" + body: | + This PR updates Python `kernel` and TypeScript `@onkernel/sdk` version constraints to the latest published releases. + branch: "github-actions/nightly-sdk-bump" + signoff: false + delete-branch: true diff --git a/scripts/update_versions.py b/scripts/update_versions.py new file mode 100644 index 0000000..e170399 --- /dev/null +++ b/scripts/update_versions.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""update_versions.py + +Fetch the latest released versions of: +* PyPI package `kernel` +* npm package `@onkernel/sdk` + +and update every version constraint inside: +* templates/python/*/pyproject.toml -> "kernel>=" +* templates/typescript/*/package.json -> "@onkernel/sdk": ">=" + +If a file is modified, it is overwritten in-place. The script exits with code 0 +whether or not modifications were required. However, it prints a summary that is +useful inside CI to decide if a commit is necessary. +""" +from __future__ import annotations + +import json +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import List + +try: + import requests # type: ignore +except ImportError: + subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"]) + import requests # type: ignore + +REPO_ROOT = Path(__file__).resolve().parent.parent +PY_TEMPLATES_GLOB = REPO_ROOT / "templates" / "python" / "*" / "pyproject.toml" +TS_TEMPLATES_GLOB = REPO_ROOT / "templates" / "typescript" / "*" / "package.json" + + +# --------------------------------------------------------------------------- +# Helpers to fetch latest versions +# --------------------------------------------------------------------------- + +def _get_latest_pypi_version(package: str) -> str: + url = f"https://pypi.org/pypi/{package}/json" + resp = requests.get(url, timeout=10) + resp.raise_for_status() + data = resp.json() + return data["info"]["version"] + + +def _get_latest_npm_version(package: str) -> str: + # NPM package names are url-encoded + import urllib.parse as _up + + encoded = _up.quote(package, safe="") + url = f"https://registry.npmjs.org/{encoded}" + resp = requests.get(url, timeout=10) + resp.raise_for_status() + data = resp.json() + return data["dist-tags"]["latest"] + + +# --------------------------------------------------------------------------- +# Updaters +# --------------------------------------------------------------------------- + +_KERN_DEP_REGEX = re.compile(r"(\"kernel)([^\"]*)(\")") + + +def _update_pyproject(file_path: Path, new_version: str) -> bool: + """Return True if file changed.""" + text = file_path.read_text() + + # Replace any appearance like "kernel>=0.8.0", "kernel==0.5.0", "kernel~=0.7" + new_constraint = f'"kernel>={new_version}"' + new_text = re.sub(r'"kernel[<>=~!0-9.]*"', new_constraint, text) + + if new_text != text: + file_path.write_text(new_text) + return True + return False + + +def _update_package_json(file_path: Path, new_version: str) -> bool: + data = json.loads(file_path.read_text()) + changed = False + + for section in ("dependencies", "peerDependencies" , "devDependencies"): + deps = data.get(section) + if deps and "@onkernel/sdk" in deps: + if deps["@onkernel/sdk"] != f">={new_version}": + deps["@onkernel/sdk"] = f">={new_version}" + changed = True + + if changed: + file_path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n") + return changed + + +# --------------------------------------------------------------------------- +# Main execution +# --------------------------------------------------------------------------- + +def main() -> None: + latest_kernel = _get_latest_pypi_version("kernel") + latest_sdk = _get_latest_npm_version("@onkernel/sdk") + + print(f"Latest kernel version on PyPI: {latest_kernel}") + print(f"Latest @onkernel/sdk version on npm: {latest_sdk}") + + modified_files: List[Path] = [] + + # Python templates + for file_path in REPO_ROOT.glob("templates/python/*/pyproject.toml"): + if _update_pyproject(file_path, latest_kernel): + modified_files.append(file_path.relative_to(REPO_ROOT)) + + # Typescript templates + for file_path in REPO_ROOT.glob("templates/typescript/*/package.json"): + if _update_package_json(file_path, latest_sdk): + modified_files.append(file_path.relative_to(REPO_ROOT)) + + if modified_files: + print("Updated the following files:") + for p in modified_files: + print(f" - {p}") + else: + print("All template files already up-to-date. No changes made.") + + +if __name__ == "__main__": + main() diff --git a/templates/python/advanced-sample/pyproject.toml b/templates/python/advanced-sample/pyproject.toml index 7661088..ab0f60f 100644 --- a/templates/python/advanced-sample/pyproject.toml +++ b/templates/python/advanced-sample/pyproject.toml @@ -5,7 +5,7 @@ description = "Sample application implementing advanced Kernel configs" readme = "README.md" requires-python = ">=3.11" dependencies = [ - "kernel>=0.6.0", + "kernel>=0.8.0", "playwright>=1.52.0" ] diff --git a/templates/python/browser-use/pyproject.toml b/templates/python/browser-use/pyproject.toml index 735d660..11d1ffe 100644 --- a/templates/python/browser-use/pyproject.toml +++ b/templates/python/browser-use/pyproject.toml @@ -6,6 +6,6 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "browser-use~=0.5.3", - "kernel>=0.7.1", + "kernel>=0.8.0", "pydantic>=2.10.6", ] diff --git a/templates/python/cua/pyproject.toml b/templates/python/cua/pyproject.toml index 5abc9a7..a8b1211 100644 --- a/templates/python/cua/pyproject.toml +++ b/templates/python/cua/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ "idna==3.10", "jiter==0.10.0", "pillow==11.2.1", - "kernel>=0.6.0", + "kernel>=0.8.0", "playwright==1.52.0", "pydantic==2.11.7", "pydantic_core==2.33.2", diff --git a/templates/python/sample-app/pyproject.toml b/templates/python/sample-app/pyproject.toml index 9b16b02..90590e1 100644 --- a/templates/python/sample-app/pyproject.toml +++ b/templates/python/sample-app/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" description = "Kernel application template - Python" readme = "README.md" requires-python = ">=3.11" -dependencies = ["kernel>=0.6.0", "playwright>=1.52.0"] +dependencies = ["kernel>=0.8.0", "playwright>=1.52.0"] [dependency-groups] dev = ["mypy>=1.15.0"] diff --git a/templates/typescript/advanced-sample/package.json b/templates/typescript/advanced-sample/package.json index e94eaa2..846688c 100644 --- a/templates/typescript/advanced-sample/package.json +++ b/templates/typescript/advanced-sample/package.json @@ -7,7 +7,7 @@ "typescript": "^5" }, "dependencies": { - "@onkernel/sdk": "^0.6.0", + "@onkernel/sdk": ">=0.8.0", "playwright": "^1.52.0" } } diff --git a/templates/typescript/computer-use/package.json b/templates/typescript/computer-use/package.json index fa8b15e..5f475fb 100644 --- a/templates/typescript/computer-use/package.json +++ b/templates/typescript/computer-use/package.json @@ -7,7 +7,7 @@ "typescript": "^5" }, "dependencies": { - "@onkernel/sdk": "^0.6.0", + "@onkernel/sdk": ">=0.8.0", "playwright": "^1.52.0", "@anthropic-ai/sdk": "0.52.0", "luxon": "3.6.0" diff --git a/templates/typescript/cua/package.json b/templates/typescript/cua/package.json index dfbb715..405ac85 100644 --- a/templates/typescript/cua/package.json +++ b/templates/typescript/cua/package.json @@ -5,7 +5,7 @@ "build": "tsc" }, "dependencies": { - "@onkernel/sdk": "^0.6.0", + "@onkernel/sdk": ">=0.8.0", "dotenv": "^16.5.0", "openai": "^5.7.0", "playwright": "^1.53.0", diff --git a/templates/typescript/sample-app/package.json b/templates/typescript/sample-app/package.json index e94eaa2..846688c 100644 --- a/templates/typescript/sample-app/package.json +++ b/templates/typescript/sample-app/package.json @@ -7,7 +7,7 @@ "typescript": "^5" }, "dependencies": { - "@onkernel/sdk": "^0.6.0", + "@onkernel/sdk": ">=0.8.0", "playwright": "^1.52.0" } } diff --git a/templates/typescript/stagehand/package.json b/templates/typescript/stagehand/package.json index 81a3af5..0ca0cf0 100644 --- a/templates/typescript/stagehand/package.json +++ b/templates/typescript/stagehand/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@browserbasehq/stagehand": "^2.2.1", - "@onkernel/sdk": "^0.6.0", + "@onkernel/sdk": ">=0.8.0", "zod": "^3.25.7" } }