Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ LOGIN_USER=username
LOGIN_PASSWORD=strongpassword
DEFAULT_GITHUB_ORG=Git-Commit-Show
ONE_CLA_PER_ORG=true
API_POST_GITHUB_COMMENT=http://localhost:3000/api/comment #Put your webhook proxy for PR/issue comment here
DOCS_AGENT_API_URL=docs_agent_api_base_url
DOCS_AGENT_API_KEY=docs_agent_api_key_here
DOCS_AGENT_API_REVIEW_URL=#full url to review endpoint of docs agent e.g. http://localhost:3001/review, overrides `DOCS_AGENT_API_URL` base url config
DOCS_AGENT_API_PRIORITIZE_URL=#full url
DOCS_AGENT_API_EDIT_URL=
DOCS_AGENT_API_LINK_URL=
DOCS_AGENT_API_AUDIT_URL=
DOCS_REPOS= #repos separated by comma
SLACK_DEFAULT_MESSAGE_CHANNEL_WEBHOOK_URL=https://hooks.slack.com/services/T05487DUMMY/B59DUMMY1U/htdsEdsdf7CNeDUMMY
GITHUB_BOT_USERS=dependabot[bot],devops-github-rudderstack
GITHUB_ORG_MEMBERS=
Expand Down
52 changes: 42 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,23 @@ A Node.js server for GitHub app to assist external contributors and save maintai
- [x] When an external contributor (not the internal team) raises a PR, post a comment to sign CLA and label PR `Pending CLA`
- [x] On signing CLA, remove `Pending CLA` label from all the PRs of that user. Never ask that user to sign the CLA on any of our repo in future
- [x] On `rudder-transformer` PR merge, post a comment to raise PR in `integrations-config`
- [ ] On `integrations-config` PR merge, psot a comment to join Slack's product-releases channel to get notified when that integration goes live
- [ ] On `integrations-config` PR merge, post a comment to join Slack's product-releases channel to get notified when that integration goes live
- [ ] On `integrations-config` PR merge, post a comment to raise PR in `rudder-docs`
- [x] List of open PRs by external contributors
- [x] Notify on Slack when `product review` label is added to a PR
- [ ] Analyze merged PRs and suggest next actions
- [x] Analyze docs pages using AI on PR labelled with `docs review`

## Features

### Next Actions Feature

The Next Actions feature automatically analyzes merged pull requests from external contributors and suggests next actions based on the code changes. Here's how it works:

1. **Triggers**: Listens to `pull_request.closed` events and checks if the PR was merged
2. **Analysis**: Extracts production code changes (excludes test files)
3. **External API**: Sends changes to services such as DocsAgent
4. **Comments**: Posts the API response as a comment on the PR

## Requirements

Expand All @@ -26,7 +40,7 @@ A Node.js server for GitHub app to assist external contributors and save maintai
2. Create a `.env` file similar to `.env.example` and set actual values. If you are using GitHub Enterprise Server, also include a `ENTERPRISE_HOSTNAME` variable and set the value to the name of your GitHub Enterprise Server instance.
3. Install dependencies with `npm install`.
4. Start the server with `npm run server`.
5. Ensure your server is reachable from the internet.
5. Ensure your server is reachable from the internet. This is necessary for GitHub to send webhook events to your local server.
- If you're using `smee`, run `smee -u <smee_url> -t http://localhost:3000/api/webhook`.
6. Ensure your GitHub App includes at least one repository on its installations.

Expand All @@ -35,15 +49,33 @@ A Node.js server for GitHub app to assist external contributors and save maintai
### Using `Docker`

1. [Register a GitHub app](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) for your GitHub organization. Make sure to activate the webhook with webhook url `https://YOUR_WEBSITE/api/webhook` in your app with a secret. Enable Permissions & Events as you may need, at minimum pull_request and issue related events should be enabled.
2. Install your GitHub app in all the repos where you need this app.
2. Install your GitHub app in all the repos where you need this app.
3. Clone this repo OR download the [`build/docker-compose.yml`](./build/docker-compose.yml) to install via dockerhub image
4. Update `docker-compose.yml` environment variables with the details received from the step 2
> To convert GitHub App's private key to base64, use this command - `openssl base64 -in /path/to/original-private-key.pem -out ./base64EncodedKey.txt -A`
5. Run `docker-componse build` to build the service
6. Run `docker-compose up` to create and start the container
7. Test by visiting `http://localhost:3000` OR whatever `WEBSITE_ADDRESS` environment variable you've configured
4. Update the `docker-compose.yml` file with the environment variables obtained from step 2. Make sure to replace placeholder values with your actual GitHub App details.
5. To convert GitHub App's private key to base64, use this command:
```
openssl base64 -in /path/to/original-private-key.pem -out ./base64EncodedKey.txt -A
```
6. Run `docker-compose build` to build the service
7. Run `docker-compose up` to create and start the container
8. Test by visiting `http://localhost:3000` OR whatever `WEBSITE_ADDRESS` environment variable you've configured

## Advanced Features Setup

### Docs Agent Setup

To set up the Docs Agent feature:

1. Locate your Docs Agent API project. This is a separate service that analyzes documentation and provides suggestions.
2. In the Docs Agent API project's environment configuration, add the following URL to the `ALLOWED_WEBHOOK_URLS` variable:
```
https://your-github-app-host.com/api/comment
```
Replace `your-github-app-host.com` with the actual hostname where your GitHub App is deployed.

This setup allows the Docs Agent to send webhook requests to your GitHub App.

## Usage
## How It Works

With your server running, you can now create a pull request on any repository that
your app can access. GitHub will emit a `pull_request.opened` event and will deliver
Expand All @@ -67,4 +99,4 @@ etc.
## References

- [Docs - octokit.rest.* methods](https://github.com/octokit/plugin-rest-endpoint-methods.js/tree/main/docs)
- [Docs - GitHub API](https://docs.github.com/en/rest)
- [Docs - GitHub API](https://docs.github.com/en/rest)
47 changes: 47 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
isMessageAfterMergeRequired,
getWebsiteAddress,
} from "./src/helpers.js";
import DocsAgent from "./src/services/DocsAgent.js";

try {
const packageJson = await import("./package.json", {
Expand Down Expand Up @@ -112,6 +113,49 @@ GitHub.app.webhooks.on("pull_request.labeled", async ({ octokit, payload }) => {
const message = `:mag: <${pull_request.html_url}|#${pull_request.number}: ${pull_request.title}> by ${pull_request.user?.login}`;
await Slack.sendMessage(message);
}
if(label.name?.toLowerCase() === "docs review") {
console.log("Processing docs review for this PR");
try {
const DOCS_REPOS = process.env.DOCS_REPOS?.split(",")?.map((item) => item?.trim()) || [];
if(DOCS_REPOS?.length > 0 && !DOCS_REPOS.includes(repository.name)) {
throw new Error("Docs agent review is not available for this repository");
}
if(!DocsAgent.isConfigured()) {
throw new Error("Docs agent service is not configured");
}
console.log("Going to analyze the docs pages in this PR");
// Get PR changes
const prChanges = await GitHub.getPRChanges(
repository.owner.login,
repository.name,
pull_request.number
);
const docsFiles = prChanges.files.filter((file) => file.filename.endsWith(".md"));
console.log(`Found ${docsFiles.length} docs files being changed`);
if(docsFiles.length === 0) {
throw new Error("No docs files being changed in this PR");
}
for(const file of docsFiles) {
const content = file.content;
// Convert relative file path to full remote github file path using PR head commit SHA https://raw.githubusercontent.com/gitcommitshow/rudder-github-app/e14433e76d74dc680b8cf9102d39f31970e8b794/.codesandbox/tasks.json
const relativePath = file.filename;
const fullPath = `https://raw.githubusercontent.com/${repository.owner.login}/${repository.name}/${prChanges.headCommit}/${relativePath}`;
const webhookUrl = process.env.API_POST_GITHUB_COMMENT || (getWebsiteAddress() + "/api/comment");//TODO: add this url to `ALLOWED_WEBHOOK_URLS` env of docs-agent project
DocsAgent.reviewDocs(content, fullPath, {
webhookUrl: webhookUrl,
webhookMetadata: {
issue_number: pull_request.number,
repo: repository.name,
owner: repository.owner.login,
},
});
console.log(`Successfully started docs review for ${fullPath}, results will be handled by webhook: ${webhookUrl}`);
}
console.log(`Successfully started all necessary docs reviews for PR ${repository.name} #${pull_request.number}`);
} catch (error) {
console.error(error);
}
}
} catch (error) {
if (error.response) {
console.error(
Expand Down Expand Up @@ -216,6 +260,9 @@ const server = http
case "POST /api/webhook":
githubWebhookRequestHandler(req, res);
break;
case "POST /api/comment":
routes.addCommentToGitHubIssueOrPR(req, res);
break;
case "GET /":
routes.home(req, res);
break;
Expand Down
Loading