Skip to content

Commit e61cf05

Browse files
decyjphrCopilot
andauthored
add proxy support for aws lambda (#807)
* add proxy support for aws lambda * Update lib/proxiedFetch.js Co-authored-by: Copilot <[email protected]> * change to commonJS format * fix the correct path for lib * correct args to createProbot * fix import * add plugins * Update deploy.md * Update docs/deploy.md Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent 5ed6d92 commit e61cf05

File tree

6 files changed

+122
-18
lines changed

6 files changed

+122
-18
lines changed

docs/deploy.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,48 @@ Optional values in the .env file can be found under the [Environment variables](
5454

5555
Once you have the `.env` file configured, you are ready to start the building of the container.
5656

57-
### Docker
58-
#### Build the Docker container
57+
## Docker
58+
### Build the Docker container
5959
Once you have configured the **GitHub App** and updated the source code, you should be ready to build the container.
6060
- Change directory to inside the code base
6161
- `cd safe-settings/`
6262
- Build the container
6363
- `docker build -t safe-settings .`
6464
- This process should complete successfully and you will then have a **Docker** container ready for deployment
6565

66-
#### Run the Docker container
66+
### Run the Docker container
6767
Once the container has been successfully built, you can deploy it and start utilizing the **GitHub App**.
6868

69-
#### Start the container with docker-compose
69+
### Start the container with docker-compose
7070
If you have docker-compose installed, you can simply start and stop the **Docker** container with:
7171
- `cd safe-settings/; docker-compose --env-file .env up -d`
7272
This will start the container in the background and detached.
7373

74-
#### Start Docker container Detached in background
74+
### Start Docker container Detached in background
7575
- Start the container detached with port assigned (*Assuming port 3000 for the webhook*)
7676
- `docker run -d -p 3000:3000 safe-settings`
7777
- You should now have the container running in the background and can validate it running with the command:
7878
- `docker ps`
7979
- This should show the `safe-settings` alive and running
8080

81-
#### Start Docker container attached in forground (Debug)
81+
### Start Docker container attached in foreground (Debug)
8282
- If you need to run the container in interactive mode to validate connectivity and functionality:
8383
- `docker run -it -p 3000:3000 safe-settings`
8484
- You will now have the log of the container showing to your terminal, and can validate connectivity and functionality.
8585

86-
#### Connect to running Docker container (Debug)
86+
### Connect to running Docker container (Debug)
8787
- If you need to connect to the container thats already running, you can run the following command:
8888
- `docker exec -it safe-settings /bin/sh`
8989
- You will now be inside the running **Docker** container and can perform any troubleshooting needed
9090

91-
### Deploy the app to AWS Lambda
91+
## Deploy the app to AWS Lambda
9292
[Serverless Framework Deployment of safe-settings on AWS](AWS-README.md)
93+
94+
### Proxy Support
95+
The AWS Lambda handler, `handler.js` uses a custom `Octokit` factory that creates Octokit with ___Proxied fetch___ instead of the regular ___fetch___ when the `http_proxy`/`https_proxy` env variables are set.
96+
97+
In the future we can use the same pattern to support proxy in all deployments of the app.
98+
9399
## Deploy the app in Kubernetes
94100

95101
### __Deploying using kubectl__

handler.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ const {
22
createLambdaFunction,
33
createProbot
44
} = require('@probot/adapter-aws-lambda-serverless')
5+
const { getProbotOctoKit } = require('./lib/proxyAwareProbotOctokit')
56

67
const appFn = require('./')
78

89
module.exports.webhooks = createLambdaFunction(appFn, {
9-
probot: createProbot()
10+
probot: createProbot({ overrides: { Octokit: getProbotOctoKit() } })
1011
})
1112

1213
module.exports.scheduler = function () {
13-
const probot = createProbot()
14+
const probot = createProbot({ overrides: { Octokit: getProbotOctoKit() } })
1415
const app = appFn(probot, {})
1516
return app.syncInstallation()
1617
}

lib/proxiedFetch.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const { getProxyForUrl } = require('proxy-from-env')
2+
const { ProxyAgent, fetch: undiciFetch } = require('undici')
3+
4+
function getProxiedFetch (url) {
5+
const proxyUrl = getProxyForUrl(url)
6+
if (proxyUrl) {
7+
// LOG.debug('Setting up proxy agent for ', url)
8+
return (url, options) => {
9+
return undiciFetch(url, {
10+
...options,
11+
dispatcher: new ProxyAgent(proxyUrl)
12+
})
13+
}
14+
}
15+
return null
16+
}
17+
18+
module.exports = getProxiedFetch

lib/proxyAwareProbotOctokit.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// This custom plugin overrides the default ProbotOctokit plugin and support Http Proxy.
2+
const { Octokit } = require('@octokit/core')
3+
const { enterpriseCompatibility } = require('@octokit/plugin-enterprise-compatibility')
4+
// const { RequestOptions } = require('@octokit/types')
5+
const { paginateRest } = require('@octokit/plugin-paginate-rest')
6+
const { legacyRestEndpointMethods } = require('@octokit/plugin-rest-endpoint-methods')
7+
const { retry } = require('@octokit/plugin-retry')
8+
const { throttling } = require('@octokit/plugin-throttling')
9+
const { config } = require('@probot/octokit-plugin-config')
10+
const { createProbotAuth } = require('octokit-auth-probot')
11+
const getProxiedFetch = require('./proxiedFetch')
12+
13+
const ProbotOctokit = Octokit.plugin(
14+
throttling,
15+
retry,
16+
paginateRest,
17+
legacyRestEndpointMethods,
18+
enterpriseCompatibility,
19+
config
20+
).defaults((instanceOptions) => {
21+
const defaultOptions = {
22+
authStrategy: createProbotAuth,
23+
throttle: {
24+
onSecondaryRateLimit: (
25+
retryAfter,
26+
options,
27+
octokit
28+
) => {
29+
octokit.log.warn(
30+
`SecondaryRateLimit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`
31+
)
32+
return true
33+
},
34+
onRateLimit: (
35+
retryAfter,
36+
options,
37+
octokit
38+
) => {
39+
octokit.log.warn(
40+
`Rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`
41+
)
42+
return true
43+
}
44+
},
45+
userAgent: 'probot',
46+
request: {
47+
fetch: getProxiedFetch(instanceOptions.baseUrl) || fetch
48+
}
49+
}
50+
// merge options deeply
51+
const options = Object.assign({}, defaultOptions, instanceOptions, {
52+
request: Object.assign({}, defaultOptions.request, instanceOptions.request),
53+
throttle: instanceOptions.throttle
54+
? Object.assign({}, defaultOptions.throttle, instanceOptions.throttle)
55+
: defaultOptions.throttle
56+
})
57+
return options
58+
})
59+
60+
function getProbotOctoKit () {
61+
return ProbotOctokit
62+
}
63+
module.exports = { getProbotOctoKit }

package-lock.json

Lines changed: 21 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"lodash": "^4.17.21",
3434
"node-cron": "^3.0.2",
3535
"octokit": "^4.1.2",
36-
"probot": "^13.4.4"
36+
"probot": "^13.4.4",
37+
"proxy-from-env": "^1.1.0",
38+
"undici": "^7.7.0"
3739
},
3840
"devDependencies": {
3941
"@eslint/eslintrc": "^3.1.0",

0 commit comments

Comments
 (0)