Αυτό το έγγραφο εξηγεί πώς να ρυθμίσεις ροές εργασίας Συνεχούς Ενσωμάτωσης (Continuous Integration, CI) για μια γλωσσική διαδρομή του Exercism χρησιμοποιώντας το GitHub Actions (GHA). Παρέχει βέλτιστες πρακτικές και παραδείγματα που μπορείς να χρησιμοποιήσεις για να φτιάξεις τις δικές σου γρήγορες, αξιόπιστες και στιβαρές ροές εργασίας CI. Οι ροές εργασίας GHA σε αυτόν τον φάκελο μπορούν να προσαρμοστούν ώστε να δουλέψουν με οποιοδήποτε CI, επειδή η βασική δομή παραμένει ίδια.
Θα:
Παράδειγμα υλοποίησης αυτών των αρχείων ροής εργασίας μπορείς να βρεις στο exercism/javascript.
Το υπόλοιπο έγγραφο είναι σχεδιασμένο για να εξηγήσει πώς λειτουργούν οι ροές εργασίας. Αν βιάζεσαι και θέλεις απλώς να περάσεις από το Travis ή το Circle στο GHA χωρίς να βελτιστοποιήσεις τα script για τα PR, ρίξε μια ματιά στον οδηγό των ~10 λεπτών μας για τη μετάβαση από το Travis.
Οι προτεινόμενες ενέργειες για τον έλεγχο της ακεραιότητας του περιεχομένου του αποθετηρίου σου είναι οι εξής:
configlet για να ελέγξεις το config.json
v3 απαιτεί νέα αρχεία· αυτό μπορεί να μετακινηθεί στο configlet)Μπορεί επίσης να υπάρχουν ενέργειες ειδικές για τη διαδρομή. Για παράδειγμα:
Και ίσως να θέλεις περισσότερους ελέγχους ποιότητας ζωής, όπως:
Για κάθε ενέργεια, σκέψου πόσο συχνά πρέπει να εκτελείται.
configlet είναι τόσο σημαντικός (επειδή μια διαδρομή μπορεί να σπάσει αν σπάσει το config.json) που μάλλον πρέπει να εκτελείται πάντα, αλλά χρειάζεται να εκτελεστεί μόνο μία φορά ανά commit.Μπορεί να είναι πολύ χρήσιμο να κάνεις τις ενέργειες που πρέπει να εκτελούνται διαθέσιμες και τοπικά. Αυτό σημαίνει ότι τα script που κάνουν την πραγματική δουλειά μπορούν να εκτελεστούν και χειροκίνητα. Για να το πετύχεις αυτό, μην ενσωματώνεις την ενέργεια μέσα στα αρχεία ροής εργασίας, αλλά δημιούργησε ένα ξεχωριστό script. Για παράδειγμα, ο έλεγχος για stubs μπορεί να γίνει εξ ολοκλήρου με bash μέσα στο αρχείο ροής εργασίας, αλλά η σύσταση εδώ είναι να δημιουργήσεις αντ' αυτού ένα νέο εκτελέσιμο script, το scripts/ci-check.
"Μα η εντολή είναι πολύ σύντομη, π.χ.
eslint . --ext ts --ext tsx".Όταν αυτή η εντολή χρειαστεί να ενημερωθεί, πρέπει τώρα να ενημερωθεί σε όλα τα σημεία στην τεκμηρίωση, στα αρχεία ροής εργασίας και στα μυαλά των maintainers. Η εξαγωγή της σε ένα script λύνει όλα αυτά. Η ανάγνωση ενός αρχείου ροής εργασίας μπορεί επίσης να είναι πολύ τρομακτική.
Τα script scripts/pr και scripts/pr-check (δες τα πρότυπα) εκτελούνται με πολλαπλά ορίσματα, ένα για κάθε αρχείο που άλλαξε ή προστέθηκε σε αυτό το PR. Για παράδειγμα, αν το two-fer έχει ενημερωθεί, μια κλήση μπορεί να μοιάζει κάπως έτσι:
scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext
Συνιστάται να εκτελείς τυχόν ενέργειες για την άσκηση που άλλαξε και όχι για το αρχείο που άλλαξε. Αυτό συμβαίνει επειδή η αλλαγή ενός αρχείου πιθανότατα προκαλεί αλλαγές σε ολόκληρη την άσκηση (σκέψου: διαμόρφωση, πακέτα).
Δεν είσαι έτοιμος; / Πολύπλοκο;
Πριν εφαρμόσεις αυτή τη βελτιστοποίηση, μπορείς να την αγνοήσεις με ασφάλεια! Ο οδηγός μετάβασης υπονοεί να την προσθέσεις σε μεταγενέστερο στάδιο. Αν αγνοήσεις τα ορίσματα εισόδου, όλοι οι έλεγχοι θα εκτελεστούν σε όλες τις ασκήσεις. Αυτό είναι απολύτως εντάξει. Απλώς θα πάρει περισσότερο χρόνο.
Αν η διαδρομή έχει ένα μόνο αρχείο εξαρτήσεων "top-level" ή/και άλλα αρχεία διαμόρφωσης, πρόσθεσε ένα βήμα ακεραιότητας (που υπάρχει δίπλα σε ένα scripts/sync ή bin/sync, το οποίο θα αντέγραφε όλα τα αρχεία διαμόρφωσης σε όλες τις ασκήσεις), το οποίο διασφαλίζει ότι τα αρχεία top-level/base είναι ίδια με αυτό που αντιγράφηκε στους καταλόγους των ασκήσεων. Τώρα οι εξαρτήσεις μπορούν να ενημερωθούν, να συγχρονιστούν σε όλο το αποθετήριο, και μπορούμε να διασφαλίσουμε ότι όλες οι ασκήσεις έχουν την ίδια διαμόρφωση.
Ένας συνηθισμένος τρόπος για να το πετύχεις είναι να χρησιμοποιήσεις ένα checksum. Το Ubuntu (και διάφορες άλλες διανομές Linux) έρχεται με ένα εργαλείο που λέγεται sha1sum, αλλά χρησιμοποιώντας οποιαδήποτε μέθοδο για να κατακερματίσεις ή να ανάγεις το αρχείο διαμόρφωσης (md5, sha1, crc32) σε μια τιμή checksum, θα δούλευε:
$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md
Αν η διαδρομή χρησιμοποιεί επιπλέον ροές εργασίας που απαιτούν πρόσβαση στο token του GitHub ή σε άλλα secrets, είναι βέλτιστη πρακτική να κλειδώσεις όλες τις ενέργειες που χρησιμοποιούνται στη ροή εργασίας σε ένα συγκεκριμένο commit. Δες τον οδηγό ενίσχυσης ασφαλείας του GitHub για λεπτομέρειες.
Για παράδειγμα:
- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1
Αν τα εργαλεία έχουν lockfiles για τη διαχείριση εξαρτήσεων, σκέψου να το κάνεις commit στο αποθετήριο και να χρησιμοποιήσεις ένα "frozen lockfile" μέσα στα αρχεία ροής εργασίας. Για παράδειγμα: npm ci, yarn install --frozen-lockfile και bundle install --frozen. Αυτό διασφαλίζει ότι το lockfile είναι ενημερωμένο όταν αλλάζεις εξαρτήσεις και αποτρέπει την είσοδο κακόβουλων πακέτων.
Σε αυτόν τον κατάλογο υπάρχουν τουλάχιστον τα ακόλουθα πρότυπα:
configlet.yml: Αυτή η ροή εργασίας θα φέρει το τελευταίο binary του configlet και θα κάνει lint σε αυτό το αποθετήριο. Εκτελείται σε κάθε commit. Για PR, εκτελείται στο πραγματικό commit και σε ένα δέντρο "after merge".ci.yml: Αυτή η ροή εργασίας εκτελείται μόνο στον κύριο κλάδο, μία φορά σε κάθε commit.
pr.ci.yml: Αυτή η ροή εργασίας εκτελείται μόνο σε PR, μία φορά σε κάθε commit.
Οι ροές εργασίας που δεν αφορούν PR μπορούν επίσης να ενεργοποιηθούν μέσω του workflow_dispatch.
Κάθε αρχείο αναφέρει στην κορυφή ποια "scripts" πρέπει να είναι διαθέσιμα. Αν θέλεις αυτά να είναι binaries, αντικατέστησε το scripts/xxx με bin/xxx. Κάποια εργαλεία θα απαιτήσουν τα binaries να βρίσκονται μέσα σε έναν φάκελο bin.
scripts/ci: ένα script που θα πρέπει να κάνει build και test σε όλες τις ασκήσεις, χρησιμοποιώντας τις λύσεις-παραδείγματα σε αντιπαραβολή με τα testsscripts/ci-check: ένα script που θα πρέπει να κάνει lint σε όλες τις ασκήσεις και, προαιρετικά, να ελέγχει για stubs, ακεραιότητα διαμόρφωσης και άλλαscripts/pr: ίδιο με το scripts/ci, αλλά θα πρέπει να εκτελείται μόνο για ασκήσεις που προκύπτουν από τα paths που δίνονται ως είσοδοςscripts/pr-check: ίδιο με το scripts/ci-check, αλλά θα πρέπει να εκτελείται μόνο για αρχεία ή ασκήσεις που προκύπτουν από τα paths που δίνονται ως είσοδοςΑν αντιμετωπίσεις οποιοδήποτε πρόβλημα ή θέλεις κάποιος να ελέγξει τις ροές εργασίας σου, κάνε ping στην ομάδα @exercism/github-actions.
Άλλαξες ένα αρχείο top-level που θα έπρεπε να προκαλέσει εκτέλεση CI σε όλες τις ασκήσεις
Τη στιγμή που γράφεται αυτό, το
pr.ci.ymlεπιτρέπει μόνο δοκιμές βάσει "επέκτασης". Ιδανικά, αυτό θα ενημερωθεί ώστε να ενεργοποιείται πάντα όταν αλλάζουν συγκεκριμένα αρχεία (για παράδειγμα το binary για την εκτέλεση των tests). Ωστόσο, αυτές οι αλλαγές είναι συχνά σπάνιες και γίνονται από maintainers, οπότε το γεγονός ότι τοci.ymlεκτελείται στο main, πάντα, για τα πάντα, είναι μάλλον αρκετά ασφαλές.
Δημιούργησες ένα αρχείο scripts/xxx στα Windows και τώρα δε δουλεύει στο {άλλο λειτουργικό σύστημα}
Από προεπιλογή, τα αρχεία που δημιουργούνται στα Windows δεν έχουν ενσωματωμένα μεταδεδομένα στο git-index σχετικά με το αν είναι εκτελέσιμα, επειδή το μοντέλο δικαιωμάτων στα Windows είναι διαφορετικό. Το Git, από προεπιλογή, θα χρησιμοποιήσει τα μεταδεδομένα του git-index για να καθορίσει αν το αρχείο πρέπει να είναι εκτελέσιμο σε συστήματα βασισμένα σε POSIX, και έτσι θα κάνει το αρχείο
scripts/xxxΜΗ εκτελέσιμο.
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"