ProHoster > Blog > διαχείριση > Εμπειρία CICD για φορητές συσκευές: ένα πρότυπο fastlane για πολλές εφαρμογές για κινητές συσκευές
Εμπειρία CICD για φορητές συσκευές: ένα πρότυπο fastlane για πολλές εφαρμογές για κινητές συσκευές
Θα ήθελα να μιλήσω για τη συνεχή ενσωμάτωση και παράδοση για εφαρμογές για κινητά χρησιμοποιώντας το fastlane. Πώς υλοποιούμε το CI/CD σε όλες τις εφαρμογές για κινητά, πώς φτάσαμε εκεί και τι έγινε τελικά.
Υπάρχει ήδη αρκετό υλικό στο δίκτυο για το εργαλείο, το οποίο μας έλειπε τόσο πολύ στην αρχή, οπότε σκόπιμα δεν θα περιγράψω το εργαλείο λεπτομερώς, αλλά θα αναφερθώ μόνο σε αυτό που είχαμε τότε:
Ιστορικό για την εμφάνιση κινητών CI/CD στην εταιρεία
Τεχνική λύση για την ανάπτυξη CI/CD για N-εφαρμογές
Το πρώτο μέρος είναι περισσότερο νοσταλγία για τα παλιά και το δεύτερο είναι μια εμπειρία που μπορείτε να εφαρμόσετε στον εαυτό σας.
Έτσι έγινε ιστορικά
Έτος 2015
Μόλις ξεκινήσαμε να αναπτύσσουμε εφαρμογές για κινητά, τότε δεν γνωρίζαμε τίποτα για τη συνεχή ενοποίηση, για τα DevOps και άλλα μοντέρνα πράγματα. Κάθε ενημέρωση εφαρμογής κυκλοφόρησε από τον ίδιο τον προγραμματιστή από το μηχάνημά του. Και αν για το Android είναι αρκετά απλό - συναρμολογημένο, υπογεγραμμένο .apk και το ανέβασε στην Κονσόλα προγραμματιστή Google, στη συνέχεια για το iOS το τότε εργαλείο διανομής μέσω Xcode μας άφησε υπέροχες βραδιές - οι προσπάθειες λήψης του αρχείου συχνά κατέληγαν σε σφάλματα και έπρεπε να προσπαθήσουμε ξανά. Αποδείχθηκε ότι ο πιο προηγμένος προγραμματιστής δεν γράφει κώδικα πολλές φορές το μήνα, αλλά απελευθερώνει την εφαρμογή.
Έτος 2016
Μεγαλώσαμε, είχαμε ήδη σκέψεις για το πώς να ελευθερώσουμε προγραμματιστές από μια ολόκληρη μέρα για κυκλοφορία και εμφανίστηκε επίσης μια δεύτερη εφαρμογή, η οποία μας ώθησε περισσότερο προς την αυτοματοποίηση. Την ίδια χρονιά, εγκαταστήσαμε το Jenkins για πρώτη φορά και γράψαμε ένα σωρό τρομακτικά σενάρια, πολύ παρόμοια με αυτά που δείχνει το fastlane στην τεκμηρίωσή του.
Δυστυχώς, μέχρι τώρα μόνο οι προγραμματιστές μας γνώριζαν πώς λειτουργούν αυτά τα σενάρια και γιατί χρειάζεται αυτή η ατελείωτη στοίβα πλήκτρων, και όταν κάτι έσπασε ξανά, πήραν τα «υπέροχα βράδια» για την ανάλυση των αρχείων καταγραφής.
Έτος 2017
Φέτος μάθαμε ότι υπάρχει τέτοιο πράγμα όπως fastlane. Δεν υπήρχαν τόσες πολλές πληροφορίες όσες υπάρχουν τώρα - πώς να ξεκινήσετε, πώς να το χρησιμοποιήσετε. Και το ίδιο το εργαλείο ήταν ακόμα ακατέργαστο εκείνη την εποχή: τα συνεχή λάθη μόνο μας απογοήτευαν και ήταν δύσκολο να πιστέψουμε στον μαγικό αυτοματισμό που υποσχέθηκαν.
Ωστόσο, τα κύρια βοηθητικά προγράμματα που περιλαμβάνονται στον πυρήνα fastlane είναι gym и pilot, καταφέραμε να το ξεκινήσουμε.
Έχουν βελτιωθεί, έστω και μόνο επειδή δεν είναι όλες οι απαραίτητες παράμετροι xcodebuild, πρέπει να υποδείξετε - gym θα καταλάβει ανεξάρτητα πού και τι βρίσκεται. Και για περισσότερη λεπτομέρεια, μπορείτε να καθορίσετε τα ίδια πλήκτρα όπως στο xcodebuild, μόνο η ονομασία των κλειδιών είναι πιο ξεκάθαρη.
Αυτή τη φορά, χάρη στο γυμναστήριο και τον ενσωματωμένο μορφοποιητή xcpretty, τα αρχεία καταγραφής έχουν γίνει πολύ πιο ευανάγνωστα. Αυτό άρχισε να εξοικονομεί χρόνο για τη διόρθωση σπασμένων συγκροτημάτων και μερικές φορές η ομάδα απελευθέρωσης μπορούσε να το καταλάβει μόνη της.
Δυστυχώς, μετρήσεις ταχύτητας συναρμολόγησης xcodebuild и gym Δεν το κάναμε, αλλά θα εμπιστευόμαστε την τεκμηρίωση - επιτάχυνση έως και 30%.
Ενιαία διαδικασία για όλες τις εφαρμογές
Έτος 2018 και σήμερα
Μέχρι το 2018, η διαδικασία δημιουργίας και διάθεσης εφαρμογών μεταφέρθηκε πλήρως στο Jenkins, οι προγραμματιστές σταμάτησαν να κυκλοφορούν από τα μηχανήματα τους και μόνο η ομάδα κυκλοφορίας είχε το δικαίωμα να κυκλοφορήσει.
Θέλαμε ήδη να βελτιώσουμε την έναρξη των δοκιμών και τη στατική ανάλυση και τα σενάρια μας μεγάλωναν και μεγάλωναν. Αναπτύχθηκε και άλλαξε μαζί με τις εφαρμογές μας. Εκείνη την εποχή, υπήρχαν περίπου 10 εφαρμογές. Λαμβάνοντας υπόψη ότι έχουμε δύο πλατφόρμες, είναι περίπου 20 «ζωντανά» σενάρια.
Κάθε φορά που θέλαμε να προσθέσουμε ένα νέο βήμα στο σενάριο, έπρεπε να κάνουμε copy-paste τα κομμάτια σε όλα τα σενάρια του κελύφους. Ίσως θα μπορούσαμε να είχαμε δουλέψει πιο προσεκτικά, αλλά συχνά τέτοιες αλλαγές κατέληγαν σε τυπογραφικά λάθη, τα οποία μετατράπηκαν σε βραδιές για την ομάδα έκδοσης για να διορθώσει τα σενάρια και να ανακαλύψει ποιος έξυπνος τύπος πρόσθεσε αυτήν την εντολή και τι κάνει στην πραγματικότητα. Σε γενικές γραμμές, δεν μπορεί να ειπωθεί ότι τα σενάρια για τη συναρμολόγηση για μία πλατφόρμα ήταν τουλάχιστον κάπως παρόμοια. Αν και σίγουρα έκαναν το ίδιο πράγμα.
Για να ξεκινήσετε μια διαδικασία για μια νέα εφαρμογή, ήταν απαραίτητο να αφιερώσετε μια μέρα για να επιλέξετε μια «φρέσκια» έκδοση αυτών των σεναρίων, να την διορθώσετε και να πείτε ότι «ναι, λειτουργεί».
Το καλοκαίρι του 2018, κοιτάξαμε για άλλη μια φορά προς το αναπτυσσόμενο fastlane.
Εργασία #1: συνοψίστε όλα τα βήματα του σεναρίου και ξαναγράψτε τα στο Fastfile
Όταν ξεκινήσαμε, τα σενάρια μας έμοιαζαν με ένα ποδόπανο που αποτελείται από όλα τα βήματα και τα δεκανίκια σε ένα σενάριο με κέλυφος στο Jenkins. Δεν έχουμε ακόμη μεταβεί σε αγωγό και διαίρεση κατά στάδιο.
Εξετάσαμε τι έχουμε και εντοπίσαμε 4 βήματα που ταιριάζουν στην περιγραφή του CI/CD μας:
κατασκευή - εγκατάσταση εξαρτήσεων, συναρμολόγηση του αρχείου,
βυθόμετρο - εκκινεί όλα τα linters και στέλνει αναφορές στο SonarQube,
ανάπτυξη — αποστολή ενός τεχνουργήματος στο 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: "[email protected]",
app_identifier: "com.example.app",
dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
team_id: "ITS_TEAM_ID")
end
Στο παραπάνω παράδειγμα, μόνο μέρος των παραμέτρων που πρέπει να καθορίσουμε: αυτές είναι οι παράμετροι κατασκευής - σχήμα, διαμόρφωση, ονόματα προφίλ παροχής, καθώς και παράμετροι διανομής - Apple ID του λογαριασμού προγραμματιστή, κωδικός πρόσβασης, αναγνωριστικό εφαρμογής κ.λπ. επί. Ως πρώτη προσέγγιση, βάζουμε όλα αυτά τα κλειδιά σε ειδικά αρχεία - Gymfile, Matchfile и Appfile.
Τώρα στο Jenkins μπορείτε να καλέσετε σύντομες εντολές που δεν θολώνουν την προβολή και είναι εύκολα αναγνώσιμες από το μάτι:
Τι πήρες? Εκκαθάριση εντολών για κάθε βήμα. Καθαρισμένα σενάρια, τακτοποιημένα σε αρχεία fastlane. Χαρούμενοι, τρέξαμε στους προγραμματιστές ζητώντας τους να προσθέσουν όλα όσα χρειάζονταν στα αποθετήρια τους.
Αλλά καταλάβαμε εγκαίρως ότι θα συναντούσαμε τις ίδιες δυσκολίες - θα είχαμε ακόμα 20 σενάρια συναρμολόγησης που με τον ένα ή τον άλλο τρόπο θα άρχιζαν να ζουν τη δική τους ζωή, θα ήταν πιο δύσκολο να τα επεξεργαστούμε, αφού τα σενάρια θα μετακινούνταν σε αποθετήρια, και δεν είχαμε πρόσβαση εκεί. Και, γενικά, δεν θα μπορέσει να λυθεί έτσι ο πόνος μας.
Εργασία #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
[email protected]
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.
Μπορείτε να δείτε ένα παράδειγμα εδώ.
Στο CI, η κλήση δεν έχει αλλάξει πολύ· έχει προστεθεί ένα κλειδί διαμόρφωσης για μια συγκεκριμένη εφαρμογή:
Άφησε αυτήν τη λύση προς το παρόν, αν και το Fastlane έχει μια λύση για τη λήψη του Fastfile μέσω δράσηimport_from_git, αλλά λειτουργεί μόνο για το Fastfile, αλλά όχι για άλλα αρχεία. Αν θέλετε «πραγματικά όμορφο», μπορείτε να γράψετε το δικό σας action.
Ένα παρόμοιο σετ έγινε για εφαρμογές Android και ReactNative, τα αρχεία βρίσκονται στο ίδιο αποθετήριο, αλλά σε διαφορετικούς κλάδους iOS, android и react_native.
Όταν η ομάδα έκδοσης θέλει να προσθέσει κάποιο νέο βήμα, οι αλλαγές στο σενάριο καταγράφονται μέσω MR στο git, δεν χρειάζεται πλέον να αναζητάτε τους ένοχους των σπασμένων σεναρίων και γενικά, τώρα πρέπει να προσπαθήσετε να το σπάσετε.
Τώρα αυτό είναι σίγουρα
Προηγουμένως, ξοδεύαμε χρόνο για να διατηρήσουμε όλα τα σενάρια, να τα ενημερώσουμε και να διορθώσουμε όλες τις συνέπειες των ενημερώσεων. Ήταν πολύ απογοητευτικό όταν οι λόγοι για τα λάθη και το χρόνο διακοπής στις εκδόσεις ήταν απλά τυπογραφικά λάθη που ήταν τόσο δύσκολο να παρακολουθούνται στο συνονθύλευμα των σεναρίων του κελύφους. Τώρα τέτοια σφάλματα μειώνονται στο ελάχιστο. Οι αλλαγές γίνονται σε όλες τις εφαρμογές ταυτόχρονα. Και χρειάζονται 15 λεπτά για να τεθεί σε διαδικασία μια νέα εφαρμογή - ρυθμίστε μια διοχέτευση προτύπων στο CI και προσθέστε τα κλειδιά στο αποθετήριο του προγραμματιστή.
Φαίνεται ότι το θέμα με το Fastfile για Android και την υπογραφή εφαρμογής παραμένει ανεξήγητο· αν το άρθρο είναι ενδιαφέρον, θα γράψω μια συνέχεια. Θα χαρώ να δω τις ερωτήσεις ή τις προτάσεις σας "πώς θα λύνατε αυτό το πρόβλημα" στα σχόλια ή στο Telegram bashkirova.