Husky Git hooks: היכן נשברת הבדיקה לפני קומיט
ההוקים מקומטים, הלינטר עובר מקומית — אבל אצל חלק מהצוות הקומיט עובר בלי בדיקה אחת. סיבות טיפוסיות: תיקיית ההוקים לא הוגדרה דרך הגדרת נתיבים, הקובץ איבד הרשאת הרצה במעבר בין מערכות קבצים, התקנת התלויות ב-build מתבצעת עם סקריפטי build מושבתים. Husky הופך את git hooks בפרויקט לחלק מהמאגר, ולא להגדרה אישית של המפתח — אבל רק בהתקנה משוחזרת.
מחיר הכשלים בקומיט לא מתגלה מיד. הסגנון מתפצל בין הענפים, והרוויו הופך לוויכוח על עיצוב: שינויים אמיתיים הולכים לאיבוד בין שורות שעוצבו מחדש. שגיאות טיפוסים וסינטקס צפות כבר במיזוג, כשהמפתח עבר למשימה אחרת, ה-build אדום, והריליס נדחה.
המחצית השנייה של הכשלים — קונפיגורציה של ההוק עצמו. בדיקת pre-commit רצה על כל העץ במקום על הקבצים ה-staged: בפרויקט בינוני אלו עשרות שניות, ועקיפה דרך --no-verify הופכת להרגל. באינדקס חלקי (git add -p) הלינטר קורא את עותק העבודה, בעוד שלקומיט נכנסת הגרסה מהאינדקס — לא בדוקה. במאגר עם כמה חבילות ההוק המשותף מלנטט הכול.
על פי הערכות בתעשייה של תהליך הפיתוח, פגם שנתפס לפני ה-build עולה פי כמה פחות במאמץ עבודה מאותו פגם באינטגרציה. מפרקים איך זה נסגר: התקנה משוחזרת של הוקים, בדיקה בדיוק של השורות שנכנסות לקומיט, ותגובה בתוך כמה שניות.
מה נותנת בדיקת קוד אוטומטית לפני שליחה
משוב בשניות במקום המתנה לרוויו
לינטר לפני קומיט ובדיקת טיפוסים רצים מקומית בשניות — המפתח לומד על השגיאה לפני שהקוד יוצא לענף המשותף. קודם אותה שגיאה צפה ב-build או ברוויו אחרי כמה שעות, והזמן הלך על החלפת קונטקסט. משוב מהיר מקצר את מחזור התיקון משעות לדקות.
סגנון אחיד ופחות תיקונים במיזוג ענפים
בדיקת קוד אוטומטית מקבעת עיצוב, סדר importים וכללי שמות לפני המיזוג, ולכן תיקונים שנויים במחלוקת ברוויו נעלמים. שיעור ההערות הנוגעות לסגנון יורד כמעט לאפס — הדיון עובר ללוגיקה ולארכיטקטורה. סגנון קוד אחיד מסיר גם חלק מהקונפליקטים במיזוג: פערי עיצוב מפסיקים לייצר הבדלים מדומים בקבצים.
ה-build מפסיק ליפול על זוטות
הבדיקות חוסמות את מה שקודם שבר את ה-build: טיפוסים לא סגורים, פלטי דיבוג נשכחים, תלויות שאינן בשימוש. שיעור כשלי ה-build יורד פי כמה, והזמן שהתפנה עובר למשימות ולא לניתוח שגיאות כתיב של אחרים. גם היקף התיקונים החוזרים באותו קובץ יורד — הכלל פועל פעם אחת ועובד לכל הצוות.
ההוקים ש-Husky מפעיל מוגדרים עבור המאגר הספציפי: תיקיות כבדות מוחרגות מהבדיקה, ולתיקון דחוף נשארת עקיפה מפורשת. הכללים חיים בפרויקט עצמו, ולכן עובדים באופן זהה אצל כולם — וגם אצל מפתח חדש מהיום הראשון.
דרכי חיבור של בדיקות: מקומית, ב-build, במאגר
ניתן להפעיל בדיקות בשלוש רמות: על מכונת המפתח, בקו ה-build ובמאגר המשותף. הרמות לא מחליפות זו את זו — הן תופסות סוגים שונים של הפרות: משגיאת כתיב בקומיט ועד לדליפת סוד לענף המשותף. להלן — מה נותנת כל אפשרות ומתי היא מספיקה.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| הוקים מקומיים על מכונת העבודה | צוות של 2-10 אנשים, סטאק אחיד, תלויות מותקנות מהמניפסט בעת השיבוט | עקיפה דרך --no-verify, שיבוט טרי בלי התקנת תלויות, סביבה שונה אצל המשתתפים |
| בדיקה בצד ה-build | כמה צוותים, ענפים ארוכים, בדיקות חובה לפני מיזוג | המשוב מגיע מאוחר יותר — לא שניות אלא דקות; עם ריבוי ענפים מצטבר תור משימות |
| בקרה במאגר המשותף | כללים אחידים לכולם, הגנה על ענפי ריליס ותגים | נדרשות הרשאות הגדרה, חלק מהבדיקות משכפל מקומיות, קשה יותר לשנות כללים נקודתית |
מתי בקרה מקומית מספיקה
כל עוד הכללים נוגעים לפורמט, ללינטר ולהודעות קומיט, הוקים מקומיים יספיקו — הם נותנים משוב בשניות, לפני שהקוד יצא לענף המשותף. מספיק שהתלויות יותקנו בשלב התקנת החבילות, ולא בפקודה נפרדת שמפתח חדש ישכח להריץ.
מתי נדרשת בקרה בצד ה-build
ברגע שבמאגר יש כמה צוותים או ענפי ריליס, הבקרה המקומית מפסיקה להיות ערובה: דגל העקיפה לא בוטל. אז אותן בדיקות משוכפלות ב-build והופכות לתנאי חובה למיזוג — הפרה לא עוברת הלאה, גם אם עקפו אותה על המכונה. ההוקים המקומיים נשארים: הם חוסכים זמן, ואילו ה-build מגנים על הענף המשותף.
הטמעת Git hooks: שלבי עבודה הנדסית על הפרויקט
הטמעת git hooks מתחילה לא בהתקנת Husky, אלא באודיט של המאגר: בודקים אילו בדיקות כבר קיימות על שרת ה-build, כמה ענפים חיים לאורך זמן, והיכן הכללים המוצהרים סוטים מהקוד בפועל.
לפי התוצאות מרכיבים תוכנית עבודה שבה כל הוק קשור לסוג שגיאה קונקרטי, ולא ל"צריך לבדוק הכול" מופשט. להלן — שלבי ההגדרה מהאודיט ועד למסירה לצוות.
מה עושים בכל שלב
- אודיט של המאגר: מלאי של לינטרים, מפרמטים ובדיקות, איתור כפילויות עם ה-CI, ומדידת זמני ההרצה.
- סכימת ההוקים: commit-msg אחראי על פורמט ההודעה, pre-commit — על הקבצים באינדקס, pre-push — על טיפוסים ובדיקות מהירות.
- הגדרת סביבת הצוות: תלויות וסקריפט prepare במניפסט — ההוקים מותקנים בעת ההתקנה, בלי צעדים ידניים בכל מכונה.
- חיבור בדיקות סגנון וטיפוסים: קונפיגים משותפים, כך שהעורך, ההוקים ושרת ה-build קוראים ממקור כללים אחד.
- דיבוג על ענפים אמיתיים: ענף ארוך, שינוי שם המוני, מיזוג — בודקים זמן בדיקה וחיכוך בקומיטים תכופים.
- בדיקת התנהגות בעקיפה: מה קורה עם
--no-verify, מה נכנס להיסטוריה במקרה כזה ואיך שרת ה-build תופס זאת. את העקיפה לא אוסרים, אבל הופכים אותה לבולטת. - מסירה והדרכה: הוראות להרצה ידנית, עדכון קונפיגים וטיפול בהתראות, ומפגש קצר עם הצוות.
נקודות תיאום עם הצוות
מתאמים את הרכב ההוקים ואת סף הקפדנות: מה חוסם קומיט ומה נותן אזהרה. בנפרד קובעים מי הבעלים של הקונפיגים ואיך מבצעים תיקונים — אחרת הכללים מתפצלים בין המכונות לשרת ה-build תוך כמה שבועות.
החבילה בפלט: קונפיגורציות, סכימות, נהלים, תיעוד
את החבילה מרכיבים כך שמהנדס חדש ייכנס לעבודה בלי הסברים בעל פה, והכללים יחיו במאגר ולא בהתכתבות. להלן — מה בדיוק מועבר ללקוח יחד עם Git hooks מוגדרים.
תיעוד טכני
- קבצי קונפיגורציה של בדיקות: הגדרות ההוקים והמנתחים הקשורים במאגר, עם הערות לכל כלל וסימון מה נבדק בקומיט ומה — לפני שליחה לענף המשותף.
- סכימת מעבר הקומיט בשלבים: מתיקון בעותק העבודה ועד המיזוג — אילו בדיקות רצות, מה קורה בשגיאה ואיך נראית מעבר תקין בלי עקיפה.
- מפת התיעוד של הפרויקט: היכן נמצאים כללי הסגנון, קונפיגורציית הבדיקות ואיך הם קשורים להגדרות המקומיות של המהנדס.
נהלים והוראות לצוות
- נהל פיתוח: כללי שמות לענפים ולהודעות, פורמט הכותרת והגוף, דרישות לפיצול שינויים לקומיטים אטומיים.
- מדיניות עקיפת בדיקות: מתי מותר דילוג חירום, מי מאשר אותו, מה נשאר בהיסטוריה ואיך חוקרים את האירוע אחרי.
- הוראות למפתחים חדשים: התקנה שלב אחר שלב של הסביבה, קומיט ראשון, שגיאות טיפוסיות ודרכי תיקונן.
- נהל עדכון כללים: מי מבצע שינויים בקונפיגורציית הבדיקות, איך מתבצע התיאום ואיך מוודאים שהכללים החדשים לא חוסמים את עבודת הצוות.
קייס: בדיקה לפני קומיט במקום כשלים בענף הראשי
היה ונהיה במספרים
לפני הטמעת הבדיקות בצד המפתח, הענף הראשי התקמפל כמו מזל. לפי הלוגים של שרת ה-build: 34% מההרצות נפלו בשלב הלינטר והבדיקות — כמעט כל שלישית; המשוב הראשון הגיע בממוצע אחרי 11 דקות, ובתיקוני עיצוב ההמתנה התארכה עד חצי שעה. החזרות של משימה לעבודה אחרי רוויו היו באותו שיעור — התיקונים הגיעו כבר אחרי ההרצה על השרת.
אחרי העברת הבדיקות הבסיסיות למחזור המקומי דרך Husky, שיעור כשלי ה-build בענף הראשי ירד ל-6%, המשוב הראשון מגיע תוך 30-40 שניות על אותה קבוצת בדיקות, והחזרות לעבודה הצטמצמו למשימה אחת מתוך שתים עשרה. הבדיקות רצות על קבצים שהשתנו, ולא על כל המאגר, ולכן ההמתנה נשארת קצרה גם על בסיס קוד גדול.
מה עשינו ומה השתנה
הגדרנו הוק pre-commit לעיצוב וללינטר עם תיקון אוטומטי, ולהוק pre-push העברנו בדיקות יחידה על המודולים שנגעו בהם ובדיקת טיפוסים. תרחישים כבדים הושארו על שרת ה-build, כדי שהמחזור המקומי לא יהפוך להמתנה.
קונפיגורציית ההוקים נמצאת במאגר ומתפרסת יחד עם התקנת התלויות — מהנדס חדש מקבל את אותם כללים ביום הראשון, בלי הסכמות בעל פה.
גם נתיב העקיפה סגור: הוקים משותפים בצד השרת מתעלמים מהקלות מקומיות, וכל שינוי בקונפיגורציה עובר רוויו כמו קוד רגיל. בעת הצורך ההוק מוסר בפקודה אחת, ההיסטוריה של השינויים נשמרת — חזרה למצב הקודם לא דורשת build מחדש של הפרויקט.
מה לעשות אם הבדיקות כבר מוגדרות חלקית בפרויקט?
הוקים שמוגדרים חלקית הם נורמה, לא חריג: בדרך כלל בפרויקט כבר עומד Husky עם לינטר בשלב pre-commit, ועוד כמה סקריפטים מקומיים ובדיקה משוכפלת בקו השרת. מתחילים במלאי: רושמים כל כלל, את שלב ההרצה שלו, את זמן העבודה והקבצים המושפעים. בלי מפה כזו כל תיקון בקונפיגורציה הופך לניחוש למה אצל מהנדס אחד הקומיט עובר ואצל אחר נופל.
בהמשך מפרקים את הכללים לקבוצות. המהירים — עיצוב, לינטר, בדיקת טיפוסים על קבצים שהשתנו — נשארים בשלב הקומיט. הכבדים — build, בדיקות, בדיקת תלויות — עוברים לשלב ה-pre-push או לשרת. כפילויות מסירים לטובת מקור אמת אחד: כלל שחי בשלושה מקומות מתפצל בגרסאות בתיקון הראשון.
מעבר בלי לעצור את העבודה נבנה על מצב אזהרה: כלל חדש קודם מדפיס הערה אבל לא חוסם את הקומיט, והופך לחוסם אחרי תקופת תצפית, כשמספר ההתראות פוחת. כך הצוות לא עובר לעקיפה דרך דילוג בדיקות ולא מאבד את הקצב הרגיל.
הגירת הבדיקות דורשת המשכיות: סקריפטים מקומיים מוסרים רק אחרי שהתנהגותם שוחזרה בקונפיגורציה המשותפת, והשינויים נעשים בקומיט אחד שאפשר להחזיר כולו לאחור. חריגים לנתיבים מסוימים נשמרים בקבצי חריגים, ולא בגוף ההוק. הפקודות מורצות דרך מעטפת משותפת — ואז ההתנהגות זהה בכל הפלטפורמות וצפויה בזמן.
ספקות טכניים לפני הטמעת בדיקות בפרויקט
לפני הפעלת ההוקים בתהליך המשותף צפים אצל הצוותים אותם ספקות: האם יעקפו את הבדיקה, האם הקומיט יתחיל לקחת דקות, איך זה מסתדר עם המאגר המשותף. להלן — תשובות קצרות למה ששואלים הכי הרבה.
אפשר לעקוף את הבדיקה ואיך עוקבים אחרי זה?
הדגל --no-verify מכבה הוקים לקומיט אחד, ואי אפשר לאסור אותו בצד המפתח. לכן כללים קריטיים משוכפלים בבדיקה על שרת ה-build: מקומית הם נותנים משוב מהיר, ובאינטגרציה הם פועלים כמחסום חובה. קומיטים שעברו בלי בדיקה נראים בהיסטוריה — זה נושא לדיון, לא אנונימי.
האם זה יאט את העבודה בפרויקט גדול?
מה שמאט זה לא ההוק, אלא הרצה נאיבית של כל הכללים על כל העץ. הבדיקות רצות רק על קבצים שהשתנו עם מטמון תוצאות, ולכן בפרויקט של עשרות אלפי קבצים הקומיט נשאר בתוך שניות. הרצות כבדות מעבירים ל-pre-push או לשרת.
יש לנו מאגר משותף, ולכל אחד הגדרות משלו
את הקונפיגורציה שומרים במאגר, ולא בהגדרות מקומיות: אחרי השיבוט סקריפט prepare קולט אותה, ואצל משתתף חדש הכללים מופיעים מיד. ניסויים אישיים מובלים בנתיב נפרד דרך core.hooksPath, כדי שלא יתפצלו מהמערכת המשותפת.
מי מתחזק את הכללים כשהקוד מתפתח?
הכללים נמצאים לצד הקוד ומתעדכנים באותו תיקון כמו הקוד: הארכיטקטורה משתנה — גם הבדיקות משתנות. אחת לרבעון עורכים רוויזיה ומסירים כללים שהפסיקו לתפוס שגיאות, אחרת ההוקים רק מאטים את הקומיטים.
נדבר על המשימה ונחזור עם הערכה ותוכנית עבודה
כדי שההערכה תהיה מדויקת, ולא "פחות או יותר", כדאי להתחיל את השיחה עם נתוני פתיחה על הפרויקט. הגדרת Husky והוקים ב-pre-commit וב-pre-push היא משימה שבה התוצאה תלויה בפרטים: כמה מפתחים בצוות, אילו בדיקות כבר קיימות וכמה נמשך build מלא על מכונת המפתח.
מה כדאי לשלוח מראש:
- מבנה המאגר: מונורפו או מערכת חבילות קשורות;
- בדיקות נוכחיות — לינטר, טיפוסים, בדיקות, עיצוב — ומה מהן רץ ידנית;
- הרכב הצוות ואופן העבודה: כמה אנשים ובאיזו תדירות מבוצעים קומיטים;
- כאבים בתהליך: בדיקות איטיות, קונפליקטים במיזוג, עקיפת כללים דרך דגל הדילוג;
- דרישות אבטחה: קונטור סגור, איסור שליחת קוד לשירותים חיצוניים;
- לוחות זמנים רצויים ונקודות שאליהן צריך להגיע;
- סדר הגישה למאגר ומסירת הפרויקט, אם עובדים בצד שלכם.
לפי נתוני הפתיחה האלה אנחנו חוזרים עם הערכה ותוכנית עבודה: מה עושים ראשון, מה אפשר לדחות, ואיך בודקים את התוצאה בכל שלב. תארו את המשימה בפורמט נוח — נחזור עם הערכה, תוכנית וסדר מסירת הפרויקט לצוות שלכם.







