diff --git a/.cursor/commands/build-sdk.md b/.cursor/commands/build-sdk.md new file mode 100644 index 000000000..05cfcca62 --- /dev/null +++ b/.cursor/commands/build-sdk.md @@ -0,0 +1,20 @@ +# Build SDK and Run Validation Tests + +## Overview + +Build all API versions of the Python SDK from the OpenAPI specs and run the validation test suite. Use the same behavior as the GitHub action with default inputs: `api-specs-path=api-specs`, `skip-tests=false`. + +Works on Windows, macOS, and Linux (no shell required). + +## What to do + +1. Run the build-and-validate script from the repository root: + - **Command:** `python scripts/build_and_validate_sdk.py` + - Run from the workspace root directory. +2. Use default options (do not set `API_SPECS_PATH` or `SKIP_TESTS` unless the user asks otherwise). +3. Report the outcome: whether the build and validation tests completed successfully or any errors that occurred. + +If the user provides extra instructions after the command (e.g. "skip tests" or a different api-specs path), follow those: + +- To skip tests: set env and run, e.g. `SKIP_TESTS=true python scripts/build_and_validate_sdk.py` (Unix/macOS) or `set SKIP_TESTS=true && python scripts/build_and_validate_sdk.py` (Windows cmd) or `$env:SKIP_TESTS="true"; python scripts/build_and_validate_sdk.py` (Windows PowerShell). +- Different api-specs path: `API_SPECS_PATH= python scripts/build_and_validate_sdk.py` (Unix/macOS) or set `API_SPECS_PATH` then run the Python command (Windows). diff --git a/.cursor/commands/create-pr.md b/.cursor/commands/create-pr.md new file mode 100644 index 000000000..170ba1eca --- /dev/null +++ b/.cursor/commands/create-pr.md @@ -0,0 +1,23 @@ +# Create Pull Request + +## Overview + +Create a pull request using the GitHub CLI (`gh`). The PR uses the **current branch** as the head and **main** as the base. The PR title is whatever the user types after the slash command. + +## What to do + +1. **Title:** Use the text the user provided after the command as the PR title (e.g. `/create-pr Add streaming pagination` → title is "Add streaming pagination"). If the user did not provide any text after the command, ask them for a PR title. +2. **Push if needed:** From the repository root, if the current branch does not have an upstream on origin yet, push it first so `gh pr create` can open a PR: + - Check: `git rev-parse --abbrev-ref @{u} 2>/dev/null` or equivalent (e.g. if `git status` says "no upstream branch"). + - If the branch is not yet pushed: run `git push -u origin $(git branch --show-current)`. + - If the push fails (e.g. uncommitted changes, auth), report the error and stop; otherwise continue. +3. **Create the PR:** From the repository root, run: + - **Command:** `gh pr create --base main --title "" --body "<body>"` + - Replace `<title>` with the title from step 1. For `<body>`, use a short description (e.g. same as title or "See commits for details"). Quote both so special characters or spaces are handled correctly. (Non-interactive `gh` requires `--body`.) +4. Report the outcome: the PR URL if successful, or any error from `git push` or `gh` (e.g. not logged in, uncommitted changes, conflicts). + +## Notes + +- Ensure you are in the workspace (repo) root when running `git` and `gh`. +- The current branch is used automatically as the head by `gh pr create`. +- If the user asks for a custom body/description, use that for `--body "..."` instead of the default. diff --git a/scripts/build_and_validate_sdk.py b/scripts/build_and_validate_sdk.py new file mode 100644 index 000000000..2dbe91237 --- /dev/null +++ b/scripts/build_and_validate_sdk.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +""" +Build the Python SDK and run validation tests. +Cross-platform (Windows, macOS, Linux). + +Prerequisites: Node.js, Python 3.x, Java 17+ on PATH. +Optional env: API_SPECS_PATH (default api-specs), SKIP_TESTS (default false). + +Usage (from repo root): + python scripts/build_and_validate_sdk.py + SKIP_TESTS=true python scripts/build_and_validate_sdk.py + API_SPECS_PATH=other-specs python scripts/build_and_validate_sdk.py +""" + +import os +import shutil +import subprocess +import sys +import urllib.request + + +def repo_root(): + return os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + + +def main(): + root = repo_root() + os.chdir(root) + + api_specs_path = os.environ.get("API_SPECS_PATH", "api-specs") + skip_tests = os.environ.get("SKIP_TESTS", "false").lower() in ("1", "true", "yes") + + print(f"Building SDK (api-specs-path={api_specs_path}, skip-tests={skip_tests})") + + # Download OpenAPI Generator if not present + jar_path = os.path.join(root, "openapi-generator-cli.jar") + if not os.path.isfile(jar_path): + print("Downloading OpenAPI Generator...") + url = "https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar" + urllib.request.urlretrieve(url, jar_path) + + # Prescript + print("Running prescript...") + idn_path = os.path.join(api_specs_path, "idn") + subprocess.run(["node", "sdk-resources/prescript.js", idn_path], check=True, cwd=root) + + def build_sdk(name, spec, config, out_dir): + print(f"Building {name} SDK...") + sailpoint_dir = os.path.join(root, "sailpoint", out_dir) + if os.path.isdir(sailpoint_dir): + shutil.rmtree(sailpoint_dir) + spec_path = os.path.join(api_specs_path, "idn", spec) + subprocess.run( + [ + "java", "-jar", jar_path, "generate", + "-i", spec_path, + "-g", "python", "-o", ".", + "--global-property", "skipFormModel=false,apiDocs=true,modelDocs=true", + "--config", f"sdk-resources/{config}", + ], + check=True, + cwd=root, + ) + subprocess.run( + ["node", "sdk-resources/postscript.js", sailpoint_dir], + check=True, + cwd=root, + ) + + build_sdk("V3", "sailpoint-api.v3.yaml", "v3-config.yaml", "v3") + build_sdk("Beta", "sailpoint-api.beta.yaml", "beta-config.yaml", "beta") + build_sdk("V2024", "sailpoint-api.v2024.yaml", "v2024-config.yaml", "v2024") + build_sdk("V2025", "sailpoint-api.v2025.yaml", "v2025-config.yaml", "v2025") + build_sdk("V2026", "sailpoint-api.v2026.yaml", "v2026-config.yaml", "v2026") + + # Install and test (use current Python / venv) + pip_cmd = [sys.executable, "-m", "pip"] + print("Installing dependencies and SDK...") + subprocess.run(pip_cmd + ["install", "-r", "requirements.txt"], check=True, cwd=root) + subprocess.run(pip_cmd + ["install", "-e", "."], check=True, cwd=root) + + if not skip_tests: + print("Running validation tests...") + subprocess.run( + [sys.executable, "validation_test.py", "-v"], + check=True, + cwd=root, + ) + else: + print(f"Skipping tests (SKIP_TESTS={os.environ.get('SKIP_TESTS', '')})") + + print("Done.") + + +if __name__ == "__main__": + main()