Contributing: every change reaches main through a pull request, with main protected #940

Closed
opened 2026-10-16 13:54:45 +00:00 by tiagoagueda · 0 comments
Owner

Until now, a fix or feature was committed straight onto main and pushed: one issue per commit, often several commits per push. From now on, every change reaches main through a pull request. The change is pushed to a branch, a pull request is opened, CI runs on it, and it is merged only when CI passes.

What exists today

  • Direct pushes are the norm. Nearly every commit on main was pushed there directly. The only pull requests are Weblate's (from its weblate branch, #706) and the monthly dependency upgrade (dependencies.yml, pushed by a bot with DEPENDENCIES_TOKEN).
  • CI already runs on pull requests. .forgejo/workflows/ci.yml runs on push to main and the release branches, and on every pull_request, so no workflow change is needed for checks to run.
  • What happens after a push to main. Every push to main that passes CI builds and publishes the :dev image (dev-image.yml), and releases are tagged on main (CONTRIBUTING.md, Releasing).
  • The docs describe the old flow. CONTRIBUTING.md and CLAUDE.md (see #939) describe committing and pushing, and their rules were written for it. One issue per commit and the wiki commit pushed when the code is (CONTRIBUTING.md around line 477) both assume a direct push.
  • Nothing on the server prevents a direct push. No branch protection is set on main.

What would change

On the instance (Forgejo settings)

  1. Protect main.

    • Turn off direct pushes for everybody, the maintainer included.
    • Turn off force pushes and branch deletion.
  2. Make the CI jobs required checks. A pull request can be merged only when Checks, Unit tests and coverage, Database tests on PostgreSQL, Security audit and Browser tests have passed.

  3. Require the branch to be current, or not. One option is to require a pull request's branch to be up to date with main before merging. Decide whether to turn it on: it is safer, but costs a CI rerun after every merge to main.

  4. Keep the bots working.

    • Weblate pushes only to weblate and already opens a pull request, so it is unaffected.
    • The dependency bot pushes only its own branch, so it is unaffected too.
    • Any workflow that pushes to main itself must be found and changed to open a pull request instead.
  5. Choose a merge style. Weblate's pull requests stay merge commits, because the guard (messages.py guard) checks that translation commits are authored by Weblate. For code, choose one, for example:

    • rebase and merge, which keeps one commit per issue on a straight line;
    • or squash, which gives one commit per pull request.

    Write the choice down.

In the repository (docs)

  1. CONTRIBUTING.md. A How a change reaches main section:
    • Branches: one branch per issue, named after it (909-map, as the worktrees already do).
    • Pull requests: one issue per pull request where possible. The description says Closes #N, and the wiki change it needs is linked.
    • Checks and review: CI must be green. The maintainer reviews and merges.
    • Follow-ups: what happens to a commit that only fixes a test or a catalogue after a merge (it gets its own small pull request).
  2. Update every place that says "push to main".
    • The old rules: one issue per commit, and pushed when the code is for wiki commits.
    • The release steps: tag on main after the release pull request is merged, then wait for CI and Every Python on the merge commit.
    • The :dev image, which is built when a pull request is merged.
  3. AGENTS.md / CLAUDE.md (#939). Tell AI assistants that the way to deliver a change is a branch and a pull request, and never git push origin <branch>:main.

Done when

  • A direct push to main is refused by the server, for every account.
  • A pull request can't be merged until the five CI jobs pass.
  • CONTRIBUTING.md, AGENTS.md and the release steps describe the pull-request flow, and the next few changes land that way.

#706 (Weblate pull requests), #727 (Forgejo 16 workflow permissions and Authorized Integrations, which matter for bots that push), #939 (AGENTS.md).

Until now, a fix or feature was committed straight onto `main` and pushed: one issue per commit, often several commits per push. From now on, **every change reaches `main` through a pull request.** The change is pushed to a branch, a pull request is opened, CI runs on it, and it is merged only when CI passes. ## What exists today - **Direct pushes are the norm.** Nearly every commit on `main` was pushed there directly. The only pull requests are Weblate's (from its `weblate` branch, #706) and the monthly dependency upgrade (`dependencies.yml`, pushed by a bot with `DEPENDENCIES_TOKEN`). - **CI already runs on pull requests.** `.forgejo/workflows/ci.yml` runs on `push` to `main` and the release branches, and on every `pull_request`, so no workflow change is needed for checks to run. - **What happens after a push to `main`.** Every push to `main` that passes CI builds and publishes the `:dev` image (`dev-image.yml`), and releases are tagged on `main` (CONTRIBUTING.md, *Releasing*). - **The docs describe the old flow.** CONTRIBUTING.md and `CLAUDE.md` (see #939) describe committing and pushing, and their rules were written for it. *One issue per commit* and *the wiki commit pushed when the code is* (CONTRIBUTING.md around line 477) both assume a direct push. - **Nothing on the server prevents a direct push.** No branch protection is set on `main`. ## What would change ### On the instance (Forgejo settings) 1. **Protect `main`.** - Turn off direct pushes for everybody, the maintainer included. - Turn off force pushes and branch deletion. 2. **Make the CI jobs required checks.** A pull request can be merged only when *Checks*, *Unit tests and coverage*, *Database tests on PostgreSQL*, *Security audit* and *Browser tests* have passed. 3. **Require the branch to be current, or not.** One option is to require a pull request's branch to be up to date with `main` before merging. Decide whether to turn it on: it is safer, but costs a CI rerun after every merge to `main`. 4. **Keep the bots working.** - Weblate pushes only to `weblate` and already opens a pull request, so it is unaffected. - The dependency bot pushes only its own branch, so it is unaffected too. - Any workflow that pushes to `main` itself must be found and changed to open a pull request instead. 5. **Choose a merge style.** Weblate's pull requests stay **merge commits**, because the guard (`messages.py guard`) checks that translation commits are authored by Weblate. For code, choose one, for example: - *rebase and merge*, which keeps one commit per issue on a straight line; - or *squash*, which gives one commit per pull request. Write the choice down. ### In the repository (docs) 6. **CONTRIBUTING.md.** A *How a change reaches main* section: - **Branches:** one branch per issue, named after it (`909-map`, as the worktrees already do). - **Pull requests:** one issue per pull request where possible. The description says `Closes #N`, and the wiki change it needs is linked. - **Checks and review:** CI must be green. The maintainer reviews and merges. - **Follow-ups:** what happens to a commit that only fixes a test or a catalogue after a merge (it gets its own small pull request). 7. **Update every place that says "push to main".** - The old rules: *one issue per commit*, and *pushed when the code is* for wiki commits. - The release steps: tag on `main` after the release pull request is merged, then wait for CI and *Every Python* on the merge commit. - The `:dev` image, which is built when a pull request is merged. 8. **`AGENTS.md` / `CLAUDE.md` (#939).** Tell AI assistants that the way to deliver a change is a branch and a pull request, and never `git push origin <branch>:main`. ## Done when - A direct push to `main` is refused by the server, for every account. - A pull request can't be merged until the five CI jobs pass. - CONTRIBUTING.md, `AGENTS.md` and the release steps describe the pull-request flow, and the next few changes land that way. ## Related #706 (Weblate pull requests), #727 (Forgejo 16 workflow permissions and Authorized Integrations, which matter for bots that push), #939 (AGENTS.md).
tiagoagueda added this to the 0.5.0 milestone 2026-10-25 17:04:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#940
No description provided.