בניית מונורפו: היכן מתבזבז הזמן של הצוות
מונורפו מתחיל כפתרון נוח: ספריות משותפות יושבות לצד השירותים, כללי בדיקת הקוד אחידים, ותיקון רוחבי יוצא בסט שינויים אחד. הבעיה מתגלה עם הצמיחה — עשרות שירותים וחבילות מתחברים לגרף תלויות משותף, ושינוי במודול אחד פוגע פורמלית בשכנים דרך ספריות משותפות, חוזים וסכמות נתונים.
אחר כך נכנס לתוקף אפקט «בנייה של הכול». מערכת האינטגרציה הרציפה רואה שינוי חדש במאגר ומפעילה בדיקה של כל המודולים: לינטרים, בדיקות, בניית אימג'ים.
ריצה נמשכת עשרות דקות, וענפים מקבילים יוצרים תור של משימות בנייה — הסוכנים עסוקים בהרצות של אחרים, קומיט טרי ממתין לשחרור משאבים, אף שהשינויים שלו נוגעים לחבילה אחת.
כאן מתגלה צוואר הבקבוק של קו הבנייה. בנייה ארוכה של הפרויקט מפסיקה להיות אי-נוחות והופכת למכשול עבור כל הצוות: משוב על הקוד מגיע באיחור של שעות, המפתח עובר למשימה אחרת, קונפליקטים של מיזוג מצטברים, ושינוי שבור מתגלה כאשר ההקשר כבר אבד.
ריצות אינקרמנטליות ומטמון של תוצאות ביניים מחליקים את התמונה, אך אינם מסירים את הסיבה: קו הבנייה אינו מבדיל בין מודולים שנפגעו ללא נפגעו, ולכן משלם על הכול.
נפרק כיצד זה נסגר: בניית גרף תלויות בין מודולים, סינון רק של הנפגעים, מטמון לפי תוכן קבצים וחלוקת התור לפי עדיפות ענפים.
מה נותנת בנייה של מודולים שנפגעו בלבד
בנייה של מודולים שנפגעו נשענת על גרף התלויות של המאגר: בכל שינוי המערכת מחשבת אילו פרויקטים נפגעו — המודול עצמו וכל מה שתלוי בו באופן טרנזיטיבי. כלים כמו Nx שומרים על גרף כזה מעודכן ומחשבים אותו מחדש לפי קוד המקור, ולא לפי רשימות ידניות. כל מה שנשאר מחוץ לקבוצת הנפגעים לא נכנס לבדיקה.
כמה זמן חוסכת בדיקה לפי שינויים
זמן בדיקת השינויים מפסיק להיות תלוי בגודל המאגר ומתחיל להיות תלוי בגודל התיקון: שינוי במודול עלה גורר 3-5 משימות במקום מאות. מטמון תוצאות הבנייה מגביר את האפקט — אם הקלטים של המשימה לא השתנו (קוד מקור, קונפיגורציה, סביבה), התוצאה מוגשת מהמטמון והמשימה לא מתבצעת כלל. ענף עם תיקון ממוקד עובר בדיקה בכמה דקות במקום עשרות דקות בעבר.
כיצד יורד העומס על מכונות הבנייה
משימות בנייה מקבילות מחולקות לפי הגרף: סוכנים מקבלים ענפים בלתי תלויים ואינם בונים מחדש את קידומת התלויות המשותפת. ויתור על בנייה מלאה מחדש מסיר את תור השיא — במקום מאה משימות לכל מיזוג מגיעות 5-10, והמשבצות שהתפנו עוברות לבדיקה במקביל של כמה ענפים.
המטמון משותף לכל הסוכנים: משימה חוזרת נוטלת ארטיפקט מוכן ולא מפעילה קומפילציה מחדש, לכן מכונות הבנייה מפסיקות להיות צוואר בקבוק עם גידול במספר הצוותים.
מצבי בנייה במונורפו: השוואת אפשרויות
בחירת מצב הבנייה קובעת כמה זמן ממתין המהנדס לאחר שליחת השינויים וכמה משאבים צורך קו הבנייה. להלן חלופות ממשיות שצוותים בוחרים ביניהן, והמגבלות שלהן.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| בנייה מלאה של המאגר | מונורפו קטן, קומיטים נדירים | הזמן גדל ליניארית עם מספר המודולים |
| בנייה סלקטיבית של מודולים | עשרות שירותים, אינטגרציה תכופה | נדרש גרף תלויות מדויק: טעות בו שוברת את השחרור |
| מטמון של ארטיפקטי בנייה | מחסנית יציבה, תלויות שמשתנות לעתים רחוקות | פספוס במטמון מחזיר את זמן הבנייה המלא |
| בנייה מבוזרת | מודולים רבים בלתי תלויים, בדיקות ארוכות | דיבוג מורכב יותר, נדרשים סוכנים מבודדים |
| פיצול למספר מאגרים | תחומים בעלי קשר חלש, צוותים שונים | אובדן אטומיות השינויים, חוזים מנוהלים ידנית בגרסאות |
מטמון משותף וגרף תלויות
הגרף נבנה לפי מניפסטים של מודולים, ומהדיוק שלו תלוי אילו משימות בכלל ייכנסו לבנייה. מטמון הארטיפקטים יושב באחסון משותף ומשמש מחדש בין ענפים: בנייה חוזרת של מודול שלא השתנה אורכת שניות במקום דקות.
אם הגרף מתאר קשרים סמויים באופן חלקי, חלק מהמודולים התלויים לא נבנים מחדש — והפגם צף כבר בסביבת העבודה.
מתי משתלם לפצל מאגרים
פיצול מוצדק כאשר התחומים כמעט ואינם חולקים קוד: אז בנייה סלקטיבית מפנה מקום לקווים עצמאיים במאגרים נפרדים. המחיר — ספריות משותפות יש לתחזק בגרסאות ולעדכן ידנית, ושינוי רוחבי עובר דרך כמה אישורים. כל עוד שיעור התיקונים המשותפים גבוה, מונורפו עם בנייה של נפגעים (affected) זול יותר בתפעול.
כיצד אנו מטמיעים בנייה לפי מודולים שנפגעו
קו הבנייה במונורפו כברירת מחדל בונה הכול מחדש. כשמדובר בעשרה מודולים זה נסבל, אך במאה חבילות הבנייה מפסיקה להדביק את קצב התיקונים: התור גדל, ובדיקה שנכשלה במודול זר חוסמת את השחרור. סדר העבודות שלהלן בנוי כך שיופעלו רק מודולים שנפגעו והצרכנים שלהם.
מביקורת לבנייה סלקטיבית
- ביקורת קו הבנייה. מתעדים זמני שלבים, מסמנים מה נשמר במטמון וקובעים מדדים לפני השינויים — אחרת לא יהיה עם מה להשוות את האפקט לאחר מכן.
- מפת תלויות בין מודולים. מפרקים קשרים בין חבילות, ספריות משותפות ותלות מעגלית שבגללן הפעלה סלקטיבית מחמיצה.
- הגדרת בנייה סלקטיבית. קושרים את ההפעלה לנתיבים ששונו ולכללים: תיקון בספרייה משותפת גורר אחריו את כל הצרכנים שלה, ארטיפקטים מוכנים משמשים מחדש.
- דיבוג הפעלות שווא. עוברים על מקרי גבול — שינויי קונפיגורציה, סכמות נתונים, תלויות טרנזיטיביות — כאשר נבנה משהו מיותר או מוחמץ משהו נחוץ.
פיילוט וקריטריוני קבלה
- פיילוט על כיוון אחד. מפעילים את המצב עבור צוות אחד ומשווים את התוצאה לבנייה מלאה: בניות שהוחמצו נראות לפני פריסה על כל המאגר.
- העברת נהלים לצוות. מתארים כיצד להוסיף מודול ולהצהיר על תלויות; בהמשך הצוות מתחזק את קו הבנייה ללא מעורבותנו.
קריטריון הקבלה — אף מודול שנפגע באמת אינו מוחמץ, וההפעלות המיותרות בודדות. לאחר מכן זמן ההמתנה בתור מפסיק להיות תלוי בגודל המאגר.
ארטיפקטים ונהלים שנשארים במאגר
גרף התלויות וכללי הפעלת הבניות עובדים כל עוד הם מתועדים במאגר, ולא בהתכתבות ובוודאי לא בראשו של מהנדס אחד. לכן כל מה שמתאר את הבנייה יושב לצד הקוד ועובר את אותו נוהל בדיקות: תיקון בכללים נראה בהיסטוריה, ניתן לדון בו ולבטלו יחד עם השחרור.
- קונפיגורציות של משימות בנייה — תיאור דקלרטיבי של שלבים ותנאי הפעלה: לפי איזה ענף בונים, אילו בדיקות חובה, מה מוחמץ עבור תיקונים בתיעוד.
- סכמת תלויות — גרף החבילות והקשרים ביניהן; לפיו מחושב אילו בניות ובדיקות נפגעו מהשינוי ואילו אין צורך להפעיל.
- נוהל בדיקות קוד — סט חובה של ניתוח סטטי ובדיקות עם ספי כיסוי לפני מיזוג, סדר החריגים ומי מאשר אותם.
- מדיניות גישה לסוכני בנייה — מי רשאי להפעיל בנייה, לשנות כללים, לקרוא סודות; היכן נשמרים מפתחות, כיצד מונפקים וכיצד מבוטלים עם עזיבת אדם.
- תיעוד הבנייה — מבנה קו הבנייה, היכן לצפות בלוגים ובמדדים, אילו כשלים אופייניים ומה לעשות בנפילה בכל שלב.
- הוראות למפתחים — כיצד לשחזר בנייה מקומית, כיצד להוסיף חבילה בלי לשבור את הגרף, אילו מוסכמות שמות לענפים ולקומיטים נהוגות.
- נוהל תורנות — מי מגיב לבנייה שנפלה, תוך כמה זמן, מתי עוצרים את קו הבנייה וכיצד מודיעים על כך לצוות.
המערך הזה נשאר אצל הצוות לאחר ההפעלה: אותו לא משחזרים מהזיכרון, ומהנדס חדש מוכנס לתהליך תוך ימים, לא שבועות.
מקרה בוחן: מונורפו עם עשרות מודולים וזמן בדיקה
הלקוח הגיע עם מונורפו של כמה עשרות מודולים, שבו כל קומיט הפעיל בנייה ובדיקה של כל העץ. החציון של הבדיקה עמד על כשעה, התור למכונות הבנייה גדל מהר יותר מהצוות, והמפתחים החלו לצבור תיקונים לחבילות גדולות — רק כדי לא להמתין לקו הבנייה שוב.
המדידות נלקחו פעמיים ובלתי תלויות. תחילה לפי הלוגים של GitLab CI — זמן כל שלב על אותה קבוצת שינויים לפני ואחרי הבנייה מחדש. לאחר מכן הרצנו את אותם קומיטים על עותק של המאגר ועל מבצע נפרד, כדי לשלול את השפעת המטמון והמשימות השכנות. שתי המדידות תאמו בטווח הטעות — התוצאה משוחזרת, ולא ריצה מוצלחת חד-פעמית.
מה בדיוק השתנה בקו הבנייה
- בנינו גרף תלויות בין מודולים ושומרים אותו במאגר לצד הקוד.
- הבדיקה עוברת רק על מודולים שנפגעו ועל אלה שתלויים בהם; השאר מסומן כדילוג.
- מטמון הארטיפקטים נקשר לתוכן המודול, ולא למספר הבנייה — הוא משמש מחדש בין ענפים.
- בדיקות מהירות חוסמות שינויים שלא יעברו ממילא לפני המשימות הכבדות.
- המקביליות הוגבלה לפי מספר מכונות הבנייה, כדי שהתור לא יאכל את הרווח.
לאחר ההטמעה החציון של הבדיקה ירד משעה לכמה דקות בלבד, ובניות שנוגעות בפחות מעשירית מהמודולים הפכו לרוב. העומס על מכונות הבנייה ירד עד כדי כך שהכוח שהתפנה הוקדש לריצות לילה.
בנפרד נעלם סוג הכשלים שיוחסו ל«בדיקות לא יציבות»: הנפילות נבעו ממצב משותף ומטמון בין מודולים; כעת לכל משימה יש ספריית עבודה מבודדת.
מה לעשות אם הבנייה כבר תפחה לעשרות מודולים
כן, המעבר לבנייה סלקטיבית במונורפו נעשה בלי לעצור את הפיתוח — בתנאי אחד: קו סלקטיבי נספר תחילה במקביל לריצה מלאה ואינו משפיע על סטטוס הענף הראשי. השוואה בין שתי ריצות על אותו שינוי מראה אילו מודולים המערכת מחשיבה לנפגעים והיכן גרף התלויות משקר.
מודולים מיושנים מוציאים בשלב נפרד: מוציאים אותם מהבנייה החובה, קובעים את נקודת העבודה האחרונה ושומרים אותם כענף ארכיוני. תחילה בודקים שקוד חי אינו מפנה אליהם — תלות סמויה צפה דווקא לאחר ההחרגה.
| שלב | במה נוגע | במה אנו מסתכנים |
|---|---|---|
| סקר תלויות | גרף מודולים, ספריות משותפות | גרף חלקי: תיקון בספרייה לא גורר צרכנים, הענף נראה ירוק |
| תצפית | רק דוחות, הקו לא משתנה | פער בכללי זיהוי המודולים הנפגעים |
| העברת חלק מהמודולים | כללים לפי נתיבים, מטמון ארטיפקטי ביניים | ספרייה משותפת משתנה — יש לבנות מחדש את כל הצרכנים |
| הקפאת מודולים מיושנים | החרגה מבדיקות חובה | הפניה סמויה של קוד חי למודול מוקפא |
| העברה מלאה | ענף ראשי, בדיקות חובה | אובדן רשת הביטחון: דרוש ביטול מהיר לריצה מלאה |
כל שלב ניתן לבטל בתיקון כללים אחד, והריצה המלאה מוסרת אחרונה — כאשר הבנייה הסלקטיבית מתכנסת עמה בתוצאות. התוצאה: שינוי טיפוסי בונה מחדש בודדים מודולים במקום עשרות, והענף הראשי אינו משותק.
שאלות טכניות נפוצות לפני תחילת העבודה
לפני תחילת העבודה צוותי הנדסה שואלים בערך את אותה קבוצת שאלות: עד כמה מלאות הבדיקות בבנייה סלקטיבית, מה קורה לספריות משותפות וכיצד קו הבנייה ממשיך לחיות לאחר ההעברה. אנו עונים בקצרה — לגופו של עניין.
כיצד לוודא שבנייה סלקטיבית אינה מחמיצה בדיקות נחוצות?
גרף התלויות נבנה לפי מניפסטים של חבילות וייבוא בקוד, ולא לפי מבנה הספריות. נתיבים שהשתנו מושווים לחבילות, ולבנייה נכנסים כל אלה שתלויים בהן באופן טרנזיטיבי. מעל זה, בענפים מוגנים תמיד רצה בנייה מלאה — היא משמשת כאמת מידה שמולה משווים את התוצאה הסלקטיבית.
מה יקרה אם ספרייה משותפת השתנתה?
שינוי בחבילה משותפת מסמן את כל הצרכנים שלה, ולכן הם נבנים מחדש יחד איתה. בנפרד אנו מטפלים בתיקונים «גלובליים» — קבצי נעילת גרסאות, קונפיגורציית בנייה וכללי שורש: הם מפעילים ריצה מלאה, משום שהם משפיעים על כל המאגר.
ואם הבדיקה בכל זאת תוחמץ?
החמצות שווא אנו תופסים בהשוואה של רשימת החבילות הנפגעות לריצה מלאה בענפי שחרור. כל פער מנותח ונסגר בכלל מיפוי או בחריגה מפורשת. פערים כאלה מתועדים ביומן — נראה שהסיבה נעלמה, ולא חזרה כעבור חודש.
מי מתחזק את קו הבנייה לאחר ההפעלה?
הקונפיגורציה נמצאת במאגר לצד הקוד ומשתנה דרך סקירה רגילה. כללי ההתאמה, סכמת המטמון וסדר הוספת חבילה חדשה מתוארים בתיעוד, ולכן הצוות מקים שירותים לפי תבנית בלעדינו. התפקידים מופרדים: מפתח מפעיל בניות וקורא לוגים, תיקון כללים משותפים וסודות — דרך גישה ואישור נפרדים.
נדון במשימה: מה להבהיר לפני תחילת העבודה
כדי שהערכת העבודה על הבנייה תישען על עובדות ולא על הנחות, אנו זקוקים לנתוני מקור על המאגר: כמה חבילות ויישומים יש בו, היכן נמצאות הספריות המשותפות ומי משתמש בהן מחדש.
לפי מידע זה אנו מחשבים אילו בדיקות להפעיל רק עבור חלקי קוד שנפגעו ואילו תמיד, ומכינים תוכנית הטמעה עם לוחות זמנים מציאותיים.
להלן מה שכדאי להבהיר לפני תחילת העבודה. אם חלק מהנתונים עדיין אינו זמין, נדון במשימה לפי מה שיש: ריצת ניסיון על חבילה אחת בדרך כלל מציגה תמונה אמיתית מהר יותר מאשר תיאור מלא במילים.
- מבנה המאגר: מספר החבילות, הגבולות ביניהן, מודולים משותפים וקשרים בין בניות.
- סכמת ענפים: אילו ענפים נחשבים ראשיים, כיצד נוצרים וממוזגים שינויים.
- זמן הבדיקה הנוכחי: כמה נמשכת ריצה מלאה וכמה — בדיקת תיקון אחד.
- הבדיקות הארוכות והשבריריות ביותר: מה נופל לרוב ומדוע.
- מגבלות גישה: הרשאות למאגר, לצומתי בנייה ולאחסון ארטיפקטים.
- ציפיות לגבי לוחות זמנים של הטמעה: מה קריטי לקבל ראשון ומה ניתן לדחות.
תארו את המשימה בצורה חופשית — נחזור עם הערכה ותוכנית עבודה, בלי מילים כלליות.







