Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,36 @@ jobs:
# se reproduit pas ici est ROUGE. Le validateur refuse de jouer avec une
# autre version d'act que celle de `mise.toml`, et enregistre cette
# version avec le digest de l'image du runner.
#
# DEPUIS QUE LES SOLUTIONS SONT CHIFFRÉES, CE REJEU PEUT NE PAS AVOIR LIEU
#
# Le cycle pose la solution du formateur sur le répertoire de travail, il
# lui faut donc le clair. `.vault-pass` n'est pas sur la forge, et c'est
# la convention de toute la collection : aucun catalogue n'y confie son
# secret. Le rejeu se déclare alors NON JOUÉ, par un avertissement
# visible ici, plutôt que de passer pour un succès.
#
# Ce qu'on perd est réel : l'opposabilité du relevé ne tient plus à cette
# CI, mais à la campagne locale qui l'a produit, comme dans les onze
# autres catalogues dont la CI ne rejoue rien.
- name: Rejouer le cycle « 0 avant, 100 après »
run: mise exec -- uv run --no-sync scripts/valider-labs.py
run: |
if [ ! -f .vault-pass ]; then
echo "::warning::rejeu NON JOUÉ : les solutions sont chiffrées et .vault-pass n'est pas sur la forge. La preuve est le validation-labs.json commité, produit en local."
exit 0
fi
mise exec -- uv run --no-sync scripts/valider-labs.py

# Le verdict versionné doit couvrir TOUT le catalogue : un lab ajouté
# sans validation fait échouer ce contrôle, même si tous les autres
# verdicts sont verts.
- name: Le verdict versionné couvre le catalogue et est vert
run: uv run --no-sync scripts/valider-labs.py --check
run: |
if [ ! -f .vault-pass ]; then
echo "::warning::contrôle NON JOUÉ, même raison : il rejoue les solutions pour conclure."
exit 0
fi
uv run --no-sync scripts/valider-labs.py --check

- name: Ce que la campagne a changé, s'il y a lieu
if: always()
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ __pycache__/
# État local de dsoxlab, propre à chaque poste.
.dsoxlab.db
.dsoxlab-context.json

# Le mot de passe qui déchiffre les solutions du formateur. Jamais commité :
# le commiter annulerait le chiffrement, puisqu'il voyage avec ce qu'il ouvre.
.vault-pass
36 changes: 36 additions & 0 deletions CHANGELOG.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,42 @@ ne recule pas, et 0.2.0 sous v1.2.0 aurait menti sur l'ordre des choses.

---

## [0.2.2] - 2026-10-19

### Sécurité

- **La solution de référence est chiffrée par ansible-vault, et `meta.yml` ne
déclare plus ses solutions en clair.** Le workflow de
`fondations-premier-workflow` était commité en clair dans un dépôt public :
l'apprenant qui clone avait la réponse sous la main.

La déclaration `solutions: plaintext` motivait ce choix par le fait qu'un
workflow chiffré « ne se relirait pas ». C'était vrai des OUTILS du dépôt,
pas une fatalité : deux lecteurs lisaient le fichier en clair, et il
suffisait de leur apprendre à déchiffrer.

`scripts/valider-labs.py` pose la solution par-dessus le répertoire de
travail : il la déchiffre à la pose. `tests/test_solutions_exemplaires.py`
contrôle que la solution épingle ses actions sur un SHA et déclare ses
`permissions` : ses trois lectures déchiffrent. Sans cette seconde
adaptation, le contrôle aurait gardé ses quinze verts en n'ayant plus aucun
`uses:` à examiner, ce qui est précisément le défaut que ce dépôt traque
chez les autres.

Vérifié sur le comportement : le contrôle voit les 62 lignes du workflow et
ses 2 `uses:` épinglés ; sans le secret, la lecture lève et les tests se
déclarent non joués.

- **Le rejeu « 0 avant, 100 après » ne se joue plus en CI.** C'est le coût
assumé du chiffrement : le cycle a besoin du clair, et `.vault-pass` n'est
pas sur la forge, comme dans aucun catalogue de la collection. Les deux
étapes concernées se déclarent non jouées par un avertissement visible, au
lieu de passer pour un succès ou de rendre un rouge permanent.

L'opposabilité de `validation-labs.json` ne tient donc plus à cette CI mais
à la campagne locale qui l'a produit. L'autre voie, confier le secret à un
secret de dépôt, a été écartée en connaissance.

## [0.2.1] - 2026-10-19

### Modifié
Expand Down
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,41 @@ backwards, and 0.2.0 under v1.2.0 would have lied about the order of things.

---

## [0.2.2] - 2026-10-19

### Security

- **The reference solution is encrypted with ansible-vault, and `meta.yml` no
longer declares its solutions as plaintext.** The workflow of
`fondations-premier-workflow` was committed in plaintext in a public
repository: anyone cloning had the answer at hand.

The `solutions: plaintext` declaration justified that by saying an encrypted
workflow "would no longer be read back". That was true of the repository's
TOOLS, not a given: two readers consumed the file in plaintext, and they
only had to learn to decrypt.

`scripts/valider-labs.py` lays the solution over the working directory: it
decrypts as it lays. `tests/test_solutions_exemplaires.py` checks that the
solution pins its actions to a SHA and declares its `permissions`: its three
reads now decrypt. Without that second change, the check would have kept its
fifteen greens while having no `uses:` left to examine, which is exactly the
fault this repository hunts for elsewhere.

Verified on behaviour: the check sees the workflow's 62 lines and its 2
pinned `uses:`; without the secret, the read raises and the tests declare
themselves not run.

- **The "0 before, 100 after" replay no longer runs in CI.** That is the
accepted cost of encryption: the cycle needs the plaintext, and
`.vault-pass` is not on the forge, as in no catalogue of the collection.
Both affected steps declare themselves not run through a visible warning,
instead of passing for a success or turning permanently red.

The standing of `validation-labs.json` therefore no longer rests on this CI
but on the local campaign that produced it. The other option, entrusting the
secret to a repository secret, was knowingly set aside.

## [0.2.1] - 2026-10-19

### Changed
Expand Down
192 changes: 130 additions & 62 deletions labs/fondations-premier-workflow/solution/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,130 @@
# Solution de reference.
#
# Le nom du fichier est libre : GitHub joue TOUT fichier `.yml` ou `.yaml` de
# `.github/workflows/`. Ce qui n'est pas libre, c'est l'emplacement : un
# workflow pose ailleurs n'est jamais lu, et rien ne le signale.
name: CI

# Deux evenements, et les filtres de branche avec.
#
# act les ignore : il joue l'evenement qu'on lui nomme, quelle que soit la
# branche. Ce n'est pas une raison de les omettre, parce que sur GitHub ils
# comptent, et un workflow eprouve sans eux se comporte autrement une fois
# pousse.
on:
push:
branches: [main]
pull_request:
branches: [main]

# Les permissions se declarent au niveau du workflow, et au plus juste.
#
# Sans ce bloc, le jeton prend les permissions par defaut du depot, qui peuvent
# etre en ecriture sur tout. Ici le job ne fait que lire le code et lancer des
# tests : `contents: read` suffit, et c'est ce que Scorecard attend.
permissions:
contents: read

jobs:
test:
runs-on: ubuntu-24.04
steps:
# Chaque action est epinglee sur le SHA COMPLET de son commit, avec la
# version en commentaire. Un tag est deplacable : `@v7` peut designer un
# autre code demain, y compris du code hostile si le depot est compromis.
# Un SHA ne bouge pas.
#
# Le commentaire n'est pas decoratif : c'est lui que Dependabot lit pour
# proposer la montee de version, et lui qui rend la ligne relisible.
- name: Recuperer le code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Sans cette ligne, checkout laisse le jeton du job dans
# `.git/config`, ou tout step suivant peut le lire, et ou il finit
# dans un artefact si quelqu'un archive le repertoire. C'est le
# constat `artipacked` de zizmor, et il tombe sur ce workflow tant
# que la ligne manque.
#
# Ce job ne pousse rien : il n'a aucun usage du jeton apres le clone.
persist-credentials: false

- name: Installer Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'

- name: Installer les dependances
run: python -m pip install -r requirements.txt

# `-v` nomme les neuf tests un par un. C'est ce que la verification lit :
# un pipeline qui affiche « tests OK » sans les avoir lances ne passe pas.
- name: Lancer les tests
run: python -m pytest -v
$ANSIBLE_VAULT;1.1;AES256
38613662626433386238396564616438653534323237396265333931663232616531643130313937
3463313135343037623563383631333639393332633965340a336230363331396461363966303732
61653264333065656230376535636561353838393635383832626630373930353734316336633463
3136346663323362320a663632356130383431653861313433653934666633323930653037613334
37313637303265373662623733303731326639326133653734666135353764313335646239376138
38366566316566343536373862396130643663376430643264383465323736633330633736306431
62396265313665646535336638633265363638663234613235663434653661623265653837303666
36623836346338646164623466386130663064356633383837336165326137636663336531333863
31373430613030653666663131363339626437306165353664663737346362356161633735343637
34353565393035616237376633323538323063376339323832643761373932616438633964366234
35343033633535346633623863333538663063623639626435636533336434626634396531366365
34653633333039366134376662363764616639643335376561333339393233663265373734306362
36316362636133616233343036643063613431363663333039633138393062633838396231353633
65396166306230396163326430323534393137623061313632326464336361653137313636656438
66643939333464643164616137633834636130346433386165333561306439383036366536636634
36363333313439363635303731616566376664376364303035353835386137326338326532323962
61346463336433336238353239313438313933633466323962346166626561346338653964313861
32306337396336623938323830653362306330336264636562373935306534303733366166356661
34653939343162303062613937636635373737643932633637656436623234633735346362363431
33383935373163643534653265326638616462306463333439323935353263326163353936616332
63333332316534333166393165613430386231393139613038343833656166373231326631373463
38666138386434613538613362383364333963623737663434393632646365333738393435396662
35356433353931643665303431626339636633343332313634663230633962373031346134396238
63323232353234356539633163363662636339383066653465626238646334646631376662633830
39383562333839363939313263353131643635346166626564373238666337333933313061653663
33303635366662633162623830613366616431646637333434626233643766663435393137343266
65666133303636316630663832303835656133396632366164643939396233393162626337623765
30623633333063393236616331363633333462333934383138643930616538333334303662383666
30636162656431613261353566393562383432363662353735343566386564373631356439643964
39306232646139383830656462393832363037663762383033626338336438376163643361343632
38633535356666653239643033653065623637663836376161323266396462393462616534633734
62386337316435333437353835653139613932343461343839353462386261613635333439616530
31373730363432646162383633386637386535343738373762643961363033323661383835656238
31646461616539346262633735313237346565353238313038353762646361356162643337333066
37616232383930326261323231313834323165363837313263653264373266303565646466663231
62353964336130656530626530356561643437393432336663313535626635316564373964666332
63396463643765393964623461373365306434383136643538343930363066333036646637386363
64396431383237333032613763633837356439633832633266666233383334386235373563353637
62626233623964653238393661633938326637313635636263356165366164306134646332386536
32643033396164363036616639653538363633383462303132376636386162626631643864613466
35306532316435663265643166633631616631323435653332663437323561303163396632373864
38383062393836643134353962323431666135343937623563613163383738356431623165663765
30666261653436626632326465383435313963613263313531653263393137306165393231656331
38356464383862613061376230313266303462363332313864363339303032333131613737326436
30653761386134656635643931316666366534373965663565633238373838643261343735623737
63353133383934373931646333386164653637343264323033623936356465396363366338393330
30383264376366396334303438633566326632383130646361326631643062643438646439333163
38613432313537653339363537626332633633363262636262386434636637363466366537643733
38643238346164386236626538656166636236383863376161353563326466363064393334343562
34326538353539633363316132323735303737626664613265646232366231333035313537626539
33383337643338363634313439643038363761643138613538333363306135303739643263323433
38303534656236613338353034646437656538313731333730346639333835636635373837653137
33643063353537393763656266633834383232643735393930303335313130303265346430613638
31633538626437663333373338663730636564323239643635383231613061316637633637303037
35306439396234653030353137363438636365333730616534333634323062336664303266373438
38653362623039326262376363313762633630303532303933356433616163393639363731353663
39363334353162313937393830353266623935373533343034363032383462663836336635396531
66313330303965613839316633323161396234396537653462636462663834313264613466656533
31303937623261666235333330323030323263363162303432383866356263656537386439336666
38633939663264666535623363636266313935326566376131343365363861306661623135313463
61396163653833393937663733623331666537316662326133643465336333323531653661366239
30666334373833656630363932383637373836303464316531663239333836383532376135323963
61636138623231333436316439393535353964356139323238633962613565656233636438613330
66326665346338343538353239653734323663626331613931636465363264336330623830323661
34303436363037636564393431383162313034626439323536633832666336646166656134393538
62356531643039386463336361656561626130363764336135313039626264313537393539626163
31303732323465636336623533383238346430343834303134326565643562376564653331656433
38613066363637346335633335613934333763663235646334663830356135633332653336316336
39663835373866633862383561643962396434383037356631623939373435323764353032356163
33326661303837333832376162363266343565313133373065323633356663663561646664353263
64373864333962376161616431393961303639626661363661393334333638663533323931393065
35386538373630306532636164383032353261373035643337356330363364306563383435343664
62663239616263366663356139383531663132396230363763386334666230646436646438656631
37346462356537633439376333616533306661303563306363303132343830666433343731363335
30346362636134303866666338626561366430646134613838666361303936663164366237373035
66313965623638626663396163643537333864393164633732623532373535356262303034346438
31343961306435346635316464323439303532646231663732343564313136353938323838353530
30616166373463666533333334306335306135346139323966643563626163656263643265303664
62633662373365633434356662393335346163366464333462343862343934313535383633303938
35663864306463323436633966356261386133656535626132376636666133643239663365373937
38383231643462346632376135366464343137306130663134353134613039633561356263346236
38306334363430343134313666303964323463336638303762663736353039356630303137343062
32323762613530313366336661646333613938323434393862316636303263306638313635386535
38613630643330646130306239313038656265396630636637363731306430353131633235366666
39623839383463313236396638663938326533353032373662356263366430333739393534386534
32633563383232373637353064626330353666393964343964666561633731313665363365306563
37613538656663616630613735353965383235613366653961343037356438616137336239646538
30616566336537353937663333666666613539353464646464613337363332363962346438333861
35303062393533313239306630306364343737376330363661643865646237303365313862363266
65663836653161653030343864623131633737626338393132333832663463306565366462323435
37633164396639396132353462366439323262306337613535333330666264623131336664323366
30633862653362383931623266353931323435613734353765363637323530643862333532393530
31396561373662396530303331616466363430653666333764623130366334333230353965376465
38346430386136353534323361643361373533653538373966383030383065326531623733393761
34616439633762613366393464333033633861623035313832313637376139653536356263653164
38363763386138386565393336656633356538393034636436396261326236383231363637376265
31346366376134653532383430313832363361326465316138613234353166353464343533623864
31336333643434313937646635333766656532623233356336393864656530336164353363323933
36663765376364623638613532383134643238613937323935356265633234643730363539636663
62653362616238306330333135353238393162623036366133363239613333663339396138393735
34346239386365323366656237383862666362306361643431333935646665623161643831366265
36663535656163356364383763393062363232303332396334623034316536343935373561306237
61653737346336623464363437313439383233373864653032363965336532363138313566656338
36323432633463366335316364313362386633623064333934383433633737353536663963656135
39643363643931306632373061663433623065323133666161356261366666313461323664653563
33343530633666666230653435366366376465393633643339316432383563356536376364313565
39353561653164353538306165326137616330343761303262626637643831363561343538656162
33363237666636643632376463383933326236323135366535326565663061376362366332663336
36373036373564363238303264613864623661363731333436393735303063636430356161363636
30316135373563323536623139373832653234633434383464306365376633343031313566366464
64663532333439333831313339346131313766643466383034363361613265363034643236323663
62613738633766663364306364316234663036356666333962393937663432333237646137613331
62343338393735326637333266326366663664646631613566326262653830333333363561396465
38393565626466306131396339656432353936323134643933646165616234336464316130393033
31626534663265366636303431656234373033323939626166633464616463626631393162316461
63396437623538366131366330373634623732336432306232623966306266656665373766306432
31373238626565376564396237636662333230616462626531373161626662386331333036376665
65363465323837653039633337313463656362636361356461653836303431333732313465643438
61626230323261356332373139646165663037323035636363633566373732653234626632646337
30633964336234633135373632343764303334623235646534646536643665333765303130363966
32393438323132356532643932376366353230323561646230376233646364656136393061643764
32633530326436336561333532643138393437353761386361393064633037353061353734366261
62653162386364373936353833636434663361313934323433333765616164653833623039646632
39323861376564336335626330383635613639656333626636333634353763643965633338306330
39316666363932353330636331646239633361653861383232363433343834646464356439313136
62393939623964326439646333633463336663643165666532303662663037366436636364313761
66383836653133333666353866346663616136313433306135353539353334373935393232393563
65386661386430313365353662393532643765306131643231623038373662633939373561623461
37306264336636316633326635663265653936363961626338663535343865643061
Loading
Loading