-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from betrybe/feature/stylelint-evaluator
Cria avaliador Stylelint em GitHub Action
- Loading branch information
Showing
46 changed files
with
19,678 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name: 'Tests' | ||
on: | ||
pull_request: | ||
types: [opened, synchronize] | ||
|
||
jobs: | ||
tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- run: npm ci | ||
- run: npm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.vscode/ | ||
|
||
coverage/ | ||
|
||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,155 @@ | ||
# stylelint-linter-action | ||
# Stylelint Linter Action | ||
|
||
A GitHub action that evaluates projects with [Stylelint](https://stylelint.io/) 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/setup-node@v1.4.4 | ||
with: | ||
node-version: '12' | ||
- name: Static code analysis step | ||
uses: betrybe/stylelint-linter-action@v1 | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
``` | ||
Check the latest version to use [here](https://github.com/betrybe/stylelint-linter-action/releases). | ||
## Running command locally | ||
This GitHub Action run the command: | ||
``` | ||
npx stylelint **/*.css --config .stylelintrc.json --formatter json --ignore-disables --allow-empty-input | ||
``` | ||
|
||
## Project constraints | ||
|
||
In order for the action to comment the `Stylelint` analysis on the pull request, you must: | ||
|
||
1. Add `Stylelint` into your project's dependencies. | ||
|
||
1. Configure the `Stylelint` analysis **exclusively** via `.stylelintrc.json`. | ||
|
||
### Add `Stylelint` into your project's dependencies | ||
|
||
In order to add `Stylelint` into your project you must add `Stylelint` and its `standard configuration` as a `dev` dependency: | ||
|
||
```shell | ||
npm install stylelint stylelint-config-standard --save-dev | ||
``` | ||
|
||
If you have multiple projects to be evaluated with `Stylelint` in the repository, you must add `Stylelint` to each project. Beware that each project must have the **same** `Stylelint` version, in order to **ensure** that **all** projects are being evaluated under the same conditions (i.e., the same `Stylelint` version). | ||
|
||
### Configure the `Stylelint` analysis **exclusively** via `.stylelintrc.json` | ||
|
||
In order to configure the `Stylelint` analysis for your project, you must create a `.stylelintrc.json` file at the root of your project. Therefore, beware of the following: | ||
|
||
- There cannot be present `Stylelint` configurations in the `package.json` of the project; | ||
|
||
- There cannot be present inline configurations. | ||
|
||
Here follows an example for `.stylelintrc.json`: | ||
|
||
```json | ||
{ | ||
"extends": "stylelint-config-standard", | ||
"rules": { | ||
"block-no-empty": null, | ||
"selector-pseudo-class-no-unknown": [ | ||
true, | ||
{ | ||
"ignorePseudoClasses": ["global"] | ||
} | ||
], | ||
"identation": [ | ||
2, | ||
{ | ||
"except": ["value"], | ||
"severity": "warning" | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
If you have multiple projects to be evaluated with `Stylelint` in the repository, you must do the following: | ||
|
||
- Create a `.stylelintrc.json` file **at the root of each project**. There cannot be present a `.stylelintrc.json` at **the root of the repository**; | ||
|
||
#### Using plugins | ||
|
||
You can use plugins in the configuration file `.stylelintrc.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 `Stylelint` analysis environment. | ||
|
||
For more information related to configuring `Stylelint` with `.stylelintrc.json`, read its [guide](https://stylelint.io/user-guide/configure#plugins). | ||
|
||
## 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/stylelint-linter-action@v1 | ||
``` | ||
See the [actions tab](https://github.com/betrybe/stylelint-linter-action/actions) for runs of this action! :rocket: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
const buildFeedbackMessage = require('../feedbackMessage'); | ||
const multipleErrorsOneFile = require('./fixtures/stylelint-results/multipleErrorsOneFile.json'); | ||
const multipleWarningsOneFile = require('./fixtures/stylelint-results/multipleWarningsOneFile.json'); | ||
const multipleWarningsAndErrorsOneFile = require('./fixtures/stylelint-results/multipleErrorsAndWarningsOneFile.json'); | ||
const multipleErrorsMultipleFiles = require('./fixtures/stylelint-results/multipleErrorsMultipleFiles.json'); | ||
const multipleWarningsMultipleFiles = require('./fixtures/stylelint-results/multipleWarningsMultipleFiles.json'); | ||
const noError = require('./fixtures/stylelint-results/noError.json'); | ||
const oneError = require('./fixtures/stylelint-results/oneError.json'); | ||
const oneErrorOneFileMultipleWarningsAnotherFile = require('./fixtures/stylelint-results/oneErrorOneFileMultipleWarningsAnotherFile.json'); | ||
const multipleErrosAndWarningsMultipleFiles = require('./fixtures/stylelint-results/multipleErrorsAndWarningsMultipleFiles.json'); | ||
const oneWarning = require('./fixtures/stylelint-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 `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\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 2 erros.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\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 5 erros.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **9**: Unexpected unknown unit \"pixels\" (unit-no-unknown)\n' + | ||
'#### Arquivo `/frontend/sidebar.css`\n' + | ||
'\n' + | ||
'- Linha **8**: Unexpected duplicate name serif (font-family-no-duplicate-names)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\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 `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)' | ||
); | ||
}); | ||
|
||
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 `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)' | ||
); | ||
}); | ||
|
||
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 5 avisos.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **9**: Unexpected unknown unit \"pixels\" (unit-no-unknown)\n' + | ||
'' + | ||
'#### Arquivo `/frontend/sidebar.css`\n' + | ||
'\n' + | ||
'- Linha **8**: Unexpected duplicate name serif (font-family-no-duplicate-names)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)' | ||
); | ||
}); | ||
}); | ||
|
||
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( | ||
'### Foram encontrados 2 erros.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n'+ | ||
'\n' + | ||
'- Linha **9**: Unexpected duplicate name serif (font-family-no-duplicate-names)\n' + | ||
'- Linha **10**: Unexpected unknown unit \"pixels\" (unit-no-unknown)\n' + | ||
'\n' + | ||
'### Foram encontrados 2 avisos.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n'+ | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)' | ||
); | ||
}); | ||
|
||
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 `/frontend/main.css`\n'+ | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'\n' + | ||
'### Foram encontrados 3 avisos.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/sidebar.css`\n'+ | ||
'\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **9**: Unexpected unknown unit \"pixels\" (unit-no-unknown)' | ||
); | ||
}); | ||
|
||
test('When errors and warning are in multiple files, a message listing both errors and warnings is returned', () => { | ||
expect(buildFeedbackMessage(multipleErrosAndWarningsMultipleFiles, './')).toBe( | ||
'### Foram encontrados 2 erros.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n'+ | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'' + | ||
'#### Arquivo `/frontend/sidebar.css`\n'+ | ||
'\n' + | ||
'- Linha **8**: Unexpected duplicate name serif (font-family-no-duplicate-names)\n' + | ||
'\n' + | ||
'### Foram encontrados 3 avisos.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n'+ | ||
'\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **9**: Unexpected unknown unit \"pixels\" (unit-no-unknown)\n' + | ||
'#### Arquivo `/frontend/sidebar.css`\n'+ | ||
'\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)' | ||
); | ||
}); | ||
}); | ||
|
||
test('The root directory path for the project isn\'t displayed for each file', () => { | ||
expect(buildFeedbackMessage(multipleErrorsMultipleFiles, '/my-react-project')).toBe( | ||
'### Foram encontrados 5 erros.\n' + | ||
'\n' + | ||
'#### Arquivo `/frontend/main.css`\n' + | ||
'\n' + | ||
'- Linha **5**: Unexpected invalid hex color \"#ye\" (color-no-invalid-hex)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'- Linha **9**: Unexpected unknown unit \"pixels\" (unit-no-unknown)\n' + | ||
'' + | ||
'#### Arquivo `/frontend/sidebar.css`\n' + | ||
'\n' + | ||
'- Linha **8**: Unexpected duplicate name serif (font-family-no-duplicate-names)\n' + | ||
'- Linha **4**: Unexpected unknown property \"nokey\" (property-no-unknown)\n' + | ||
'\n' + | ||
'### Nenhum aviso encontrado.' | ||
); | ||
}); | ||
}); |
Oops, something went wrong.