From 95dc713c55ac1e79024ad42b56987f7f2cf46ac8 Mon Sep 17 00:00:00 2001 From: zi0w Date: Sun, 25 Jan 2026 21:27:43 +0900 Subject: [PATCH 1/3] chore: add opt-in pre-commit lint --write hook --- .githooks/pre-commit | 54 ++++++++++++++++++++++++++++++++++++ .github/maintainers_guide.md | 22 +++++++++++++++ 2 files changed, 76 insertions(+) create mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..527ba178e --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,54 @@ +#!/bin/sh +set -e + +changed_paths=$(git diff --name-only --cached --diff-filter=ACMR) +if [ -z "$changed_paths" ]; then + exit 0 +fi + +repo_root=$(git rev-parse --show-toplevel 2>/dev/null) +if [ -z "$repo_root" ]; then + exit 1 +fi + +cd "$repo_root" + +packages="" +for path in $changed_paths; do + case "$path" in + packages/*/*) + pkg=${path#packages/} + pkg=${pkg%%/*} + case " $packages " in + *" $pkg "*) ;; + *) packages="$packages $pkg" ;; + esac + ;; + esac +done + +if [ -z "$packages" ]; then + exit 0 +fi + +run_lint() { + pkg_dir="$1" + pkg_json="$repo_root/$pkg_dir/package.json" + + if node -e "const p=require(process.argv[1]);process.exit(p.scripts&&p.scripts['lint:fix']?0:1)" "$pkg_json"; then + echo "[pre-commit] npm --prefix $pkg_dir run lint:fix" + npm --prefix "$pkg_dir" run lint:fix + elif node -e "const p=require(process.argv[1]);process.exit(p.scripts&&p.scripts.lint?0:1)" "$pkg_json"; then + echo "[pre-commit] npm --prefix $pkg_dir run lint -- --fix" + npm --prefix "$pkg_dir" run lint -- --fix + fi + + git add -u "$pkg_dir" +} + +for pkg in $packages; do + pkg_dir="packages/$pkg" + if [ -f "$pkg_dir/package.json" ]; then + run_lint "$pkg_dir" + fi +done diff --git a/.github/maintainers_guide.md b/.github/maintainers_guide.md index 177c26ea9..3a4df0159 100644 --- a/.github/maintainers_guide.md +++ b/.github/maintainers_guide.md @@ -10,6 +10,28 @@ Maintaining this project requires installing [Node.js](https://nodejs.org). All ### ⚗️ Testing and Linting The Node SDK is made up of multiple, individual packages, each with their own tests. As such, tests are run on a per-package basis. However, the top-level directory contains some development dependencies applicable to all packages. As a result, to run tests for any package, first ensure you run `npm install` from the top-level directory. Then, for a given package, navigate to the package's directory (ie, `packages/web-api`) and run `npm install` to install that package's required dependencies. Finally, run `npm test` to run that package's tests. To run just the linting and not the entire test suite, run `npm run lint`. +#### Pre-commit lint hook (optional) +We provide an opt-in Git hook that runs the linter with auto-fix for any packages touched in your staged changes. This helps ensure formatting is applied before commits are created. + +Enable it once per clone: + +```sh +git config core.hooksPath .githooks +``` + +Disable it: + +```sh +git config --unset core.hooksPath +``` + +Notes: +- The hook runs `npm --prefix packages/ run lint:fix` when available, otherwise `npm --prefix packages/ run lint -- --fix`. +- The hook currently uses `npm --prefix`. If you use a different package manager locally, adjust the hook for your environment. +- It only runs for packages that have staged changes. +- You can skip it with `git commit --no-verify` if needed. +- It stages tracked changes under each package after auto-fixing. + This project has tests for individual packages as `*.spec.js` files and inside of each's package's `src` directory. Also, for verifying the behavior with the real Slack server-side and developer experience with installed packages, you can run the tests amd scripts under `prod-server-integration-tests`. Refer to the README file in the directory for details. These tests are supposed to be run in the project maintainers' manual execution. They are not part of CI builds for now. Upon opening a PR, tests are executed by GitHub Actions, our continuous integration system. GitHub Actions runs several, more granular builds in order to report on success and failure in a more targeted way. From 788916b3df0f79678cde7fe90c2652f2ced64061 Mon Sep 17 00:00:00 2001 From: zi0w Date: Wed, 28 Jan 2026 00:09:44 +0900 Subject: [PATCH 2/3] chore: simplify pre-commit hook --- .githooks/pre-commit | 70 ++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 48 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 527ba178e..7dbea61fc 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,54 +1,28 @@ #!/bin/sh set -e -changed_paths=$(git diff --name-only --cached --diff-filter=ACMR) -if [ -z "$changed_paths" ]; then - exit 0 -fi +cd "$(git rev-parse --show-toplevel)" || exit 1 -repo_root=$(git rev-parse --show-toplevel 2>/dev/null) -if [ -z "$repo_root" ]; then - exit 1 -fi - -cd "$repo_root" - -packages="" -for path in $changed_paths; do - case "$path" in - packages/*/*) - pkg=${path#packages/} - pkg=${pkg%%/*} - case " $packages " in - *" $pkg "*) ;; - *) packages="$packages $pkg" ;; - esac - ;; - esac -done +pkgs=$(git diff --cached --name-only --diff-filter=ACMR -- 'packages/*/*' \ + | cut -d/ -f2 | sort -u) + +[ -z "$pkgs" ] && exit 0 + +for pkg in $pkgs; do + dir="packages/$pkg" + [ -f "$dir/package.json" ] || continue -if [ -z "$packages" ]; then - exit 0 -fi - -run_lint() { - pkg_dir="$1" - pkg_json="$repo_root/$pkg_dir/package.json" - - if node -e "const p=require(process.argv[1]);process.exit(p.scripts&&p.scripts['lint:fix']?0:1)" "$pkg_json"; then - echo "[pre-commit] npm --prefix $pkg_dir run lint:fix" - npm --prefix "$pkg_dir" run lint:fix - elif node -e "const p=require(process.argv[1]);process.exit(p.scripts&&p.scripts.lint?0:1)" "$pkg_json"; then - echo "[pre-commit] npm --prefix $pkg_dir run lint -- --fix" - npm --prefix "$pkg_dir" run lint -- --fix - fi - - git add -u "$pkg_dir" -} - -for pkg in $packages; do - pkg_dir="packages/$pkg" - if [ -f "$pkg_dir/package.json" ]; then - run_lint "$pkg_dir" - fi + echo "[pre-commit] $dir" + + out="$(npm --prefix "$dir" run -s lint:fix 2>&1)" && { git add -u "$dir"; continue; } + + echo "$out" | grep -qi 'missing script:.*lint:fix' && { + out2="$(npm --prefix "$dir" run -s lint -- --fix 2>&1)" && { git add -u "$dir"; continue; } + echo "$out2" | grep -qi 'missing script:.*lint' && { echo "[pre-commit] no lint script, skipping"; continue; } + echo "$out2" >&2 + exit 1 + } + + echo "$out" >&2 + exit 1 done From c0d8de3eddecef7ac04fc532cb0035502f55ae9d Mon Sep 17 00:00:00 2001 From: zi0w Date: Wed, 28 Jan 2026 01:37:30 +0900 Subject: [PATCH 3/3] chore: show lint output in pre-commit hook --- .githooks/pre-commit | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 7dbea61fc..39d61d96e 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -14,15 +14,20 @@ for pkg in $pkgs; do echo "[pre-commit] $dir" - out="$(npm --prefix "$dir" run -s lint:fix 2>&1)" && { git add -u "$dir"; continue; } - - echo "$out" | grep -qi 'missing script:.*lint:fix' && { - out2="$(npm --prefix "$dir" run -s lint -- --fix 2>&1)" && { git add -u "$dir"; continue; } - echo "$out2" | grep -qi 'missing script:.*lint' && { echo "[pre-commit] no lint script, skipping"; continue; } - echo "$out2" >&2 - exit 1 - } - - echo "$out" >&2 + tmp="$(mktemp)" + if npm --prefix "$dir" run lint:fix 2>&1 | tee "$tmp"; then + rm -f "$tmp" + git add -u "$dir" + continue + fi + + if grep -qi 'missing script:.*lint:fix' "$tmp"; then + rm -f "$tmp" + npm --prefix "$dir" run lint -- --fix + git add -u "$dir" + continue + fi + + rm -f "$tmp" exit 1 -done +done \ No newline at end of file