Skip to content

Commit

Permalink
Setup ESLint in order to lint JavaScript (#568)
Browse files Browse the repository at this point in the history
* Init new ESLint config to lint .js and .js.erb files

* Add default settings/extensions for VSCode

(maybe also something for another PR?)

* Add ESLint to CI/CD

* Introduce dummy changes to see ESLint in action

* Fix wrong fetch depth for checkout action

* Remove unnecessary "--" to pass arguments

* Outsource retrieval of changed files to reusable action

* Correct location of reusable action

* Fix further stuff related to GitHub action

* Clean up GitHub Actions files

* Cache global yarn cache directory

* Remove VSCode specific settings in favor of #569

* Revert "Introduce dummy changes to see ESLint in action"

This reverts commit cdf3473.
  • Loading branch information
Splines authored Dec 19, 2023
1 parent e87caf4 commit b421193
Show file tree
Hide file tree
Showing 6 changed files with 712 additions and 42 deletions.
43 changes: 43 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Starting with v9, this config will be deprecated in favor of the new
// configuration files [1]. @stylistic is already ready for the new "flat config",
// when it's time, copy the new config from [2].
// [1] https://eslint.org/docs/latest/use/configure/configuration-files-new
// [2] https://eslint.style/guide/config-presets#configuration-factory

// Stylistic Plugin for ESLint
// see the rules in [3] and [4].
// [3] https://eslint.style/packages/js#rules
// [4] https://eslint.org/docs/rules/
const stylistic = require("@stylistic/eslint-plugin");

const customizedStylistic = stylistic.configs.customize({
"indent": 2,
"quotes": "double",
"jsx": false,
"quote-props": "always",
"semi": "always",
"brace-style": "1tbs",
});

module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2022,
sourceType: "module",
},
env: {
node: true,
browser: true,
jquery: true,
},
extends: [
"eslint:recommended",
// Allow linting of ERB files, see https://github.com/Splines/eslint-plugin-erb
"plugin:erb/recommended",
],
plugins: ["@stylistic", "erb"],
rules: {
...customizedStylistic.rules,
"no-unused-vars": "warn",
},
};
11 changes: 0 additions & 11 deletions .eslintrc.json

This file was deleted.

42 changes: 42 additions & 0 deletions .github/actions/changed_files/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Why is this file in a subdirectory? Because GitHub Actions requires it to be :(
# see: https://github.com/orgs/community/discussions/26245#discussioncomment-5962450
name: "Get changed files"
description: "Checks out the code and returns the filenames of files that have changed in the pull request"

inputs:
file-extensions:
# for example: "\.rb$" or something like "\.js$|\.js.erb$"
description: "Regex expressions for grep to filter for specific files"
required: true

outputs:
changed-files:
description: "A space-separated list of the files that have changed in the pull request"
value: ${{ steps.get-changed-files.outputs.files }}

runs:
using: "composite"
steps:
# This has to be done in the main workflow, not in the action, because
# otherwise this reusable action is not available in the workflow.
# - name: "Checkout code (on a PR branch)"
# uses: actions/checkout@v4
# with:
# fetch-depth: 2 # to also fetch parent of PR

# Adapted from this great comment [1]. Git diff adapted from [2].
# "|| test $? = 1;" is used to ignore the exit code of grep when no files
# are found matching the pattern. For the "three dots" ... syntax, see [3].
#
# Resources:
# number [1] being most important
# [1] https://github.com/actions/checkout/issues/520#issuecomment-1167205721
# [2] https://robertfaldo.medium.com/commands-to-run-rubocop-and-specs-you-changed-in-your-branch-e6d2f2e4110b
# [3] https://community.atlassian.com/t5/Bitbucket-questions/Git-diff-show-different-files-than-PR-Pull-Request/qaq-p/2331786
- name: Get changed files
shell: bash
id: get-changed-files
run: |
files_pretty=$(git diff --name-only --diff-filter=ACMR -r HEAD^1...HEAD | egrep '${{inputs.file-extensions}}' || test $? = 1;)
printf "🎴 Changed files: \n$files_pretty"
echo "files=$(echo ${files_pretty} | xargs)" >> $GITHUB_OUTPUT
62 changes: 43 additions & 19 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,62 @@ on:

jobs:

# Resources:
# number [1] being most important
# [1] https://github.com/actions/checkout/issues/520#issuecomment-1167205721
# [2] https://robertfaldo.medium.com/commands-to-run-rubocop-and-specs-you-changed-in-your-branch-e6d2f2e4110b
# [3] https://community.atlassian.com/t5/Bitbucket-questions/Git-diff-show-different-files-than-PR-Pull-Request/qaq-p/2331786
rubocop:
name: RuboCop
name: RuboCop (Ruby)
runs-on: ubuntu-latest
steps:
- name: 'Checkout PR branch (with test merge-commit)'
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2 # to also fetch parent of PR

# Adapted from this great comment [1]. Git diff adapted from [2].
# "|| test $? = 1;" is used to ignore the exit code of grep when no files
# are found matching the pattern. For the "three dots" ... syntax, see [3].
fetch-depth: 2 # to also fetch parent of PR (used to get changed files)

- name: Get changed files
run: |
files=$(git diff --name-only --diff-filter=ACMR -r HEAD^1...HEAD | grep '\.rb$' || test $? = 1;)
printf "🎴 Changed ruby files: \n$files"
echo "CHANGED_FILES=$(echo ${files} | xargs)" >> $GITHUB_ENV
id: rb-changed
uses: ./.github/actions/changed_files/
with:
file-extensions: \.rb$

- name: Set up Ruby 3
if: env.CHANGED_FILES != ''
if: ${{ steps.rb-changed.outputs.changed-files != ''}}
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.1.4
bundler-cache: true

- name: Run RuboCop
if: env.CHANGED_FILES != ''
if: ${{ steps.rb-changed.outputs.changed-files != ''}}
run: |
echo "🚨 Running RuboCop version: $(bundle info rubocop | head -1)"
bundle exec rubocop --format github --fail-level 'convention' --force-exclusion -- $CHANGED_FILES
eslint:
name: ESLint (JS)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2 # to also fetch parent of PR (used to get changed files)

- name: Get changed files
id: js-changed
uses: ./.github/actions/changed_files/
with:
file-extensions: \.js$|\.js.erb$

- name: Setup Node.js
if: ${{ steps.js-changed.outputs.changed-files != ''}}
uses: actions/setup-node@v4
with:
node-version: '20' # End of Life (EOL): April 2026
cache: 'yarn'

- name: Install dependencies
if: ${{ steps.js-changed.outputs.changed-files != ''}}
run: yarn install

- name: Run ESLint
if: ${{ steps.js-changed.outputs.changed-files != ''}}
run: |
echo "🚨 Running ESLint version: $(yarn run --silent eslint --version)"
yarn run eslint --ignore-path .gitignore --max-warnings 0 ${{ steps.js-changed.outputs.changed-files }}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@
},
"scripts": {
"lint": "eslint ."
},
"devDependencies": {
"@stylistic/eslint-plugin": "^1.5.0",
"eslint": "^8.55.0",
"eslint-plugin-erb": "^1.1.0"
}
}
}
Loading

0 comments on commit b421193

Please sign in to comment.