פיתוח CircleCI Orbs פרטיים ומותאמים אישית עבור CI/CD

אנחנו מפתחים CircleCI Orbs פרטיים בהתאמה מלאה: שלבי בנייה חוזרים הופכים למודולים לשימוש חוזר עם גרסאות ברורות. זמן הבנייה מתקצר פי כמה, כפילויות קונפיגורציות נעלמות, והשקת פרויקטים חדשים מואצת.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

CircleCI Orbs: מדוע תצורת הבנייה מתנפחת

בכל מאגר, הבנייה חיה בקובץ תצורה אחד — .circleci/config.yml: התקנת תלויות, הרצת בדיקות, בניית אימג', פרסום, פריסה. כשהפרויקטים הופכים לעשרות, השלבים האלה מתחילים להיות מועתקים ממאגר למאגר.

בדיוק כאן מופיעים CircleCI Orbs — חלק משותף של התצורה שהוצא החוצה ומנוהל בגרסאות, אבל עד שמגיעים אליהם, הצוות בדרך כלל מספיק לצבור כמה דורות של עותקים של אותו תרחיש.

הפער כמעט לא נראה בהתחלה. אחר כך מתברר שבפרויקט אחד מטמון התלויות ממופתח לפי שם ענף, באחר לפי סכום ביקורת של קובץ הנעילה, ובשלישי המפתח בכלל לא השתנה מאז היצירה. במקום אחד נוסף דגל לשלב הבדיקות, במקום אחר לא, ובמקום אחר נשאר אימג' מריץ מיושן.

תיקון של דבר אחד — החלפת מפתח מטמון או סדר השלבים — צריך לבצע בשלושים קבצים, וחצי מהם נשארים בלי שימת לב. אותו קומיט נבנה אחרת, ובנייה ירוקה מפסיקה להוכיח משהו: יכולת השחזור נופלת בדיוק במקום שבו מסתמכים עליה בעת הפריסה.

המקור השני לגידול — לוגיקה מותנית בתוך השלבים. ענפים בסגנון "אם תג — מפרסמים, אם ענף ראשי — פורסים לסביבת בדיקות, אחרת רק בדיקות", סטים נפרדים של שלבים לסביבות שונות, מטריצות הרצה.

הקובץ מתנפח למאות שורות, מפסיקים לעשות לו סקירה, ותחזוקת תרחישי הבנייה הופכת לסנכרון ידני של עותקים — כל עריכה חדשה מגדילה את הפער במקום לצמצם אותו.

בהמשך נפרק איך להוציא את החלק המשותף לפקודות ואימג'ים לשימוש חוזר, לתת לו גרסאות ולשמור את תצורת הבנייה במקום אחד — כך שהעדכון יגיע לכל הפרויקטים באופן מודע, ולא על ידי שכתוב שלושים קבצים.

האפקט של מודולי בנייה לשימוש חוזר

מודולי בנייה לשימוש חוזר ב-CircleCI הם לא "מבנה תצורה מסודר", אלא אפקטים מדידים שנראים בסטטיסטיקת הבנייה כבר בחודש הראשון לעבודה.

זמן בנייה בשלבים חוזרים

הכנת הסביבה, התקנת תלויות, בדיקות ופרסום אימג' מתוארים פעם אחת במודול משותף, והפרויקט רק מתחבר לגרסה הנדרשת. שלבים חוזרים מפסיקים להתבצע מחדש בכל מאגר: בנייה שנמשכה 11-12 דקות מסתדרת ב-6-8, וההמתנה בתור למריץ משותף מתקצרת.

שיעור העריכות הידניות בתצורות

בעבר אותה לוגיקה חייתה במהדורה משל עצמה בעשרות קבצים, וכל תיקון היה צריך לחזור עליו ביד. עכשיו השינוי נעשה במודול, והפרויקטים רק מעלים את הגרסה שלו. מספר המקומות שבהם צריך לתקן את התקן בנפרד מצטמצם לאחד.

מחלקת כשלים שנסתמה בגלל פערי סביבות

המודול מקבע גרסאות סביבה, סדר שלבים והרכב בדיקות לפני פרסום — תקן בנייה אחיד הופך לחובה לכל השירותים. כשלים מהסוג "כאן זה עובד, בבנייה לא" יוצאים מהסטטיסטיקה: כשל מעיד כעת על בעיה בקוד, לא בסביבה.

מהירות חיבור מאגר חדש

החיבור מצטמצם לציון המודול והגרסה שלו — בדיקות, בנייה ופרסום כבר מתוארים בפנים. שירות חדש מקבל תקן עובד תוך שעה במקום יום, והמהנדס לא צריך להבין בפרטי הפרטים של הבנייה.

אפשרויות לשימוש חוזר בבניות: מה ומתי מתאים

אפשר להשתמש מחדש בלוגיקת בנייה בארבע דרכים, והבחירה ביניהן נקבעת לא לפי טעם, אלא לפי מספר הצוותים על צינור משותף ותדירות השינויים. להלן השוואה לפי תרחישים ועומס תחזוקה: לכל גישה מחלקת מגבלות משלה, וניתן לראות איזו מהן תיתקל במחסום ראשונה ככל שמספר המאגרים גדל.

אפשרות מתי מתאימה מגבלות הגישה
תבנית בנייה משותפת במאגר צוות אחד או שניים, התצורה משתנה לעיתים רחוקות, צריך שליטה מלאה בכל שורה העריכה לא מגיעה למאגרים השכנים: גרסאות מתפצלות, התבניות חיות חיים משל עצמן
מודול בנייה פרטי ברג'יסטרי משותף כמה צוותים עם שלבים משותפים והרשאות גישה שונות, הקוד סגור כלפי חוץ צריך רג'יסטרי מודולים וכלל ניהול גרסאות: העדכון חייב להישאר תואם לאחור
מודול חיצוני משותף שלבים טיפוסיים — בדיקות סגנון, פרסום ארטיפקטים, התראות תלות במתחזק חיצוני: השינויים שלו מגיעים מחוץ ללוח הזמנים שלכם ושוברים את הבנייה בלי שליטה מצדכם
יצירת תצורה ממטא-נתונים של הפרויקט הרבה מאגרים אחידים, ההבדלים מתוארים בפרמטרים נוצר שכבת ביניים: בלי הגנרטור אי אפשר לקרוא את התצורה או לתקן אותה ביד

בפועל הגישות משולבות: מודול פרטי מכסה שלבים משותפים, יצירה — מאגרים טיפוסיים, והתבנית נשארת לשירותים נדירים. המעבר נעשה בלי לעצור את האספקה — המודול החדש מתחבר לצד השלבים הישנים, והכפילויות נחתכות עם ההעברה.

איך מתבצעת הטמעת רג'יסטרי מודולים פרטי

הטמעת רג'יסטרי מודולים פרטי היא לא התקנת שירות, אלא בנייה מחדש של האופן שבו צוותים בונים ומשתמשים מחדש בתצורה. סדר העבודות בנוי כך שכל שלב נשען על הקודם שנבדק, ובניות של שירותים פעילים לא נעצרות אפילו ליום.

  1. ביקורת תצורות בנייה. מבצעים מיפוי מלאי: כמה קבצי בנייה יש, היכן שלבים כפולים, אילו סודות מונחים בגלוי, כמה נמשכת הרצה טיפוסית. בפלט — מפת תלויות ורשימת מקטעים שבאמת כדאי להוציא למודולים.
  2. סכמת מודולים וניהול גרסאות. מסמנים מודולים לפי תחומי אחריות, מסכימים על סכמת תגים וטווחי תאימות, כדי שעדכון של מודול אחד לא ישבור בניות של אחרים.
  3. הגדרת גישה לרג'יסטרי. מחברים רג'יסטרי Orbs פרטי, מנפיקים לצוותים טוקנים עם ההרשאות המינימליות הנדרשות, מפרידים בין קריאה לפרסום, מגדירים מטמון כדי ששליפת מודול לא תאט את ההרצה.
  4. הרצת ניסוי על שירות אחד. מעבירים את השירות הכי מייצג, משווים זמן בנייה ומספר עריכות ידניות לפני ואחרי, מתקנים ממשקי מודולים לפי אי-נוחות בפועל.
  5. בדיקת נסיגות בבנייה. מריצים תרחישים: מודול בוטל, תג נכתב מחדש, רג'יסטרי לא זמין. הבנייה צריכה ליפול באופן צפוי או לעלות על גרסה מקובעת — בלי עריכת קונפיגים ידנית ברגע התקלה.
  6. מסירה וסדר עבודה בהמשך. מוסרים תקנון פרסום, תבנית למודול חדש וכללי הוצאה משימוש, מלמדים תורנים לטפל בכשלים טיפוסיים.

אחרי זה שאר השירותים מועברים במסלול שכבר נסלל — אחד לספרינט, בלי לעצור את הפרסומים.

מה נשאר אצלכם: תצורות, תפקידים, תקנונים

אורבים פרטיים והעטיפה סביבם נשארים בקונטור שלכם — יחד עם ערכה שלפיה המודולים מתוחזקים בלי צוות חיצוני. הכול מועבר למאגר שלכם ומתוחזק עד הרגע שבו המהנדסים מתחילים לבצע שינויים בעצמם.

  • תצורות בנייה — תיאורים פרמטריים של משימות: שלבים, מטמון, תנאי הרצה. לפיהם משוחזרת אותה תוצאה כמו בסביבת הייחוס.
  • סכמת תלויות — איזה מודול נשען על מה ומה תיגע עריכת בלוק משותף. רואים היכן השינוי מבודד והיכן הוא יגרור צרכנים.
  • מדיניות גישה ותפקידים — מי מפרסם גרסה חדשה של מודול משותף, ומי רק מחבר אותו לפרויקט שלו. סודות מופרדים לפי רמות ולא עוברים בירושה אוטומטית.
  • תיאור ניהול גרסאות — הסכמה לגבי שינויים שוברים ותואמים: הראשון הולך בענף נפרד, פרמטר חדש מגיע עם ערך ברירת מחדל.
  • תקנון עדכוני מודולים — תדירות בדיקת אימג'י בסיס ותלויות, וסדר הרצת ניסוי בפרויקט בדיקה לפני העברת השאר.
  • תיעוד — כרטיס לכל מודול: ייעוד, פרמטרים, דוגמת חיבור, מגבלות ידועות ותקלות טיפוסיות.
  • הוראה למהנדסים — איך להוסיף שלב, איך להחזיר פרסום אחורה ולאן להסתכל בעת תקלה.

תקנונים אינם סטטיים: כשהתהליכים משתנים, מתקנים את המסמכים באותו שינוי שבו מתקנים את הקוד, אחרת הם מתפצלים מהמציאות תוך כמה חודשים.

מקרה בוחן: זמן הבנייה התקצר, כפילויות התצורה נעלמו

מה היה

ארבעה-עשר שירותים, לכל אחד קובץ תצורה משלו, שהועתק מהשכן ומשם נערך ביד. שלבי בנייה ופרסום התפצלו לתשעה וריאנטים של אותה פעולה, ובשלושה שירותים הבדיקות בכלל לא רצו.

מחיר הפערים: הרצה מלאה ארכה כארבעים דקות — לא היה מטמון תלויות משותף, כל שירות משך ובנה הכול מחדש. בערך כל כשל חמישי בפרודקשן נבע לא מהקוד, אלא משלב שגוי בתצורה שכבר תוקן בשירות אחד ובאחרים לא.

מה נהיה

אספנו CircleCI Orbs פרטיים — מודול משותף עם פקודות לבניית אימג', מטמון תלויות, הרצת בדיקות ופרסום לפי תג. קונפיג השירות התכווץ לחמש-עשרה שורות: לציין אימג' ולקרוא לפקודה משותפת. עריכת שלב נעשית כעת במקום אחד ונקלטת בכל השירותים.

ההרצה התקצרה מארבעים דקות לשלוש-עשרה בזכות מטמון והרצת בדיקות במקביל. עותקי שלב הבנייה הפכו לאחד במקום תשעה, כשלים בגלל פערי תצורה — שניים ברבעון במקום חמישה-שישה בחודש, ושניהם נתפסים בשלב ההכנה, לא בפרודקשן.

גם הנסיגה הפכה לניהולית: גרסת המודול מקובעת בתג, חזרה לענף הקודם של המודול המשותף מחזירה את ההתנהגות הקודמת לכל השירותים בבת אחת, בלי לעבור בין מאגרים. בהמשך נפרק איך מודול כזה בנוי מבפנים ומה כדאי להעביר אליו, ומה להשאיר בשירות.

במה CircleCI Orbs פרטיים שונים מתבניות

Orb פרטי הוא מודול ארוז: פקודות, משימות ומריצים עם פרמטרים וערכי ברירת מחדל, שפורסם ברג'יסטרי של CircleCI תחת מרחב השמות שלכם. בתצורת הפרויקט הוא מתחבר בקישור עם ציון גרסה, כלומר עובד כתלות חיצונית, לא כקובץ מועתק. תבנית במאגר היא רק טקסט שמוכפל בין פרויקטים: הקשר בין העותקים הולך לאיבוד ברגע ההעתקה.

ניהול גרסאות של מודולים הוא ההבדל העיקרי. עדכון Orb פרטי — פרסום אחד של גרסה חדשה: פרויקטים שקבעו את הקודמת ממשיכים להיבנות כמו קודם, והמעבר לחדשה הוא קומיט נפרד בתצורה, והנסיגה נכנסת לאותה שורה. עם תבנית כל עריכה הופכת למעבר בין עשרות מאגרים, וחלקם בהכרח מפגרים או מתפצלים בהתנהגות.

הזכויות על המודול המשותף מתחלקות לפי תפקידים: צוות הפלטפורמה מפרסם גרסאות, וצוותי המוצר רק מתחברים ל-Orb ומעבירים את הפרמטרים שלהם. שינויים עוברים סקירה במקום אחד ולא נכתבים מחדש תוך כדי תנועה, שלא כמו תבנית שכל אחד יכול להתאים לעצמו ולשבור את ההתנהגות המשותפת. בידוד השינויים נשען על הגרסה, לא על משמעת.

מאגר אחד או שניים, סטאק אחיד, אין צרכנים חיצוניים — תבנית מקומית מספיקה בהחלט: היא לא דורשת פרסום ופשוטה יותר לתחזוקה. Orbs פרטיים משתלמים כשת�רחישי בנייה חוזרים על עצמם בכמה מאגרים, צוותים שונים צריכים לבנות באופן זהה, וצריך לשנות מודול משותף באופן מרוכז וצפוי.

ספקות טכניים נפוצים לפני תחילת העבודה

חמש שאלות בדרך כלל עולות לפני ההתחלה, וכולן על תפעול, לא על הקוד עצמו. להלן תשובות קצרות; אם אצלכם משהו מאורגן אחרת, אמרו בשלב הדיון — נתאים את התצורה לקונטור הנוכחי.

איך לעדכן מודולים פרטיים ולא לשבור בניות?

מנהלים גרסאות לפי כללים סמנטיים: שינויים שאינם תואמים לאחור עוברים רק לענף המאג'ורי, והשאר — למינוריים. פרויקטים מקובעים לגרסה מאג'ורית, והעדכון מורץ קודם על ענף בדיקה — הפער נראה לפני המיזוג לענף הראשי.

איך מונפקות הרשאות גישה לרג'יסטרי ולסביבת הבנייה?

לפי עקרון המינימום הנדרש: טוקנים נפרדים לקריאה ולכתיבה, תוחלת חיים מוגבלת, קישור להקשרי סביבות. כל שינוי משאיר רשומה ביומן — רואים מי ומה פרסם.

למי שייך הרג'יסטרי אחרי המסירה?

הרג'יסטרי נרשם על הארגון שלכם, והרשאות הבעלים נשארות אצלכם. אנחנו מתחברים כקבלן משנה עם זכות פרסום; אחרי המסירה אתם מחליפים הרשאות בצעד אחד ועובדים עם המודולים בעצמכם.

יש לנו כמה סטאקים — מודול אחד יתאים?

כן, בזכות פרמטריזציה: שפה, סביבת הרצה, סט שלבים ואימג' מועברים כארגומנטים עם ערכי ברירת מחדל. מודול אחד מכסה כמה סטאקים, ולא מחזיקים עותקים כפולים לכל אחד.

יש לנו כבר תבניות משל עצמנו — לשכתב הכול מחדש?

לא. עוטפים את התבניות הקיימות במודול פרטי ומעבירים שירות אחד בכל פעם: הבניות הישנות ממשיכות לעבוד עד שהקונטור החדש יכסה את כל הפרויקטים. נסיגה של כל שלב — חזרה לתיאור הבנייה הקודם.

נדון בסכמת הבנייה שלכם ונחזור עם תוכנית

כדי שהערכת ההטמעה תישען על עובדות ולא על ניחושים, צריך חילופי מידע קצרים. שלחו את מה שכבר קיים — זה מספיק כדי לראות צווארי בקבוק ולהציע סכמה. אם חלק מהבניות כבר הועבר ל-Orbs משותפים והם עובדים, אמרו זאת: לא נבנה מחדש את מה שלא מפריע.

  • רשימת מאגרים ושירותים שצריך להעביר לבניות משותפות, עם סימון אילו מהם קריטיים לפרסומים.
  • קבצי תצורה נוכחיים של בנייה ופריסה — כפי שהם, יחד עם פתרונות עקיפה זמניים.
  • סכמת ענפים וכללי פרסום: מה נחשב לגרסה, מי מאשר אותה ואיך.
  • דרישות גישה: אילו תפקידים נדרשים למהנדסים, לאילו סביבות, רג'יסטרי אימג'ים וסודות.
  • מגבלות שאסור להפר: קוד סגור, קונטורים מבודדים, חלונות לבניות כבדות.
  • מדדים ליעד: זמן בנייה, שיעור בדיקות אוטומטיות, תדירות פרסומים.
  • פרטי קשר של האחראי על התשתית — איתו נתאם את הפרטים הטכניים.

לאחר מכן הסדר הוא כזה: מנתחים את הנתונים, חוזרים עם הערכת הטמעה ותוכנית עבודה בשלבים — ממאגר פיילוט ועד שכפול לשאר. בנפרד מתעדים את סדר המסירה: מה נשאר בקונטור שלכם, אילו הרשאות ותיעוד עוברים לצוות שלכם, ואיך התוצאה מתוחזקת אחרי ההרצה. תארו את המשימה — נחזור עם הערכה ותוכנית.