diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0eafcec..c8e0cdc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,13 +4,18 @@ on: pull_request: branches: - master + paths: + - 'src/**' types: [opened, synchronize, reopened] + # Support manual trigger of the CI in case we need to retry + workflow_dispatch: permissions: - contents: write + contents: read jobs: run-ci: + name: CI runs-on: ubuntu-latest steps: # Checkout Action: https://github.com/actions/checkout @@ -27,16 +32,10 @@ jobs: - name: Install dependencies run: npm ci - - name: Run Prettier - run: npm run prettier - - # Auto Commit Action Repo: https://github.com/stefanzweifel/git-auto-commit-action - - name: Commit and push formatting changes - uses: stefanzweifel/git-auto-commit-action@v7 - with: - commit_message: "style: auto-format code with prettier" - commit_user_name: "github-actions[bot]" - commit_user_email: "github-actions[bot]@users.noreply.github.com" + # Prettier Check: Verifies all files in src/ adhere to .prettierrc convention + - name: Check Prettier formatting + run: npx prettier --check src/ + # ESLint: Enforces style and syntax rules - name: Run ESLint run: npm run lint diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7dd4b2..58cc74d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,18 +35,17 @@ This repository requires `node`/`npm` 1. Fork the repository 2. Clone the fork of the repository 3. `cd` into the project directory -4. `npm install` to install necessary dependencies +4. `npm install` to install necessary dependencies + necessary hooks 5. `npm run start` to start local version of the app 6. The site should be locally accessible from `localhost:3000` ## Submitting a PR -Before creating a pull request, please ensure your code passes ESLint and Prettier by running the following commands: +Before creating a pull request, ensure that the only committed changes are in files relevant to the PR. Do not push changes to package-lock.json, node_modules or anything else that is unrelated to your ticket! -- `npm run lint` -- `npm run prettier` - -Also ensure that the only committed changes are in files relevant to the PR. Do not push changes to package-lock.json, node_modules or anything else that is unrelated to your ticket! +The ESLint and Prettier formatting standards are automatically applied for each JS/TS file under `src/` you modify on commit via a hook. To double check that your code meets the standards, you can run the below commands: +- `npm run lint` +- `npm run prettier` To make a PR: @@ -55,4 +54,5 @@ To make a PR: 3. Base repo should be csvistool/master and head repo should be the relevant branch on your fork 4. Name the PR something simple and descriptive 5. In the description, make sure to reference the issue you worked on (such as “closes #155”, “addresses #150”, etc) -6. Add anything else to the description that you think makes your changes more understandable \ No newline at end of file +6. Add anything else to the description that you think makes your changes more understandable +7. Verify that the CI check passes! If there are any failures, please fix those and update the PR \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b0c6261..0222907 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,8 @@ "eslint-plugin-import": "^2.27.5", "eslint-plugin-react": "^7.17.0", "eslint-plugin-react-hooks": "^4.6", + "husky": "^9.1.7", + "lint-staged": "^17.6.0", "prettier": "^2.8.3" } }, @@ -8848,6 +8850,22 @@ "node": ">=0.10.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", @@ -10716,6 +10734,60 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/lint-staged": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.6.0.tgz", + "integrity": "sha512-nOhBfYkZEwkFtNzD5pK9s9LkcWoxJ+whLzEnhqi9nl7zTB5n7tg8+9iYgMGx2Wm3VlLu8cbNj0RACzY+nWi5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^4.0.7", + "string-argv": "^0.3.2", + "tinyexec": "^1.3.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=22.22.1" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + }, + "optionalDependencies": { + "yaml": "^2.9.1" + } + }, + "node_modules/lint-staged/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -14796,6 +14868,16 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -15470,6 +15552,16 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 065eadd..457e582 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,52 @@ -{ - "name": "visualization-tool", - "version": "0.1.0", - "private": true, - "homepage": "https://csvistool.com/", - "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", - "@mui/material": "5.11.7", - "@mui/styles": "^5.11.7", - "babel-eslint": "^10.1.0", - "gh-pages": "^2.1.1", - "js-cookie": "^3.0.5", - "prop-types": "^15.7.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-ga4": "^2.0.0", - "react-icons": "^4.10.1", - "react-router-dom": "^6.26.2", - "react-scripts": "5.0.1" - }, - "devDependencies": { - "eslint": "^7.32.0", - "eslint-config-react-app": "^5.1.0", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-react": "^7.17.0", - "eslint-plugin-react-hooks": "^4.6", - "prettier": "^2.8.3" - }, - "scripts": { - "predeploy": "npm run build", - "deploy": "gh-pages -d build", - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", - "lint": "eslint src/.", - "prettier": "prettier --write src/." - }, - "browserslist": [ - "defaults" - ] -} +{ + "name": "visualization-tool", + "version": "0.1.0", + "private": true, + "homepage": "https://csvistool.com/", + "dependencies": { + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@mui/material": "5.11.7", + "@mui/styles": "^5.11.7", + "babel-eslint": "^10.1.0", + "gh-pages": "^2.1.1", + "js-cookie": "^3.0.5", + "prop-types": "^15.7.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-ga4": "^2.0.0", + "react-icons": "^4.10.1", + "react-router-dom": "^6.26.2", + "react-scripts": "5.0.1" + }, + "devDependencies": { + "eslint": "^7.32.0", + "eslint-config-react-app": "^5.1.0", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-react": "^7.17.0", + "eslint-plugin-react-hooks": "^4.6", + "husky": "^9.1.7", + "lint-staged": "^17.6.0", + "prettier": "^2.8.3" + }, + "scripts": { + "predeploy": "npm run build", + "deploy": "gh-pages -d build", + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "lint": "eslint src/.", + "prettier": "prettier --write src/.", + "prepare": "husky" + }, + "lint-staged": { + "src/**/*.{js,jsx,json,css}": [ + "prettier --write" + ] + }, + "browserslist": [ + "defaults" + ] +}