Μετάβαση στο περιεχόμενο

Συνομιλίες PR

Ένα pull request είναι ήδη το μέρος όπου συμβαίνει η συζήτηση για τον κώδικα. Οι συνομιλίες PR το κάνουν επιφάνεια ενός χώρου εργασίας του Control Center, με τον ίδιο τρόπο που μια γέφυρα συνομιλίας κάνει το Slack μία: κάντε @-αναφορά στο bot της GitHub App του διακομιστή σε ένα PR, απαντήστε μέσα στα νήματα ελέγχου του ή προσθέστε την ετικέτα ai-review, και η εργασία γίνεται στον χώρο ελέγχου του PR — με την ίδια απόδοση και τους ίδιους περιορισμούς όπως οτιδήποτε πληκτρολογείται στην εφαρμογή. Ένα σχόλιο περνά επίσης από πύλη βάσει ιδιότητας μέλους· η ετικέτα όχι, γιατί δεν έχει συντάκτη. Οι απαντήσεις του bot επιστρέφουν στο GitHub, στο νήμα όπου τέθηκε η ερώτηση.

Τρεις αποφάσεις διαμορφώνουν τη λειτουργία και καθεμία είναι η ίδια απόφαση που πήρε η γέφυρα συνομιλίας για τη συνομιλία, διατυπωμένη ξανά για έναν κεντρικό υπολογιστή κώδικα: προς ποια κατεύθυνση τρέχει η σύνδεση, τι εξουσιοδοτεί ένα σχόλιο που φτάνει από έξω και σε ποιον αποδίδεται κάθε πλευρά.

Ο περιοδικός έλεγχος είναι το μέσο μεταφοράς

Ενότητα με τίτλο «Ο περιοδικός έλεγχος είναι το μέσο μεταφοράς»

Το μόνο κανάλι push του GitHub για μια εφαρμογή είναι το webhook, και ένα webhook χρειάζεται ένα URL εισόδου — το μόνο πράγμα που αυτή η επιφάνεια σκόπιμα δεν απαιτεί ποτέ. Έτσι, η ανακάλυψη γίνεται με σάρωση: περίπου κάθε λεπτό, μία αναζήτηση με ψευδώνυμο ανά εγκατάσταση εφαρμογής ζητά από το GitHub PR που αναφέρουν το bot (ή το σύντομο slug του) και ανοιχτά PR που φέρουν την ετικέτα ελέγχου, για τα PR που έχουν ήδη χώρο ελέγχου διαβάζονται τα νήματα σχολίων τους, και τα πάντα συγκρίνονται με βάση το αναγνωριστικό σχολίου με ό,τι είχε εμφανιστεί στην προηγούμενη σάρωση.

Οι συνέπειες του σχεδιασμού αξίζει να ονομαστούν:

  • Η καθυστέρηση είναι διάστημα σάρωσης, όχι γεγονός. Η επιβεβαίωση με 👀 φτάνει μέσα σε περίπου ένα λεπτό. Τίποτα επείγον δεν εξαρτάται από αυτό.
  • Ακριβώς μία φορά, ανά σχόλιο. Τα αναγνωριστικά σχολίων είναι μοναδικά σε όλο το GitHub· καθένα καταγράφεται τη στιγμή που χαρακτηρίζεται κατάλληλο, πριν ενεργήσει κάτι πάνω του. Μια κατάρρευση μπορεί να χάσει τον χειρισμό ενός σχολίου, ποτέ να τον ενεργοποιήσει δύο φορές.
  • Ο χρόνος εκτός λειτουργίας καλύπτεται, δεν αναπαράγεται. Το σύνολο όσων έχουν εμφανιστεί αποθηκεύεται, ώστε μια επανεκκίνηση να παραδίδει ό,τι έφτασε όσο ήταν εκτός λειτουργίας. Η μόνη εξαίρεση είναι η πρώτη σάρωση που έγινε ποτέ: χωρίς μνήμη για σύγκριση, ό,τι εκκρεμεί καταγράφεται σιωπηλά — ένας χειριστής που είχε βάλει ετικέτα σε είκοσι PR πριν υπάρξει αυτός ο διακομιστής δεν πρέπει να επιστρέψει σε είκοσι ελέγχους σε εξέλιξη.
  • Η ετικέτα είναι σύνολο, όχι γεγονός. Η αναζήτηση αναφέρει την παρουσία της ετικέτας, οπότε ένα PR με ετικέτα ενεργοποιείται μία φορά, για πάντα. Η εκ νέου προσθήκη μιας ετικέτας αφού αφαιρεθεί είναι αόρατη στη σάρωση· η @-αναφορά είναι η διαδρομή επανεκτέλεσης.

Η αναζήτηση εκτελείται μία φορά ανά λογαριασμό εγκατάστασης, στον πελάτη του ίδιου του κατόχου, γιατί ένα token εγκατάστασης βλέπει μόνο τα αποθετήρια της δικής του εγκατάστασης — ένα μεμονωμένο διαπιστευτήριο για όλο τον διακομιστή θα έχανε σιωπηλά κάθε PR στις άλλες εγκαταστάσεις της εφαρμογής.

Η ιδιότητα μέλους εξουσιοδοτεί, όχι το σχόλιο

Ενότητα με τίτλο «Η ιδιότητα μέλους εξουσιοδοτεί, όχι το σχόλιο»

Ένα σχόλιο σε PR φτάνει κουβαλώντας λίγο περισσότερο από το όνομα σύνδεσης του συντάκτη — μια μη επαληθευμένη εξωτερική ταυτότητα μέχρι αποδείξεως του αντιθέτου. Το bot το αντιστοιχίζει σε ένα αντίστροφο ευρετήριο των μελών του χώρου εργασίας και των συνδεδεμένων λογαριασμών τους στο GitHub, το οποίο ξαναχτίζεται με TTL, γιατί άνθρωποι συνδέονται και προσκαλούνται όσο ο διακομιστής εκτελείται.

Το κλείσιμο κατά την αποτυχία μοιάζει με σκάλα, και κάθε σκαλοπάτι απαντά στο νήμα στο οποίο αρνήθηκε:

  • Ένα άγνωστο όνομα σύνδεσης — χωρίς σύνδεση με λογαριασμό, ή συνδεδεμένο από κάποιον που δεν είναι μέλος αυτού του χώρου εργασίας — λαμβάνει την οδηγία να συνδεθεί και να βεβαιωθεί ότι ανήκει
  • Ένα μέλος μόνο για ανάγνωση (viewer ή guest) ενημερώνεται ότι ο ρόλος του δεν μπορεί να ξεκινήσει εργασία

Οι δύο περιπτώσεις άγνωστου ονόματος σύνδεσης μοιράζονται μία απάντηση: το αντίστροφο ευρετήριο επιστρέφει μόνο μέλη αυτού του χώρου εργασίας, οπότε ένας λογαριασμός χωρίς σύνδεση και ένας συνδεδεμένος μη μέλος είναι η ίδια αστοχία. Καμία από τις δύο δεν προχωρά. Ένα σχόλιο δεν αποδίδεται ποτέ σε κάποιον που δεν το έστειλε, και τα λόγια ενός αγνώστου δεν μπαίνουν ποτέ σε έναν χώρο εργασίας που δεν μπορεί να δει.

Η ετικέτα ai-review δεν έχει συντάκτη προς αντιστοίχιση, οπότε δεν ανεβαίνει αυτή τη σκάλα. Η προσθήκη της ξεκινά τον έλεγχο στον χώρο εργασίας που έχει ήδη συνδεδεμένο το αποθετήριο.

Κάθε πλευρά της συνομιλίας φέρει διαφορετική ταυτότητα, και η διαφορά είναι η ίδια η λειτουργία:

  • Στο GitHub, το bot είναι ο διακομιστής. Κάθε σχόλιο, αντίδραση και απάντηση που αναρτά η γέφυρα χρησιμοποιεί το token εγκατάστασης της εφαρμογής. Κανείς δεν πάτησε τίποτα σε έναν πελάτη, οπότε τίποτα δεν δανείζεται τον λογαριασμό ενός ανθρώπου — ο ίδιος κανόνας που κρατά τα webhook και τον περιοδικό έλεγχο έξω από ανθρώπινα διαπιστευτήρια.
  • Στον χώρο, η ερώτηση είναι δική σας. Το μήνυμα αποδίδεται στο μέλος στο οποίο αντιστοιχίστηκε ο συντάκτης, και η εκτέλεση του πράκτορα γίνεται για λογαριασμό του: τα commits τον αναφέρουν ως συνδημιουργό, και ο δείκτης αυτονομίας και οι περιορισμοί ενεργειών του χώρου εφαρμόζονται ακριβώς όπως σε ένα μήνυμα που πληκτρολογήθηκε στην εφαρμογή. Οι εγγραφές στον κεντρικό υπολογιστή κώδικα από την εκτέλεση εξακολουθούν να γίνονται ως η εφαρμογή — ο ίδιος κανόνας με την παραπάνω κουκκίδα — όχι με το προσωπικό token του μέλους.

Η δημοσίευση των ευρημάτων ελέγχου πίσω στο GitHub παραμένει απόφαση ενός ανθρώπου, που λαμβάνεται στο Control Center. Μια @-αναφορά μπορεί να ξεκινήσει έναν έλεγχο· μόνο ένας άνθρωπος δημοσιεύει έναν.

Ό,τι έχει συνταχθεί από λογαριασμό bot απορρίπτεται πριν εκτελεστεί οποιαδήποτε πύλη — το δικό μας ειδικά, και κάθε κατάληξη [bot], ώστε ούτε το bot ελέγχου μιας άλλης εφαρμογής να μπορεί να ξυπνήσει το δικό μας. Χωρίς αυτό, οι απαντήσεις του ίδιου του bot θα έφταναν ως νέα σχόλια και θα το ενεργοποιούσαν ξανά για πάντα.

Η κατάληξη [bot] είναι επίσης ο λόγος που υπάρχει η σύντομη μορφή. Το GitHub καθορίζει το όνομα σύνδεσης του λογαριασμού μιας εφαρμογής σε <slug>[bot], δεν προσφέρει αυτόματη συμπλήρωση γι’ αυτό και δεν αντιστοιχίζει ποτέ το @slug στην εφαρμογή — οπότε η αποδοχή του γυμνού slug είναι απόφαση του δικού μας αντιστοιχιστή, και η ανακάλυψή του απαιτεί ένα κανάλι αναζήτησης σε ακατέργαστο κείμενο σχολίων αντί για το ευρετήριο αναφορών του GitHub. Το κόστος δηλώνεται αντί να εξομαλύνεται: ένας ανθρώπινος χρήστης που μοιράζεται το slug της εφαρμογής απευθύνεται στο bot με κάθε σύντομη αναφορά του εαυτού του. Τα χαρακτηριστικά ονόματα εφαρμογών κάνουν τη σύγκρουση υποθετική.

  • Χωρίς αυτόματη δημοσίευση. Τα ευρήματα προσγειώνονται στον χώρο ελέγχου· η δημοσίευση στο GitHub είναι ξεχωριστή, ανθρώπινη ενέργεια
  • Χωρίς ασαφή ταυτότητα. Ο συντάκτης αντιστοιχίζεται σε ακριβώς ένα μέλος ή απορρίπτεται — δεν υπάρχει απόδοση κατ’ εκτίμηση
  • Χωρίς webhook της GitHub App. Αυτή η επιφάνεια δεν καταχωρεί ποτέ ένα, οπότε δεν υπάρχει URL εισόδου που να εκτίθεται για σχόλια PR. Τα άλλα webhook του προϊόντος (pipeline, συγχρονισμός εισιτηρίων) αποτελούν ξεχωριστή, προαιρετική ρύθμιση.