@ministryofjustice/hmpps-precommit-hooks 1.0.2 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,21 @@
1
1
  # @ministryofjustice/hmpps-precommit-hooks
2
2
 
3
- This package aims to automatically install and configure husky with gitleaks to help catch potential secrets before committing them to github.
3
+ This package aims to automatically install and configure pre-commit hooks using [prek](https://github.com/pre-commit/pre-commit) to help catch potential secrets and code quality issues before committing them to github.
4
4
 
5
5
  ## Status
6
6
 
7
7
  **This library is currently: ready to adopt.**
8
8
  Teams are welcome to use this library. Please provide feedback via slack to the `#typescript` channel.
9
9
 
10
+ ## Migration from Husky
11
+
12
+ This package has migrated from using Husky to using [prek](https://github.com/pre-commit/pre-commit) (pre-commit) for managing git hooks. The migration will happen automatically during `npm install`:
13
+
14
+ - Husky will be uninstalled if present
15
+ - Existing husky hooks will be removed
16
+ - prek will be installed via Homebrew (if not already installed)
17
+ - A `.pre-commit-config.yaml` file will be created with the default hooks configuration
18
+
10
19
  ## Migrating existing projects
11
20
 
12
21
  #### Automatically installing the library
@@ -19,35 +28,68 @@ Once the project has been initialised, other developers should be able to develo
19
28
 
20
29
  ### How this works
21
30
 
22
- Initialising will add new precommit scripts and a new prepare script in `package.json`:
31
+ Initialising will add a new prepare script in `package.json`:
23
32
 
24
33
  ```json
25
34
  "scripts": {
26
35
  //...
27
- "prepare": "hmpps-precommit-hooks",
28
- "precommit:secrets": "gitleaks git --pre-commit --redact --staged --verbose",
29
- "precommit:lint": "node_modules/.bin/lint-staged",
30
- "precommit:verify": "npm run typecheck && npm test"
36
+ "prepare": "hmpps-precommit-hooks"
31
37
  }
32
38
  ```
33
39
 
34
- It will also configure a husky precommit hook using these scripts:
35
-
36
- ```sh
37
- #!/bin/bash
38
- NODE_ENV=dev \
39
- npm run precommit:secrets \
40
- && npm run precommit:lint \
41
- && npm run precommit:verify
40
+ The package will create a `.pre-commit-config.yaml` file in your project root that configures the hooks to run:
41
+
42
+ ```yaml
43
+ HMPPS_HOOKS_VERSION: 1
44
+
45
+ repos:
46
+ - repo: local
47
+ hooks:
48
+ - id: gitleaks
49
+ name: Scan commit for secrets
50
+ language: system
51
+ entry: gitleaks git --pre-commit --redact --staged --verbose --config .gitleaks/config.toml --gitleaks-ignore-path .gitleaks/.gitleaksignore
52
+ - id: lint
53
+ name: linting code
54
+ language: system
55
+ entry: npm run lint
56
+ - id: typecheck
57
+ name: verify types
58
+ language: system
59
+ entry: npm run typecheck
60
+ - id: test
61
+ name: running tests
62
+ language: system
63
+ entry: npm run test
64
+ - repo: builtin
65
+ hooks:
66
+ - id: end-of-file-fixer
67
+ - id: trailing-whitespace
68
+ - id: check-json
69
+ - id: check-yaml
70
+ - id: check-merge-conflict
42
71
  ```
43
72
 
44
- The prepare script will trigger on any install and ensure that `gitleaks` is installed and `husky` is initiated.
73
+ The prepare script will trigger on any install and ensure that `prek` (pre-commit) is installed via Homebrew.
74
+
75
+ Note: `prek` is installed by `brew`. If `brew` is not available, `prepare` will display a message indicating you need to install prek manually.
45
76
 
46
- Note: `gitleaks` is installed by `brew`, if `brew` is not available then `prepare` will currently fail loudly and display a message.
77
+ **Important:** The `.pre-commit-config.yaml` file will only be created if it doesn't exist. Once created, it will not be overwritten, allowing you to customize hooks for your project's needs. Legacy precommit scripts (`precommit:secrets`, `precommit:lint`, `precommit:verify`) will be automatically removed from `package.json` when the config file is created.
47
78
 
48
79
  ### Prevent precommit script initialising on prepare
49
80
 
50
- To disable the tool running on `npm install` and initialising husky and installing gitleaks, you can pass the `SKIP_PRECOMMIT_INIT=true` env var.
81
+ To disable the tool running on `npm install` and initialising prek, you can pass the `SKIP_PRECOMMIT_INIT=true` env var.
82
+
83
+ ### Customizing hooks
84
+
85
+ You can modify the `.pre-commit-config.yaml` file in your project to:
86
+
87
+ - Add additional hooks
88
+ - Remove hooks that don't apply to your project
89
+ - Modify hook configurations
90
+ - Add hooks from external repositories
91
+
92
+ See the [pre-commit documentation](https://pre-commit.com/) for more details on hook configuration.
51
93
 
52
94
  ### Dealing with false positives
53
95
 
@@ -67,6 +109,21 @@ Repo specific rules can be added by teams in `.gitleaks/config.toml` in their in
67
109
 
68
110
  See the gitleaks documentation for how to create rules and [examples](https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml) or use the [online rule wizard](https://gitleaks.io/playground).
69
111
 
112
+ ### Running hooks manually
113
+
114
+ You can run all hooks manually using:
115
+
116
+ ```bash
117
+ prek run --all-files
118
+ ```
119
+
120
+ Or run specific hooks:
121
+
122
+ ```bash
123
+ prek run gitleaks
124
+ prek run lint
125
+ ```
126
+
70
127
  ### Testing that hooks are configured correctly
71
128
 
72
129
  Secret protection can be tested using the following command:
@@ -92,7 +149,7 @@ Attempting to commit file containing secret
92
149
  ○ ░
93
150
  ░ gitleaks
94
151
 
95
- Finding: fake_aws_key=REDACTED
152
+ Finding: fake__key=REDACTED
96
153
  Secret: REDACTED
97
154
  RuleID: aws-access-token
98
155
  Entropy: 3.546439
package/bin/init.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/bin/bash
2
2
  #
3
- # Used to install husky with gitleaks
3
+ # Used to install prek with gitleaks
4
4
  #
5
5
 
6
6
  set -euo pipefail
@@ -44,22 +44,13 @@ else
44
44
  npm --silent install
45
45
  fi
46
46
 
47
- startStage " * Adding npm scripts"
48
- npm pkg --silent set scripts.precommit:secrets="gitleaks git --pre-commit --redact --staged --verbose --config .gitleaks/config.toml --gitleaks-ignore-path .gitleaks/.gitleaksignore"
49
- npm pkg --silent set scripts.precommit:lint="node_modules/.bin/lint-staged"
50
- npm pkg --silent set scripts.precommit:verify="npm run typecheck && npm test"
51
- endStage " ✅"
47
+ # Copy default-hooks.yaml to target location
48
+ SOURCE_HOOKS="./node_modules/@ministryofjustice/hmpps-precommit-hooks/default-hooks.yaml"
49
+ TARGET_HOOKS=".pre-commit-config.yaml"
52
50
 
53
- startStage " * Setting precommit hook"
54
- mkdir -p .husky
55
- printf "%s\n" \
56
- "#!/bin/bash" \
57
- "NODE_ENV=dev \\" \
58
- "npm run precommit:secrets \\" \
59
- "&& npm run precommit:lint \\" \
60
- "&& npm run precommit:verify" \
61
- > .husky/pre-commit
62
- endStage " ✅"
51
+ startStage "Creating .pre-commit-config.yaml"
52
+ cp "$SOURCE_HOOKS" "$TARGET_HOOKS"
53
+ endStage ""
63
54
 
64
55
  startStage " * Creating .gitleaksignore "
65
56
  mkdir -p .gitleaks
package/bin/prepare.sh CHANGED
@@ -22,18 +22,58 @@ if [ "$CI" = "true" ] || [ "$SKIP_PRECOMMIT_INIT" = "true" ]; then
22
22
  exit 0
23
23
  fi
24
24
 
25
- # Initialise husky
26
- node_modules/.bin/husky
25
+
26
+ # Remove husky if installed
27
+ if [ -f "node_modules/.bin/husky" ]; then
28
+ startStage "Removing husky"
29
+ npm uninstall husky
30
+ endStage " ✅ "
31
+
32
+ if [ -f ".husky/pre-commit" ]; then
33
+ startStage "Deleting existing husky pre-commit hook"
34
+ rm .husky/pre-commit
35
+ endStage " ✅ "
36
+ fi
37
+ fi
27
38
 
28
39
  # Check brew exists
29
40
  if ! command -v brew > /dev/null 2> /dev/null; then
30
- printError "Brew is not installed. You will need to install gitleaks separately and ensure it's on your PATH. exiting..."
41
+ printError "Brew is not installed. You will need to install prek separately and ensure it's on your PATH. exiting..."
31
42
  exit 0
32
43
  fi
33
44
 
34
- # Initialise gitleaks
45
+ # Install gitleaks if not present - this will be used by prek for secret scanning until we move over to devsecops hooks
35
46
  if ! command -v gitleaks > /dev/null 2> /dev/null; then
36
47
  startStage "Installing gitleaks"
37
48
  brew install gitleaks
38
49
  endStage " ✅ "
39
50
  fi
51
+
52
+ # Install prek
53
+ if ! command -v prek > /dev/null 2> /dev/null; then
54
+ startStage "Installing prek"
55
+ brew install prek
56
+ endStage " ✅ "
57
+ fi
58
+
59
+ # Copy default-hooks.yaml to target location
60
+ SOURCE_HOOKS="./node_modules/@ministryofjustice/hmpps-precommit-hooks/default-hooks.yaml"
61
+ TARGET_HOOKS=".pre-commit-config.yaml"
62
+
63
+
64
+ if [ ! -f "$TARGET_HOOKS" ]; then
65
+ startStage "Creating .pre-commit-config.yaml"
66
+ cp "$SOURCE_HOOKS" "$TARGET_HOOKS"
67
+ endStage " ✅ "
68
+
69
+ startStage "Deleting existing precommit scripts"
70
+ npm pkg --silent delete scripts.precommit:secrets
71
+ npm pkg --silent delete scripts.precommit:lint
72
+ npm pkg --silent delete scripts.precommit:verify
73
+ endStage " ✅ "
74
+ fi
75
+
76
+ startStage "Initialising prek hooks on this repo"
77
+ git config --unset-all --local core.hooksPath || true
78
+ prek install
79
+ endStage " ✅ "
package/bin/test.sh CHANGED
@@ -3,11 +3,11 @@
3
3
  # Test that secret protection is set up correctly.
4
4
  # This will create a separate file ./demo-password.txt which will need to be deleted separately.
5
5
 
6
- RANDOM_NUMBER="$(LC_ALL=C tr -cd '[:digit:]' < /dev/urandom | fold -w 13 | head -n 1)"
7
- AWS_KEY="AKIA${RANDOM_NUMBER}ASD"
6
+ RANDOM_NUMBER="$(LC_ALL=C tr -cd '[:digit:]' < /dev/urandom | fold -w 10 | head -n 1)"
7
+ FAKE_KEY="sk-${RANDOM_NUMBER}abcdef"
8
8
 
9
- echo "Creating test file containing dummy AWS_KEY=${AWS_KEY}"
10
- echo "fake_aws_key=${AWS_KEY}" > ./demo-password.txt
9
+ echo "Creating test file containing dummy key: 'fake_key=${FAKE_KEY}'"
10
+ echo "fake_key=${FAKE_KEY}" > ./demo-password.txt
11
11
 
12
12
  echo "Attempting to commit file containing secret"
13
- git add ./demo-password.txt && git commit -m "This should fail due to detecting dummy AWS creds"
13
+ git add ./demo-password.txt && git commit -m "This should fail due to detecting dummy creds"
@@ -0,0 +1,48 @@
1
+ # Pre-commit hook configuration file
2
+ #
3
+ # This contains the list of hooks to be run before committing code.
4
+ # The devsecops-hooks baseline hook is temporarily disabled while we investigate issues with it but will eventually become compulsory.
5
+ # Other hooks maybe added or removed as needed to suit individual project requirements.
6
+
7
+ repos:
8
+ #. Temporary disabled while we investigate issues with it
9
+ # - repo: https://github.com/ministryofjustice/devsecops-hooks
10
+ # rev: v1.1.0
11
+ # hooks:
12
+ # - id: baseline
13
+ - repo: local
14
+ hooks:
15
+ - id: gitleaks
16
+ name: Scan commit for secrets
17
+ language: system
18
+ entry: gitleaks git --pre-commit --redact --staged --verbose --config .gitleaks/config.toml --gitleaks-ignore-path .gitleaks/.gitleaksignore
19
+ require_serial: true
20
+ pass_filenames: false
21
+ - id: lint
22
+ name: linting code
23
+ language: system
24
+ entry: npm run lint
25
+ types: [ts]
26
+ require_serial: true
27
+ pass_filenames: false
28
+ - id: typecheck
29
+ name: verify types
30
+ language: system
31
+ entry: npm run typecheck
32
+ types: [ts]
33
+ require_serial: true
34
+ pass_filenames: false
35
+ - id: test
36
+ name: running tests
37
+ language: system
38
+ entry: npm run test
39
+ types: [ts]
40
+ require_serial: true
41
+ pass_filenames: false
42
+ - repo: builtin
43
+ hooks:
44
+ - id: end-of-file-fixer
45
+ - id: trailing-whitespace
46
+ - id: check-json
47
+ - id: check-yaml
48
+ - id: check-merge-conflict
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ministryofjustice/hmpps-precommit-hooks",
3
- "version": "1.0.2",
3
+ "version": "2.0.0-beta.1",
4
4
  "description": "Precommit hooks for HMPPS typescript projects",
5
5
  "keywords": [
6
6
  "precommit"
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "publishConfig": {
16
16
  "access": "public",
17
- "tag": "latest"
17
+ "tag": "beta"
18
18
  },
19
19
  "bin": {
20
20
  "hmpps-precommit-hooks-prepare": "bin/prepare.sh",
@@ -27,7 +27,8 @@
27
27
  "files": [
28
28
  "*.md",
29
29
  "bin/*.sh",
30
- "config.toml"
30
+ "config.toml",
31
+ "default-hooks.yaml"
31
32
  ],
32
33
  "engines": {
33
34
  "node": "20 || 22 || 24"