קודם כל פייפליין

מבוא

לרגל הגעתו של הבלוג ל150,000 כניסות החלטתי לחזור לפוסט קצר ואולי קצת פילוסופי (שאולי יחזיר לי את המוטיבציה לחזור לכתוב) על החשיבות הכנסה של continuous integration (CI) בסיסי לקוד שלנו עוד לפני שבכלל יש לנו קוד שעובד.

אני לא אתעקב הרבה על מה זה CI כי יש על זה טונות של מידע באינטרנט, הצחיק אותי לגלות שבעברית קראו לזה ״אינטרגציה רציפה״.

אני רק אגיד במשפט, שכשאני אומר CI אני מתכוון לתהליך שמושך את הקוד, ומבצע עליו פעולות כדי לוודא שהוא לא שבור לחלוטין. לדוגמה - מריץ עליו כלים של static analysis, מקמפל אותו, מריץ עליו unit tests, מעלה אותו לסביבת בדיקות, בונה ממנו package, מריץ עליו integration tests ועוד מיליון דברים שאפשר לעשות - וכל זה על שרת מרוחק.

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

למה CI כל כך חשוב בעיני

סיבה 1 - fail fast

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

ובמשפט - אנחנו רוצים feedback loop כמה שיותר מהיר!

סיבה 2 - לדאוג שתמיד יש לנו גרסה שעובדת

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

סיבה 3 - לרוץ במכונה אחרת זה תמיד טוב יותר מלרוץ לוקאלית

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

סיבה 4 - self maintained documentation

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

אוקי, נעשה CI אבל מה הלחץ כל כך מוקדם ועוד לפני שיש קוד?

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

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

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

בנוסף רצוי מאוד לשים את הפייפליין כ step שחוסם pull requests מלהתמרג׳ג׳ כי אחרת אנחנו בעיקר נהיה חכמים לגבי הנפילות של הפייפליין בדיעבד ולא נרוויח מה benefits האמיתיים.

המוצר שלנו כבר לא בחיתולים, מה אנחנו עושים?

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

לא חייבים pipeline מפונפן שמריץ חמש מאות סוגים של static analysis, code coverage tools, לינטרים וטסטים כדי לקבל value. מהרגע שמתחילים ורואים את הערך, הרבה יותר קל להמשיך.

סיכום

התחלנו פרויקט והדבר הראשון שאנחנו צריכים לעשות זה פייפליין שמושך את הקוד שלנו מהריפו, מתקין אותו ואת כל התלויות שלו (Docker לרוב משתלב כאן אחלה), מריץ אותו ומריץ עליו בדיקה פשוטה (או כמה). לא משנה באיזה פלטפורמה אנחנו מנהלים את הקוד שלנו ואיפה אנחנו רוצים להריץ (github/azure/jenkins/bamboo/gitlab), למתכנת הסביר, ליצור את הפייפליין הזה יקח שעות בודדות של עבודה במקרה הרע (במידה והפרויקט עדיין בתולי) והאימפקט שזה יתן על תהליך הפיתוח הוא אדיר.


תגובות

פוסטים פופולריים מהבלוג הזה

מהם קבצי DLL ואיך להשתמש בהם?

תכנות מונחה עצמים | Dependency Inversion Principle

מה ההבדל בין אוטומציה לפיתוח רגיל