From a846be0dcf5f971ef1cfbbf6c48a09b90aec243f Mon Sep 17 00:00:00 2001 From: Christophe Lesur Date: Sun, 7 Jun 2026 18:38:39 +0200 Subject: [PATCH] docs(readme): document GitHub-driven workflow + track WORKSPACE_WORKFLOW_GIT.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a "Contributing" section to README.md and README.fr.md explaining that the project is piloted entirely through GitHub (issues, branches, PRs, reviews via the gh CLI — agent-friendly), and link to the canonical workflow file. Also commit WORKSPACE_WORKFLOW_GIT.md itself (was untracked) so the README links resolve in the repo. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.fr.md | 28 +++++ README.md | 27 +++++ WORKSPACE_WORKFLOW_GIT.md | 210 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 WORKSPACE_WORKFLOW_GIT.md diff --git a/README.fr.md b/README.fr.md index 8743090..74311a2 100644 --- a/README.fr.md +++ b/README.fr.md @@ -30,6 +30,7 @@ - [Sécurité](#-sécurité) - [Structure du projet](#-structure-du-projet) - [Troubleshooting](#-troubleshooting) +- [Contribuer](#-contribuer) --- @@ -730,6 +731,33 @@ docker compose logs waf --tail 20 --- +## 🤝 Contribuer + +Le développement se pilote **entièrement via GitHub** — issues, branches, pull +requests, revues de code et statut projet y vivent tous. Cela rend le projet +facile à **piloter à distance depuis le terminal** avec la CLI `gh` (y compris +par des agents IA de code) : créer une issue, brancher, ouvrir une PR, relire +et merger sans jamais quitter la ligne de commande ou l'interface GitHub. + +Le workflow complet et obligatoire est documenté dans +**[`WORKSPACE_WORKFLOW_GIT.md`](WORKSPACE_WORKFLOW_GIT.md)** : + +- **Branche + PR uniquement** — aucun merge local dans `main` ; chaque + changement arrive via une pull request mergée sur GitHub. +- **Cycle de vie de l'issue** — auto-assignation, passage du statut Projects à + *In Progress*, discussion de conception conservée dans l'issue. +- **Lien PR ↔ issue** — un mot-clé `Closes #N` dans le **corps** de la PR + ferme l'issue automatiquement au merge. +- **Revues dans le canal PR** — dès qu'une PR est ouverte, la discussion de + revue passe dans la PR ; toute conclusion de revue est publiée sur GitHub + (`gh pr review` / `gh pr comment`), pas seulement en chat. + +Suivre ce fichier garde les historiques d'issues et de PR propres et +auditables, et permet à un contributeur (ou un agent) de dérouler tout le +cycle de façon reproductible via `gh`. + +--- + ## 🔗 Projets liés | Projet | Description | Lien | diff --git a/README.md b/README.md index 27d991b..7333274 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ - [Security](#-security) - [Project Structure](#-project-structure) - [Troubleshooting](#-troubleshooting) +- [Contributing](#-contributing) --- @@ -730,6 +731,32 @@ docker compose logs waf --tail 20 --- +## 🤝 Contributing + +Development is driven **entirely through GitHub** — issues, branches, pull +requests, code reviews and project status all live there. This makes the +project easy to **pilot remotely from the command line** with the `gh` CLI +(including by AI coding agents): create an issue, branch, open a PR, review +and merge without ever leaving the terminal or the GitHub UI. + +The full, mandatory workflow is documented in +**[`WORKSPACE_WORKFLOW_GIT.md`](WORKSPACE_WORKFLOW_GIT.md)**: + +- **Branch + PR only** — no local merge into `main`; every change lands + through a pull request merged on GitHub. +- **Issue lifecycle** — self-assign, move the Projects status to *In + Progress*, keep solution-design discussion in the issue. +- **PR ↔ issue link** — a `Closes #N` keyword in the PR **body** auto-closes + the issue on merge. +- **PR-channel reviews** — once a PR is open, code-review discussion moves to + the PR; every review conclusion is published on GitHub (`gh pr review` / + `gh pr comment`), not only in chat. + +Following this file keeps the issue and PR histories clean and auditable, and +lets a contributor (or an agent) drive the whole cycle reproducibly via `gh`. + +--- + ## 🔗 Related Projects | Project | Description | Link | diff --git a/WORKSPACE_WORKFLOW_GIT.md b/WORKSPACE_WORKFLOW_GIT.md new file mode 100644 index 0000000..f337f19 --- /dev/null +++ b/WORKSPACE_WORKFLOW_GIT.md @@ -0,0 +1,210 @@ +## Git Workflow (MANDATORY) + +**Rule:** All merges into `main` must happen **exclusively on GitHub through +a Pull Request**. Do not merge locally into `main`. + +- Work must happen on a dedicated branch (`phaseX/y-issue`). +- Integration into `main` happens through a PR merged on GitHub. +- Local `main` is only used for `git pull --ff-only` after the GitHub merge. +- Before opening a PR: run `git fetch origin && git rebase origin/main` + **from the feature branch** to synchronize it. + +**Why:** a local merge into `main` while a PR is still evolving on GitHub +creates divergence and corrupts the shared history. + +### Commands Forbidden by Default + +- `git merge` (or any equivalent operation) on local `main`, except + `git pull --ff-only` after the GitHub merge. +- `git push --force` (or `--force-with-lease`) to `main`. +- `git commit` directly on local `main`. + +### Nominal Cycle + +```bash +# 0. Start work on the issue: assign yourself and move the Project status to +# "In Progress" +gh issue edit --add-assignee "@me" +# Then update the GitHub Projects "Status" field through the GitHub API. +# Forbidden: gh issue edit --add-label "status:in-progress" + +# 1. Start from a clean main +git checkout main && git pull --ff-only + +# 2. Create the feature branch +git checkout -b phaseX/y-issue-slug + +# 3. Work and make atomic commits +git add ... && git commit -m "..." + +# 4. Before the PR: rebase onto the up-to-date main +git fetch origin && git rebase origin/main + +# 5. Push and open the PR with gh +git push -u origin phaseX/y-issue-slug +gh pr create --base main --title "..." --body "..." +# MANDATORY: the body MUST contain a "Closes #" line at the top +# (see the "PR-Issue Link" section below). + +# 6. After the GitHub merge: clean up locally +git checkout main && git pull --ff-only +git branch -d phaseX/y-issue-slug +``` + +### PR-Issue Link (MANDATORY) + +**Rule:** any PR that resolves an issue MUST contain a GitHub closing keyword +(`Closes`, `Fixes`, `Resolves`) followed by the issue number, **in the PR +body**, ideally on the first line. + +```text +Closes # +``` + +**Why:** + +- Only a keyword in the **body** of a PR (or in a commit message merged into + the default branch) triggers automatic issue closing on GitHub. A + `Closes #N` in the PR **title** is not enough, because GitHub does not parse + closing keywords there. +- This populates the issue API field `closedByPullRequestsReferences`, which + propagates the link to the "Development" views of other issues, + notifications, and release-notes tooling. +- This avoids forgetting to close the issue manually after the merge. + +**GitHub accepted keywords** (case-insensitive): `close`, `closes`, `closed`, +`fix`, `fixes`, `fixed`, `resolve`, `resolves`, `resolved`. Prefer +`Closes #` for consistency. + +**For a PR that references an issue without closing it** (dependency, context, +partial work): use `Refs #` or `Related to #`, which create a soft link +without automatic closing. + +**Post-creation verification:** + +```bash +gh issue view --json closedByPullRequestsReferences +# The field must contain the created PR. If it is empty, the keyword is +# missing or malformed. Fix it with `gh pr edit --body "..."`. +``` + +## GitHub Issues Workflow (MANDATORY) + +**Rule:** each issue follows an explicit lifecycle on GitHub, and conversations +must stay in the **right channel** between the issue and its PR to keep both +histories readable. + +### When Starting Work on an Issue + +1. **Assign yourself the issue** with the configured `gh` account: + + ```bash + gh issue edit --add-assignee "@me" + ``` + +2. **Move the Project status to In Progress through the GitHub API:** + + - Never use a `status:in-progress` label to represent progress status. A + label is not the issue status. + - Update the GitHub Projects `Status` field of the item linked to the issue + and set it to the `In Progress` option. + - Use the GitHub Projects v2 API, for example through `gh api graphql`, + after resolving `PROJECT_ID`, `PROJECT_ITEM_ID`, `STATUS_FIELD_ID`, and + `IN_PROGRESS_OPTION_ID` for the relevant project. + + ```bash + gh api graphql -f query=' + mutation( + $projectId: ID! + $itemId: ID! + $statusFieldId: ID! + $inProgressOptionId: String! + ) { + updateProjectV2ItemFieldValue(input: { + projectId: $projectId + itemId: $itemId + fieldId: $statusFieldId + value: { singleSelectOptionId: $inProgressOptionId } + }) { + projectV2Item { id } + } + }' \ + -F projectId="$PROJECT_ID" \ + -F itemId="$PROJECT_ITEM_ID" \ + -F statusFieldId="$STATUS_FIELD_ID" \ + -F inProgressOptionId="$IN_PROGRESS_OPTION_ID" + ``` + + If the issue is not yet present in the project, first add it through the + GitHub Projects v2 API (`addProjectV2ItemById`), then apply the status + mutation above. + +### During Implementation (Before Opening the PR) + +All conversations related to the **solution design** remain in the issue. Post +there: + +- the technical decisions made and their rationale; +- the implementation trade-offs that were arbitrated; +- the clarifications requested and the answers received; +- the divergences identified against the initial plan. + +```bash +gh issue comment --body "..." +``` + +### After Opening the PR + +As soon as a PR is opened to resolve the issue, **code review discussions** +move to the PR. The issue stops being the discussion channel: + +- reviewer comments (findings, change requests, refactoring suggestions) go + **in the PR**, not in the issue; +- implementer replies (applied fixes, rationales, counter-arguments to a + comment) also go **in the PR**, not in the issue; +- the issue receives only high-level summary updates when necessary (major + blocker, scope change). + +```bash +# General comment in the PR +gh pr comment --body "..." + +# Formal review (approve / request-changes / comment) +gh pr review --comment --body "..." +``` + +### PR Verification / Review (MANDATORY) + +When the user asks to **verify**, **reread**, **review**, **check**, or +**validate** a GitHub PR, treat the request as a PR review, not as a simple +local analysis. + +**Rule:** every review conclusion must be published on GitHub in the PR before +the final response, unless the user explicitly instructs otherwise (`local +only`, `do not post`, draft, etc.). + +Mandatory checklist before responding: + +1. Inspect the PR (`gh pr view`, `gh pr diff`, CI checks, linked issue when + applicable) and run the relevant local tests. +2. Write findings with severity, files/lines, impact, and the expected fix. +3. Publish the review in the PR: + - blocking finding: prefer `gh pr review --request-changes --body + "..."`; + - non-blocking findings or informational review: `gh pr review + --comment --body "..."`; + - no finding: post at least a comment/review stating the checks performed + and the residual risk. +4. If GitHub refuses the formal review (for example, the configured `gh` + account is the PR author and cannot request changes), immediately fall back + to `gh pr comment --body "..."` with the same content. +5. The final response must include the link to the published GitHub + comment/review, the checks that were run, and any limitations. + +**Guardrail:** a chat-only response after a PR review request is incomplete. +Never finish the task without a GitHub trace, unless the user explicitly asks +not to post. + +**Why:** an issue captures the *problem* and the chosen direction; a PR captures +the *execution* and code review. Mixing the two dilutes both histories and +makes later review harder (audit, post-mortem, new contributor onboarding).