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

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Change log
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Breaking Changes
6
+
7
+ - **Migrated from Husky to prek (pre-commit)** for managing git hooks
8
+ - Husky is automatically uninstalled during `npm install` if present
9
+ - Existing husky hooks are automatically removed
10
+ - prek is installed via Homebrew
11
+
12
+ ### New Features
13
+
14
+ - Added `.pre-commit-config.yaml` configuration file with default hooks
15
+ - Configuration file is only created if it doesn't exist, preserving custom configurations
16
+ - Added automatic cleanup of legacy precommit scripts (`precommit:secrets`, `precommit:lint`, `precommit:verify`) from package.json
17
+
18
+ ### Changes
19
+
20
+ - `prepare` script now installs prek instead of configuring husky
21
+ - Hooks are now managed through `.pre-commit-config.yaml` instead of husky scripts
22
+
3
23
  ## 1.0.2
4
24
 
5
25
  Fix versions, accidentally mixed 1.0.0 and 0.1.0
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` via a prepare hook:
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
+ - repo: https://github.com/ministryofjustice/devsecops-hooks
49
+ rev: v1.x.x
50
+ hooks:
51
+ - id: baseline
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,34 @@ 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
+ ### Keeping up to date
113
+
114
+ `prek auto-update` can be used to pull in later versions of hooks including the devsecops-hooks.
115
+
116
+ Also, a manager can be added to your renovate.json config to allow renovate to raise PRs to keep hooks up to date:
117
+
118
+ ```json
119
+ {
120
+ "matchManagers": ["pre-commit"],
121
+ "groupName": "all pre-commit dependencies"
122
+ }
123
+ ```
124
+
125
+ ### Running hooks manually
126
+
127
+ You can run all hooks manually using:
128
+
129
+ ```bash
130
+ prek run --all-files
131
+ ```
132
+
133
+ Or run specific hooks:
134
+
135
+ ```bash
136
+ prek run gitleaks
137
+ prek run lint
138
+ ```
139
+
70
140
  ### Testing that hooks are configured correctly
71
141
 
72
142
  Secret protection can be tested using the following command:
@@ -92,7 +162,7 @@ Attempting to commit file containing secret
92
162
  ○ ░
93
163
  ░ gitleaks
94
164
 
95
- Finding: fake_aws_key=REDACTED
165
+ Finding: fake__key=REDACTED
96
166
  Secret: REDACTED
97
167
  RuleID: aws-access-token
98
168
  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,50 @@ 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 hooks"
34
+ rm -Rf .husky
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
35
- if ! command -v gitleaks > /dev/null 2> /dev/null; then
36
- startStage "Installing gitleaks"
37
- brew install gitleaks
45
+ # Install prek
46
+ if ! command -v prek > /dev/null 2> /dev/null; then
47
+ startStage "Installing prek"
48
+ brew install prek
49
+ endStage " ✅ "
50
+ fi
51
+
52
+ SOURCE_HOOKS="./node_modules/@ministryofjustice/hmpps-precommit-hooks/default-hooks.yaml"
53
+ TARGET_HOOKS=".pre-commit-config.yaml"
54
+
55
+ # Copy default-hooks.yaml to target location for first time initialisation only
56
+ if [ ! -f "$TARGET_HOOKS" ]; then
57
+ startStage "Creating .pre-commit-config.yaml"
58
+ cp "$SOURCE_HOOKS" "$TARGET_HOOKS"
59
+ endStage " ✅ "
60
+
61
+ startStage "Deleting existing precommit scripts"
62
+ npm pkg --silent delete scripts.precommit:secrets
63
+ npm pkg --silent delete scripts.precommit:lint
64
+ npm pkg --silent delete scripts.precommit:verify
38
65
  endStage " ✅ "
39
66
  fi
67
+
68
+ startStage "Initialising prek hooks on this repo"
69
+ git config --unset-all --local core.hooksPath || true
70
+ prek install
71
+ 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,41 @@
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
+ - repo: https://github.com/ministryofjustice/devsecops-hooks
9
+ rev: v1.3.0
10
+ hooks:
11
+ - id: baseline
12
+ - repo: local
13
+ hooks:
14
+ - id: lint
15
+ name: linting code
16
+ language: system
17
+ entry: ./node_modules/.bin/lint-staged
18
+ types_or: [ts,javascript,css]
19
+ require_serial: true
20
+ pass_filenames: false
21
+ - id: typecheck
22
+ name: verify types
23
+ language: system
24
+ entry: npm run typecheck
25
+ types: [ts]
26
+ require_serial: true
27
+ pass_filenames: false
28
+ - id: test
29
+ name: running tests
30
+ language: system
31
+ entry: npm run test
32
+ types: [ts]
33
+ require_serial: true
34
+ pass_filenames: false
35
+ - repo: builtin
36
+ hooks:
37
+ - id: end-of-file-fixer
38
+ - id: trailing-whitespace
39
+ - id: check-json
40
+ - id: check-yaml
41
+ - 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.3",
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"