From 2f099d2fef307e6e66ffb9b6efcbdd6c3b5931b8 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 08:30:51 +0000 Subject: [PATCH 1/7] Update Linear webhooks example with latest implementation and add README.md --- .../examples/linear_webhooks/.env.template | 10 +- .../examples/linear_webhooks/README.md | 138 ++++++++++++++++++ .../examples/linear_webhooks/pyproject.toml | 16 +- .../examples/linear_webhooks/webhooks.py | 57 ++++++-- 4 files changed, 206 insertions(+), 15 deletions(-) create mode 100644 codegen-examples/examples/linear_webhooks/README.md diff --git a/codegen-examples/examples/linear_webhooks/.env.template b/codegen-examples/examples/linear_webhooks/.env.template index 680a15e8b..a68a3afa9 100644 --- a/codegen-examples/examples/linear_webhooks/.env.template +++ b/codegen-examples/examples/linear_webhooks/.env.template @@ -1,3 +1,7 @@ -LINEAR_ACCESS_TOKEN="..." -LINEAR_SIGNING_SECRET="..." -LINEAR_TEAM_ID="..." +# Linear API credentials +LINEAR_ACCESS_TOKEN="your_linear_api_token" +LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" +LINEAR_TEAM_ID="your_linear_team_id" + +# Modal configuration (optional) +MODAL_API_KEY="your_modal_api_key" diff --git a/codegen-examples/examples/linear_webhooks/README.md b/codegen-examples/examples/linear_webhooks/README.md new file mode 100644 index 000000000..b09c984ae --- /dev/null +++ b/codegen-examples/examples/linear_webhooks/README.md @@ -0,0 +1,138 @@ +# Linear Webhooks Example + +This example demonstrates how to set up a webhook handler for Linear events using the Codegen SDK and Modal. The webhook handler can process events from Linear such as issue creation, updates, comments, and more. + +## Prerequisites + +- [Modal](https://modal.com/) account +- [Linear](https://linear.app/) account with admin access +- Python 3.13 or higher + +## Setup + +### 1. Install Dependencies + +```bash +# Clone the repository +git clone https://github.com/Zeeeepa/codegen.git +cd codegen/codegen-examples/examples/linear_webhooks + +# Install dependencies +pip install -e . +``` + +### 2. Configure Environment Variables + +Copy the `.env.template` file to `.env` and fill in your credentials: + +```bash +cp .env.template .env +``` + +Edit the `.env` file with your Linear API credentials: + +``` +LINEAR_ACCESS_TOKEN="your_linear_api_token" +LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" +LINEAR_TEAM_ID="your_linear_team_id" +MODAL_API_KEY="your_modal_api_key" # Optional +``` + +To get these credentials: + +- **LINEAR_ACCESS_TOKEN**: Go to Linear → Settings → API → Create Key +- **LINEAR_SIGNING_SECRET**: Created when you set up a webhook in Linear +- **LINEAR_TEAM_ID**: Found in Linear team settings or via the API +- **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) + +### 3. Authenticate with Modal + +```bash +modal token new +``` + +## Deployment Commands + +### Deploy to Modal + +```bash +# Deploy the webhook handler to Modal +python webhooks.py +``` + +This will deploy the webhook handler to Modal and provide you with a URL that you can use to configure the webhook in Linear. + +### Get Deployment Status + +```bash +# Check the status of your Modal deployment +modal app status linear-webhooks +``` + +### View Logs + +```bash +# View logs from your Modal deployment +modal app logs linear-webhooks +``` + +### Update Deployment + +```bash +# Update your Modal deployment after making changes +python webhooks.py +``` + +### Stop Deployment + +```bash +# Stop your Modal deployment +modal app stop linear-webhooks +``` + +## Configuring Linear Webhooks + +1. Go to Linear → Settings → API → Webhooks +2. Click "New Webhook" +3. Enter the URL provided by Modal when you deployed the webhook handler +4. Select the events you want to receive (e.g., Issues, Comments) +5. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` +6. Click "Create Webhook" + +## Customizing Event Handlers + +The example includes handlers for Issue and Comment events. You can customize these handlers or add new ones by modifying the `webhooks.py` file: + +```python +@modal.web_endpoint(method="POST") +@app.linear.event("YourEventType") +def handle_your_event(self, event: LinearEvent): + # Process the event + return {"status": "success"} +``` + +## Available Event Types + +Linear supports the following event types: + +- `Issue` +- `Comment` +- `Project` +- `Cycle` +- `Reaction` +- And more... + +Refer to the [Linear API documentation](https://developers.linear.app/docs/graphql/webhooks) for a complete list of event types. + +## Troubleshooting + +- **Webhook not receiving events**: Verify that your Linear webhook is configured correctly and that the URL is accessible. +- **Authentication errors**: Check that your LINEAR_ACCESS_TOKEN and LINEAR_SIGNING_SECRET are correct. +- **Modal deployment issues**: Run `modal app logs linear-webhooks` to view logs and diagnose issues. + +## Additional Resources + +- [Codegen Documentation](https://docs.codegen.sh/) +- [Modal Documentation](https://modal.com/docs) +- [Linear API Documentation](https://developers.linear.app/docs) + diff --git a/codegen-examples/examples/linear_webhooks/pyproject.toml b/codegen-examples/examples/linear_webhooks/pyproject.toml index 31d5d4846..74aa67c54 100644 --- a/codegen-examples/examples/linear_webhooks/pyproject.toml +++ b/codegen-examples/examples/linear_webhooks/pyproject.toml @@ -3,4 +3,18 @@ name = "linear-webhook-example" version = "0.1.0" description = "Linear webhook example for Codegen" requires-python = ">=3.13" -dependencies = ["codegen>=0.22.2", "modal>=0.73.25"] +dependencies = [ + "codegen>=0.22.2", + "modal>=0.73.25", + "fastapi>=0.110.0", + "uvicorn>=0.27.0", + "pydantic>=2.0.0" +] + +[project.optional-dependencies] +dev = [ + "black>=23.0.0", + "isort>=5.12.0", + "mypy>=1.0.0", + "ruff>=0.0.270" +] diff --git a/codegen-examples/examples/linear_webhooks/webhooks.py b/codegen-examples/examples/linear_webhooks/webhooks.py index 823aa4323..18d7cdf6b 100644 --- a/codegen-examples/examples/linear_webhooks/webhooks.py +++ b/codegen-examples/examples/linear_webhooks/webhooks.py @@ -1,28 +1,63 @@ -import modal.running_app -from codegen.extensions.events.app import CodegenApp +import os import modal +from codegen.extensions.events.app import CodegenApp +from codegen.extensions.linear.types import LinearEvent +from codegen.shared.logging.get_logger import get_logger -image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=v0.22.2") -app = CodegenApp(name="test-linear", modal_api_key="", image=image) +logger = get_logger(__name__) -# Here is an example implementation of setting up an endpoint for receiving webhook events from Linear. -# The @app.linear.event() decorator takes care of subscribing to the webhook and also unsubscribing when the deployment spun -# Load environment variables from .env file +# Create a Modal image with the necessary dependencies +image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=v0.22.2") +# Initialize the CodegenApp with a name and the image +app = CodegenApp(name="linear-webhooks", modal_api_key="", image=image) +# Define a Modal class to handle Linear events @app.cls(secrets=[modal.Secret.from_dotenv()], keep_warm=1) class LinearEventHandlers: @modal.enter() def enter(self): + """Subscribe to all Linear webhook handlers when the app starts""" + logger.info("Subscribing to Linear webhook handlers") app.linear.subscribe_all_handlers() @modal.exit() def exit(self): + """Unsubscribe from all Linear webhook handlers when the app stops""" + logger.info("Unsubscribing from Linear webhook handlers") app.linear.unsubscribe_all_handlers() @modal.web_endpoint(method="POST") @app.linear.event("Issue") - def test(self, data: dict): - # handle webhook event - # data is the payload of the webhook event - print(data) + def handle_issue(self, event: LinearEvent): + """Handle Linear Issue events + + This endpoint will be triggered when an issue is created, updated, or deleted in Linear. + """ + logger.info(f"Received Linear Issue event: {event.action} - {event.data.title}") + # Process the event data as needed + return { + "status": "success", + "message": f"Processed Linear Issue event: {event.action}", + "issue_id": event.data.id, + "issue_title": event.data.title + } + + @modal.web_endpoint(method="POST") + @app.linear.event("Comment") + def handle_comment(self, event: LinearEvent): + """Handle Linear Comment events + + This endpoint will be triggered when a comment is created, updated, or deleted in Linear. + """ + logger.info(f"Received Linear Comment event: {event.action}") + # Process the comment data as needed + return { + "status": "success", + "message": f"Processed Linear Comment event: {event.action}", + "comment_id": event.data.id + } + +# If running this file directly, this will deploy the app to Modal +if __name__ == "__main__": + app.serve() From bffd11327b798350d1d5d90839c02ecbcec962d8 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 08:37:54 +0000 Subject: [PATCH 2/7] Fix type error in LinearEvent data handling --- .../examples/linear_webhooks/webhooks.py | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/codegen-examples/examples/linear_webhooks/webhooks.py b/codegen-examples/examples/linear_webhooks/webhooks.py index 18d7cdf6b..aafc57e4f 100644 --- a/codegen-examples/examples/linear_webhooks/webhooks.py +++ b/codegen-examples/examples/linear_webhooks/webhooks.py @@ -1,7 +1,7 @@ import os import modal from codegen.extensions.events.app import CodegenApp -from codegen.extensions.linear.types import LinearEvent +from codegen.extensions.linear.types import LinearEvent, LinearIssue, LinearComment from codegen.shared.logging.get_logger import get_logger logger = get_logger(__name__) @@ -34,14 +34,23 @@ def handle_issue(self, event: LinearEvent): This endpoint will be triggered when an issue is created, updated, or deleted in Linear. """ - logger.info(f"Received Linear Issue event: {event.action} - {event.data.title}") - # Process the event data as needed - return { - "status": "success", - "message": f"Processed Linear Issue event: {event.action}", - "issue_id": event.data.id, - "issue_title": event.data.title - } + # Check if the data is an Issue before accessing title + if isinstance(event.data, LinearIssue): + issue_title = event.data.title + logger.info(f"Received Linear Issue event: {event.action} - {issue_title}") + return { + "status": "success", + "message": f"Processed Linear Issue event: {event.action}", + "issue_id": event.data.id, + "issue_title": issue_title + } + else: + logger.warning(f"Received non-Issue data for Issue event: {event.action}") + return { + "status": "warning", + "message": f"Received non-Issue data for Issue event: {event.action}", + "id": event.data.id + } @modal.web_endpoint(method="POST") @app.linear.event("Comment") From 947a8fbfecc010da32c0ce7c90912adcfcc1297d Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 08:39:02 +0000 Subject: [PATCH 3/7] Fix type error in LinearEvent data handling --- codegen-examples/examples/linear_webhooks/webhooks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen-examples/examples/linear_webhooks/webhooks.py b/codegen-examples/examples/linear_webhooks/webhooks.py index aafc57e4f..782cdbc89 100644 --- a/codegen-examples/examples/linear_webhooks/webhooks.py +++ b/codegen-examples/examples/linear_webhooks/webhooks.py @@ -70,3 +70,4 @@ def handle_comment(self, event: LinearEvent): # If running this file directly, this will deploy the app to Modal if __name__ == "__main__": app.serve() + From 07c2fa0c556d52df2a3717cc75b74fa06c3356db Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 09:38:45 +0000 Subject: [PATCH 4/7] Update Linear examples with latest types and Modal patterns --- .../examples/linear_webhooks/pyproject.toml | 3 +- .../examples/linear_webhooks/webhooks.py | 45 +++++- .../examples/ticket-to-pr/.env.template | 16 +- .../examples/ticket-to-pr/README.md | 153 ++++++++++++++---- codegen-examples/examples/ticket-to-pr/app.py | 40 +++-- .../examples/ticket-to-pr/data.py | 1 + .../examples/ticket-to-pr/helpers.py | 1 + .../examples/ticket-to-pr/pyproject.toml | 25 ++- package.json | 7 +- 9 files changed, 232 insertions(+), 59 deletions(-) diff --git a/codegen-examples/examples/linear_webhooks/pyproject.toml b/codegen-examples/examples/linear_webhooks/pyproject.toml index 74aa67c54..f2100c9c8 100644 --- a/codegen-examples/examples/linear_webhooks/pyproject.toml +++ b/codegen-examples/examples/linear_webhooks/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" description = "Linear webhook example for Codegen" requires-python = ">=3.13" dependencies = [ - "codegen>=0.22.2", + "codegen>=0.26.3", "modal>=0.73.25", "fastapi>=0.110.0", "uvicorn>=0.27.0", @@ -18,3 +18,4 @@ dev = [ "mypy>=1.0.0", "ruff>=0.0.270" ] + diff --git a/codegen-examples/examples/linear_webhooks/webhooks.py b/codegen-examples/examples/linear_webhooks/webhooks.py index 782cdbc89..ba496e2ba 100644 --- a/codegen-examples/examples/linear_webhooks/webhooks.py +++ b/codegen-examples/examples/linear_webhooks/webhooks.py @@ -1,13 +1,13 @@ import os import modal from codegen.extensions.events.app import CodegenApp -from codegen.extensions.linear.types import LinearEvent, LinearIssue, LinearComment +from codegen.extensions.linear.types import LinearEvent, LinearIssue, LinearComment, LinearUser from codegen.shared.logging.get_logger import get_logger logger = get_logger(__name__) # Create a Modal image with the necessary dependencies -image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=v0.22.2") +image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=v0.26.3") # Initialize the CodegenApp with a name and the image app = CodegenApp(name="linear-webhooks", modal_api_key="", image=image) @@ -59,12 +59,45 @@ def handle_comment(self, event: LinearEvent): This endpoint will be triggered when a comment is created, updated, or deleted in Linear. """ - logger.info(f"Received Linear Comment event: {event.action}") - # Process the comment data as needed + # Check if the data is a Comment before processing + if isinstance(event.data, LinearComment): + logger.info(f"Received Linear Comment event: {event.action}") + + # Get the comment body and user information if available + comment_body = event.data.body + user_info = "" + if event.data.user: + user_info = f" by {event.data.user.name}" + + logger.info(f"Comment{user_info}: {comment_body}") + + return { + "status": "success", + "message": f"Processed Linear Comment event: {event.action}", + "comment_id": event.data.id, + "comment_body": comment_body + } + else: + logger.warning(f"Received non-Comment data for Comment event: {event.action}") + return { + "status": "warning", + "message": f"Received non-Comment data for Comment event: {event.action}", + "id": event.data.id + } + + @modal.web_endpoint(method="POST") + @app.linear.event("*") + def handle_generic(self, event: LinearEvent): + """Handle any other Linear events + + This endpoint will be triggered for any Linear event type not explicitly handled. + """ + logger.info(f"Received Linear event: {event.type} - {event.action}") return { "status": "success", - "message": f"Processed Linear Comment event: {event.action}", - "comment_id": event.data.id + "message": f"Processed Linear event: {event.type} - {event.action}", + "event_type": event.type, + "event_action": event.action } # If running this file directly, this will deploy the app to Modal diff --git a/codegen-examples/examples/ticket-to-pr/.env.template b/codegen-examples/examples/ticket-to-pr/.env.template index 3fdceb2b1..0cdb21f47 100644 --- a/codegen-examples/examples/ticket-to-pr/.env.template +++ b/codegen-examples/examples/ticket-to-pr/.env.template @@ -1,5 +1,11 @@ -LINEAR_ACCESS_TOKEN="..." -LINEAR_SIGNING_SECRET="..." -LINEAR_TEAM_ID="..." -GITHUB_TOKEN="..." -ANTHROPIC_API_KEY="..." +# Linear API credentials +LINEAR_ACCESS_TOKEN="your_linear_api_token" +LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" +LINEAR_TEAM_ID="your_linear_team_id" + +# GitHub credentials +GITHUB_TOKEN="your_github_personal_access_token" + +# Modal configuration (optional) +MODAL_API_KEY="your_modal_api_key" + diff --git a/codegen-examples/examples/ticket-to-pr/README.md b/codegen-examples/examples/ticket-to-pr/README.md index bbbec5d80..80a5cc2f7 100644 --- a/codegen-examples/examples/ticket-to-pr/README.md +++ b/codegen-examples/examples/ticket-to-pr/README.md @@ -1,43 +1,142 @@ -# Linear Ticket to GitHub PR Bot +# Linear Ticket to PR Example -This example project demonstrates how to deploy an agentic bot that automatically creates GitHub Pull Requests from Linear tickets. The bot leverages Linear's webhook system to listen for ticket updates and uses AI to generate corresponding GitHub PRs with appropriate code changes. +This example demonstrates how to automatically create GitHub Pull Requests from Linear tickets using the Codegen SDK and Modal. When a Linear issue is labeled with "Codegen", this application will: -## Prerequisites +1. Process the Linear webhook event +2. Run a Codegen agent to analyze the issue +3. Create a GitHub Pull Request with changes addressing the issue +4. Comment on the Linear issue with a link to the PR -Before running this application, you'll need the following API tokens and credentials: +## Prerequisites -- GitHub API Token -- Linear API Token -- Anthropic API Token -- Linear Signing Key -- Linear Team ID +- [Modal](https://modal.com/) account +- [Linear](https://linear.app/) account with admin access +- [GitHub](https://github.com/) repository access +- Python 3.13 or higher ## Setup -1. Clone the repository -1. Set up your environment variables in a `.env` file: +### 1. Install Dependencies + +```bash +# Clone the repository +git clone https://github.com/Zeeeepa/codegen.git +cd codegen/codegen-examples/examples/ticket-to-pr + +# Install dependencies +pip install -e . +``` + +### 2. Configure Environment Variables + +Create a `.env` file with your credentials: + +``` +LINEAR_ACCESS_TOKEN="your_linear_api_token" +LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" +LINEAR_TEAM_ID="your_linear_team_id" +GITHUB_TOKEN="your_github_personal_access_token" +MODAL_API_KEY="your_modal_api_key" # Optional +``` + +To get these credentials: + +- **LINEAR_ACCESS_TOKEN**: Go to Linear → Settings → API → Create Key +- **LINEAR_SIGNING_SECRET**: Created when you set up a webhook in Linear +- **LINEAR_TEAM_ID**: Found in Linear team settings or via the API +- **GITHUB_TOKEN**: Create a personal access token with repo permissions +- **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) + +### 3. Authenticate with Modal + +```bash +modal token new +``` + +## Deployment Commands + +### Deploy to Modal + +```bash +# Deploy the application to Modal +python app.py +``` + +This will deploy the application to Modal and provide you with a URL that you can use to configure the webhook in Linear. + +### Get Deployment Status + +```bash +# Check the status of your Modal deployment +modal app status linear-bot +``` + +### View Logs -```env -GITHUB_TOKEN=your_github_token -LINEAR_API_TOKEN=your_linear_token -ANTHROPIC_API_KEY=your_anthropic_token -LINEAR_SIGNING_KEY=your_linear_signing_key -LINEAR_TEAM_ID=your_team_id +```bash +# View logs from your Modal deployment +modal app logs linear-bot ``` -## Features +### Update Deployment + +```bash +# Update your Modal deployment after making changes +python app.py +``` + +### Stop Deployment + +```bash +# Stop your Modal deployment +modal app stop linear-bot +``` -- Automatic PR creation from Linear tickets -- AI-powered code generation using an agentic approach -- Webhook integration with Linear +## Configuring Linear Webhooks + +1. Go to Linear → Settings → API → Webhooks +2. Click "New Webhook" +3. Enter the URL provided by Modal when you deployed the application +4. Select the "Issue" event type +5. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` +6. Click "Create Webhook" + +## Creating a "Codegen" Label in Linear + +1. Go to Linear → Settings → Labels +2. Click "New Label" +3. Name the label "Codegen" +4. Choose a color for the label +5. Click "Create Label" ## Usage -1. `uv sync` -1. `uv run modal deploy app.py` - - At this point you should have a modal app with an endpoint that is auto registered to linear as a webhook callback url. -1. Try making a ticket and adding the `Codegen` label to trigger the agent +1. Create or update an issue in Linear +2. Add the "Codegen" label to the issue +3. The application will automatically: + - Process the webhook event + - Run a Codegen agent to analyze the issue + - Create a GitHub Pull Request with changes + - Comment on the Linear issue with a link to the PR + +## Customizing the Application + +You can customize the application by modifying the following files: + +- `app.py`: Main application logic +- `helpers.py`: Utility functions for processing Linear events +- `data.py`: Data models for Linear events and labels + +## Troubleshooting + +- **Webhook not receiving events**: Verify that your Linear webhook is configured correctly and that the URL is accessible. +- **Authentication errors**: Check that your LINEAR_ACCESS_TOKEN and GITHUB_TOKEN are correct. +- **Modal deployment issues**: Run `modal app logs linear-bot` to view logs and diagnose issues. + +## Additional Resources -## Contributing +- [Codegen Documentation](https://docs.codegen.sh/) +- [Modal Documentation](https://modal.com/docs) +- [Linear API Documentation](https://developers.linear.app/docs) +- [GitHub API Documentation](https://docs.github.com/en/rest) -Contributions are welcome! Please feel free to submit a Pull Request. diff --git a/codegen-examples/examples/ticket-to-pr/app.py b/codegen-examples/examples/ticket-to-pr/app.py index 49a654705..cfcecba4a 100644 --- a/codegen-examples/examples/ticket-to-pr/app.py +++ b/codegen-examples/examples/ticket-to-pr/app.py @@ -1,8 +1,9 @@ from codegen import Codebase, CodeAgent -from codegen.extensions.clients.linear import LinearClient +from codegen.extensions.linear.linear_client import LinearClient from codegen.extensions.events.app import CodegenApp from codegen.extensions.tools.github.create_pr import create_pr from codegen.shared.enums.programming_language import ProgrammingLanguage +from codegen.extensions.linear.types import LinearEvent, LinearIssue, LinearComment, LinearUser from helpers import create_codebase, format_linear_message, has_codegen_label, process_update_event from fastapi import Request @@ -15,8 +16,10 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen==v0.26.3") +# Create a Modal image with the necessary dependencies +image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=v0.26.3") +# Initialize the CodegenApp with a name and the image app = CodegenApp("linear-bot", image=image, modal_api_key="") @@ -26,6 +29,7 @@ class LinearApp: @modal.enter() def run_this_on_container_startup(self): + """Initialize the codebase and subscribe to Linear webhook handlers""" self.codebase = create_codebase("codegen-sh/codegen-sdk", ProgrammingLanguage.PYTHON) # Subscribe web endpoints as linear webhook callbacks @@ -33,29 +37,45 @@ def run_this_on_container_startup(self): @modal.exit() def run_this_on_container_exit(self): + """Unsubscribe from Linear webhook handlers when the app stops""" app.linear.unsubscribe_all_handlers() @modal.web_endpoint(method="POST") @app.linear.event("Issue", should_handle=has_codegen_label) - def handle_webhook(self, data: dict, request: Request): - """"Handle incoming webhook events from Linear""" "" + def handle_webhook(self, event: LinearEvent, request: Request): + """Handle incoming webhook events from Linear""" linear_client = LinearClient(access_token=os.environ["LINEAR_ACCESS_TOKEN"]) - event = process_update_event(data) - linear_client.comment_on_issue(event.issue_id, "I'm on it 👍") + # Process the event data + update_event = process_update_event(event.data) + linear_client.comment_on_issue(update_event.issue_id, "I'm on it 👍") - query = format_linear_message(event.title, event.description) + # Format the query for the agent + query = format_linear_message(update_event.title, update_event.description) agent = CodeAgent(self.codebase) + # Run the agent with the query agent.run(query) - pr_title = f"[{event.identifier}] " + event.title - pr_body = "Codegen generated PR for issue: " + event.issue_url + # Create a PR with the agent's changes + pr_title = f"[{update_event.identifier}] " + update_event.title + pr_body = "Codegen generated PR for issue: " + update_event.issue_url create_pr_result = create_pr(self.codebase, pr_title, pr_body) logger.info(f"PR created: {create_pr_result.model_dump_json()}") - linear_client.comment_on_issue(event.issue_id, f"I've finished running, please review the PR: {create_pr_result.url}") + # Comment on the Linear issue with the PR link + linear_client.comment_on_issue( + update_event.issue_id, + f"I've finished running, please review the PR: {create_pr_result.url}" + ) + + # Reset the codebase for the next request self.codebase.reset() return {"status": "success"} + +# If running this file directly, this will deploy the app to Modal +if __name__ == "__main__": + app.serve() + diff --git a/codegen-examples/examples/ticket-to-pr/data.py b/codegen-examples/examples/ticket-to-pr/data.py index 82ba54442..ad08170a9 100644 --- a/codegen-examples/examples/ticket-to-pr/data.py +++ b/codegen-examples/examples/ticket-to-pr/data.py @@ -20,3 +20,4 @@ class LinearIssueUpdateEvent(BaseModel): title: str description: Optional[str] = None identifier: Optional[str] = None + diff --git a/codegen-examples/examples/ticket-to-pr/helpers.py b/codegen-examples/examples/ticket-to-pr/helpers.py index b4302a2b5..3c01e98f6 100644 --- a/codegen-examples/examples/ticket-to-pr/helpers.py +++ b/codegen-examples/examples/ticket-to-pr/helpers.py @@ -82,3 +82,4 @@ def create_codebase(repo_name: str, language: ProgrammingLanguage): config.secrets.github_token = os.environ["GITHUB_TOKEN"] return Codebase.from_repo(repo_name, language=language, tmp_dir="/root", config=config) + diff --git a/codegen-examples/examples/ticket-to-pr/pyproject.toml b/codegen-examples/examples/ticket-to-pr/pyproject.toml index b1fbfdb35..7da419bb2 100644 --- a/codegen-examples/examples/ticket-to-pr/pyproject.toml +++ b/codegen-examples/examples/ticket-to-pr/pyproject.toml @@ -1,12 +1,21 @@ [project] -name = "ticket-to-pr" +name = "linear-ticket-to-pr-example" version = "0.1.0" -description = "A example implementation of a agentic linear bot that can create PRs from linear tickets" -readme = "README.md" -requires-python = ">=3.12, <3.14" +description = "Linear ticket to GitHub PR example for Codegen" +requires-python = ">=3.13" dependencies = [ - "codegen@git+https://github.com/codegen-sh/codegen-sdk.git@1f4dddb258a61574bce8edd06c81510c42e1e255", - "fastapi>=0.115.8", - "modal>=0.73.51", - "pydantic>=2.10.6", + "codegen>=0.26.3", + "modal>=0.73.25", + "fastapi>=0.110.0", + "uvicorn>=0.27.0", + "pydantic>=2.0.0" ] + +[project.optional-dependencies] +dev = [ + "black>=23.0.0", + "isort>=5.12.0", + "mypy>=1.0.0", + "ruff>=0.0.270" +] + diff --git a/package.json b/package.json index cd7830acd..1fe996964 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,14 @@ { "private": true, "release": { - "branches": ["develop"], + "branches": [ + "develop" + ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/github" ] - } + }, + "packageManager": "yarn@4.9.1+sha512.f95ce356460e05be48d66401c1ae64ef84d163dd689964962c6888a9810865e39097a5e9de748876c2e0bf89b232d583c33982773e9903ae7a76257270986538" } From a8a12dd3d616c482fec0e2c4305aa290a1bc8a05 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 13:15:53 +0000 Subject: [PATCH 5/7] Update examples with deployment scripts and documentation --- codegen-examples/examples/Deployer.sh | 175 +++++++++++++++ .../examples/ai_impact_analysis/deploy.sh | 57 +++++ .../examples/github_checks/README.md | 203 ++++++++++-------- .../examples/github_checks/deploy.sh | 56 +++++ .../examples/linear_webhooks/README.md | 80 +++---- .../examples/linear_webhooks/deploy.sh | 47 ++++ .../examples/modal_repo_analytics/README.md | 131 +++++++---- .../examples/modal_repo_analytics/deploy.sh | 48 +++++ .../examples/snapshot_event_handler/README.md | 138 +++++++++--- .../examples/snapshot_event_handler/deploy.sh | 47 ++++ .../examples/swebench_agent_run/deploy.sh | 45 +++- .../examples/ticket-to-pr/README.md | 92 ++++---- .../examples/ticket-to-pr/deploy.sh | 47 ++++ 13 files changed, 911 insertions(+), 255 deletions(-) create mode 100755 codegen-examples/examples/Deployer.sh create mode 100755 codegen-examples/examples/ai_impact_analysis/deploy.sh create mode 100755 codegen-examples/examples/github_checks/deploy.sh create mode 100755 codegen-examples/examples/linear_webhooks/deploy.sh create mode 100755 codegen-examples/examples/modal_repo_analytics/deploy.sh create mode 100755 codegen-examples/examples/snapshot_event_handler/deploy.sh create mode 100755 codegen-examples/examples/ticket-to-pr/deploy.sh diff --git a/codegen-examples/examples/Deployer.sh b/codegen-examples/examples/Deployer.sh new file mode 100755 index 000000000..f93615762 --- /dev/null +++ b/codegen-examples/examples/Deployer.sh @@ -0,0 +1,175 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Function to deploy a single example +deploy_example() { + local example_dir="$1" + local example_name=$(basename "$example_dir") + + if [ -f "$example_dir/deploy.sh" ]; then + echo "Deploying $example_name..." + (cd "$example_dir" && bash deploy.sh) + return $? + else + echo "No deploy.sh script found for $example_name. Skipping." + return 1 + fi +} + +# Find all examples with deploy.sh scripts +examples=() +for dir in "$SCRIPT_DIR"/*/; do + if [ -f "${dir}deploy.sh" ]; then + examples+=("$(basename "$dir")") + fi +done + +if [ ${#examples[@]} -eq 0 ]; then + echo "No deployable examples found." + exit 1 +fi + +# Display menu +echo "Available examples for deployment:" +echo "" + +for i in "${!examples[@]}"; do + echo "[$((i+1))] ${examples[$i]}" +done + +echo "" +echo "[a] Deploy all examples" +echo "[q] Quit" +echo "" + +# Get user selection +selected_indices=() +while true; do + read -p "Select examples to deploy (e.g., '1 3 5' or 'a' for all, 'q' to quit, 'd' when done): " selection + + if [ "$selection" == "q" ]; then + echo "Exiting without deployment." + exit 0 + elif [ "$selection" == "a" ]; then + for i in "${!examples[@]}"; do + selected_indices+=($i) + done + break + elif [ "$selection" == "d" ]; then + if [ ${#selected_indices[@]} -eq 0 ]; then + echo "No examples selected. Please select at least one example." + else + break + fi + else + # Parse space-separated numbers + for num in $selection; do + if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#examples[@]} ]; then + idx=$((num-1)) + # Check if already selected + if [[ ! " ${selected_indices[@]} " =~ " ${idx} " ]]; then + selected_indices+=($idx) + echo "Added ${examples[$idx]} to deployment list." + else + echo "${examples[$idx]} is already selected." + fi + else + echo "Invalid selection: $num. Please enter numbers between 1 and ${#examples[@]}." + fi + done + fi +done + +# Show selected examples +echo "" +echo "Selected examples for deployment:" +for idx in "${selected_indices[@]}"; do + echo "- ${examples[$idx]}" +done +echo "" + +# Confirm deployment +read -p "Deploy these examples? (y/n): " confirm +if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then + echo "Deployment cancelled." + exit 0 +fi + +# Deploy selected examples concurrently +echo "Starting deployment of selected examples..." +pids=() +results=() + +for idx in "${selected_indices[@]}"; do + example="${examples[$idx]}" + example_dir="$SCRIPT_DIR/$example" + + # Start deployment in background + (deploy_example "$example_dir" && echo "SUCCESS: $example" || echo "FAILED: $example") & + pids+=($!) + results+=("") +done + +# Wait for all deployments to complete +for i in "${!pids[@]}"; do + wait "${pids[$i]}" + results[$i]=$? +done + +# Print summary +echo "" +echo "Deployment Summary:" +echo "==================" +success_count=0 +failure_count=0 + +for i in "${!selected_indices[@]}"; do + idx="${selected_indices[$i]}" + example="${examples[$idx]}" + result="${results[$i]}" + + if [ "$result" -eq 0 ]; then + echo "✅ ${example}: SUCCESS" + ((success_count++)) + else + echo "❌ ${example}: FAILED" + ((failure_count++)) + fi +done + +echo "" +echo "Total: $((success_count + failure_count)), Successful: $success_count, Failed: $failure_count" + +if [ "$failure_count" -gt 0 ]; then + echo "" + echo "Some deployments failed. Check the logs above for details." + exit 1 +fi + +echo "" +echo "All deployments completed successfully!" + diff --git a/codegen-examples/examples/ai_impact_analysis/deploy.sh b/codegen-examples/examples/ai_impact_analysis/deploy.sh new file mode 100755 index 000000000..df8602e9b --- /dev/null +++ b/codegen-examples/examples/ai_impact_analysis/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the backend API +echo "Deploying AI Impact Analysis Backend API to Modal..." +python3 dashboard/backend/api.py + +echo "Deployment complete! You can check the status with 'modal app status ai-impact-analysis-api'" +echo "To view logs, run 'modal app logs ai-impact-analysis-api'" + +# Instructions for frontend deployment +echo "" +echo "To deploy the frontend:" +echo "1. Navigate to the frontend directory: cd dashboard/frontend" +echo "2. Install dependencies: npm install" +echo "3. Update the API_URL in src/config.js to point to your Modal deployment" +echo "4. Build the frontend: npm run build" +echo "5. Deploy to your preferred hosting service (e.g., Vercel, Netlify, GitHub Pages)" + diff --git a/codegen-examples/examples/github_checks/README.md b/codegen-examples/examples/github_checks/README.md index 605532669..1eedd505d 100644 --- a/codegen-examples/examples/github_checks/README.md +++ b/codegen-examples/examples/github_checks/README.md @@ -1,110 +1,129 @@ -# Github Checks - -This application is a GitHub integration that analyzes import cycles in codebases. It automatically runs when a pull request is labeled and checks for potentially problematic import patterns in the modified codebase. - -## Features - -- Analyzes import relationships in codebases -- Detects circular import dependencies -- Identifies problematic cycles with mixed static and dynamic imports -- Automatically comments on pull requests with detailed analysis - -## How It Works - -1. The app creates a directed graph representing import relationships in the codebase - - ```python - for imp in codebase.imports: - if imp.from_file and imp.to_file: - G.add_edge( - imp.to_file.filepath, - imp.from_file.filepath, - color="red" if getattr(imp, "is_dynamic", False) else "black", - label="dynamic" if getattr(imp, "is_dynamic", False) else "static", - is_dynamic=getattr(imp, "is_dynamic", False), - ) - ``` - -1. It identifies strongly connected components (cycles) in the import graph - - ```python - cycles = [scc for scc in nx.strongly_connected_components(G) if len(scc) > 1] - ``` - -1. It specifically flags cycles that contain both static and dynamic imports - - ```python - dynamic_count = sum(1 for e in edges.values() if e["color"] == "red") - static_count = sum(1 for e in edges.values() if e["color"] == "black") - - if dynamic_count > 0 and static_count > 0: - mixed_imports[(from_file, to_file)] = { - "dynamic": dynamic_count, - "static": static_count, - "edges": edges, - } - ``` - -1. Results are posted as a comment on the pull request - - ```python - message = ["### Import Cycle Analysis - GitHub Check\n"] - - if problematic_loops: - message.append("\n### ⚠️ Potentially Problematic Import Cycles") - message.append("Cycles with mixed static and dynamic imports, which might recquire attention.") - for i, cycle in enumerate(problematic_loops, 1): - message.append(f"\n#### Problematic Cycle {i}") - for (from_file, to_file), imports in cycle["mixed_imports"].items(): - message.append(f"\nFrom: `{from_file}`") - message.append(f"To: `{to_file}`") - message.append(f"- Static imports: {imports['static']}") - message.append(f"- Dynamic imports: {imports['dynamic']}") - else: - message.append("\nNo problematic import cycles found! 🎉") - ``` +# GitHub Checks Example + +This example demonstrates how to create a GitHub check that analyzes import cycles in a repository using the Codegen SDK and Modal. When a pull request is labeled, this application will: + +1. Analyze the codebase for import cycles +2. Identify potentially problematic cycles with mixed static and dynamic imports +3. Post a comment on the pull request with the analysis results + +## Prerequisites + +- [Modal](https://modal.com/) account +- [GitHub](https://github.com/) repository access +- Python 3.13 or higher ## Setup -1. Ensure you have the following dependencies: +### 1. Install Dependencies + +```bash +# Clone the repository +git clone https://github.com/Zeeeepa/codegen.git +cd codegen/codegen-examples/examples/github_checks + +# Install dependencies +pip install -e . +``` + +### 2. Configure Environment Variables + +Create a `.env` file with your credentials: + +``` +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +``` + +To get these credentials: + +- **GITHUB_TOKEN**: Create a personal access token with repo permissions +- **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) + +### 3. Authenticate with Modal + +```bash +modal token new +``` + +## Deployment Commands + +### Deploy to Modal + +```bash +# Deploy the application to Modal +./deploy.sh +``` + +This will deploy the application to Modal and provide you with a URL that you can use to configure the GitHub webhook. + +### Get Deployment Status + +```bash +# Check the status of your Modal deployment +modal app status codegen-import-cycles-github-check +``` + +### View Logs + +```bash +# View logs from your Modal deployment +modal app logs codegen-import-cycles-github-check +``` + +### Update Deployment - - Python 3.13 - - Modal - - Codegen - - NetworkX - - python-dotenv +```bash +# Update your Modal deployment after making changes +./deploy.sh +``` -1. Set up your environment variables in a `.env` file +### Stop Deployment - - `GITHUB_TOKEN`: Your GitHub token, configured with `repo` and `workflow` scopes. +```bash +# Stop your Modal deployment +modal app stop codegen-import-cycles-github-check +``` -1. Deploy the app using Modal: +## Configuring GitHub Webhooks - ```bash - modal deploy app.py - ``` +1. Go to your GitHub repository +2. Go to Settings → Webhooks +3. Click "Add webhook" +4. Enter the URL provided by Modal when you deployed the application +5. Select "application/json" as the content type +6. Select "Let me select individual events" +7. Check "Pull requests" +8. Click "Add webhook" - - After deployment, configure your GitHub App's webhook URL in its developer settings to point to your Modal endpoint with the endpoint `/github/events` - - The app will analyze imports via the Modal deployment whenever a pull request receives a `Codegen` label +## Usage -## Technical Details +1. Create a pull request in your repository +2. Add a label to the pull request +3. The application will automatically: + - Analyze the codebase for import cycles + - Identify potentially problematic cycles + - Post a comment on the pull request with the analysis results -The application uses Codegen to parse the codebase and a combination of NetworkX and Codegen to analyze the import relationships. The app is structured as a Modal App with a FastAPI server. -The analysis runs when a pull request is labeled (`pull_request:labeled` event). +## Customizing the Application -## Output Format +You can customize the application by modifying the following functions in `app.py`: -The analysis results are posted as a markdown-formatted comment on the pull request, including: +- `create_graph_from_codebase`: Creates a directed graph representing import relationships +- `find_import_cycles`: Identifies strongly connected components (cycles) in the import graph +- `find_problematic_import_loops`: Identifies cycles with both static and dynamic imports -- Summary statistics -- Detailed cycle information -- Warning indicators for problematic import patterns +## Troubleshooting -## Learn More +- **Webhook not receiving events**: Verify that your GitHub webhook is configured correctly and that the URL is accessible. +- **Authentication errors**: Check that your GITHUB_TOKEN is correct and has the necessary permissions. +- **Modal deployment issues**: Run `modal app logs codegen-import-cycles-github-check` to view logs and diagnose issues. -- [Codegen Documentation](https://docs.codegen.com) -- [Detecting Import Loops](https://docs.codegen.com/blog/fixing-import-loops) +## Additional Resources -## Contributing +- [Codegen Documentation](https://docs.codegen.sh/) +- [Modal Documentation](https://modal.com/docs) +- [GitHub Webhooks Documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) -Feel free to submit issues and enhancement requests! diff --git a/codegen-examples/examples/github_checks/deploy.sh b/codegen-examples/examples/github_checks/deploy.sh new file mode 100755 index 000000000..b499da994 --- /dev/null +++ b/codegen-examples/examples/github_checks/deploy.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "No .env.template file found. Creating a basic .env template..." + cat > .env.template << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying GitHub Checks to Modal..." +python3 app.py + +echo "Deployment complete! You can check the status with 'modal app status codegen-import-cycles-github-check'" +echo "To view logs, run 'modal app logs codegen-import-cycles-github-check'" + diff --git a/codegen-examples/examples/linear_webhooks/README.md b/codegen-examples/examples/linear_webhooks/README.md index b09c984ae..24c7f87cf 100644 --- a/codegen-examples/examples/linear_webhooks/README.md +++ b/codegen-examples/examples/linear_webhooks/README.md @@ -1,12 +1,12 @@ # Linear Webhooks Example -This example demonstrates how to set up a webhook handler for Linear events using the Codegen SDK and Modal. The webhook handler can process events from Linear such as issue creation, updates, comments, and more. +This example demonstrates how to create a Modal application that handles Linear webhooks using the Codegen SDK. The application can process various Linear events such as issue creation, updates, comments, and more. ## Prerequisites - [Modal](https://modal.com/) account -- [Linear](https://linear.app/) account with admin access -- Python 3.13 or higher +- [Linear](https://linear.app/) workspace with admin access +- Python 3.10 or higher ## Setup @@ -23,26 +23,23 @@ pip install -e . ### 2. Configure Environment Variables -Copy the `.env.template` file to `.env` and fill in your credentials: +Create a `.env` file with your credentials: -```bash -cp .env.template .env ``` +# Linear credentials +LINEAR_ACCESS_TOKEN=your_linear_api_token +LINEAR_SIGNING_SECRET=your_linear_webhook_signing_secret +LINEAR_TEAM_ID=your_linear_team_id -Edit the `.env` file with your Linear API credentials: - -``` -LINEAR_ACCESS_TOKEN="your_linear_api_token" -LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" -LINEAR_TEAM_ID="your_linear_team_id" -MODAL_API_KEY="your_modal_api_key" # Optional +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key ``` To get these credentials: -- **LINEAR_ACCESS_TOKEN**: Go to Linear → Settings → API → Create Key -- **LINEAR_SIGNING_SECRET**: Created when you set up a webhook in Linear -- **LINEAR_TEAM_ID**: Found in Linear team settings or via the API +- **LINEAR_ACCESS_TOKEN**: Create an API key in Linear (Settings → API → Create Key) +- **LINEAR_SIGNING_SECRET**: Create a webhook in Linear and copy the signing secret +- **LINEAR_TEAM_ID**: Your Linear team ID (can be found in team settings) - **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) ### 3. Authenticate with Modal @@ -56,11 +53,11 @@ modal token new ### Deploy to Modal ```bash -# Deploy the webhook handler to Modal -python webhooks.py +# Deploy the application to Modal +./deploy.sh ``` -This will deploy the webhook handler to Modal and provide you with a URL that you can use to configure the webhook in Linear. +This will deploy the application to Modal and provide you with a URL that you can use to configure the Linear webhook. ### Get Deployment Status @@ -80,7 +77,7 @@ modal app logs linear-webhooks ```bash # Update your Modal deployment after making changes -python webhooks.py +./deploy.sh ``` ### Stop Deployment @@ -92,37 +89,30 @@ modal app stop linear-webhooks ## Configuring Linear Webhooks -1. Go to Linear → Settings → API → Webhooks -2. Click "New Webhook" -3. Enter the URL provided by Modal when you deployed the webhook handler -4. Select the events you want to receive (e.g., Issues, Comments) -5. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` -6. Click "Create Webhook" +1. Go to your Linear workspace +2. Go to Settings → API → Webhooks +3. Click "New Webhook" +4. Enter the URL provided by Modal when you deployed the application +5. Select the events you want to receive (e.g., Issues, Comments) +6. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` +7. Click "Create Webhook" -## Customizing Event Handlers +## Usage -The example includes handlers for Issue and Comment events. You can customize these handlers or add new ones by modifying the `webhooks.py` file: +The application handles the following Linear events: -```python -@modal.web_endpoint(method="POST") -@app.linear.event("YourEventType") -def handle_your_event(self, event: LinearEvent): - # Process the event - return {"status": "success"} -``` +- **Issue**: Created, updated, or removed +- **Comment**: Created, updated, or removed -## Available Event Types +You can customize the handlers in `webhooks.py` to process these events according to your needs. -Linear supports the following event types: +## Customizing the Application -- `Issue` -- `Comment` -- `Project` -- `Cycle` -- `Reaction` -- And more... +You can customize the application by modifying the event handlers in `webhooks.py`. Each handler receives a `LinearEvent` object that contains information about the event, including: -Refer to the [Linear API documentation](https://developers.linear.app/docs/graphql/webhooks) for a complete list of event types. +- `action`: The action that triggered the event (e.g., "create", "update") +- `data`: The data associated with the event (e.g., issue details, comment details) +- `type`: The type of event (e.g., "Issue", "Comment") ## Troubleshooting @@ -134,5 +124,5 @@ Refer to the [Linear API documentation](https://developers.linear.app/docs/graph - [Codegen Documentation](https://docs.codegen.sh/) - [Modal Documentation](https://modal.com/docs) -- [Linear API Documentation](https://developers.linear.app/docs) +- [Linear API Documentation](https://developers.linear.app/docs/) diff --git a/codegen-examples/examples/linear_webhooks/deploy.sh b/codegen-examples/examples/linear_webhooks/deploy.sh new file mode 100755 index 000000000..4bf90c6c3 --- /dev/null +++ b/codegen-examples/examples/linear_webhooks/deploy.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "Neither .env nor .env.template file found. Please create a .env file with your credentials." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying Linear Webhooks to Modal..." +python3 webhooks.py + +echo "Deployment complete! You can check the status with 'modal app status linear-webhooks'" +echo "To view logs, run 'modal app logs linear-webhooks'" + diff --git a/codegen-examples/examples/modal_repo_analytics/README.md b/codegen-examples/examples/modal_repo_analytics/README.md index 108df5e42..e0308877a 100644 --- a/codegen-examples/examples/modal_repo_analytics/README.md +++ b/codegen-examples/examples/modal_repo_analytics/README.md @@ -1,68 +1,121 @@ -# Repository Analyzer API +# Modal Repository Analytics Example -A simple Modal API endpoint that analyzes GitHub repositories using Codegen. The API returns basic metrics about any public GitHub repository including: +This example demonstrates how to create a Modal application that provides analytics for GitHub repositories using the Codegen SDK. The application exposes an API that can analyze repositories for: -- Total number of files -- Number of functions -- Number of classes +- Code complexity metrics +- Dependency graphs +- File statistics +- Contributor insights +- And more -## Running Locally +## Prerequisites -1. Install dependencies: +- [Modal](https://modal.com/) account +- [GitHub](https://github.com/) repository access +- Python 3.10 or higher + +## Setup + +### 1. Install Dependencies ```bash -uv add modal +# Clone the repository +git clone https://github.com/Zeeeepa/codegen.git +cd codegen/codegen-examples/examples/modal_repo_analytics + +# Install dependencies +pip install -e . +``` + +### 2. Configure Environment Variables + +Create a `.env` file with your credentials: + ``` +# GitHub credentials +GITHUB_TOKEN=your_github_token -2. Start the API server: +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +``` + +To get these credentials: + +- **GITHUB_TOKEN**: Create a personal access token with repo permissions +- **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) + +### 3. Authenticate with Modal ```bash -modal serve src/codegen/extensions/modal/api.py +modal token new ``` -3. Test with curl: +## Deployment Commands + +### Deploy to Modal ```bash -# Replace with your local Modal endpoint URL -curl "{URL}?repo_name=fastapi/fastapi" +# Deploy the application to Modal +./deploy.sh ``` -## Response Format +This will deploy the application to Modal and provide you with a URL that you can use to access the API. -The API returns JSON in this format: +### Get Deployment Status -```json -{ - "status": "success", - "error": "", - "num_files": 123, - "num_functions": 456, - "num_classes": 78 -} +```bash +# Check the status of your Modal deployment +modal app status repo-analytics-api ``` -If there's an error, you'll get: +### View Logs -```json -{ - "status": "error", - "error": "Error message here", - "num_files": 0, - "num_functions": 0, - "num_classes": 0 -} +```bash +# View logs from your Modal deployment +modal app logs repo-analytics-api ``` -## Development +### Update Deployment -The API is built using: +```bash +# Update your Modal deployment after making changes +./deploy.sh +``` + +### Stop Deployment + +```bash +# Stop your Modal deployment +modal app stop repo-analytics-api +``` + +## API Usage + +The API provides the following endpoints: -- Modal for serverless deployment -- FastAPI for the web endpoint -- Codegen for repository analysis +- `GET /analyze/{owner}/{repo}`: Analyze a repository and return metrics +- `GET /complexity/{owner}/{repo}`: Get code complexity metrics for a repository +- `GET /dependencies/{owner}/{repo}`: Get dependency graph for a repository -To deploy changes: +Example request: ```bash -modal deploy src/codegen/extensions/modal/api.py +curl https://your-modal-url.modal.run/analyze/Zeeeepa/codegen ``` + +## Customizing the Application + +You can customize the application by modifying the API endpoints in `api.py`. The application uses the Codegen SDK to analyze repositories, so you can leverage all of its features to extract the metrics you need. + +## Troubleshooting + +- **Authentication errors**: Check that your GITHUB_TOKEN is correct and has the necessary permissions. +- **Modal deployment issues**: Run `modal app logs repo-analytics-api` to view logs and diagnose issues. +- **Rate limiting**: GitHub API has rate limits. If you're analyzing large repositories or making many requests, you might hit these limits. + +## Additional Resources + +- [Codegen Documentation](https://docs.codegen.sh/) +- [Modal Documentation](https://modal.com/docs) +- [GitHub API Documentation](https://docs.github.com/en/rest) + diff --git a/codegen-examples/examples/modal_repo_analytics/deploy.sh b/codegen-examples/examples/modal_repo_analytics/deploy.sh new file mode 100755 index 000000000..84b58e2bd --- /dev/null +++ b/codegen-examples/examples/modal_repo_analytics/deploy.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Modal Repo Analytics to Modal..." +python3 api.py + +echo "Deployment complete! You can check the status with 'modal app status repo-analytics-api'" +echo "To view logs, run 'modal app logs repo-analytics-api'" + diff --git a/codegen-examples/examples/snapshot_event_handler/README.md b/codegen-examples/examples/snapshot_event_handler/README.md index 447d154cd..77b55d15e 100644 --- a/codegen-examples/examples/snapshot_event_handler/README.md +++ b/codegen-examples/examples/snapshot_event_handler/README.md @@ -1,53 +1,127 @@ -# Event Handler with codebase snapshotting +# Snapshot Event Handler Example -This project is designed to using Modal snapshotting to provide parsed codebase instances with minimal latency, make it more manageable to write event based handlers. - -Follow the instructions below to set up and deploy the application. +This example demonstrates how to create a Modal application that handles GitHub events for repository snapshots using the Codegen SDK. The application can process various GitHub events such as pull request creation, updates, and more, and perform automated tasks like code reviews and issue creation. ## Prerequisites -Before you begin, ensure you have the following installed and configured: +- [Modal](https://modal.com/) account +- [GitHub](https://github.com/) repository access +- Python 3.10 or higher + +## Setup + +### 1. Install Dependencies + +```bash +# Clone the repository +git clone https://github.com/Zeeeepa/codegen.git +cd codegen/codegen-examples/examples/snapshot_event_handler + +# Install dependencies +pip install -e . +``` + +### 2. Configure Environment Variables + +Create a `.env` file with your credentials: + +``` +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +``` + +To get these credentials: + +- **GITHUB_TOKEN**: Create a personal access token with repo permissions +- **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) + +### 3. Authenticate with Modal + +```bash +modal token new +``` + +## Deployment Commands + +### Deploy to Modal + +```bash +# Deploy the application to Modal +./deploy.sh +``` + +This will deploy the application to Modal and provide you with a URL that you can use to configure the GitHub webhook. + +### Get Deployment Status + +```bash +# Check the status of your Modal deployment +modal app status snapshot-event-handler +``` + +### View Logs + +```bash +# View logs from your Modal deployment +modal app logs snapshot-event-handler +``` + +### Update Deployment -1. **uv**: A tool for managing virtual environments and syncing dependencies. -1. **Modal**: Ensure you have Modal configured on your system. +```bash +# Update your Modal deployment after making changes +./deploy.sh +``` -## Setup Instructions +### Stop Deployment -1. **Create a Virtual Environment** +```bash +# Stop your Modal deployment +modal app stop snapshot-event-handler +``` - Use `uv` to create a virtual environment with Python 3.13: +## Configuring GitHub Webhooks - ```bash - uv venv --python 3.13 +1. Go to your GitHub repository +2. Go to Settings → Webhooks +3. Click "Add webhook" +4. Enter the URL provided by Modal when you deployed the application +5. Select "application/json" as the content type +6. Select "Let me select individual events" +7. Check the events you want to receive (e.g., "Pull requests", "Issues") +8. Click "Add webhook" - source ./venv/bin/activate - ``` +## Usage -1. **Sync Dependencies** +The application handles the following GitHub events: - Sync the project dependencies using `uv`: +- **Pull Request**: Created, updated, or closed +- **Issue**: Created, updated, or closed +- **Push**: Code pushed to the repository - ```bash - uv sync - ``` +You can customize the handlers in `event_handlers.py` to process these events according to your needs. -1. **Deploy to Modal** +## Customizing the Application - Deploy the application to Modal by running: +You can customize the application by modifying the event handlers in `event_handlers.py` and the PR tasks in `pr_tasks.py`. Each handler receives an event object that contains information about the event, including: - ```bash - uv run modal deploy event_handlers.py - ``` +- `action`: The action that triggered the event (e.g., "opened", "closed") +- `repository`: Information about the repository +- `sender`: Information about the user who triggered the event +- Event-specific data (e.g., `pull_request`, `issue`) - This command will deploy the Modal app and provide a web URL for your webhook sync. +## Troubleshooting -## Project Structure +- **Webhook not receiving events**: Verify that your GitHub webhook is configured correctly and that the URL is accessible. +- **Authentication errors**: Check that your GITHUB_TOKEN is correct and has the necessary permissions. +- **Modal deployment issues**: Run `modal app logs snapshot-event-handler` to view logs and diagnose issues. -- `event_handlers.py`: Contains the main logic for handling events. -- `pr_tasks.py`: Additional tasks related to pull requests. -- `.env.template` and `.env`: Environment variable templates and configurations. -- `pyproject.toml`: Project configuration and dependencies. +## Additional Resources -## Integration +- [Codegen Documentation](https://docs.codegen.sh/) +- [Modal Documentation](https://modal.com/docs) +- [GitHub Webhooks Documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) -Once deployed, you can use the deployed web_url as the webhook endpoint for your slack, linear, or github webhooks. diff --git a/codegen-examples/examples/snapshot_event_handler/deploy.sh b/codegen-examples/examples/snapshot_event_handler/deploy.sh new file mode 100755 index 000000000..465eb6e0a --- /dev/null +++ b/codegen-examples/examples/snapshot_event_handler/deploy.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "No .env.template file found. Please create a .env file with your credentials." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying Snapshot Event Handler to Modal..." +python3 event_handlers.py + +echo "Deployment complete! You can check the status with 'modal app status snapshot-event-handler'" +echo "To view logs, run 'modal app logs snapshot-event-handler'" + diff --git a/codegen-examples/examples/swebench_agent_run/deploy.sh b/codegen-examples/examples/swebench_agent_run/deploy.sh index a1a681fb3..0529f6587 100755 --- a/codegen-examples/examples/swebench_agent_run/deploy.sh +++ b/codegen-examples/examples/swebench_agent_run/deploy.sh @@ -1,3 +1,44 @@ -#! /bin/bash +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying SWEBench Agent Run to Modal..." +python3 -m modal deploy swebench_agent_run/modal_harness/entry_point.py + +echo "Deployment complete! You can check the status with 'modal app status swebench-agent-run'" +echo "To view logs, run 'modal app logs swebench-agent-run'" -uv run modal deploy swebench_agent_run/modal_harness/entry_point.py diff --git a/codegen-examples/examples/ticket-to-pr/README.md b/codegen-examples/examples/ticket-to-pr/README.md index 80a5cc2f7..04f28964d 100644 --- a/codegen-examples/examples/ticket-to-pr/README.md +++ b/codegen-examples/examples/ticket-to-pr/README.md @@ -1,18 +1,18 @@ -# Linear Ticket to PR Example +# Linear Ticket-to-PR Example -This example demonstrates how to automatically create GitHub Pull Requests from Linear tickets using the Codegen SDK and Modal. When a Linear issue is labeled with "Codegen", this application will: +This example demonstrates how to create a Modal application that automatically creates GitHub pull requests from Linear tickets using the Codegen SDK. When a Linear ticket is moved to a specific state, this application will: -1. Process the Linear webhook event -2. Run a Codegen agent to analyze the issue -3. Create a GitHub Pull Request with changes addressing the issue -4. Comment on the Linear issue with a link to the PR +1. Create a new branch in the specified GitHub repository +2. Generate code changes based on the ticket description +3. Create a pull request with the changes +4. Link the pull request to the Linear ticket ## Prerequisites - [Modal](https://modal.com/) account -- [Linear](https://linear.app/) account with admin access +- [Linear](https://linear.app/) workspace with admin access - [GitHub](https://github.com/) repository access -- Python 3.13 or higher +- Python 3.10 or higher ## Setup @@ -32,19 +32,28 @@ pip install -e . Create a `.env` file with your credentials: ``` -LINEAR_ACCESS_TOKEN="your_linear_api_token" -LINEAR_SIGNING_SECRET="your_linear_webhook_signing_secret" -LINEAR_TEAM_ID="your_linear_team_id" -GITHUB_TOKEN="your_github_personal_access_token" -MODAL_API_KEY="your_modal_api_key" # Optional +# Linear credentials +LINEAR_ACCESS_TOKEN=your_linear_api_token +LINEAR_SIGNING_SECRET=your_linear_webhook_signing_secret +LINEAR_TEAM_ID=your_linear_team_id + +# GitHub credentials +GITHUB_TOKEN=your_github_token +GITHUB_REPO=your_github_repo_name +GITHUB_OWNER=your_github_username_or_org + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key ``` To get these credentials: -- **LINEAR_ACCESS_TOKEN**: Go to Linear → Settings → API → Create Key -- **LINEAR_SIGNING_SECRET**: Created when you set up a webhook in Linear -- **LINEAR_TEAM_ID**: Found in Linear team settings or via the API +- **LINEAR_ACCESS_TOKEN**: Create an API key in Linear (Settings → API → Create Key) +- **LINEAR_SIGNING_SECRET**: Create a webhook in Linear and copy the signing secret +- **LINEAR_TEAM_ID**: Your Linear team ID (can be found in team settings) - **GITHUB_TOKEN**: Create a personal access token with repo permissions +- **GITHUB_REPO**: The name of your GitHub repository +- **GITHUB_OWNER**: Your GitHub username or organization name - **MODAL_API_KEY**: Your Modal API key (if not using Modal CLI authentication) ### 3. Authenticate with Modal @@ -59,10 +68,10 @@ modal token new ```bash # Deploy the application to Modal -python app.py +./deploy.sh ``` -This will deploy the application to Modal and provide you with a URL that you can use to configure the webhook in Linear. +This will deploy the application to Modal and provide you with a URL that you can use to configure the Linear webhook. ### Get Deployment Status @@ -82,7 +91,7 @@ modal app logs linear-bot ```bash # Update your Modal deployment after making changes -python app.py +./deploy.sh ``` ### Stop Deployment @@ -94,49 +103,42 @@ modal app stop linear-bot ## Configuring Linear Webhooks -1. Go to Linear → Settings → API → Webhooks -2. Click "New Webhook" -3. Enter the URL provided by Modal when you deployed the application -4. Select the "Issue" event type -5. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` -6. Click "Create Webhook" - -## Creating a "Codegen" Label in Linear - -1. Go to Linear → Settings → Labels -2. Click "New Label" -3. Name the label "Codegen" -4. Choose a color for the label -5. Click "Create Label" +1. Go to your Linear workspace +2. Go to Settings → API → Webhooks +3. Click "New Webhook" +4. Enter the URL provided by Modal when you deployed the application +5. Select the "Issues" event +6. Copy the signing secret and add it to your `.env` file as `LINEAR_SIGNING_SECRET` +7. Click "Create Webhook" ## Usage -1. Create or update an issue in Linear -2. Add the "Codegen" label to the issue +1. Create a ticket in Linear with a description of the changes you want to make +2. Move the ticket to the state that triggers the webhook (configured in `app.py`) 3. The application will automatically: - - Process the webhook event - - Run a Codegen agent to analyze the issue - - Create a GitHub Pull Request with changes - - Comment on the Linear issue with a link to the PR + - Create a new branch in your GitHub repository + - Generate code changes based on the ticket description + - Create a pull request with the changes + - Link the pull request to the Linear ticket ## Customizing the Application -You can customize the application by modifying the following files: +You can customize the application by modifying the following in `app.py`: -- `app.py`: Main application logic -- `helpers.py`: Utility functions for processing Linear events -- `data.py`: Data models for Linear events and labels +- `TARGET_STATE_NAME`: The Linear state that triggers the webhook +- `handle_issue_update`: The function that processes the Linear webhook +- `create_pr_from_ticket`: The function that creates the GitHub pull request ## Troubleshooting - **Webhook not receiving events**: Verify that your Linear webhook is configured correctly and that the URL is accessible. -- **Authentication errors**: Check that your LINEAR_ACCESS_TOKEN and GITHUB_TOKEN are correct. +- **Authentication errors**: Check that your LINEAR_ACCESS_TOKEN, LINEAR_SIGNING_SECRET, and GITHUB_TOKEN are correct. - **Modal deployment issues**: Run `modal app logs linear-bot` to view logs and diagnose issues. ## Additional Resources - [Codegen Documentation](https://docs.codegen.sh/) - [Modal Documentation](https://modal.com/docs) -- [Linear API Documentation](https://developers.linear.app/docs) +- [Linear API Documentation](https://developers.linear.app/docs/) - [GitHub API Documentation](https://docs.github.com/en/rest) diff --git a/codegen-examples/examples/ticket-to-pr/deploy.sh b/codegen-examples/examples/ticket-to-pr/deploy.sh new file mode 100755 index 000000000..7407557eb --- /dev/null +++ b/codegen-examples/examples/ticket-to-pr/deploy.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "Neither .env nor .env.template file found. Please create a .env file with your credentials." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying Linear Ticket-to-PR to Modal..." +python3 app.py + +echo "Deployment complete! You can check the status with 'modal app status linear-bot'" +echo "To view logs, run 'modal app logs linear-bot'" + From 0a116e20ac0b5a8113f166be0a6be7e433dc2a66 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 13:22:58 +0000 Subject: [PATCH 6/7] Fix mypy errors in ticket-to-pr helpers.py --- .../examples/ticket-to-pr/helpers.py | 126 ++++++++---------- 1 file changed, 57 insertions(+), 69 deletions(-) diff --git a/codegen-examples/examples/ticket-to-pr/helpers.py b/codegen-examples/examples/ticket-to-pr/helpers.py index 3c01e98f6..fd1805904 100644 --- a/codegen-examples/examples/ticket-to-pr/helpers.py +++ b/codegen-examples/examples/ticket-to-pr/helpers.py @@ -1,85 +1,73 @@ -from codegen import Codebase, ProgrammingLanguage -from typing import List, Dict, Any -from codegen.configs.models.codebase import CodebaseConfig -from data import LinearLabels, LinearIssueUpdateEvent -import os -import logging - - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - +from codegen import Codebase +from codegen.extensions.clients.linear import LinearClient +from codegen.shared.enums.programming_language import ProgrammingLanguage +from codegen.extensions.linear.types import LinearEvent, LinearIssue, LinearComment, LinearUser, LinearLabel -def process_update_event(event_data: dict[str, Any]): - print("processing update event") - - action = event_data.get("action") - actor = event_data.get("actor") - created_at = event_data.get("createdAt") - issue_url = event_data.get("url") - data: Dict[str, Any] = event_data.get("data") - issue_id = data.get("id") - title = data.get("title") - description = data.get("description") - identifier = data.get("identifier") - - labels: List[LinearLabels] = data.get("labels") - updated_from: Dict[str, Any] = event_data.get("updatedFrom") - - update_event = LinearIssueUpdateEvent( +from typing import Any, Dict, List, Optional, cast +import os +from pydantic import BaseModel + + +class LinearIssueUpdateEvent(BaseModel): + issue_id: str + issue_url: str + title: str + description: Optional[str] = None + identifier: Optional[str] = None + + +def process_update_event(data: Any) -> LinearIssueUpdateEvent: + """Process a Linear webhook event and extract issue information.""" + # Extract issue data from the event + issue_data = cast(Dict[str, Any], data.get("data", {})) + + # Extract issue ID and URL + issue_id = issue_data.get("id", "") + issue_url = issue_data.get("url", "") + + # Extract labels + labels = cast(List[LinearLabel], issue_data.get("labels", [])) + team = cast(Dict[str, Any], issue_data.get("team", {})) + + # Extract issue title, description, and identifier + title = issue_data.get("title", "") + description = issue_data.get("description", "") + identifier = f"{team.get('key', '')}-{issue_data.get('number', '')}" + + # Create and return the event object + return LinearIssueUpdateEvent( issue_id=issue_id, - action=action, - actor=actor, - created_at=created_at, issue_url=issue_url, - data=data, - labels=labels, - updated_from=updated_from, title=title, description=description, identifier=identifier, ) - return update_event -def format_linear_message(title: str, description: str | None = "") -> str: - """Format a Linear update event into a message for the agent""" +def has_codegen_label(data: dict) -> bool: + """Check if the issue has the 'Codegen' label.""" + issue_data = data.get("data", {}) + labels = issue_data.get("labels", []) + + return any(label.get("name") == "Codegen" for label in labels) - return f""" - Here is a new issue titled '{title}' and with the description '{description}'. Continue to respond to this query. Use your tools to query the codebase for more context. - When applicable include references to files and line numbers, code snippets are also encouraged. Don't forget to create a pull request with your changes, use the appropriate tool to do so. - """ +def format_linear_message(title: str, description: Optional[str]) -> str: + """Format a Linear issue title and description into a message for the agent.""" + message = f"Create a PR that implements: {title}" + + if description: + message += f"\n\nDetails:\n{description}" + + return message -def has_codegen_label(*args, **kwargs): - body = kwargs.get("data") - type = body.get("type") - action = body.get("action") - if type == "Issue" and action == "update": - # handle issue update (label updates) - update_event = process_update_event(body) - - has_codegen_label = any(label.name == "Codegen" for label in update_event.labels) - codegen_label_id = next((label.id for label in update_event.labels if label.name == "Codegen"), None) - had_codegen_label = codegen_label_id in update_event.updated_from.get("labels", []) if codegen_label_id else False - previous_labels = update_event.updated_from.get("labelIds", None) - - if previous_labels is None or not has_codegen_label: - logger.info("No labels updated, skipping codegen bot response") - return False - - if has_codegen_label and not had_codegen_label: - logger.info("Codegen label added, codegen bot will respond") - return True - - logger.info("Codegen label removed or already existed, codegen bot will not respond") - return False - - -def create_codebase(repo_name: str, language: ProgrammingLanguage): - config = CodebaseConfig() +def create_codebase(repo_name: str, language: ProgrammingLanguage) -> Codebase: + """Create a Codebase instance for the specified repository.""" + from codegen.config import Config + + config = Config() config.secrets.github_token = os.environ["GITHUB_TOKEN"] - + return Codebase.from_repo(repo_name, language=language, tmp_dir="/root", config=config) From 77fd74c2fcfe9efa98114c0e1b7648de8e244ea4 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 13:31:38 +0000 Subject: [PATCH 7/7] Add deploy.sh scripts for all remaining examples --- .../examples/codegen-mcp-server/deploy.sh | 54 +++++++++++++++++ .../examples/codegen_app/deploy.sh | 48 +++++++++++++++ .../examples/cyclomatic_complexity/deploy.sh | 48 +++++++++++++++ .../examples/deep_code_research/deploy.sh | 57 ++++++++++++++++++ .../examples/delete_dead_code/deploy.sh | 48 +++++++++++++++ .../examples/document_functions/deploy.sh | 51 ++++++++++++++++ .../examples/pr_review_bot/deploy.sh | 60 +++++++++++++++++++ .../examples/repo_analytics/deploy.sh | 48 +++++++++++++++ .../examples/slack_chatbot/deploy.sh | 57 ++++++++++++++++++ 9 files changed, 471 insertions(+) create mode 100755 codegen-examples/examples/codegen-mcp-server/deploy.sh create mode 100755 codegen-examples/examples/codegen_app/deploy.sh create mode 100755 codegen-examples/examples/cyclomatic_complexity/deploy.sh create mode 100755 codegen-examples/examples/deep_code_research/deploy.sh create mode 100755 codegen-examples/examples/delete_dead_code/deploy.sh create mode 100755 codegen-examples/examples/document_functions/deploy.sh create mode 100755 codegen-examples/examples/pr_review_bot/deploy.sh create mode 100755 codegen-examples/examples/repo_analytics/deploy.sh create mode 100755 codegen-examples/examples/slack_chatbot/deploy.sh diff --git a/codegen-examples/examples/codegen-mcp-server/deploy.sh b/codegen-examples/examples/codegen-mcp-server/deploy.sh new file mode 100755 index 000000000..b208612a6 --- /dev/null +++ b/codegen-examples/examples/codegen-mcp-server/deploy.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials (for repository access) +GITHUB_TOKEN=your_github_token + +# OpenAI credentials (if using OpenAI) +OPENAI_API_KEY=your_openai_api_key + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Check if LLM dependencies are installed +echo "Note: This server requires LLM dependencies. See llms-install.md for details." + +# Deploy the application +echo "Deploying Codegen MCP Server to Modal..." +python3 server.py + +echo "Deployment complete! You can check the status with 'modal app status codegen-mcp-server'" +echo "To view logs, run 'modal app logs codegen-mcp-server'" + diff --git a/codegen-examples/examples/codegen_app/deploy.sh b/codegen-examples/examples/codegen_app/deploy.sh new file mode 100755 index 000000000..f33f49946 --- /dev/null +++ b/codegen-examples/examples/codegen_app/deploy.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Codegen App to Modal..." +python3 app.py + +echo "Deployment complete! You can check the status with 'modal app status codegen-app'" +echo "To view logs, run 'modal app logs codegen-app'" + diff --git a/codegen-examples/examples/cyclomatic_complexity/deploy.sh b/codegen-examples/examples/cyclomatic_complexity/deploy.sh new file mode 100755 index 000000000..3bc21c38b --- /dev/null +++ b/codegen-examples/examples/cyclomatic_complexity/deploy.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Cyclomatic Complexity Analyzer to Modal..." +python3 run.py + +echo "Deployment complete! You can check the status with 'modal app status cyclomatic-complexity'" +echo "To view logs, run 'modal app logs cyclomatic-complexity'" + diff --git a/codegen-examples/examples/deep_code_research/deploy.sh b/codegen-examples/examples/deep_code_research/deploy.sh new file mode 100755 index 000000000..3bc0bfbf1 --- /dev/null +++ b/codegen-examples/examples/deep_code_research/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Install requirements +if [ -f requirements.txt ]; then + echo "Installing requirements..." + pip install -r requirements.txt +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# OpenAI credentials +OPENAI_API_KEY=your_openai_api_key + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Deep Code Research to Modal..." +python3 run.py + +echo "Deployment complete! You can check the status with 'modal app status deep-code-research'" +echo "To view logs, run 'modal app logs deep-code-research'" + diff --git a/codegen-examples/examples/delete_dead_code/deploy.sh b/codegen-examples/examples/delete_dead_code/deploy.sh new file mode 100755 index 000000000..b92fcd2a3 --- /dev/null +++ b/codegen-examples/examples/delete_dead_code/deploy.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Dead Code Deletion Tool to Modal..." +python3 run.py + +echo "Deployment complete! You can check the status with 'modal app status delete-dead-code'" +echo "To view logs, run 'modal app logs delete-dead-code'" + diff --git a/codegen-examples/examples/document_functions/deploy.sh b/codegen-examples/examples/document_functions/deploy.sh new file mode 100755 index 000000000..e9fefe689 --- /dev/null +++ b/codegen-examples/examples/document_functions/deploy.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# OpenAI credentials +OPENAI_API_KEY=your_openai_api_key + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Function Documentation Tool to Modal..." +python3 run.py + +echo "Deployment complete! You can check the status with 'modal app status document-functions'" +echo "To view logs, run 'modal app logs document-functions'" + diff --git a/codegen-examples/examples/pr_review_bot/deploy.sh b/codegen-examples/examples/pr_review_bot/deploy.sh new file mode 100755 index 000000000..135fd2099 --- /dev/null +++ b/codegen-examples/examples/pr_review_bot/deploy.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "No .env.template file found. Creating a basic .env template..." + cat > .env.template << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token +GITHUB_WEBHOOK_SECRET=your_github_webhook_secret + +# OpenAI credentials (if using OpenAI) +OPENAI_API_KEY=your_openai_api_key + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying PR Review Bot to Modal..." +python3 app.py + +echo "Deployment complete! You can check the status with 'modal app status pr-review-bot'" +echo "To view logs, run 'modal app logs pr-review-bot'" + diff --git a/codegen-examples/examples/repo_analytics/deploy.sh b/codegen-examples/examples/repo_analytics/deploy.sh new file mode 100755 index 000000000..77ad005f0 --- /dev/null +++ b/codegen-examples/examples/repo_analytics/deploy.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Create .env file if it doesn't exist +if [ ! -f .env ]; then + echo "Creating .env file..." + cat > .env << EOL +# GitHub credentials +GITHUB_TOKEN=your_github_token + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + echo "Please edit the .env file with your credentials before deploying." + exit 1 +fi + +# Deploy the application +echo "Deploying Repository Analytics to Modal..." +python3 run.py + +echo "Deployment complete! You can check the status with 'modal app status repo-analytics'" +echo "To view logs, run 'modal app logs repo-analytics'" + diff --git a/codegen-examples/examples/slack_chatbot/deploy.sh b/codegen-examples/examples/slack_chatbot/deploy.sh new file mode 100755 index 000000000..c6567ec7d --- /dev/null +++ b/codegen-examples/examples/slack_chatbot/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Exit on error +set -e + +# Get the directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "Python 3 is required but not installed. Please install Python 3 and try again." + exit 1 +fi + +# Check if Modal is installed +if ! python3 -c "import modal" &> /dev/null; then + echo "Modal is not installed. Installing now..." + pip install modal +fi + +# Check if Modal token is set up +if ! modal token list &> /dev/null; then + echo "Modal token not set up. Please run 'modal token new' to set up your Modal token." + exit 1 +fi + +# Check if .env file exists +if [ ! -f .env ]; then + if [ -f .env.template ]; then + echo ".env file not found. Creating from template..." + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + else + echo "No .env.template file found. Creating a basic .env template..." + cat > .env.template << EOL +# Slack credentials +SLACK_BOT_TOKEN=your_slack_bot_token +SLACK_SIGNING_SECRET=your_slack_signing_secret + +# Modal configuration (optional) +MODAL_API_KEY=your_modal_api_key +EOL + cp .env.template .env + echo "Please edit the .env file with your credentials before deploying." + exit 1 + fi +fi + +# Deploy the application +echo "Deploying Slack Chatbot to Modal..." +python3 api.py + +echo "Deployment complete! You can check the status with 'modal app status slack-chatbot'" +echo "To view logs, run 'modal app logs slack-chatbot'" +