חווית CICD ניידת: תקן מהיר אחד עבור יישומים ניידים רבים

חווית CICD ניידת: תקן מהיר אחד עבור יישומים ניידים רבים
אני רוצה לדבר על אינטגרציה רציפה ומסירה (Continuous Interactive Delivery) עבור אפליקציות מובייל באמצעות Fastlane. איך אנחנו מיישמים CI/CD בכל אפליקציות המובייל, איך הגענו לשם ומה קרה בסוף.

כבר יש מספיק חומר באינטרנט על הכלי שחסר לנו כל כך בהתחלה, אז בכוונה לא אתאר את הכלי בפירוט, אלא אתייחס רק למה שהיה לנו אז:

המאמר מורכב משני חלקים:

  • הרקע להופעת CI/CD נייד בחברה
  • פתרון טכני לפריסה של CI/CD ליישומי N

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

זה פשוט קרה ככה מבחינה היסטורית

שנה 2015

Мы только начали заниматься разработкой мобильных приложений, тогда еще мы ничего не знали про непрерывную интеграцию, про DevOps и другие модные штуки. Каждое обновление приложения выкатывал сам разработчик со своей машины. И если для Android это достаточно просто — собрал, подписал .apk וזרקנו אותו לתוך מסוף המפתחים של גוגל, ואז עבור iOS כלי ההפצה דאז דרך Xcode השאיר אותנו עם ערבים נהדרים - ניסיונות להוריד את הארכיון הסתיימו לעתים קרובות בשגיאות ונאלצנו לנסות שוב. התברר שהמפתח הכי נלהב מספר פעמים בחודש לא כותב קוד, אלא עוסק בשחרור האפליקציה.

שנה 2016

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

$ xcodebuild clean archive -archivePath build/MyApp 
    -scheme MyApp

$ xcodebuild -exportArchive 
                        -exportFormat ipa 
                        -archivePath "build/MyApp.xcarchive" 
                        -exportPath "build/MyApp.ipa" 
                        -exportProvisioningProfile "ProvisioningProfileName"

$ cd /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

$ ./altool —upload-app 
-f {abs path to your project}/build/{release scheme}.ipa  
-u "appleId@example.com" 
-p "PASS_APPLE_ID"

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

שנה 2017

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

עם זאת, התוכנות העיקריות הכלולות בליבת המסלול המהיר הן: gym и pilot, הצלחנו להתחיל את זה.

התסריטים שלנו שוכללו מעט.

$ fastlane gym  —-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                —-buildlog_path "/tmp" 
                -—clean

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

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

למרבה הצער, אין מדידות על מהירות ההרכבה. xcodebuild и gym לא עשינו את זה, אבל נסמוך על התיעוד - האצה של עד 30%.

תהליך יחיד לכל היישומים

שנת 2018 והווה

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

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

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

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

בקיץ 2018, בחנו שוב את הנתיב המהיר שעדיין מתפתח.

משימה מס' 1: לסכם את כל שלבי הסקריפט ולכתוב אותם מחדש לתוך Fastfile

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

בדקנו את מה שיש לנו וזיהינו 4 שלבים שמתאימים לתיאור של CI/CD שלנו:

  • בנייה - התקנת תלויות, בניית ארכיון,
  • בדיקה - הפעלת בדיקות יחידה למפתחים, חישוב כיסוי,
  • סונאר - הפעל את כל הלינטרים ושלח דוחות ל-SonarQube,
  • deploy — שליחת ארטיפקט ל-alpha (TestFlight).

ואם לא ניכנס לפרטים, ונשמיט את המקשים המשמשים בפעולות, נקבל Fastfile כזה:

default_platform(:ios)

platform :ios do
  before_all do
    unlock
  end

  desc "Build stage"
  lane :build do
    match
    prepare_build
    gym
  end

  desc "Prepare build stage: carthage and cocoapods"
  lane :prepare_build do
    pathCartfile = ""
    Dir.chdir("..") do
      pathCartfile = File.join(Dir.pwd, "/Cartfile")
    end
    if File.exist?(pathCartfile)
      carthage
    end
    pathPodfile = ""
    Dir.chdir("..") do
      pathPodfile = File.join(Dir.pwd, "/Podfile")
    end
    if File.exist?(pathPodfile)
      cocoapods
    end
  end

  desc "Test stage"
  lane :test do
    scan
    xcov
  end

  desc "Sonar stage (after run test!)"
  lane :run_sonar do
    slather
    lizard
    swiftlint
    sonar
  end

  desc "Deploy to testflight stage"
  lane :deploy do
    pilot
  end

  desc "Unlock keychain"
  private_lane :unlock do
    pass = ENV['KEYCHAIN_PASSWORD']
    unlock_keychain(
      password: pass
    )
  end
end

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

lane :build do
carthage(
  command: "update",
  use_binaries: false,
  platform: "ios",
  cache_builds: true)
cocoapods(
  clean: true,
    podfile: "./Podfile",
    use_bundle_exec: false)

gym(
  workspace: "MyApp.xcworkspace",
  configuration: "Release",
  scheme: "MyApp",
  clean: true,
  output_directory: "/build",
  output_name: "my-app.ipa")
end 

lane :deploy do
 pilot(
  username: "appleId@example.com",
  app_identifier: "com.example.app",
  dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
  team_id: "ITS_TEAM_ID")
end

בדוגמה שלמעלה, רק חלק מהפרמטרים שעלינו לציין הם פרמטרי הבנייה - סכימה, תצורה, שמות פרופילי האספקה, כמו גם פרמטרי ההפצה - Apple ID של חשבון המפתח, סיסמה, מזהה אפליקציה וכן הלאה. כקירוב ראשון, אנו שמים את כל המפתחות הללו בקבצים מיוחדים - Gymfile, Matchfile и Appfile.

כעת בג'נקינס ניתן לקרוא לפקודות קצרות שלא "מטשטשות" את התצוגה וקלות לקריאה בעין:

# fastlane ios <lane_name>

$ fastlane ios build
$ fastlane ios test
$ fastlane ios run_sonar
$ fastlane ios deploy

הידד, אנחנו מסתדרים נהדר!

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

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

חווית CICD ניידת: תקן מהיר אחד עבור יישומים ניידים רבים

משימה מס' 2: השגת Fastfile יחיד עבור יישומי N

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

Fastlane יכול להתמודד עם משתני סביבה, וכבר ניסינו זאת על ידי הגדרת סיסמה מ-Keychain:

ENV['KEYCHAIN_PASSWORD']

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

#for build, test and deploy
APPLICATION_SCHEME_NAME=appScheme
APPLICATION_PROJECT_NAME=app.xcodeproj
APPLICATION_WORKSPACE_NAME=app.xcworkspace
APPLICATION_NAME=appName

OUTPUT_IPA_NAME=appName.ipa

#app info
APP_BUNDLE_IDENTIFIER=com.example.appName
APPLE_ID=appleID@example.com
TEAM_ID=ABCD1234
FASTLANE_ITC_TEAM_ID=123456789

כעת, כדי להתחיל להשתמש במפתחות אלה בקבצי fastlane, היינו צריכים להבין כיצד להעביר אותם לשם. ל-Fastlane יש פתרון לכך: טעינת משתנים דרך dotenvבתיעוד נכתב שאם חשוב לך לטעון מפתחות למטרות שונות, צור מספר קבצי תצורה בספריית fastlane. .env, .env.default, .env.development.

ואז החלטנו להשתמש בספרייה הזו קצת אחרת. נמקם במאגרי המפתחים לא את הסקריפטים של Fastlane ואת המטא-מידע שלהם, אלא את המפתחות הייחודיים של האפליקציה הזו בקובץ. .env.appName.

עצמם Fastfile, Appfile, Matchfile и Gymfile, הסתרנו אותו במאגר נפרד. הסתרנו שם גם קובץ נוסף עם מפתחות-סיסמאות משירותים אחרים - .env.
לדוגמה, אתה יכול לראות כאן.

חווית CICD ניידת: תקן מהיר אחד עבור יישומים ניידים רבים

ב-CI הקריאה לא השתנתה הרבה, נוסף מפתח תצורה עבור יישום ספציפי:

# fastlane ios <lane_name> --env appName

$ fastlane ios build --env appName
$ fastlane ios test --env appName
$ fastlane ios run_sonar --env appName
$ fastlane ios deploy --env appName

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

git clone git@repository.com/FastlaneCICD.git fastlane_temp

cp ./fastlane_temp/fastlane/* ./fastlane/
cp ./fastlane_temp/fastlane/.env fastlane/.env

לעת עתה השארנו את הפתרון הזה, למרות של-Fastlane יש פתרון לטעינת Fastfile דרך פעולה import_from_git, אבל זה עובד רק עבור Fastfile, עבור קבצים אחרים - לא. אם אתם רוצים "יפה באמת", אתם יכולים לכתוב משלכם action.

Аналогичный набор сделали для Android приложений и ReactNative, файлы лежат в одном репозитории, но в разных ветках iOS, android и react_native.

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

עכשיו זה הכל בטוח

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

Кажется, остался неосвещенным пункт с Fastfile для Android и подпись приложений, если статья будет интересна, напишу продолжение. Буду рада вашим вопросам или предложениям «как бы вы решили эту задачу» в комментариях или в Telegram בשקירובה.

מקור: www.habr.com

קנה אירוח אמין לאתרים עם הגנת DDoS, שרתי VPS VDS 🔥 קנה אחסון אתרים אמין עם הגנת DDoS, שרתי VPS VDS | ProHoster