While feature branches may have different requirements for the Forgejo tables, they are constrained by the migration logic that requires they happen in sequence and are listed in the same list. If each feature branch changes the `forgejo_migrations/migrate.go` file independently, it is bound to conflict with other feature branches trying to do the same. To avoid this situation it is proposed that once a migration developped and tested in a freature branch is final, it is isolated in a commit and moved to the `forgejo-development` branch. This can happen during a rebase or with a pull request. It is probably better that all migrations are ultimately squashed in a single commit in the `forgejo-development` branch instead of an ever growing list of commits. But this is up to the person in charge of the migrations and since the directory is owned by forgejo, there is no risk of conflict.
7.9 KiB
title | license |
---|---|
Development workflow | CC-BY-SA-4.0 |
Forgejo is a set of commits applied to the Gitea development branch and the stable branches. On a regular basis those commits are cherry-picked and modified if necessary to keep working. All Forgejo commits are merged into a branch from which binary releases and packages are created and distributed. The development workflow is a set of conventions Forgejo developers are expected to follow to work together.
Naming conventions
Development
- Gitea: main
- Forgejo: forgejo
- Feature branches: forgejo-feature-name
Stable
- Gitea: release/vX.Y
- Forgejo: vX.Y/forgejo
- Feature branches: vX.Y/forgejo-feature-name
Branches history
Before cherry-picking on top of Gitea, all branches are copied to soft-fork/YYYY-MM-DD/<branch>
for safekeeping. Older soft-fork/*/<branch>
branches are converted into references under the same name. Similar to how pull requests store their head, they do not clutter the list of branches but can be retrieved if needed with git fetch +refs/soft-fork/*:refs/soft-fork/*
. Tooling to automate this archival process is available.
Cherry-picking
Feature branches
On a weekly basis all of Forgejo commits are cherry-picked on top of the latest Gitea development branch. It starts like this:
- the
forgejo-ci
branch isreset --hard
with Gitea main - all the commits it contained are
cherry-pick -x
and conflicts resolved - the
forgejo-ci
branch is force pushed after the CI confirms it is sane
The same is done for the forgejo-development
branch is based on
forgejo-ci
and the commits it contains are similarly cherry-pick -x
. The same is done for each Feature branch until they all pass
the CI.
Development branch
Once all Feature branches are ready, the forgejo
branch is reset --hard
with Gitea main, all Feature branches are merged into it
and it is force pushed.
Stable branches
The stable branches are not force pushed because they would no longer contain the tags from which releases were made. Instead, the following is done:
- The Gitea commits are cherry-picked
- If there is a conflict
- revert the Forgejo commit that caused the conflict
- cherry-pick the Gitea commit
- cherry-pick the Forgejo commit back and resolve the conflict
This ensures the conflict resolution is documented in the relevant Forgejo commit. The conflict must not be resolved in the Gitea commit because there would be no convenient way to know why and how it happened when browing the commit history.
To improve the readability of the git history, pull requests to stable branches are rebased on top of the branch instead of being merged. It saves one merge commit and creates a linear history.
Feature branches
All Feature branches are based on the {vX.Y/,}forgejo-development branch which provides development tools and documentation.
The forgejo-development
branch is based on the {vX.Y/,}forgejo-ci branch which provides the CI configuration.
The purpose of each Feature branch is documented below:
General purpose
-
forgejo-ci based on main CI configuration, including the release process.
-
forgejo-development based on forgejo-ci Forgejo development tools, tests etc. that do not fit in a feature branch or that are used by multiple feature branches. The commits titles should be prefixed with a string that reflects their purpose such as
[DOCS]
,[DB]
,[TESTS]
etc.The database migrations of all feature branches must be in the
forgejo-development
branch. This is a requirement to ensure they do not conflict with each other and happen in sequence.
Dependency
- forgejo-dependency based on forgejo-development Each commit is prefixed with the name of dependency in uppercase, for instance [GOTH] or [GITEA]. They are standalone and implement either a bug fix or a feature that is in the process of being contributed to the dependency. It is better to contribute directly to the dependency instead of adding a commit to this branch but it is sometimes not possible, for instance when someone does not have a GitHub account. The author of the commit is responsible for rebasing and resolve conflicts. The ultimate goal of this branch is to be empty and it is expected that a continuous effort is made to reduce its content so that the technical debt it represents does not burden Forgejo long term.
Privacy
- forgejo-privacy based on forgejo-development Customize Forgejo to have more privacy.
Moderation
- forgejo-moderation based on forgejo-development Add moderation tooling for users and admins.
Branding
- forgejo-branding based on forgejo-development Replace hardcoded dependencies branding with a Forgejo equivalent.
Internationalization
- forgejo-i18n based on forgejo-development Internationalization and localization support.
Accessibility
- forgejo-a11y based on forgejo-development Accessibility improvements.
Federation
-
forgejo-federation based on forgejo-development Federation support.
-
forgejo-f3 based on forgejo-development F3 support.
Pull requests and feature branches
Most people who are used to contributing will be familiar with the workflow of sending a pull request against the default branch. When that happens the reviewer may ask to change the base branch to the appropriate Feature branch instead. If the pull request does not fit in any Feature branch, the reviewer needs to make decision to either:
- Decline the pull request because it is best contributed to the relevant dependency
- Create a new Feature branch
Granularity
Feature branches can contain a number of commits grouped together, for instance for branding the documentation, the landing page and the footer. It makes it convenient for people working on that topic to get the big picture without browsing multiple branches. Creating a new Feature branch for each individual commit, while possible, is likely to be difficult to work with.
Observing the granularity of the existing Feature branches is the best way to figure out what works and what does not. It requires adjustments from time to time depending on the number of contributors and the complexity of the Forgejo codebase.