Skip to content

Commit 55ade81

Browse files
authored
Launch a Render Deploy (#3)
* Update * Use the installation script
1 parent 3c21033 commit 55ade81

File tree

4 files changed

+64
-33
lines changed

4 files changed

+64
-33
lines changed

.github/workflows/example.yaml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ name: example
44
on:
55
# Allows you to trigger this workflow via the GitHub API
66
workflow_dispatch:
7-
8-
env:
9-
GIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
7+
inputs:
8+
serviceID:
9+
type: string
10+
description: 'Render Service ID to deploy (e.g. srv-xxx)'
1011

1112
jobs:
12-
print-trigger-info:
13+
deploy-service:
1314
runs-on: ubuntu-latest
1415
steps:
15-
- name: checkout
16-
uses: actions/checkout@v4
17-
with:
18-
ref: ${{ env.GIT_SHA }}
19-
- name: Print Info
20-
run: |
21-
echo "hello"
16+
- name: Install Render CLI
17+
run: |
18+
curl -fsSL https://raw.githubusercontent.com/render-oss/cli/refs/heads/main/bin/install.sh | sh
19+
- name: Create Deploy
20+
env:
21+
RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }}
22+
CI: true
23+
run: |
24+
render deploys create ${{ inputs.serviceID }} --output json --confirm

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
# Example to Trigger GitHub Actions from a Render Webhook
22

3-
This example triggers a GitHub Action workflow when a deploy ended webhook is received for a specific service.
3+
This example triggers a GitHub Action workflow that creates a deploy when a deploy ended webhook is received for a specific service.
44

55
## Deploy to Render
66

77
1. Use the button below to deploy to Render </br>
88
<a href="https://render.com/deploy?repo=https://github.com/render-examples/webhook-github-action/tree/main"><img src="https://render.com/images/deploy-to-render-button.svg" alt="Deploy to Render"></a>
99

10-
2. Follow [instructions](https://render.com/docs/webhooks) to create a webhook with the URL from your service and `/webhook` path
11-
3. Follow [instructions](https://render.com/docs/api#1-create-an-api-key) to create a Render API Key
12-
4. Follow [instructions](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) to create a GitHub api token with read/write permissions for `Actions`
13-
5. Create a github workflow with a dispatch trigger as shown in the [example](./.github/workflows/example.yaml)
14-
6. Set the following env vars
15-
- `RENDER_WEBHOOK_SECRET` environment variable to the secret from the webhook created in step 2
16-
- `RENDER_API_KEY` to the key created in step 3
17-
- `GITHUB_API_TOKEN` to the token created in step 4
10+
2. Set the following environment variables:
1811
- `GITHUB_OWNER_NAME` to the owner of the GitHub repo the workflow is in (ex. `render-examples`)
1912
- `GITHUB_REPO_NAME` to the GitHub repo the workflow is in (ex. `webhook-github-action`)
2013
- `GITHUB_WORKFLOW_ID` to the ID or filename of the workflow to trigger (ex. `example.yaml`)
21-
7. Trigger a service deploy and watch the GitHub workflow get triggered.
14+
15+
3. Follow the [Render documentation](https://render.com/docs/webhooks) to create a webhook with the URL from your service and `/webhook` path that is triggered upon only the `DeployEnded` event. Save the signing secret as the `RENDER_WEBHOOK_SECRET` environment variable.
16+
4. Follow the [Render documentation](https://render.com/docs/api#1-create-an-api-key) to create a Render API Key. Save the key as the `RENDER_API_KEY` environment variable.
17+
5. Follow [the GitHub documentation](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) to create a GitHub Action secret named `RENDER_API_KEY` in your GitHub repo with the Render API key you created.
18+
6. Follow [the GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) to create a GitHub API token with read/write permissions for `Actions`. Save the token as the `GITHUB_API_TOKEN` environment variable.
19+
7. Create a GitHub workflow with a dispatch trigger as shown in the [example](./.github/workflows/example.yaml)
20+
8. Trigger a service deploy and watch the GitHub workflow get triggered.

app.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,30 @@ const app = express();
77
const port = process.env.PORT || 3001;
88
const renderWebhookSecret = process.env.RENDER_WEBHOOK_SECRET || '';
99

10+
if (!renderWebhookSecret ) {
11+
console.error("Error: RENDER_WEBHOOK_SECRET is not set.");
12+
process.exit(1);
13+
}
14+
1015
const renderAPIURL = process.env.RENDER_API_URL || "https://api.render.com/v1"
1116

1217
// To create a Render API token, follow instructions here: https://render.com/docs/api#1-create-an-api-key
13-
const renderAPIToken = process.env.RENDER_API_TOKEN || '';
18+
const renderAPIToken = process.env.RENDER_API_KEY || '';
19+
20+
if (!renderAPIToken) {
21+
console.error("Error: RENDER_API_KEY is not set.");
22+
process.exit(1);
23+
}
1424

1525
const githubAPIToken = process.env.GITHUB_API_TOKEN || '';
1626
const githubOwnerName = process.env.GITHUB_OWNER_NAME || '';
1727
const githubRepoName = process.env.GITHUB_REPO_NAME || '';
28+
29+
if (!githubAPIToken || !githubOwnerName || !githubRepoName) {
30+
console.error("Error: GITHUB_API_TOKEN, GITHUB_OWNER_NAME, or GITHUB_REPO_NAME is not set.");
31+
process.exit(1);
32+
}
33+
1834
const githubWorkflowID = process.env.GITHUB_WORKFLOW_ID || 'example.yaml';
1935

2036
const octokit = new Octokit({
@@ -45,6 +61,10 @@ app.use((err: any, req: Request, res: Response, next: NextFunction) => {
4561
}
4662
});
4763

64+
app.get('/', (req: Request, res: Response) => {
65+
res.send('Render Webhook GitHub Action is listening!')
66+
})
67+
4868
const server = app.listen(port, () => console.log(`Example app listening on port ${port}!`));
4969

5070
function validateWebhook(req: Request) {
@@ -62,6 +82,7 @@ async function handleWebhook(payload: WebhookPayload) {
6282
try {
6383
switch (payload.type) {
6484
case "deploy_ended":
85+
console.log("handling deploy_ended event")
6586
const event = await fetchEventInfo(payload)
6687

6788
// TODO add human readable status
@@ -84,7 +105,7 @@ async function handleWebhook(payload: WebhookPayload) {
84105
}
85106

86107
console.log(`triggering github workflow for ${githubOwnerName}/${githubRepoName} for ${service.name}`)
87-
await triggerWorkflow(service.name, service.branch)
108+
await triggerWorkflow(service.id, service.branch)
88109
return
89110
default:
90111
console.log(`unhandled webhook type ${payload.type} for service ${payload.data.serviceId}`)
@@ -94,14 +115,14 @@ async function handleWebhook(payload: WebhookPayload) {
94115
}
95116
}
96117

97-
async function triggerWorkflow(serviceName: string, branch: string) {
118+
async function triggerWorkflow(serviceID: string, branch: string) {
98119
await octokit.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', {
99120
owner: githubOwnerName,
100121
repo: githubRepoName,
101122
workflow_id: githubWorkflowID,
102123
ref: branch,
103124
inputs: {
104-
// service: serviceName
125+
serviceID: serviceID
105126
},
106127
headers: {
107128
'X-GitHub-Api-Version': '2022-11-28'
@@ -113,21 +134,23 @@ async function triggerWorkflow(serviceName: string, branch: string) {
113134
// some events have additional information that isn't in the webhook payload
114135
// for example, deploy events have the deploy id
115136
async function fetchEventInfo(payload: WebhookPayload): Promise<RenderEvent> {
137+
const url = `${renderAPIURL}/events/${payload.data.id}`
138+
console.log(`fetching event info at ${url}`)
116139
const res = await fetch(
117-
`${renderAPIURL}/events/${payload.data.id}`,
140+
url,
118141
{
119-
method: "get",
142+
method: "GET",
120143
headers: {
121-
"Content-Type": "application/json",
122-
Accept: "application/json",
123-
Authorization: `Bearer ${renderAPIToken}`,
144+
accept: "application/json",
145+
authorization: `Bearer ${renderAPIToken}`,
124146
},
125147
},
126148
)
149+
127150
if (res.ok) {
128151
return res.json()
129152
} else {
130-
throw new Error(`unable to fetch event info; received code :${res.status.toString()}`)
153+
throw new Error(`unable to fetch event info; received code ${res.status.toString()}`)
131154
}
132155
}
133156

render.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ services:
22
- type: web
33
name: webhook-github-action
44
runtime: node
5-
repo: https://github.com/render-examples/webhook-github-action
6-
branch: create-webhook-github-action
75
plan: starter
86
envVars:
7+
- key: GITHUB_OWNER_NAME
8+
sync: false
9+
- key: GITHUB_REPO_NAME
10+
sync: false
11+
- key: GITHUB_WORKFLOW_ID
12+
sync: false
913
- key: RENDER_WEBHOOK_SECRET
1014
sync: false
1115
- key: RENDER_API_KEY
1216
sync: false
17+
- key: GITHUB_API_TOKEN
18+
sync: false
1319
region: oregon
1420
buildCommand: pnpm install && pnpm run build
1521
startCommand: pnpm run start

0 commit comments

Comments
 (0)