Skip to content

Commit 0b8d1f6

Browse files
committed
CLOUDP-301527: Migrate from custom pre-commit to official pre-commit framework
This commit migrates from the custom .githooks/pre-commit bash script to the official pre-commit framework (https://pre-commit.com). Changes: - Add .pre-commit-config.yaml with all existing hooks migrated - Add .yamllint.yaml for YAML linting configuration - Create scripts/dev/generate_files.sh - extracted file generation logic - Create scripts/dev/regenerate_multicluster_rbac.sh - extracted RBAC regeneration - Simplify .githooks/pre-commit to delegate to pre-commit framework - Update scripts/evergreen/check_precommit.sh for CI integration - Update Makefile precommit targets - Add pre-commit to requirements.txt - Fix prepare-openshift-bundles-for-e2e.sh to call generate_files.sh directly - Fix validate_snippets.py to ignore git-ignored directories - Fix pyproject.toml isort config to use line_length=120 (matching black) Note: trailing-whitespace and end-of-file-fixer hooks are commented out for now (they modify 200+ files). These will be enabled in a follow-up PR.
1 parent ada6a0e commit 0b8d1f6

File tree

12 files changed

+541
-288
lines changed

12 files changed

+541
-288
lines changed

.githooks/pre-commit

Lines changed: 10 additions & 281 deletions
Original file line numberDiff line numberDiff line change
@@ -1,289 +1,18 @@
11
#!/usr/bin/env bash
2+
#
3+
# Git pre-commit hook that delegates to the pre-commit framework.
4+
# This file is kept for backwards compatibility with existing dev setups.
5+
#
6+
# To set up: git config core.hooksPath .githooks
7+
#
28

39
set -Eeou pipefail
410

511
source scripts/dev/set_env_context.sh
6-
source scripts/funcs/printing
712

8-
if [ -f "${PROJECT_DIR}"/venv/bin/activate ]; then
9-
source "${PROJECT_DIR}"/venv/bin/activate
13+
if [ -f "${PROJECT_DIR}/venv/bin/activate" ]; then
14+
source "${PROJECT_DIR}/venv/bin/activate"
1015
fi
1116

12-
if [[ -z "${EVERGREEN_MODE:-}" ]]; then
13-
# According to the latest SSDLC recommendations, the CI needs to always check all the files. Not just delta.
14-
git_last_changed=$(git ls-tree -r origin/master --name-only)
15-
else
16-
git_last_changed=$(git diff --cached --name-only --diff-filter=ACM origin/master)
17-
fi
18-
19-
mkdir -p "$(go env GOPATH)/bin"
20-
21-
update_mco_tests() {
22-
echo "Regenerating MCO evergreen tests configuration"
23-
python scripts/evergreen/e2e/mco/create_mco_tests.py >.evergreen-mco.yml
24-
git add .evergreen-mco.yml
25-
}
26-
27-
# Generates a yaml file to install the operator from the helm sources.
28-
generate_standalone_yaml() {
29-
HELM_OPTS=$@
30-
31-
charttmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'charttmpdir')
32-
charttmpdir=${charttmpdir}/chart
33-
mkdir -p "${charttmpdir}"
34-
35-
FILES=(
36-
"${charttmpdir}/mongodb-kubernetes/templates/operator-roles-base.yaml"
37-
"${charttmpdir}/mongodb-kubernetes/templates/operator-roles-clustermongodbroles.yaml"
38-
"${charttmpdir}/mongodb-kubernetes/templates/operator-roles-pvc-resize.yaml"
39-
"${charttmpdir}/mongodb-kubernetes/templates/operator-roles-telemetry.yaml"
40-
"${charttmpdir}/mongodb-kubernetes/templates/operator-roles-webhook.yaml"
41-
"${charttmpdir}/mongodb-kubernetes/templates/database-roles.yaml"
42-
"${charttmpdir}/mongodb-kubernetes/templates/operator-sa.yaml"
43-
"${charttmpdir}/mongodb-kubernetes/templates/operator.yaml"
44-
)
45-
46-
# generate normal public example
47-
helm template --namespace mongodb -f helm_chart/values.yaml helm_chart --output-dir "${charttmpdir}" ${HELM_OPTS[@]}
48-
cat "${FILES[@]}" >public/mongodb-kubernetes.yaml
49-
cat "helm_chart/crds/"* >public/crds.yaml
50-
51-
# generate openshift public example
52-
rm -rf "${charttmpdir:?}"/*
53-
helm template --namespace mongodb -f helm_chart/values.yaml helm_chart --output-dir "${charttmpdir}" --values helm_chart/values-openshift.yaml ${HELM_OPTS[@]}
54-
cat "${FILES[@]}" >public/mongodb-kubernetes-openshift.yaml
55-
56-
# generate openshift files for kustomize used for generating OLM bundle
57-
rm -rf "${charttmpdir:?}"/*
58-
helm template --namespace mongodb -f helm_chart/values.yaml helm_chart --output-dir "${charttmpdir}" --values helm_chart/values-openshift.yaml \
59-
--set operator.webhook.registerConfiguration=false --set operator.webhook.installClusterRole=false ${HELM_OPTS[@]}
60-
61-
# update kustomize files for OLM bundle with files generated for openshift
62-
cp "${charttmpdir}/mongodb-kubernetes/templates/operator.yaml" config/manager/manager.yaml
63-
cp "${charttmpdir}/mongodb-kubernetes/templates/database-roles.yaml" config/rbac/database-roles.yaml
64-
cp "${charttmpdir}/mongodb-kubernetes/templates/operator-roles-base.yaml" config/rbac/operator-roles-base.yaml
65-
cp "${charttmpdir}/mongodb-kubernetes/templates/operator-roles-clustermongodbroles.yaml" config/rbac/operator-roles-clustermongodbroles.yaml
66-
cp "${charttmpdir}/mongodb-kubernetes/templates/operator-roles-pvc-resize.yaml" config/rbac/operator-roles-pvc-resize.yaml
67-
cp "${charttmpdir}/mongodb-kubernetes/templates/operator-roles-telemetry.yaml" config/rbac/operator-roles-telemetry.yaml
68-
69-
# generate multi-cluster public example
70-
rm -rf "${charttmpdir:?}"/*
71-
helm template --namespace mongodb -f helm_chart/values.yaml helm_chart --output-dir "${charttmpdir}" --values helm_chart/values-multi-cluster.yaml ${HELM_OPTS[@]}
72-
cat "${FILES[@]}" >public/mongodb-kubernetes-multi-cluster.yaml
73-
74-
}
75-
76-
python_formatting() {
77-
# installing Black
78-
if ! command -v "black" >/dev/null; then
79-
pip install -r requirements.txt
80-
fi
81-
82-
echo "formatting isort"
83-
isort .
84-
echo "formatting black"
85-
black .
86-
}
87-
88-
generate_manifests() {
89-
make manifests
90-
91-
git add config/crd/bases
92-
git add helm_chart/crds
93-
git add public/crds.yaml
94-
}
95-
96-
update_values_yaml_files() {
97-
# ensure that all helm values files are up to date.
98-
# shellcheck disable=SC2154
99-
python scripts/evergreen/release/update_helm_values_files.py
100-
101-
# commit any changes we made
102-
git add helm_chart/values.yaml
103-
git add helm_chart/values-openshift.yaml
104-
105-
# these can change if the version of community operator is different
106-
git add go.mod
107-
git add go.sum
108-
}
109-
110-
update_release_json() {
111-
# ensure that release.json is up 2 date
112-
# shellcheck disable=SC2154
113-
python scripts/evergreen/release/update_release.py
114-
115-
# commit any changes we made
116-
git add release.json
117-
}
118-
119-
regenerate_public_rbac_multi_cluster() {
120-
if echo "$git_last_changed" | grep -q -e 'cmd/kubectl-mongodb' -e 'pkg/kubectl-mongodb'; then
121-
echo 'regenerating multicluster RBAC public example'
122-
pushd pkg/kubectl-mongodb/common/
123-
EXPORT_RBAC_SAMPLES="true" go test ./... -run TestPrintingOutRolesServiceAccountsAndRoleBindings
124-
popd
125-
git add public/samples/multi-cluster-cli-gitops
126-
fi
127-
}
128-
129-
update_licenses() {
130-
if [[ "${MDB_UPDATE_LICENSES:-""}" == "true" ]]; then
131-
echo 'regenerating licenses'
132-
time scripts/evergreen/update_licenses.sh 2>&1 | prepend "update_licenses"
133-
git add LICENSE-THIRD-PARTY
134-
fi
135-
}
136-
137-
check_erroneous_kubebuilder_annotations() {
138-
# Makes sure there are not erroneous kubebuilder annotations that can
139-
# end up in CRDs as descriptions.
140-
if grep "// kubebuilder" ./* -r --exclude-dir=vendor --include=\*.go; then
141-
echo -e "${RED}Found an erroneous kubebuilder annotation${NO_COLOR}"
142-
exit 1
143-
fi
144-
}
145-
146-
check_incorrect_makefile_variable_brackets() {
147-
if find . -name "Makefile" | grep -v vendor | xargs grep "\${"; then
148-
echo -e "${RED}ERROR: Makefiles should NEVER contain curly brackets variables${NO_COLOR}"
149-
exit 1
150-
fi
151-
}
152-
153-
update_jobs() {
154-
# Update release.json first in case there is a newer version
155-
time update_release_json
156-
# We need to generate the values files first
157-
time update_values_yaml_files
158-
# The values files are used for generating the standalone yaml
159-
time generate_standalone_yaml
160-
}
161-
162-
lint_code() {
163-
scripts/evergreen/lint_code.sh
164-
}
165-
166-
lint_helm_chart() {
167-
scripts/dev/lint_helm_chart.sh
168-
}
169-
170-
function validate_snippets() {
171-
scripts/code_snippets/validate_snippets.py
172-
}
173-
174-
# bg_job_ vars are global; run_job_in_background function is appending to them on each call
175-
bg_job_pids=()
176-
bg_job_pids_with_names=()
177-
178-
get_job_name() {
179-
local search_pid="$1"
180-
local match
181-
match=$(printf '%s\n' "${bg_job_pids_with_names[@]}" | grep "^${search_pid}:")
182-
echo "${match#*:}" # Remove everything up to and including the colon
183-
}
184-
185-
# Executes function given on the first argument as background job.
186-
# It's ensuring logs are properly prefixed by the name and
187-
# the job's pid is captured in bg_jobs array in order to wait for completion.
188-
run_job_in_background() {
189-
job_name=$1
190-
time ${job_name} 2>&1 | prepend "${job_name}" &
191-
192-
local job_pid=$!
193-
bg_job_pids+=("${job_pid}")
194-
bg_job_pids_with_names+=("${job_pid}:${job_name}")
195-
echo "Started ${job_name} with PID: ${job_pid}"
196-
}
197-
198-
# Waits for all background jobs stored in bg_job_pids and check their exit codes.
199-
wait_for_all_background_jobs() {
200-
failures=()
201-
for pid in "${bg_job_pids[@]}"; do
202-
wait "${pid}" || {
203-
job_name=$(get_job_name "${pid}")
204-
failures+=(" ${RED}${job_name} (PID ${pid})${NO_COLOR}")
205-
}
206-
done
207-
208-
if [[ ${#failures[@]} -gt 0 ]]; then
209-
echo -e "${RED}Some checks have failed:${NO_COLOR}"
210-
for failure in "${failures[@]}"; do
211-
echo -e "$failure"
212-
done
213-
echo -e "${RED}To see the details look/filter for the job's logs by it's prefixed name (e.g. \"start_shellcheck:\", \"lint_code:\", \"shellcheck failed\").${NO_COLOR}"
214-
return 1
215-
fi
216-
217-
return 0
218-
}
219-
220-
pre_commit() {
221-
run_job_in_background "update_jobs"
222-
run_job_in_background "update_licenses"
223-
run_job_in_background "lint_code"
224-
run_job_in_background "start_shellcheck"
225-
run_job_in_background "regenerate_public_rbac_multi_cluster"
226-
run_job_in_background "python_formatting"
227-
run_job_in_background "check_erroneous_kubebuilder_annotations"
228-
run_job_in_background "validate_snippets"
229-
230-
if wait_for_all_background_jobs; then
231-
# lint_helm_chart must be run after all the background jobs are finished because one of the BG jobs (update_jobs)
232-
# updates the helm chart. And lint_helm_chart requires the helm chart to be updated already.
233-
lint_helm_chart
234-
235-
local lint_helm_chart_status=$?
236-
if [ "$lint_helm_chart_status" -eq 0 ]; then
237-
echo -e "${GREEN}pre-commit: All checks passed!${NO_COLOR}"
238-
return 0
239-
else
240-
return 1
241-
fi
242-
else
243-
return 1
244-
fi
245-
}
246-
247-
# Function to run shellcheck on a single file
248-
run_shellcheck() {
249-
local file="$1"
250-
251-
local diff_output
252-
diff_output=$(shellcheck -f diff "$file" -e SC2154 -e SC1091 -e SC1090 -e SC2148 -o require-variable-braces -P "scripts" 2>&1)
253-
254-
if [[ -n "$diff_output" && "$diff_output" != *"Issues were detected, but none were auto-fixable"* ]]; then
255-
echo "$diff_output" | git apply
256-
echo "Applied auto-fixes for $file"
257-
elif [[ "$diff_output" == *"Issues were detected, but none were auto-fixable"* ]]; then
258-
echo -e "${RED}shellcheck failed on $file${NO_COLOR}"
259-
shellcheck --color=always -x "$file" -e SC2154 -e SC1091 -e SC1090 -e SC2148 -o require-variable-braces -P "scripts"
260-
return 1
261-
fi
262-
}
263-
264-
# Export function so it's available in subshells (for xargs)
265-
export -f run_shellcheck
266-
267-
start_shellcheck() {
268-
# shellcheck disable=SC2016
269-
{
270-
find scripts -type f -name "*.sh"
271-
find scripts/dev/contexts -type f | grep -v private-context
272-
find scripts/funcs -type f
273-
find public/architectures -type f -name "*.sh"
274-
find docs/ -type f -name "*.sh"
275-
} | xargs -I {} -P 20 bash -c 'run_shellcheck "$1"' _ {}
276-
}
277-
278-
cmd=${1:-"pre-commit"}
279-
280-
if [[ "${cmd}" == "generate_standalone_yaml" ]]; then
281-
shift 1
282-
generate_standalone_yaml "$@"
283-
elif [[ "${cmd}" == "pre-commit" ]]; then
284-
time pre_commit
285-
elif [[ "${cmd}" == "shellcheck" ]]; then
286-
start_shellcheck
287-
elif [[ "${cmd}" == "lint" ]]; then
288-
lint_code
289-
fi
17+
# Run pre-commit framework
18+
exec pre-commit run --all-files

0 commit comments

Comments
 (0)