Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
PrinceGupta1999 committed Jan 16, 2023
1 parent 5491d56 commit ec7da65
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 19 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/test-action-pr-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test Action (PR Comment)

on:
issue_comment:
types:
- created

permissions:
checks: write
contents: read

jobs:
test:
name: Run action
if: github.event.issue.pull_request && contains(github.event.comment.body, 'run-lint')
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- name: Clone git repo
uses: actions/checkout@v3

- name: Checkout Pull Request
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_URL="${{ github.event.issue.pull_request.url }}"
PR_NUM=${PR_URL##*/}
hub pr checkout $PR_NUM
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version-file: ".nvmrc"
cache: "yarn"

- name: Install dependencies
run: yarn install

- name: Build action
run: yarn build

- name: Run linters
uses: ./
with:
continue_on_error: false
eslint: true
prettier: true
prettier_extensions: "css,html,js,json,jsx,less,md,scss,ts,tsx,vue,yaml,yml"
neutral_check_on_warning: true
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lint-action",
"version": "2.2.0",
"version": "2.3.0",
"description": "GitHub Action for detecting and fixing linting errors",
"repository": "github:wearerequired/lint-action",
"license": "MIT",
Expand Down
5 changes: 3 additions & 2 deletions src/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ function checkOutRemoteBranch(context) {

// Switch to remote branch
core.info(`Switching to the "${context.branch}" branch`);
run(`git branch --force ${context.branch} --track ${remote}/${context.branch}`);
run(`git checkout ${context.branch}`);
// run(`git branch --force ${context.branch} --track ${remote}/${context.branch}`);
run(`git reset --hard ${remote}/${context.branch}`);
run(`git checkout -- ${context.branch}`);
}

/**
Expand Down
50 changes: 49 additions & 1 deletion src/github/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,52 @@ async function createCheck(linterName, sha, context, lintResult, neutralCheckOnW
}
}

module.exports = { createCheck };
/**
* Fetches a Pull Request on GitHub
* @param {string} repository - The Github Repository with user name ex: wearerequired/master
* @param {string} pullRequestNumber - SHA of the commit which should be annotated
* @param {string} token - github token for authentication
* @returns {object} pull request information
*/
async function fetchPullRequest(repository, pullRequestNumber, token) {
try {
core.info(`fetchPullRequest for owner ${repository}`);
const response = await request(
`${process.env.GITHUB_API_URL}/repos/${repository}/pulls/${pullRequestNumber}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${token}`,
"User-Agent": actionName,
},
},
);
core.info(
`fetchPullRequest completed successfully for owner:${repository} pull:${pullRequestNumber}`,
);
return response.data;
} catch (err) {
let errorMessage = err.message;
if (err.data) {
try {
const errorData = JSON.parse(err.data);
if (errorData.message) {
errorMessage += `. ${errorData.message}`;
}
if (errorData.documentation_url) {
errorMessage += ` ${errorData.documentation_url}`;
}
} catch (e) {
// Ignore
}
}
core.error(errorMessage);
throw new Error(
`Error while trying to fetch PR for owner:${repository} pull:${pullRequestNumber}`,
);
}
}

module.exports = { createCheck, fetchPullRequest };
56 changes: 45 additions & 11 deletions src/github/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const core = require("@actions/core");

const { name: actionName } = require("../../package.json");
const { getEnv } = require("../utils/action");
const { fetchPullRequest } = require("./api");

/**
* GitHub Actions workflow's environment variables
Expand Down Expand Up @@ -69,14 +70,23 @@ function parseEnvFile(eventPath) {
* Parses the name of the current branch from the GitHub webhook event
* @param {string} eventName - GitHub event type
* @param {object} event - GitHub webhook event payload
* @param {object | undefined} pullRequest - pull request payload associated to event
* @returns {string} - Branch name
*/
function parseBranch(eventName, event) {
function parseBranch(eventName, event, pullRequest) {
if (eventName === "push" || eventName === "workflow_dispatch") {
return event.ref.substring(11); // Remove "refs/heads/" from start of string
}
if (eventName === "pull_request" || eventName === "pull_request_target") {
return event.pull_request.head.ref;
return pullRequest.head.ref;
}
if (eventName === "issue_comment") {
if (event.issue.pull_request) {
return pullRequest.head.ref;
}
throw Error(
`${actionName} does not support issue_comment event that is not associated to a PR`,
);
}
throw Error(`${actionName} does not support "${eventName}" GitHub events`);
}
Expand All @@ -86,20 +96,26 @@ function parseBranch(eventName, event) {
* Fork detection is only supported for the "pull_request" event
* @param {string} eventName - GitHub event type
* @param {object} event - GitHub webhook event payload
* @param {object | undefined} pullRequest - pull request payload associated to event
* @returns {GithubRepository} - Information about the GitHub repository and its fork (if it exists)
*/
function parseRepository(eventName, event) {
function parseRepository(eventName, event, pullRequest) {
const repoName = event.repository.full_name;
const cloneUrl = event.repository.clone_url;
let forkName;
let forkCloneUrl;
if (eventName === "pull_request" || eventName === "pull_request_target") {

if (
eventName === "pull_request" ||
eventName === "pull_request_target" ||
(eventName === "issue_comment" && event.issue.pull_request)
) {
// "pull_request" events are triggered on the repository where the PR is made. The PR branch can
// be on the same repository (`forkRepository` is set to `null`) or on a fork (`forkRepository`
// is defined)
const headRepoName = event.pull_request.head.repo.full_name;
const headRepoName = pullRequest.head.repo.full_name;
forkName = repoName === headRepoName ? undefined : headRepoName;
const headForkCloneUrl = event.pull_request.head.repo.clone_url;
const headForkCloneUrl = pullRequest.head.repo.clone_url;
forkCloneUrl = cloneUrl === headForkCloneUrl ? undefined : headForkCloneUrl;
}
return {
Expand All @@ -111,20 +127,38 @@ function parseRepository(eventName, event) {
};
}

/**
* Parses the name of the current branch from the GitHub webhook event
* @param {string} eventName - GitHub event type
* @param {object} event - GitHub webhook event payload
* @param {string} token - GitHub token
* @returns {Promise<object | undefined>} - The payload corresponding to the pull request
*/
async function parsePullRequest(eventName, event, token) {
if (eventName === "pull_request" || eventName === "pull_request_target") {
return event.pull_request;
}
if (eventName === "issue_comment" && event.issue.pull_request) {
return fetchPullRequest(event.repository.full_name, event.issue.number, token);
}
return undefined;
}

/**
* Returns information about the GitHub repository and action trigger event
* @returns {GithubContext} context - Information about the GitHub repository and action trigger
* event
* @returns {Promise<GithubContext>} context - Information about the GitHub repository
* and action trigger event
*/
function getContext() {
async function getContext() {
const { actor, eventName, eventPath, token, workspace } = parseActionEnv();
const event = parseEnvFile(eventPath);
const pullRequest = await parsePullRequest(eventName, event, token);
return {
actor,
branch: parseBranch(eventName, event),
branch: await parseBranch(eventName, event, pullRequest),
event,
eventName,
repository: parseRepository(eventName, event),
repository: parseRepository(eventName, event, pullRequest),
token,
workspace,
};
Expand Down
14 changes: 10 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const { getSummary } = require("./utils/lint-result");
* Parses the action configuration and runs all enabled linters on matching files
*/
async function runAction() {
const context = getContext();
const context = await getContext();
const autoFix = core.getInput("auto_fix") === "true";
const commit = core.getInput("commit") === "true";
const skipVerification = core.getInput("git_no_verify") === "true";
Expand All @@ -24,10 +24,16 @@ async function runAction() {
const checkName = core.getInput("check_name", { required: true });
const neutralCheckOnWarning = core.getInput("neutral_check_on_warning") === "true";
const isPullRequest =
context.eventName === "pull_request" || context.eventName === "pull_request_target";
context.eventName === "pull_request" ||
context.eventName === "pull_request_target" ||
(context.eventName === "issue_comment" && context.event.issue.pull_request);

// If on a PR from fork: Display messages regarding action limitations
if (context.eventName === "pull_request" && context.repository.hasFork) {
if (
(context.eventName === "pull_request" ||
(context.eventName === "issue_comment" && context.event.issue.pull_request)) &&
context.repository.hasFork
) {
core.error(
"This action does not have permission to create annotations on forks. You may want to run it only on `pull_request_target` events with checks permissions set to write. See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#permissions for details.",
);
Expand Down Expand Up @@ -155,4 +161,4 @@ async function runAction() {
runAction().catch((error) => {
core.debug(error.stack || "No error stack trace");
core.setFailed(error.message);
});
});

0 comments on commit ec7da65

Please sign in to comment.