Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce PR Standards #5941

Closed
wants to merge 6 commits into from
Closed
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
6 changes: 5 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
- [ ] I have [reviewed the guidelines](https://github.com/TykTechnologies/tyk-docs/blob/master/CONTRIBUTING.md) for contributing to this repository.
- [ ] I have [read the technical guidelines](https://github.com/TykTechnologies/tyk-docs/blob/master/CONTRIBUTING-TECHNICAL-GUIDE.md) for contributing to this repository.
- [ ] Make sure you have started *your change* off *our latest `master`*.
- [ ] I **labeled** the PR
- [ ] For internal users - Please add a Jira DX PR ticket to the subject!
- [ ] I have added the appropriate release label to this PR:
- If it is for a future release, label it as **`future-release`** and specify the version (e.g., `future-release, 6.0`).
- If it should be merged into an older version, use the specific version label (e.g., `4.1`, `5.1`).
- If no label is added, it will be assumed that the PR should be merged into the latest current version (e.g., `5.5`) and `master`.
<!-- Label your PR according to the type of changes that your code introduces. This ensures that we know how/when to publish the PR. These are the options:
- Fixing typo (please merge to production) - add the label `now`
- Documenting a new feature (please merge to production) - add the label `now`
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/enforce-pr-standards.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Enforce PR Standards

on:
pull_request:
types: [ready_for_review, reopened, opened, edited]

jobs:
check-pr:
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '22' # Use your desired Node.js version

- name: Install dependencies
run: cd scripts/pr-review-bot/ && npm install

- name: Install dependencies
run: cd scripts/pr-review-bot/ && npm install

- name: Run PR checklist script
run: node scripts/pr-review-bot/index.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use GitHub's automatically generated token
PR_NUMBER: ${{ github.event.pull_request.number }}
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ node_modules/
node_modules
package-lock.json
package.json
changed-files.txt
changed-files.txt

# Allow specific files
!scripts/pr-review-bot/package.json
!scripts/pr-review-bot/package-lock.json
71 changes: 71 additions & 0 deletions scripts/pr-review-bot/github.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Octokit } from "@octokit/rest";

// Variables
const owner = "TykTechnologies";
const repo = "tyk-docs";
// const pull_number = parseInt(process.env.PR_NUMBER); // Convert to integer
const pull_number = process.env.PR_NUMBER; // Convert to integer
const github_token = process.env.GITHUB_TOKEN

// Create a new Octokit instance with your personal access token
const octokit = new Octokit({ auth: github_token });

export async function getPRBody() {
try {
const { data } = await octokit.pulls.get({
owner,
repo,
pull_number
});

// Access and log the pull request body
return data.body;
} catch (error) {
console.error('Error fetching PR:', error);
}
}

export async function commentOnPullRequest(title, message, failedItems) {
try {
// Get the pull request details
const { data: pullRequest } = await octokit.rest.pulls.get({
owner,
repo,
pull_number,
});

// Get the author's login name
const author = pullRequest.user.login;

// Construct the comment message
const commentMessage = `
# ${title}

@${author} ${message}

### Failed Items
${failedItems}`;

// Create a comment on the pull request
await octokit.rest.issues.createComment({
owner,
repo,
issue_number: pull_number,
body: commentMessage,
});

// Update the pull request status to draft
await octokit.rest.pulls.update({
owner,
repo,
pull_number,
state: 'closed', // Set draft to true
});

console.log("Pull request status changed to draft successfully!");

console.log("Comment created successfully!");
} catch (error) {
console.error("Error creating comment:", error);
}
}
51 changes: 51 additions & 0 deletions scripts/pr-review-bot/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { commentOnPullRequest, getPRBody } from './github.js'
import fs from 'fs';

const genericMessage = "This PR does not meet all the required checklist items mentioned in the description. As a result, we are closing the PR. Please re-open it once all checklist items are completed (ensure they are checked in the description)."

import { marked } from 'marked';

const filePath = '.github/pull_request_template.md';
const fileContent = fs.readFileSync(filePath, 'utf8');

// const prBody = await getPRBody()
// console.log("Read PR body")

// Function to check if an item is a checklist
function isChecklistItem(item) {
return item.raw && (item.raw.includes('[ ]') || item.raw.includes('[x]'));
}

// Parse the markdown to HTML or AST (Abstract Syntax Tree)
const lexer = marked.lexer(fileContent);

// Find the checklist items in the parsed output
const checklistItems = lexer
.filter(item => item.type === 'list') // Filter out non-list items and comments
.flatMap(list => list.items) // Extract list items
.filter(isChecklistItem) // Only checklist items
.map(item => {
const isChecked = item.raw.includes('[x]');
const text = item.raw.replace(/- \[.\] /, '').trim(); // Remove the checklist syntax
return { text, checked: isChecked };
});

let checklistFailedTitles = ""

const lastTwoListItems = checklistItems.slice(-2);


// Create message for comment on PR
for (let index = 0; index < lastTwoListItems.length; index++) {
const element = lastTwoListItems[index];
if (!element.checked) {
checklistFailedTitles += index + 1 + ": " + element.text + '\n'
}
}

const title = "PR Checklist Failed"

if (checklistFailedTitles !== "") {
console.log("Comment on pr & closing it")
commentOnPullRequest(title, genericMessage, checklistFailedTitles);
}
194 changes: 194 additions & 0 deletions scripts/pr-review-bot/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions scripts/pr-review-bot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "pr-reviewer-github-bot",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@octokit/rest": "^21.0.2",
"marked": "^14.1.2"
}
}
Loading