Skip to content

Commit 8bc318a

Browse files
feat: add GitHub App configuration (env vars, coder template, triggers) (#91)
* feat: add GitHub App configuration (env vars, coder template, triggers) Add the three GitHub App environment variables (GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET) to: - .env.example with documentation on required App permissions and events - coder-template/main.tf as workspace parameters wired to both the agent env block and container env block Add github_app triggers to opentower.config.json: - github-app-event: issues, pull_request, check_suite:completed, workflow_run:completed, push (mirrors github-event) - github-app-comment: PR review comments, issue comments, PR reviews with $BOT_LOGIN self-loop guard (mirrors github-comment) Both trigger sets use source: "github_app" so they route through the GithubAppHandler which uses installation tokens for entity enrichment API calls. * chore(coder-template): increase memory limit to 8Gi and disk to 50Gi - Memory: requests 1Gi -> 2Gi, limits 4Gi -> 8Gi - PVC storage: 10Gi -> 50Gi
1 parent 1f7a2bc commit 8bc318a

3 files changed

Lines changed: 91 additions & 5 deletions

File tree

.env.example

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ GITHUB_WEBHOOK_SECRET=
8181
# If GH_TOKEN is unset or invalid, $BOT_LOGIN won't be substituted
8282
# (the self-loop guard is degraded). Set GH_TOKEN for autonomous flows.
8383

84+
# === Optional: GitHub App authentication ===
85+
# Alternative to org-level webhooks + PAT. A GitHub App uses JWT-based
86+
# auth with per-installation tokens. Create an app at
87+
# https://github.com/settings/apps with these permissions:
88+
# Contents (read & write), Issues (read & write),
89+
# Pull requests (read & write), Checks (read), Actions (read & write)
90+
# Subscribe to events: check_suite, issue_comment, issues, pull_request,
91+
# pull_request_review, pull_request_review_comment, push, workflow_run
92+
#
93+
# All three variables are required to enable the GitHub App handler.
94+
# The private key is the PEM file generated when creating the app;
95+
# literal \n in the value is auto-converted to real newlines.
96+
# GITHUB_APP_ID=
97+
# GITHUB_APP_PRIVATE_KEY=
98+
# GITHUB_APP_WEBHOOK_SECRET=
99+
84100
# Override the bundled opentower.config.json with one of your own. Default
85101
# resolves to ~/.config/opencode/opentower.config.json (the baked-in file).
86102
# Point this at a path on the persistent ~/dev volume to customize

coder-template/main.tf

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,36 @@ data "coder_parameter" "github_webhook_secret" {
8181
order = 2
8282
}
8383

84+
data "coder_parameter" "github_app_id" {
85+
name = "github_app_id"
86+
display_name = "GitHub App ID"
87+
description = "App ID from the GitHub App settings page. Required for GitHub App webhook handler."
88+
type = "string"
89+
mutable = true
90+
default = ""
91+
order = 4
92+
}
93+
94+
data "coder_parameter" "github_app_private_key" {
95+
name = "github_app_private_key"
96+
display_name = "GitHub App Private Key"
97+
description = "PEM private key generated when creating the GitHub App. Literal \\n is auto-converted to newlines."
98+
type = "string"
99+
mutable = true
100+
default = ""
101+
order = 5
102+
}
103+
104+
data "coder_parameter" "github_app_webhook_secret" {
105+
name = "github_app_webhook_secret"
106+
display_name = "GitHub App Webhook Secret"
107+
description = "Webhook secret configured in the GitHub App settings. Used for HMAC signature verification."
108+
type = "string"
109+
mutable = true
110+
default = ""
111+
order = 6
112+
}
113+
84114
data "coder_parameter" "webhook_port" {
85115
name = "webhook_port"
86116
display_name = "Webhook Port"
@@ -183,7 +213,7 @@ resource "kubernetes_persistent_volume_claim_v1" "dev" {
183213
access_modes = ["ReadWriteOnce"]
184214
resources {
185215
requests = {
186-
storage = "10Gi"
216+
storage = "50Gi"
187217
}
188218
}
189219
}
@@ -206,8 +236,11 @@ resource "coder_agent" "main" {
206236
GEMINI_API_KEY = data.coder_parameter.gemini_api_key.value
207237
GROQ_API_KEY = data.coder_parameter.groq_api_key.value
208238
OPENROUTER_API_KEY = data.coder_parameter.openrouter_api_key.value
209-
GITHUB_WEBHOOK_SECRET = data.coder_parameter.github_webhook_secret.value
210-
EMAIL_WEBHOOK_SECRET = data.coder_parameter.email_webhook_secret.value
239+
GITHUB_WEBHOOK_SECRET = data.coder_parameter.github_webhook_secret.value
240+
GITHUB_APP_ID = data.coder_parameter.github_app_id.value
241+
GITHUB_APP_PRIVATE_KEY = data.coder_parameter.github_app_private_key.value
242+
GITHUB_APP_WEBHOOK_SECRET = data.coder_parameter.github_app_webhook_secret.value
243+
EMAIL_WEBHOOK_SECRET = data.coder_parameter.email_webhook_secret.value
211244
WEBHOOK_PORT = tostring(data.coder_parameter.webhook_port.value)
212245
OPENTOWER_API_TOKEN = data.coder_parameter.opentower_api_token.value
213246
SENTRY_DSN = data.coder_parameter.sentry_dsn.value
@@ -441,6 +474,18 @@ resource "kubernetes_deployment_v1" "workspace" {
441474
name = "GITHUB_WEBHOOK_SECRET"
442475
value = data.coder_parameter.github_webhook_secret.value
443476
}
477+
env {
478+
name = "GITHUB_APP_ID"
479+
value = data.coder_parameter.github_app_id.value
480+
}
481+
env {
482+
name = "GITHUB_APP_PRIVATE_KEY"
483+
value = data.coder_parameter.github_app_private_key.value
484+
}
485+
env {
486+
name = "GITHUB_APP_WEBHOOK_SECRET"
487+
value = data.coder_parameter.github_app_webhook_secret.value
488+
}
444489
env {
445490
name = "EMAIL_WEBHOOK_SECRET"
446491
value = data.coder_parameter.email_webhook_secret.value
@@ -469,11 +514,11 @@ resource "kubernetes_deployment_v1" "workspace" {
469514
resources {
470515
requests = {
471516
"cpu" = "500m"
472-
"memory" = "1Gi"
517+
"memory" = "2Gi"
473518
}
474519
limits = {
475520
"cpu" = "4"
476-
"memory" = "4Gi"
521+
"memory" = "8Gi"
477522
}
478523
}
479524

opentower.config.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,31 @@
3131
"event": ["email.*"],
3232
"agent": "jared",
3333
"prompt_template": "An email was received. Read it and decide what to do. It could be a GitHub notification, a Sentry alert, a forwarded issue, or anything else. Use the email content to determine the appropriate action.\n\nDelivery: {{ delivery_id }}\n\nFrom: {{ payload.from }}\nTo: {{ payload.to }}\nSubject: {{ payload.subject }}\nMessage-ID: {{ payload.message_id }}\nIn-Reply-To: {{ payload.in_reply_to }}\nReferences: {{ payload.references }}\nList-ID: {{ payload.list_id }}\nX-GitHub-Reason: {{ payload.x_github_reason }}\nX-GitHub-Sender: {{ payload.x_github_sender }}\n\nBody:\n{{ payload.body_text }}"
34+
},
35+
{
36+
"name": "github-app-event",
37+
"source": "github_app",
38+
"event": [
39+
"issues",
40+
"pull_request",
41+
"check_suite:completed",
42+
"workflow_run:completed",
43+
"push"
44+
],
45+
"agent": "jared",
46+
"prompt_template": "A GitHub webhook just arrived. Read the payload and decide what to do.\n\nEvent: {{ event }}\nAction: {{ action }}\nDelivery: {{ delivery_id }}\n\nPayload:\n{{ payload }}"
47+
},
48+
{
49+
"name": "github-app-comment",
50+
"source": "github_app",
51+
"event": [
52+
"pull_request_review_comment",
53+
"issue_comment",
54+
"pull_request_review"
55+
],
56+
"agent": "jared",
57+
"ignore_authors": ["$BOT_LOGIN"],
58+
"prompt_template": "A GitHub webhook just arrived. Read the payload and decide what to do.\n\nEvent: {{ event }}\nAction: {{ action }}\nDelivery: {{ delivery_id }}\n\nPayload:\n{{ payload }}"
3459
}
3560
]
3661
}

0 commit comments

Comments
 (0)