Αυτό το έγγραφο περιέχει τις πλήρεις λύσεις των 4 αποστολών, τις εξηγήσεις γραμμή προς γραμμή των παρεχόμενων workflows, τις επισκευές των 3 βλαβών, και τις απαντήσεις στις ερωτήσεις προβληματισμού.
Μην το ανοίξετε παρά μόνο αφού προσπαθήσετε πραγματικά. Η ανάγνωση της λύσης πριν δοκιμάσετε, σημαίνει ότι χάνετε το 80 % της μάθησης.
config.jsonΠαράδειγμα έγκυρου αρχείου:
{
"titre": "Portfolio de <votre nom>",
"sous_titre": "Deploiement automatique via GitHub Actions",
"couleur_fond": "#7c3aed",
"couleur_texte": "#f8fafc",
"couleur_accent": "#22d3ee",
"auteur": "<Votre Nom>",
"version": "1.0.0"
}Σημεία προς τήρηση:
titre, sous_titre, couleur_fond, couleur_texte, couleur_accent, auteur, version) είναι υποχρεωτικά.#RRGGBB (6 δεκαεξαδικοί χαρακτήρες μετά το #).Τοπική επικύρωση:
python .\outils\build.pyΠρέπει να εμφανίσει OK dist/index.html genere και OK dist/css/style.css genere. Κάθε σφάλμα ERREUR : σταματά το σενάριο και θα μπλοκάρει έπειτα το workflow GitHub.
Προτεινόμενη παλέτα για δοκιμή του βρόχου στην αποστολή 2:
| Χρώμα | Φόντο | Κείμενο | Έμφαση |
|---|---|---|---|
| Σκοτεινή νύχτα | #0f172a | #f1f5f9 | #38bdf8 |
| Ζωντανό βιολετί | #7c3aed | #f8fafc | #22d3ee |
| Έντονο κόκκινο | #dc2626 | #fef2f2 | #facc15 |
| Δασικό πράσινο | #16a34a | #f0fdf4 | #fbbf24 |
| Ωκεάνιο μπλε | #0891b2 | #ecfeff | #f472b6 |
deployer-pages.ymlname: Deployer sur GitHub Pages # όνομα που εμφανίζεται στο UI ActionsΑυτό το όνομα είναι καθαρά αισθητικό — βοηθά στον εντοπισμό του workflow στην καρτέλα Actions του αποθετηρίου.
on:
push:
branches: [main]
workflow_dispatch:Δύο ενεργοποιητές:
main (η κανονική περίπτωση).permissions:
contents: read
pages: write
id-token: writeΤο μαγικό τρίο του Pages. Χωρίς αυτές τις τρεις γραμμές, λαμβάνουμε Resource not accessible by integration στο job deployer (αυτή είναι ακριβώς η βλάβη 1 της αποστολής 3):
contents: read — επιτρέπει στο actions/checkout@v4 να διαβάσει τον κώδικα.pages: write — επιτρέπει στο actions/deploy-pages@v4 να δημοσιεύσει.id-token: write — απαραίτητο για την πιστοποίηση OIDC μεταξύ του runner και της υπηρεσίας Pages.concurrency:
group: pages
cancel-in-progress: falseΑν δύο git push φτάσουν σχεδόν ταυτόχρονα, το GitHub Actions δεν εκκινεί δύο αναπτύξεις παράλληλα στην ίδια ομάδα pages — τα runs εκτελούνται το ένα μετά το άλλο. cancel-in-progress: false = αφήνουμε το τρέχον run να τελειώσει πριν ξεκινήσει το επόμενο. Αυτό είναι κρίσιμο για το Pages: δύο ταυτόχρονες δημοσιεύσεις παράγουν ασυνεπείς καταστάσεις.
jobs:
construire:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # 1. ανάκτηση του κώδικα
- uses: actions/setup-python@v5 # 2. εγκατάσταση Python
with:
python-version: "3.12"
- run: python outils/build.py # 3. παραγωγή του dist/
- uses: actions/upload-pages-artifact@v3 # 4. προετοιμασία του τεχνουργήματος
with:
path: dist # <-- ΣΗΜΑΝΤΙΚΟ : φάκελος προς δημοσίευσηΤέσσερα διαδοχικά βήματα. Αν ένα αποτύχει, τα επόμενα δεν εκτελούνται.
deployer:
needs: construire # περιμένει να πετύχει το "construire"
environment:
name: github-pages # επίσημο περιβάλλον Pages
url: ${{ steps.publication.outputs.page_url }} # εμφανίζει το URL στο UI
steps:
- uses: actions/deploy-pages@v4
id: publicationΤο job deployer περιμένει ρητά το construire χάρη στο needs:. Στο τέλος, το UI GitHub εμφανίζει έναν κλικαρίσιμο σύνδεσμο προς https://<vous>.github.io/<depot>/.
verifier-config.ymlon:
pull_request:
branches: [main]
push:
branches-ignore: [main]Ενεργοποιείται σε PR προς main και σε push προς κάθε κλάδο εκτός main. Ο στόχος: επικύρωση πριν συγχωνευτεί ο κώδικας. Σημειώστε ότι εξαιρούμε το main από το push: — αλλιώς θα διπλασιάζαμε τη δουλειά με το deployer-pages.yml.
Τα υπόλοιπα βήματα είναι ίδια με το deployer-pages.yml εκτός του ότι δεν δημοσιεύουμε: αρκούμαστε να επαληθεύσουμε ότι το dist/ παράγεται χωρίς σφάλμα.
Ακολουθία προς αναπαραγωγή δύο φορές:
# --- Επανάληψη 1 : βιολετί φόντο ---
# Επεξεργασία site/config.json : "couleur_fond": "#7c3aed"
git add site/config.json
git commit -m "fond violet"
git push
# Αναμονή ~40 s -> άνοιγμα https://<vous>.github.io/<depot>/ -> βιολετί φόντο
# --- Επανάληψη 2 : κόκκινο φόντο ---
# Επεξεργασία site/config.json : "couleur_fond": "#dc2626"
git add site/config.json
git commit -m "fond rouge"
git push
# Αναμονή ~40 s -> άνοιγμα του ίδιου URL -> κόκκινο φόντοΕπαληθεύσεις προς συμπερίληψη στην έκθεση:
git log --oneline: δείχνει τις 2 δεσμεύσεις με τα σύντομα SHA τους.Deployer sur GitHub Pages είναι πράσινα.Diff της διόρθωσης στο .github/workflows/casse-1-permissions-manquantes.yml:
name: Casse 1 - Permissions manquantes
on:
push:
branches: [main]
workflow_dispatch:
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
concurrency:
group: pages
cancel-in-progress: false
jobs:
...Γραπτή διάγνωση προς τοποθέτηση στην έκθεση:
Χωρίς το μπλοκ permissions:, το GitHub χορηγεί στο workflow μόνο contents: read (ανάγνωση του κώδικα) — όχι το δικαίωμα δημοσίευσης στο Pages. Η ενέργεια actions/deploy-pages@v4 απαιτεί ρητά pages: write και id-token: write (διακριτικό OIDC). Εξ ου και το σφάλμα Resource not accessible by integration (403 Forbidden) στο job deployer.
Κανόνας ασφάλειας: δίνουμε τα λιγότερα δυνατά δικαιώματα, αλλά όχι λιγότερα. Η αρχή του ελάχιστου προνομίου εφαρμοσμένη στο CI/CD.
Diff της διόρθωσης:
name: Casse 2 - Declencheur errone
on:
- pushh:
+ push:
branches: [main]Γραπτή διάγνωση προς τοποθέτηση στην έκθεση:
Το GitHub Actions δεν σηματοδοτεί τους άγνωστους ενεργοποιητές στο on: — τους αγνοεί σιωπηλά. Ένα απλό pushh (με δύο h) κάνει ώστε κανένα run να μην ενεργοποιηθεί: δεν βλέπουμε σφάλμα, δεν βλέπουμε τίποτα απολύτως στην καρτέλα Actions.
Πώς ανακαλύπτουμε τη βλάβη; Ωθούμε μια δέσμευση, πηγαίνουμε στο Actions, διαπιστώνουμε ότι κανένα run δεν εμφανίζεται για αυτό το workflow. Το μόνο στοιχείο είναι η απουσία.
Αντιπαγίδα: ένα γρήγορο Run workflow (χειροκίνητο κουμπί, διαθέσιμο αν υπάρχει workflow_dispatch:) επαληθεύει ότι το ίδιο το workflow είναι συντακτικά έγκυρο. Το workflow_dispatch: λειτουργεί ανεξάρτητα από το push:.
Diff της διόρθωσης:
- name: Preparer le dossier a publier
uses: actions/upload-pages-artifact@v3
with:
- path: public
+ path: distΓραπτή διάγνωση προς τοποθέτηση στην έκθεση:
Το outils/build.py γράφει συστηματικά στο dist/ (σταθερά DIST = RACINE / "dist" στον κώδικα Python). Το workflow ζητούσε path: public — έναν φάκελο που δεν υπάρχει. Εξ ου:
Error: Path does not exist: ./publicΤο actions/upload-pages-artifact@v3 επαληθεύει την ύπαρξη του φακέλου πριν δημιουργήσει το τεχνουργήμα και αποτυγχάνει αμέσως αν η διαδρομή είναι λάθος. Καλή πρακτική: πάντα να δείχνει το workflow στον ακριβή φάκελο που παράγει το σενάριο κατασκευής.
README.mdΣτο README.md του αποθετηρίου GitHub σας (στη ρίζα, όχι στον φάκελο projet14-github-actions-pages-tp/ του μαθήματος), προσθέστε:
# Mon site portfolio

Site publie : https://<vous>.github.io/<depot>/Το σήμα γίνεται πράσινο αν το τελευταίο run πέρασε, κόκκινο αλλιώς. Ενημερώνεται μόνο του.
config.jsongit checkout -b test-config-cassee
# Επεξεργασία site/config.json και αντικατάσταση "couleur_fond": "#0f172a" από "couleur_fond": "rouge"
git add site/config.json
git commit -m "test : couleur invalide"
git push -u origin test-config-cassee
# Έπειτα στο GitHub : άνοιγμα PR από test-config-cassee προς mainΤο workflow Verifier la configuration θα ενεργοποιηθεί, το build.py θα φωνάξει:
ERREUR : couleur_fond doit etre au format #RRGGBB (recu : 'rouge')Η PR εμφανίζει κόκκινο τετράγωνο και το κουμπί Merge pull request μπλοκάρεται αν έχετε διαμορφώσει προστασία κλάδου (Settings → Branches → Add rule → Require status checks to pass).
.github/workflows/notifier.yml:
name: Notifier une URL
on:
workflow_dispatch:
jobs:
notifier:
runs-on: ubuntu-latest
steps:
- name: Ping du webhook
env:
URL: ${{ secrets.URL_WEBHOOK }}
run: |
curl -X POST "$URL" \
-H "Content-Type: application/json" \
-d '{"texte":"Un utilisateur a declenche notifier.yml"}'Το μυστικό URL_WEBHOOK ορίζεται στο Settings → Secrets and variables → Actions → New repository secret. Δεν θα εμφανιστεί ποτέ στα ημερολόγια: το GitHub καλύπτει αυτόματα κάθε τιμή που αντιστοιχεί σε μυστικό.
1. on: push χωρίς branches: — πότε ενεργοποιείται;
Ενεργοποιείται σε κάθε push σε όλους τους κλάδους. Σπάνια είναι επιθυμητό: ένα git push σε κλάδο δυνατότητας υπό ανάπτυξη θα εκκινήσει ανάπτυξη Pages στην παραγωγή. Πάντα να περιορίζετε με branches: [main] ή ρητή λίστα.
2. Γιατί το id-token: write είναι απαραίτητο για το Pages; Σε τι χρησιμεύει το διακριτικό OIDC;
Το actions/deploy-pages@v4 χρησιμοποιεί OIDC (OpenID Connect) για να αποδείξει στην υπηρεσία Pages ότι το αίτημα προέρχεται όντως από εξουσιοδοτημένο run GitHub Actions, χωρίς κωδικό ούτε PAT (Personal Access Token). Το διακριτικό OIDC είναι εφήμερο (διάρκεια ζωής περιορισμένη στο run) και υπογεγραμμένο από το GitHub — ασφαλέστερο από στατικό μυστικό. Το id-token: write επιτρέπει στον runner να παράγει αυτό το διακριτικό για αυτό το workflow.
3. Δύο ταυτόχρονα push στο main — τι κάνει το concurrency;
Χωρίς concurrency, το GitHub εκκινεί δύο workflows παράλληλα. Το πρώτο τελειώνει το ανέβασμα τεχνουργήματος, το δεύτερο ξεκινά το δικό του ανέβασμα, και το Pages μπορεί να λάβει και τις δύο δημοσιεύσεις σε λάθος σειρά → η τελική σειρά δεν είναι πλέον εγγυημένη. Με concurrency: { group: pages, cancel-in-progress: false }, τα δύο runs σειριοποιούνται: το δεύτερο περιμένει να τελειώσει το πρώτο. Το cancel-in-progress: true θα είχε άλλο αποτέλεσμα — ακύρωση του τρέχοντος run μόλις ξεκινήσει ένα νέο, χρήσιμο για εξαιρετικά γρήγορο rebuild αλλά επικίνδυνο για το Pages.
4. Μπορεί ένα μυστικό να εμφανιστεί στα ημερολόγια;
Το GitHub καλύπτει αυτόματα κάθε τιμή καταχωρισμένη ως μυστικό: εμφανίζεται ως *** στα ημερολόγια. Αλλά αν μετασχηματίσετε το μυστικό (π.χ. echo "$SECRET" | base64), η κάλυψη δεν εφαρμόζεται πλέον στη μετασχηματισμένη τιμή. Κανόνας: ποτέ μην μετασχηματίζετε ένα μυστικό σε run:, χρησιμοποιήστε το ως έχει μέσω env: και περάστε το απευθείας στο εργαλείο (εδώ curl).
5. Γιατί να κρατήσουμε τα δύο workflows deployer-pages.yml και verifier-config.yml;
deployer-pages.yml δημοσιεύει στο main: είναι το workflow παράδοσης. Τρέχει μόνο μετά από συγχώνευση.verifier-config.yml επικυρώνει στους κλάδους δυνατότητας και στις PR: είναι το workflow πρόληψης. Εμποδίζει ένα σπασμένο config.json να φτάσει στο main.Τα δύο σχηματίζουν ένα δίχτυ δύο στρωμάτων: η επαλήθευση μπλοκάρει ανάντη, η ανάπτυξη παραδίδει κατάντη. Αυτό είναι το μοτίβο CI (Continuous Integration) + CD (Continuous Deployment).
6. Τι θα συνέβαινε αν το build.py δημιουργούσε ένα αρχείο historique.log;
Τίποτα διαρκές. Ο runner είναι μια εφήμερη VM που καταστρέφεται στο τέλος του run. Το αρχείο θα εξαφανιζόταν με την VM. Για να διατηρήσετε ιστορικό μεταξύ runs, θα έπρεπε να το δεσμεύσετε στο αποθετήριο (όχι ιδανικό, μολύνει το repo), να το αποθηκεύσετε σε τεχνουργήμα με actions/upload-artifact (διάρκεια ζωής 90 ημέρες το πολύ), ή να το στείλετε σε εξωτερική υπηρεσία (S3, Postgres, κ.λπ.).
| Σύμπτωμα | Πιθανή αιτία | Λύση |
|---|---|---|
Resource not accessible by integration | Μπλοκ permissions: απόν ή ελλιπές | Προσθήκη pages: write + id-token: write |
| Κανένα run δεν ενεργοποιείται | Τυπογραφικό στο on: (pushh:, pull_requests:) | Ελέγξτε την ορθογραφία των κλειδιών YAML |
Path does not exist: ./xxx | Η διαδρομή στο upload-pages-artifact.path: δεν αντιστοιχεί στον φάκελο εξόδου του build.py | Επαληθεύστε path: = dist |
| Η δημοσιευμένη σελίδα δείχνει το παλιό περιεχόμενο | Προσωρινή μνήμη περιηγητή | Ctrl+Shift+R για σκληρή επαναφόρτωση |
| Η πρώτη ανάπτυξη παίρνει > 5 λεπτά | Διάδοση DNS του GitHub Pages | Κανονικό την πρώτη φορά, ~40 s έπειτα |
Κόκκινο workflow στο βήμα python outils/build.py | Άκυρο config.json | Εκτελέστε python .\outils\build.py τοπικά για να δείτε το ακριβές σφάλμα |
| Το workflow τρέχει αλλά το URL επιστρέφει 404 | Η πηγή Pages είναι ακόμη σε λειτουργία « Deploy from a branch » | Περάστε σε GitHub Actions στο Settings → Pages |
| Δύο runs Pages ταυτόχρονα παράγουν ασυνεπές περιεχόμενο | Απόν concurrency: | Προσθέστε το μπλοκ concurrency: { group: pages } |
Ο καθηγητής ανοίγει τρεις καρτέλες:
config.json, παρουσία του .github/workflows/ με τουλάχιστον τα 3 διορθωμένα workflows (τα πρωτότυπα deployer-pages.yml και verifier-config.yml + οι 3 επισκευασμένες βλάβες).Deployer sur GitHub Pages (αποστολή 2), συν τα runs της αποστολής 3 (πριν/μετά την επισκευή).https://<vous>.github.io/<votre-depot>/ — πρέπει να εμφανίζεται με τα εξατομικευμένα χρώματά σας και ένα πρόσφατο SHA.Έπειτα διαβάζει την RAPPORT.md σας:
Καθαρή έκθεση + καλά δομημένο αποθετήριο = εύκολο άριστα. Η δυσκολία δεν είναι τεχνική, είναι στην αυστηρότητα της απόδειξης.
Μάθημα δημιουργημένο από τον Dr. Haythem REHOUMA — Ανάπτυξη και ανάπτυξη λύσεων δεδομένων