Skip to content

Commit

Permalink
impl: copia eslint-linter-action
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanpsv committed Nov 9, 2020
1 parent 3a24b78 commit 69ed0ad
Show file tree
Hide file tree
Showing 39 changed files with 28,177 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode/

coverage/

node_modules/
163 changes: 162 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,162 @@
# stylelint-linter-action
# ESLint Linter Action

A GitHub action that evaluates projects with [ESLint](https://eslint.org/) and comments the evaluation outcome on the student's pull request.

## Inputs

This action accepts the following configuration parameters via `with:`

- `token`

**Required**

The GitHub token to use for making API requests

## Example usage

```yaml
steps:
- uses: actions/[email protected]
with:
node-version: '12'
- name: Static code analysis step
uses: betrybe/eslint-linter-action@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
```
Check the latest version to use [here](https://github.com/betrybe/eslint-linter-action/releases).
## Project constraints
In order for the action to comment the `ESLint` analysis on the pull request, you must:

1. Add `ESLint` into your project's dependencies.

1. Configure the `ESLint` analysis **exclusively** via `.eslintrc.json`.

### Add `ESLint` into your project's dependencies

In order to add `ESLint` into your project you must add `ESLint` as a `dev` dependency:

```shell
npm install eslint --save-dev
```

If you have multiple projects to be evaluated with `ESLint` in the repository, you must add `ESLint` to each project. Beware that each project must have the **same** `ESLint` version, in order to **ensure** that **all** projects are being evaluated under the same conditions (i.e., the same `ESLint` version).

### Configure the `ESLint` analysis **exclusively** via `.eslintrc.json`

In order to configure the `ESLint` analysis for your project, you must create a `.eslintrc.json` file at the root of your project. Therefore, beware the following:

- There cannot be present `ESLint` configurations in the `package.json` of the project;

- There cannot be present inline configurations.

Here follows an example for `.eslintrc.json`:

```json
{
"env": {
"es6": true
},
"parserOptions": {
"ecmaVersion": 6
},
"rules": {
"no-console": "error",
"semi": "error",
"max-params": ["error", 2]
}
}
```

If you have multiple projects to be evaluated with `ESLint` in the repository, you must do the following:

- Create a `.eslintrc.json` file **at the root of each project**. There cannot be present a `.eslintrc.json` at **the root of the repository**;

- Add `"root": true` for each `.eslintrc.json`, in order to **ensure** the `ESLint` analysis for one project does not use `ESLint` configured in another project in your repository.

Here follows an example for `.eslintrc.json` defined in one of the projects in your repository:

```json
{
"root": true,
"env": {
"es6": true
},
"parserOptions": {
"ecmaVersion": 6
},
"rules": {
"no-console": "error",
"semi": "error",
"max-params": ["error", 2]
}
}
```

#### Using plugins

You can use plugins in the configuration file `.eslintrc.json`. However, beware to follow the instructions as stated in the plugin's documentation and install all dependencies associated with the plugin. There cannot be any warning raised by `npm` stating uninstalled plugin dependencies when installing a project; otherwise you will have an incomplete `ESLint` analysis environment.

For more information related to configuring `ESLint` with `.eslintrc.json`, read its [guide](https://eslint.org/docs/user-guide/configuring).

## Development

Install the dependencies
```bash
$ npm install
```

Run the tests :heavy_check_mark:
```bash
$ npm test
```

## Package for distribution

GitHub Actions will run the entry point from the action.yml. Packaging assembles the code into one file that can be checked in to Git, enabling fast and reliable execution and preventing the need to check in node_modules.

Actions are run from GitHub repos. Packaging the action will create a packaged action in the dist folder.

Run package

```bash
npm run pack
```

Since the packaged index.js is run from the dist folder.

```bash
git add dist
```

## Create a release branch

Users shouldn't consume the action from master since that would be latest code and actions can break compatibility between major versions.

Checking to the v1 release branch

```bash
$ git checkout -b v1
$ git commit -a -m "v1 release"
```

```bash
$ git push origin v1
```

Your action is now published! :rocket:

See the [versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)

## Usage

You can now consume the action by referencing the v1 branch

```yaml
uses: betrybe/eslint-linter-action@v1
```

See the [actions tab](https://github.com/betrybe/eslint-linter-action/actions) for runs of this action! :rocket:
170 changes: 170 additions & 0 deletions __tests__/feedbackMessage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
const buildFeedbackMessage = require('../feedbackMessage');
const multipleErrorsOneFile = require('./fixtures/eslint-results/multipleErrorsOneFile.json');
const multipleWarningsOneFile = require('./fixtures/eslint-results/multipleWarningsOneFile.json');
const multipleWarningsAndErrorsOneFile = require('./fixtures/eslint-results/multipleWarningsAndErrorsOneFile.json');
const multipleErrorsMultipleFiles = require('./fixtures/eslint-results/multipleErrorsMultipleFiles.json');
const multipleWarningsMultipleFiles = require('./fixtures/eslint-results/multipleWarningsMultipleFiles.json');
const noError = require('./fixtures/eslint-results/frontEndNoError.json');
const oneError = require('./fixtures/eslint-results/oneError.json');
const oneErrorOneFileMultipleWarningsAnotherFile = require('./fixtures/eslint-results/oneErrorOneFileMultipleWarningsAnotherFile.json');
const oneWarning = require('./fixtures/eslint-results/oneWarning.json');

describe('Feedback message', () => {
describe('No issue is found', () => {
test('When there is no file to be evaluated, a no issue encountered message is returned', () => {
expect(buildFeedbackMessage([], './')).toBe(
'### Nenhum erro encontrado.\n' +
'### Nenhum aviso encontrado.'
)
});

test('When there are files to be evaluated, a no issue encountered message is returned', () => {
expect(buildFeedbackMessage(noError, './')).toBe(
'### Nenhum erro encontrado.\n' +
'### Nenhum aviso encontrado.'
)
});
});

test('When one error is found, a message showing the error is returned', () => {
expect(buildFeedbackMessage(oneError, './')).toBe(
'### Foi encontrado 1 erro.\n' +
'\n' +
'#### Arquivo `/my-project/index.js`\n' +
'\n' +
'- Linha **1**: Function \'isPentagon\' has too many parameters (5). Maximum allowed is 4.\n' +
'\n' +
'### Nenhum aviso encontrado.'
);
});

describe('Multiple errors are found', () => {
test('When all errors are contained in one file, a message listing all those errors is returned', () => {
expect(buildFeedbackMessage(multipleErrorsOneFile, './')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/my-react-project/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n' +
'- Linha **3**: `Hello, ` must be placed on a new line\n' +
'- Linha **3**: `{name}` must be placed on a new line\n' +
'- Linha **5**: Missing semicolon.\n' +
'\n' +
'### Nenhum aviso encontrado.'
);
});

test('When the errors span multiple files, a message listing all those errors is returned', () => {
expect(buildFeedbackMessage(multipleErrorsMultipleFiles, './')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/my-react-project/src/App.js`\n' +
'\n' +
'- Linha **2**: `react` import should occur before import of `./components/Greeting`\n' +
'- Linha **12**: `code` must be placed on a new line\n' +
'- Linha **24**: Expected indentation of 6 space characters but found 4.\n' +
'' +
'#### Arquivo `/my-react-project/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n' +
'\n' +
'### Nenhum aviso encontrado.'
);
});
});

test('When one warning is found, a message showing the warning is returned', () => {
expect(buildFeedbackMessage(oneWarning, './')).toBe(
'### Nenhum erro encontrado.\n' +
'### Foi encontrado 1 aviso.\n' +
'\n' +
'#### Arquivo `/back-end/index.js`\n' +
'\n' +
'- Linha **8**: Unexpected console statement.\n'
);
});

describe('Multiple warnings are found', () => {
test('When all warnings are contained in one file, a message listing all those warnings is returned', () => {
expect(buildFeedbackMessage(multipleWarningsOneFile, './')).toBe(
'### Nenhum erro encontrado.\n' +
'### Foram encontrados 2 avisos.\n' +
'\n' +
'#### Arquivo `/front-end/src/App.js`\n' +
'\n' +
'- Linha **7**: Unexpected console statement.\n' +
'- Linha **28**: Unexpected alert.\n'
);
});

test('When the warnings span multiple files, a message listing all those warnings is returned', () => {
expect(buildFeedbackMessage(multipleWarningsMultipleFiles, './')).toBe(
'### Nenhum erro encontrado.\n' +
'### Foram encontrados 3 avisos.\n' +
'\n' +
'#### Arquivo `/front-end/src/App.js`\n' +
'\n' +
'- Linha **7**: Unexpected console statement.\n' +
'- Linha **28**: Unexpected alert.\n' +
'' +
'#### Arquivo `/front-end/src/components/Greeting.js`\n' +
'\n' +
'- Linha **7**: Missing trailing comma.\n'
);
});
});

describe('Errors and warnings are found', () => {
test('When all errors and warnings are contained in one file, a message listing both errors and warnings is returned', () => {
expect(buildFeedbackMessage(multipleWarningsAndErrorsOneFile, './')).toBe(
'### Foi encontrado 1 erro.\n' +
'\n' +
'#### Arquivo `/front-end/src/App.js`\n'+
'\n' +
'- Linha **33**: Newline required at end of file but not found.\n' +
'\n' +
'### Foram encontrados 2 avisos.\n' +
'\n' +
'#### Arquivo `/front-end/src/App.js`\n'+
'\n' +
'- Linha **7**: Unexpected console statement.\n' +
'- Linha **28**: Unexpected alert.\n'
);
});

test('When errors are in one file and warnings are in another one, a message listing both errors and warnings for those files is returned', () => {
expect(buildFeedbackMessage(oneErrorOneFileMultipleWarningsAnotherFile, './')).toBe(
'### Foi encontrado 1 erro.\n' +
'\n' +
'#### Arquivo `/front-end/src/components/Greeting.js`\n'+
'\n' +
'- Linha **2**: Missing semicolon.\n' +
'\n' +
'### Foram encontrados 2 avisos.\n' +
'\n' +
'#### Arquivo `/front-end/src/App.js`\n'+
'\n' +
'- Linha **7**: Unexpected console statement.\n' +
'- Linha **28**: Unexpected alert.\n'
);
});
});

test('The root directory path for the project isn\'t displayed for each file', () => {
expect(buildFeedbackMessage(multipleErrorsMultipleFiles, '/my-react-project')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/src/App.js`\n' +
'\n' +
'- Linha **2**: `react` import should occur before import of `./components/Greeting`\n' +
'- Linha **12**: `code` must be placed on a new line\n' +
'- Linha **24**: Expected indentation of 6 space characters but found 4.\n' +
'' +
'#### Arquivo `/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n' +
'\n' +
'### Nenhum aviso encontrado.'
);
});
});
Loading

0 comments on commit 69ed0ad

Please sign in to comment.