genome_pousser : la simulation dit ce que la poussee ferait, puis s'arrete

En --check, la sonde de l'organisation (une lecture uri) etait sautee et la
tache suivante echouait sur un statut absent, cache par no_log. La suite
(colis, reception, poussee) est faite de command et d'ecritures que --check
saute aussi : le verdict n'aurait rien prouve.

Les deux sondes de la forge tournent desormais en simulation. En --check, le
playbook lit la branche de la forge, la compare au poste (rev-list
--left-right), nomme pour chaque depot ce que la poussee ferait, et s'arrete
avant la premiere ecriture. Temoin : quatre cas nommes contre des clones
jetables ; a jour partout contre les vrais depots, aux deux sites.

CHANGELOG 150.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-10-14 04:11:52 -04:00
parent 968caed3b1
commit ee5aad5f41
2 changed files with 113 additions and 0 deletions

View file

@ -1,3 +1,21 @@
## 2026-10-14 (150) — La simulation de `genome-pousser` dit ce que la poussée ferait
**95 preuves.** `make verifier` passe (site de Chezlepro), `make test` passe. Témoin : contre
des clones jetables (`-e genome_freres=…`), la simulation au site de TechnoLibre a nommé les
quatre cas — à jour, un commit en avance rapide, un commit de la forge absent du poste (le
runner refusera), un commit de la forge inconnu du poste. Contre les vrais dépôts, aux deux
sites : « à jour » partout, 0 changement.
**`--check` échouait à la première lecture.** La sonde « l'organisation existe-t-elle ? »
(`uri`, une simple lecture) était sautée en simulation, et la tâche suivante tombait sur un
statut absent, en silence (`no_log`). Même réparée là, la suite n'aurait rien montré : colis,
réception et poussée sont des `command` ou des écritures `uri`, que `--check` saute, et le
verdict final aurait comparé une forge intacte à des colis jamais reçus.
- Les deux sondes de la forge tournent aussi en simulation (`check_mode: false`).
- En simulation, le playbook lit la branche que porte la forge, la compare au poste
(`git rev-list --count --left-right`), dit pour chaque dépôt ce que la poussée ferait,
puis s'arrête avant la première écriture.
## 2026-10-14 (149) — Le second serveur de noms, sur l'autre site, par le tunnel
**95 preuves.** `make verifier` passe (site de Chezlepro), `make test` passe. Témoin de bout en

View file

@ -22,6 +22,7 @@
#
# make genome-pousser tous les depots portes par le runner
# make genome-pousser DEPOT=<nom> un seul (le nom du depot sur la forge)
# make genome-pousser ARGS=--check ce que la poussee ferait, depot par depot, sans rien ecrire
#
# L'ECRITURE S'AUTHENTIFIE, LA LECTURE NON. `serveur_ops` clone en anonyme, par doctrine.
# Pousser est un autre acte : le runner s'y presente avec SA cle — celle que `serveur_ops`
@ -123,6 +124,9 @@
url: "https://forge.{{ domaine_interne }}/api/v1/orgs/{{ serveur_ops_forge_organisation | default('genome') }}"
validate_certs: false
status_code: [200, 404]
# UNE LECTURE, DONC AUSSI EN SIMULATION : sans elle, `--check` sautait la sonde et la
# tache suivante echouait sur un statut absent (2026-10-14).
check_mode: false
register: genome_org
- name: Créer l'organisation du génome
@ -153,8 +157,99 @@
loop_control:
label: "{{ item.depot }}"
no_log: true
check_mode: false
register: genome_depots_forge
# LA SIMULATION DIT CE QUE LA POUSSEE FERAIT, PUIS S'ARRETE (2026-10-14).
#
# Tout ce qui suit est `uri` en ecriture ou `command` : `--check` le saute, et le verdict
# final comparait alors une forge intacte a des colis jamais recus. On ne lit donc que la
# forge et le poste, on compare, et on rend la main avant la premiere ecriture.
- name: Simulation — la branche que porte la forge
ansible.builtin.uri:
url: >-
https://forge.{{ domaine_interne }}/api/v1/repos/{{ serveur_ops_forge_organisation
| default('genome') }}/{{ item.item.depot }}/branches/{{ item.item.branche | default('main') }}
url_username: forgejo-admin
url_password: "{{ vault_forgejo_admin }}"
force_basic_auth: true
validate_certs: false
status_code: [200, 404]
loop: "{{ genome_depots_forge.results }}"
loop_control:
label: "{{ item.item.depot }}"
register: genome_sim_forge
retries: 4
delay: 3
until: genome_sim_forge is succeeded
check_mode: false
no_log: true
when:
- ansible_check_mode
- item.status == 200
# `--left-right` : a gauche ce que la forge porte et que le poste n'a pas (le runner
# refusera, `--ff-only`), a droite ce qui serait pousse. rc 128 : le poste ne connait
# pas le commit de la forge — l'avance rapide est impossible a juger d'ici.
- name: Simulation — l'écart entre la forge et le poste
ansible.builtin.command:
argv:
- git
- -C
- "{{ genome_freres }}/{{ item.item.item.dest }}"
- rev-list
- --count
- --left-right
- "{{ item.json.commit.id }}...refs/heads/{{ item.item.item.branche | default('main') }}"
delegate_to: localhost
become: false
loop: "{{ genome_sim_forge.results }}"
loop_control:
label: "{{ item.item.item.depot }}"
register: genome_sim_ecart
check_mode: false
changed_when: false
failed_when: false
when:
- ansible_check_mode
- item.status | default(0) == 200
- name: Simulation — ce que la poussée ferait
vars:
genome_sim_lignes: >-
{%- set out = [] -%}
{%- if genome_org.status == 404 -%}
{%- set _ = out.append('organisation ' ~ (serveur_ops_forge_organisation | default('genome')) ~ ' : à créer') -%}
{%- endif -%}
{%- for r in genome_sim_ecart.results -%}
{%- set d = r.item.item.item.depot -%}
{%- if r.item.item.status == 404 -%}
{%- set _ = out.append(d ~ ' : dépôt à créer, puis tout poussé') -%}
{%- elif r.item.status | default(0) == 404 -%}
{%- set _ = out.append(d ~ ' : dépôt vide, tout poussé') -%}
{%- elif r.rc != 0 -%}
{%- set _ = out.append(d ~ ' : la forge porte ' ~ r.item.json.commit.id[:7]
~ ', inconnu du poste — avance rapide impossible à juger d ici') -%}
{%- else -%}
{%- set lr = r.stdout.split() | map('int') | list -%}
{%- if lr[0] > 0 -%}
{%- set _ = out.append(d ~ ' : la forge a ' ~ lr[0] ~ ' commit(s) absent(s) du poste — le runner REFUSERA (--ff-only)') -%}
{%- elif lr[1] == 0 -%}
{%- set _ = out.append(d ~ ' : à jour (' ~ r.item.json.commit.id[:7] ~ ')') -%}
{%- else -%}
{%- set _ = out.append(d ~ ' : ' ~ r.item.json.commit.id[:7] ~ ' → ' ~ lr[1] ~ ' commit(s) en avance rapide') -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{{ out }}
ansible.builtin.debug:
msg: "{{ genome_sim_lignes }}"
when: ansible_check_mode
- name: Simulation — s'arrêter avant la première écriture
ansible.builtin.meta: end_host
when: ansible_check_mode
- name: Créer les dépôts qui manquent
ansible.builtin.uri:
url: "https://forge.{{ domaine_interne }}/api/v1/orgs/{{ serveur_ops_forge_organisation | default('genome') }}/repos"