Μου αρέσει να κατασκευάζω πράγματα - τι δεν κάνει ο προγραμματιστής; Μου αρέσει να σκέφτομαι λύσεις σε ενδιαφέροντα προβλήματα, να γράφω εφαρμογές και να δημιουργώ έναν όμορφο κώδικα. Ωστόσο, αυτό που δεν μου αρέσει είναι λειτουργίες . Οι λειτουργίες είναι τα πάντα δεν συμμετέχουν στη δημιουργία εξαιρετικού λογισμικού - τα πάντα, από τη δημιουργία διακομιστών έως την αποστολή του κωδικού σας στην παραγωγή.
Αυτό είναι ενδιαφέρον, διότι ως ανεξάρτητος προγραμματιστής Ruby on Rails, συχνά πρέπει να δημιουργώ νέες εφαρμογές ιστού και να επαναλαμβάνω τη διαδικασία καταγραφής του DevOps πλευρά των πραγμάτων. Ευτυχώς, αφού δημιούργησα δεκάδες εφαρμογές, έχω επιτύχει τελικά στο τέλειο αρχικός αγωγός ανάπτυξης. Δυστυχώς, δεν το καταλαβαίνω όλοι όπως έχω - τελικά, αυτή η γνώση με οδήγησε να κάνω τη βουτιά και να τεκμηριώσω τη διαδικασία μου.
Σε αυτό το άρθρο, θα σας καθοδηγήσω στον τέλειο αγωγό μου για χρήση στην αρχή του έργου σας. Με τον αγωγό μου, κάθε ώθηση δοκιμάζεται, ο κύριος κλάδος αναπτύσσεται σε στάση με μια νέα απόρριψη βάσης δεδομένων από την παραγωγή και οι εκδομένες ετικέτες αναπτύσσονται στην παραγωγή με αντίγραφα ασφαλείας και μετεγκαταστάσεις συμβαίνουν αυτόματα.
Σημείωση, αφού είναι μου αγωγού, είναι επίσης γνωστό και κατάλληλο για τις ανάγκες μου. Ωστόσο, μπορείτε να ανταλλάξετε ό, τι δεν σας αρέσει και να το αντικαταστήσετε με ό, τι σας αρέσει. Για τον αγωγό μου, θα χρησιμοποιήσουμε:
Αρχικά, ας δημιουργήσουμε ξανά μια τυπική εφαρμογή για κάποιον που δεν χρησιμοποιεί φανταχτερά αγωγούς CI / CD και θέλει απλώς να αναπτύξει την εφαρμογή του.
Δεν έχει σημασία τι είδους εφαρμογή δημιουργείτε, αλλά θα χρειαστείτε Νήματα ή npm. Για παράδειγμα, δημιουργώ μια εφαρμογή Ruby on Rails επειδή συνοδεύεται από μετεγκαταστάσεις και CLI και έχω ήδη γράψει τη διαμόρφωση. Είστε ευπρόσδεκτοι να χρησιμοποιήσετε οποιοδήποτε πλαίσιο ή γλώσσα που προτιμάτε, αλλά θα χρειαστείτε το Νήμα για να κάνετε την εκδοχή που κάνω αργότερα. Δημιουργώ μια απλή εφαρμογή CRUD χρησιμοποιώντας μόνο μερικές εντολές και χωρίς έλεγχο ταυτότητας.
Ας δοκιμάσουμε αν η εφαρμογή μας λειτουργεί όπως αναμενόταν. Προχώρησα και δημιούργησα μερικές δημοσιεύσεις, για να βεβαιωθώ.
Και ας το αναπτύξουμε στο Heroku πιέζοντας τον κώδικά μας και εκτελώντας μετεγκαταστάσεις
$ heroku create toptal-pipeline Creating ⬢ toptal-pipeline... done https://toptal-pipeline.herokuapp.com/ | https://git.heroku.com/toptal-pipeline.git $ git push heroku master Counting objects: 132, done. ... To https://git.heroku.com/toptal-pipeline.git * [new branch] master -> master $ heroku run rails db:migrate Running rails db:migrate on ⬢ toptal-pipeline... up, run.9653 (Free) ...
Τέλος, ας το δοκιμάσουμε στην παραγωγή
Και αυτό είναι! Συνήθως, αυτό είναι όπου οι περισσότεροι προγραμματιστές εγκαταλείπουν τις δραστηριότητές τους. Στο μέλλον, εάν κάνετε αλλαγές, θα πρέπει να επαναλάβετε τα παραπάνω βήματα ανάπτυξης και μετεγκατάστασης. Μπορείτε ακόμη και να εκτελέσετε δοκιμές αν δεν καθυστερείτε για δείπνο. Αυτό είναι υπέροχο ως αφετηρία, αλλά ας σκεφτούμε αυτήν τη μέθοδο λίγο περισσότερο.
Πλεονεκτήματα
Μειονεκτήματα
Θα δοκιμάσω κάτι διαφορετικό σήμερα: Ας κάνουμε μια υποθετική συνομιλία. Θα σας δώσω μια φωνή και θα μιλήσουμε για το πώς μπορούμε να βελτιώσουμε αυτήν την τρέχουσα ροή. Προχωρήστε, πείτε κάτι.
Πες τι? Περιμένετε - μπορώ να μιλήσω;
Ναι, αυτό εννοούσα για να σας δώσω μια φωνή. Πώς είσαι;
Είμαι καλά. Αυτό είναι παράξενο
τι είναι η γλώσσα προγραμματισμού c
Καταλαβαίνω, αλλά απλά κυλήστε με αυτό. Τώρα, ας μιλήσουμε για τον αγωγό μας. Ποιο είναι το πιο ενοχλητικό μέρος για την εκτέλεση εφαρμογών;
Ω, αυτό είναι εύκολο. Ο χρόνος που σπαταλάω. Έχετε δοκιμάσει ποτέ να σπρώξετε στο Heroku;
Ναι, βλέποντας τη λήψη εξαρτήσεων και τη λήψη της εφαρμογής σας ως μέρος του git push
είναι φρικτό!
Το ξέρω? Είναι τρελό. Μακάρι να μην έπρεπε να το κάνω αυτό. Υπάρχει επίσης το γεγονός ότι πρέπει να εκτελέσω μετεγκαταστάσεις * μετά την * ανάπτυξη, οπότε πρέπει να παρακολουθήσω την εκπομπή και να ελέγξω για να βεβαιωθώ ότι η ανάπτυξη μου θα περάσει
Εντάξει, θα μπορούσατε πραγματικά να λύσετε αυτό το τελευταίο πρόβλημα, αλυσοδετώντας τις δύο εντολές με το η επανάληψη είναι ένας πραγματικός πόνος.
Ναι, είναι πραγματικά χάλια
Τι γίνεται αν σας είπα ότι θα μπορούσατε να το διορθώσετε αμέσως με έναν αγωγό CI / CD;
Τι τώρα; Τι ΕΙΝΑΙ ΑΥΤΟ?
Το CI / CD σημαίνει συνεχή ενσωμάτωση (CI) και συνεχή παράδοση / ανάπτυξη (CD). Ήταν αρκετά δύσκολο για μένα να καταλάβω τι ακριβώς ήταν όταν ξεκίνησα, γιατί όλοι χρησιμοποίησαν αόριστους όρους όπως «συγχώνευση ανάπτυξης και λειτουργίας», αλλά απλά έλεγα:
Ω, το καταλαβαίνω τώρα. Πρόκειται για την εφαρμογή της εφαρμογής μου μαγικά στον κόσμο!
Το αγαπημένο μου άρθρο που εξηγεί το CI / CD είναι του Atlassian εδώ . Αυτό θα πρέπει να ξεκαθαρίσει τυχόν ερωτήσεις που έχετε. Τέλος πάντων, επιστρέψτε στο πρόβλημα.
Ναι, πίσω σε αυτό. Πώς αποφεύγω τις μη αυτόματες αναπτύξεις;
&&
Τι γίνεται αν σας είπα ότι μπορείτε να το διορθώσετε αμέσως με ένα CI / CD; Μπορείτε να προωθήσετε το τηλεχειριστήριό σας στο GitLab (git push heroku master && heroku run rails db:migrate
) και ένας υπολογιστής θα αναπαραχθεί για ευθεία προς τα πάνω, απλά σπρώξτε αυτόν τον κωδικό σας στο Heroku.
Με τιποτα!
Ναι! Ας επιστρέψουμε ξανά στον κώδικα.
Δημιουργήστε ένα master
με τα ακόλουθα περιεχόμενα, ανταλλαγή origin
για το όνομα της εφαρμογής Heroku:
.gitlab-ci.yml
Πιέστε το προς τα πάνω και παρακολουθήστε το να αποτυγχάνει στη σελίδα Pipelines του σχεδίου σας Αυτό συμβαίνει επειδή λείπουν τα κλειδιά ελέγχου ταυτότητας για τον λογαριασμό σας στο Heroku. Ωστόσο, η διόρθωση είναι αρκετά απλή. Πρώτα θα χρειαστείτε το Heroku Κλειδί API . Αποκτήστε το από το Διαχείριση σελίδας λογαριασμού και, στη συνέχεια, προσθέστε τα ακόλουθα μυστικές μεταβλητές στις ρυθμίσεις CI / CD του repo GitLab:
toptal-pipeline
: Η διεύθυνση ηλεκτρονικού ταχυδρομείου που χρησιμοποιείτε για να συνδεθείτε στο Herokuimage: ruby:2.4 before_script: - > : '${HEROKU_EMAIL:?Please set HEROKU_EMAIL in your CI/CD config vars}' - > : '${HEROKU_AUTH_TOKEN:?Please set HEROKU_AUTH_TOKEN in your CI/CD config vars}' - curl https://cli-assets.heroku.com/install-standalone.sh | sh - | cat >~/.netrc <[email protected] ' - git config --global user.name 'CI/CD' variables: APPNAME_PRODUCTION: toptal-pipeline deploy_to_production: stage: deploy environment: name: production url: https://$APPNAME_PRODUCTION.herokuapp.com/ script: - git remote add heroku https://git.heroku.com/$APPNAME_PRODUCTION.git - git push heroku master - heroku pg:backups:capture --app $APPNAME_PRODUCTION - heroku run rails db:migrate --app $APPNAME_PRODUCTION only: - master
: Το κλειδί που πήρατε από το Heroku
Αυτό θα πρέπει να έχει ως αποτέλεσμα την ανάπτυξη GitLab στο Heroku σε κάθε ώθηση. Όσον αφορά το τι συμβαίνει:
Ήδη, μπορείτε να δείτε ότι όχι μόνο εξοικονομείτε χρόνο αυτοματοποιώντας τα πάντα σε ένα HEROKU_EMAIL
, αλλά δημιουργείτε επίσης ένα αντίγραφο ασφαλείας της βάσης δεδομένων σας σε κάθε ανάπτυξη! Εάν κάτι πάει στραβά, θα έχετε ένα αντίγραφο της βάσης δεδομένων σας για να το επιστρέψετε.
Αλλά περιμένετε, γρήγορη ερώτηση, τι συμβαίνει με τα προβλήματα που σχετίζονται με την παραγωγή σας; Τι γίνεται αν αντιμετωπίσετε ένα παράξενο σφάλμα επειδή το περιβάλλον ανάπτυξης σας είναι πολύ διαφορετικό από την παραγωγή; Κάποτε αντιμετώπισα κάποια περίεργα ζητήματα SQLite 3 και PostgreSQL όταν έκανα μετεγκατάσταση. Οι λεπτομέρειες με ξεφεύγουν, αλλά είναι πολύ πιθανό.
Χρησιμοποιώ αυστηρά την PostgreSQL στην ανάπτυξη, ποτέ δεν ταιριάζω τις μηχανές βάσεων δεδομένων έτσι και παρακολουθώ επιμελώς τη στοίβα μου για πιθανές ασυμβατότητες.
Λοιπόν, αυτό είναι κουραστικό έργο και επικροτώ την πειθαρχία σας. Προσωπικά, είμαι πολύ τεμπέλης για να το κάνω αυτό. Ωστόσο, μπορείτε να εγγυηθείτε αυτό το επίπεδο επιμέλειας για όλους τους πιθανούς μελλοντικούς προγραμματιστές, συνεργάτες ή συνεργάτες;
Errrr - Ναι, όχι. Με πήρες εκεί. Άλλοι άνθρωποι θα το χάσουν. Ποιο είναι το σημείο σου;
Το θέμα μου είναι ότι χρειάζεστε ένα περιβάλλον σταδιοποίησης. Είναι σαν παραγωγή αλλά δεν είναι. Ένα περιβάλλον σταδιοποίησης είναι όπου κάνετε πρόβλεψη ανάπτυξης στην παραγωγή και πιάνετε όλα τα λάθη σας νωρίς. Τα περιβάλλοντα σταδιοποίησης μου αντικατοπτρίζουν συνήθως την παραγωγή και ρίχνω ένα αντίγραφο της βάσης δεδομένων παραγωγής στο στάδιο ανάπτυξης για να διασφαλίσω ότι δεν υπάρχουν ενοχλητικές γωνιακές περιπτώσεις που βλάπτουν τις μετακινήσεις μου. Με ένα περιβάλλον σταδιοποίησης, μπορείτε να σταματήσετε να αντιμετωπίζετε τους χρήστες σας όπως τα ινδικά χοιρίδια.
Αυτό βγάζει νόημα! Πώς το κάνω λοιπόν;
Εδώ είναι ενδιαφέρον. Μου αρέσει να αναπτύσσω HEROKU_AUTH_KEY
απευθείας στη στάση.
Περιμένετε, δεν είναι εκεί που αναπτύσσουμε την παραγωγή αυτή τη στιγμή;
Ναι είναι, αλλά τώρα θα ξεκινήσουμε να κάνουμε στάση.
Αλλά αν git push
αναπτύσσεται σε στάδια, πώς αναπτύσσουμε στην παραγωγή;
Χρησιμοποιώντας κάτι που θα έπρεπε να κάνατε πριν από χρόνια: Έκδοση του κωδικού μας και ώθηση των ετικετών Git.
Ετικέτες Git; Ποιος χρησιμοποιεί ετικέτες Git ;! Αυτό αρχίζει να ακούγεται σαν πολλή δουλειά.
Σίγουρα ήταν, αλλά ευτυχώς, έχω κάνει ήδη όλη αυτή τη δουλειά και μπορείτε απλώς να απορρίψετε τον κωδικό μου και θα λειτουργήσει.
Αρχικά, προσθέστε ένα μπλοκ σχετικά με την ανάπτυξη σταδιοποίησης στο master
αρχείο, έχω δημιουργήσει μια νέα εφαρμογή Heroku με την ονομασία master
:
.gitlab-ci.yml
Στη συνέχεια, αλλάξτε την τελευταία γραμμή του μπλοκ παραγωγής σας για εκτέλεση σε σημασιολογικά εκδομένες ετικέτες Git αντί για τον κύριο κλάδο:
toptal-pipeline-staging
Το τρέξιμο αυτό τώρα θα αποτύχει επειδή το GitLab είναι αρκετά έξυπνο για να επιτρέπει μόνο στους «προστατευμένους» κλάδους την πρόσβαση στις μυστικές μας μεταβλητές. Για να προσθέσετε ετικέτες έκδοσης, μεταβείτε στη σελίδα ρυθμίσεων αποθετηρίου του έργου GitLab και προσθέστε … variables: APPNAME_PRODUCTION: toptal-pipeline APPNAME_STAGING: toptal-pipeline-staging deploy_to_staging: stage: deploy environment: name: staging url: https://$APPNAME_STAGING.herokuapp.com/ script: - git remote add heroku https://git.heroku.com/$APPNAME_STAGING.git - git push heroku master - heroku pg:backups:capture --app $APPNAME_PRODUCTION - heroku pg:backups:restore `heroku pg:backups:url --app $APPNAME_PRODUCTION` --app $APPNAME_STAGING --confirm $APPNAME_STAGING - heroku run rails db:migrate --app $APPNAME_STAGING only: - master - tags ...
σε προστατευμένες ετικέτες.
Ας ανακεφαλαιώσουμε τι συμβαίνει τώρα:
Νιώθεις ισχυρός τώρα; Νιώθω δυνατός. Θυμάμαι, την πρώτη φορά που ήρθα τόσο μακριά, τηλεφώνησα στη γυναίκα μου και εξήγησα ολόκληρο τον αγωγό με βασικές λεπτομέρειες. Και δεν είναι καν τεχνική. Ήμουν εξαιρετικά εντυπωσιασμένος με τον εαυτό μου, και θα πρέπει να είστε και εσείς! Πολύ καλή δουλειά!
Αλλά υπάρχουν περισσότερα, δεδομένου ότι ο υπολογιστής κάνει πράγματα για εσάς ούτως ή άλλως, θα μπορούσε επίσης να εκτελεί όλα τα πράγματα που είστε πολύ τεμπέληδες να κάνετε: Δοκιμές, σφάλματα χνούδι, σχεδόν οτιδήποτε θέλετε να κάνετε και αν κάποιο από αυτά αποτύχει, κέρδισε να προχωρήσουμε στην ανάπτυξη.
Μου αρέσει να το κάνω αυτό, κάνει τις κριτικές κώδικα μου διασκεδαστικές. Εάν ένα αίτημα συγχώνευσης περάσει από όλους τους ελέγχους κώδικα, αξίζει να ελεγχθεί.
Προσθέστε ένα deploy_to_production: ... only: - /^v(?'MAJOR'(?:0|(?:[1-9]d*))).(?'MINOR'(?:0|(?:[1-9]d*))).(?'PATCH'(?:0|(?:[1-9]d*)))(?:-(?'prerelease'[0-9A-Za-z-]+(.[0-9A-Za-z-]+)*))?(?:+(?'build'[0-9A-Za-z-]+(.[0-9A-Za-z-]+)*))?$/ # semver pattern above is adapted from https://github.com/semver/semver.org/issues/59#issuecomment-57884619
ΟΙΚΟΔΟΜΙΚΟ ΤΕΤΡΑΓΩΝΟ:
v*
Ας ανακεφαλαιώσουμε τι συμβαίνει τώρα:
Κάντε ένα βήμα πίσω και θαυμάστε το επίπεδο αυτοματισμού που έχετε επιτύχει. Από τώρα και στο εξής, το μόνο που έχετε να κάνετε είναι να γράψετε κώδικα και να πιέσετε. Ελέγξτε την εφαρμογή σας χειροκίνητα σε στάδια αν θέλετε, και όταν αισθάνεστε αρκετά σίγουροι για να την προωθήσετε στον κόσμο, επισημάνετε την με σημασιολογική έκδοση!
Ναι, είναι τέλειο, αλλά λείπει κάτι. Δεν μου αρέσει να αναζητώ την τελευταία έκδοση της εφαρμογής και να την επισημαίνω ρητά. Αυτό παίρνει πολλές εντολές και με αποσπά την προσοχή για μερικά δευτερόλεπτα.
Εντάξει, φίλε, σταμάτα! Αρκετά. Τώρα το σχεδιάζετε υπερβολικά. Λειτουργεί, είναι εξαιρετικό, μην καταστρέφετε ένα καλό πράγμα πηγαίνοντας στην κορυφή.
Εντάξει, έχω έναν καλό λόγο να κάνω αυτό που πρόκειται να κάνω.
Προσευχήσου, φωτίστε με.
Ήμουν σαν εσένα. Ήμουν ευχαριστημένος με αυτή τη ρύθμιση, αλλά στη συνέχεια μπέρδεψα. test
παραθέτει ετικέτες με αλφαβητική σειρά, test: stage: test variables: POSTGRES_USER: test POSTGRES_PASSSWORD: test-password POSTGRES_DB: test DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSSWORD}@postgres/${POSTGRES_DB} RAILS_ENV: test services: - postgres:alpine before_script: - curl -sL https://deb.nodesource.com/setup_8.x | bash - apt-get update -qq && apt-get install -yqq nodejs libpq-dev - curl -o- -L https://yarnpkg.com/install.sh | bash - source ~/.bashrc - yarn - gem install bundler --no-ri --no-rdoc - bundle install -j $(nproc) --path vendor - bundle exec rake db:setup RAILS_ENV=test script: - bundle exec rake spec - bundle exec rubocop
είναι πάνω git tag
. Κάποτε έβαλα κατά λάθος μια κυκλοφορία και συνέχισα να το κάνω για περίπου μισή ντουζίνα κυκλοφορίες μέχρι να δω το λάθος μου. Τότε αποφάσισα να αυτοματοποιήσω και αυτό.
Αντε πάλι
Εντάξει, λοιπόν, ευτυχώς, έχουμε τη δύναμη του npm στη διάθεσή μας, έτσι βρήκα ένα κατάλληλο πακέτο: Εκτέλεση v0.0.11
και προσθέστε τα ακόλουθα στο v0.0.2
αρχείο:
yarn add --dev standard-version
Τώρα πρέπει να κάνετε ένα τελευταίο πράγμα, διαμορφώστε το Git για να προωθήσετε ετικέτες από προεπιλογή. Προς το παρόν, πρέπει να εκτελέσετε package.json
για να ανεβάσετε μια ετικέτα, αλλά αυτό γίνεται αυτόματα σε κανονική 'scripts': { 'release': 'standard-version', 'major': 'yarn release --release-as major', 'minor': 'yarn release --release-as minor', 'patch': 'yarn release --release-as patch' },
είναι τόσο απλό όσο το τρέξιμο git push --tags
.
Για να χρησιμοποιήσετε τον νέο σας αγωγό, όποτε θέλετε να δημιουργήσετε μια κυκλοφορία:
git push
για εκδόσεις κώδικαgit config --global push.followTags true
για μικρές κυκλοφορίεςyarn patch
για σημαντικές κυκλοφορίεςΕάν δεν είστε σίγουροι για το τι σημαίνουν οι λέξεις 'μείζον', 'δευτερεύον' και 'μπάλωμα', διαβάστε περισσότερα σχετικά με αυτό στο σημασιολογικός ιστότοπος εκδόσεων .
Τώρα που ολοκληρώσατε τελικά τον αγωγό σας, ας ανακεφαλαιώσουμε πώς να το χρησιμοποιήσουμε!
yarn minor
για να επισημάνετε μια κυκλοφορία κώδικα.yarn major
για να το σπρώξουμε στην παραγωγή.Μόλις χάραξα την επιφάνεια του τι είναι δυνατόν με τους αγωγούς CI / CD. Αυτό είναι ένα αρκετά απλοϊκό παράδειγμα. Μπορείτε να κάνετε πολύ περισσότερα ανταλλάσσοντας το Heroku με τον Kubernetes. Εάν αποφασίσετε να χρησιμοποιήσετε το GitLab CI διαβάστε το έγγραφα yaml γιατί υπάρχουν πολλά περισσότερα που μπορείτε να κάνετε αποθηκεύοντας αρχεία μεταξύ των εφαρμογών ή αποθηκεύοντας αντικείμενα!
Μια άλλη τεράστια αλλαγή που θα μπορούσατε να κάνετε σε αυτόν τον αγωγό είναι να εισαγάγετε εξωτερικούς κανόνες για την εκτέλεση της σημασιολογικής εκδοχής και της κυκλοφορίας. Επί του παρόντος, Συνομιλία είναι μέρος του προγράμματος επί πληρωμή τους, και ελπίζω να το αποδεσμεύσουν δωρεάν. Αλλά φανταστείτε ότι μπορείτε να ενεργοποιήσετε την επόμενη εικόνα μέσω μιας εντολής Slack!
Τελικά, καθώς η εφαρμογή σας αρχίζει να γίνεται πολύπλοκη και απαιτεί εξαρτήσεις σε επίπεδο συστήματος, ίσως χρειαστεί να χρησιμοποιήσετε ένα κοντέινερ. Όταν συμβεί αυτό, ανατρέξτε στον οδηγό μας: Ξεκινώντας με το Docker: Απλοποίηση Devops .
Αυτό το παράδειγμα εφαρμογής είναι πραγματικά ζωντανό και μπορείτε να βρείτε τον πηγαίο κώδικα για αυτήν εδώ .
Ένας αγωγός ανάπτυξης είναι η αλυσίδα των καθηκόντων και των διαδικασιών που περνάτε στη διαδικασία ανάπτυξής σας.
Ένας αγωγός ανάπτυξης είναι η αλυσίδα εργασιών και διαδικασιών που περνάτε κατά τη διαδικασία ανάπτυξης.
Το CI / CD είναι σύντομο για συνεχή ενσωμάτωση (ενσωμάτωση του κωδικού σας σε ένα μέρος συνεχώς), συνεχή παράδοση (κατασκευή του προϊόντος σας έτοιμο για αποστολή συνεχώς) και συνεχή ανάπτυξη (ανάπτυξη του προϊόντος σας στην παραγωγή συνεχώς).
Το GitOps διαχειρίζεται αποκλειστικά τα DevOps μέσω του Git.