diff --git a/README.md b/README.md index 691beed..464435d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # git-next +- Status: Alpha - dog-fooding + `git-next` is a combined server and command-line tool that enables trunk-based development workflows where each commit must pass CI before being included in the main branch. @@ -14,12 +16,19 @@ the main branch. ## Prerequisits -- Rust 1.76.0 or later +- Rust 1.76.0 or later - https://www.rust-lang.org - pgk-config - libssl-dev + +### x86_64-unknown-linux-gnu + +Additionally for this platform, to improved compilation times: + - clang-16 - mold +See `.cargo/config.toml` for how they are configured. + ## Installation You can install `git-next` using Cargo: @@ -28,15 +37,143 @@ You can install `git-next` using Cargo: cargo install --path . ``` +Not yet available to install from `crates.io`. + +## Branch Names + +`git-next` uses three branches, `main`, `next` and `dev`, although they do not +need to have those names. In the documentation we will use those names, but +each repo must specify the names of the branches to use for each, even if they +happen to have those same names. + ## Configuration -- The repo has a `.git-next.toml` file in it's root. (N.B. see - [#28](https://git.kemitix.net/kemitix/git-next/issues/28) for a planned - alternative) +- The branches to use for `main`, `next` and `dev` must be specified in either + the `.git-next.toml` in the repo itself, or in the server configuration file, + `git-next-server.toml`. See below for details. - CI checks should be configured to run when the `next` branch is `pushed`. - The `dev` branch _must_ have the `main` branch as an ancestor. - The `next` branch _must_ have the `main` branch as an ancestor. +### Server + +The server is configured by the `git-next-server.toml` file. + +#### http + +The server needs to be able to receive webhook notifications from your forge, +(e.g. github.com). You can do this via any method that suits your environment, +e.g. ngrok or a reverse proxy from a web server that itself can route traffic +to the machine you are running the git-next server on. + +Specify the address and port the server should listen to for incoming webhooks. +This is the address and port that your reverse proxy should route traffic to. + +- **addr** - the IP address the server should bind to +- **port** - the IP port the server should bind to + +#### webhook + +Your forges need to know where they should route webhooks to. This should be +an address this is accessible to the forge. So, for github.com, it would need +to be a publicly accessible HTTPS URL. For a self-hosted forge, e.g. ForgeJo, +on your own network, then it only needs to be accessible from the server your +forge is running on. + +- **url** - the HTTPS URL for forges to send webhook to + +#### storage + +`git-next` will create a bare clone of each repo that you configure it to +monitor. They will all be created in the directory specified here. This data +does not need to be backed up, as any missing information will be cloned when +the server starts up. + +- **path** - directory to store local copies of monitored repos + +#### forge + +Within the forge tree, specify each forge you want to monitore repos on. + +Give your forge an alias, e.g. `default`, `gh`, `github`. + +e.g. + +```toml +[forge.github] +forge_type = "GitHub" +hostname = "github.com" +user = "username" +token = "api-key" +``` + +- **forge_type** - one of: `ForgeJo` or `GitHub` +- **hostname** - the hostname for the forge. +- **user** - the user to authenticate as +- **token** - application token for the user. See below for the permissions + required for on each forge. + +Generally, the `user` will need to be able to push to `main` and to _force-push_ +to `next`. + +#### repos + +For each forge, you need to specify which repos on the forge you want to +monitor. They do not need to be owned by the `user`, but they `user` must have +the `push` and `force-push` permissions as mentioned above for each of the +repositories. + +e.g. + +```toml +[forge.github.repos] +my-repo = { repo = "owner/repo", branch = "main", gitdir = "/home/pcampbell/project/my-repo" } + +[forge.github.repos.other-repo] +repo = "user/other" +branch = "master" +main = "master" +next = "ci-testing" +dev = "trunk" +``` + +Note that toml allows specifying the values on one line, or across multiple +lines. Both are equivalent. What is not equivalent between `my-repo` and +`other-repo`, is that one will require a configuration file within the repo +itself. `other-repo` specifies the `main`, `next` and `dev` branches to be +used, but `my-repo` doesn't. + +A sample `.git-next-toml` file that would need to exist in the `user/other` +repo, on the `main` branch: + +```toml +[branches] +main = "main" +next = "next" +dev = "dev" +``` + +- **repo** - the owner and name of the repo to be monitored +- **branch** - the branch to look for a `.git-next.toml` file is needed +- **gitdir** - (optional) you can use local copy of the repo +- **main** - the branch to use as `main` +- **next** - the branch to use as `next` +- **dev** - the branch to use as `dev` + +##### gitdir + +Additional notes on using `gitdir`: + +When you specify the `gitdir` value, the repo will be used for perform the +equivalent of `git fetch`, `git push` and `git push --force-with-lease`. + +These commands will not affect the contents of your working tree, not will +it change any local branches. Only the details about branches on the remote +forge will be updated. + +Currently `git-next` can only use a `gitdir` if the forge is the same one +specified as `origin`. Otherwise the behaviour is untested/undefined. + ## Behaviour Development happens on the `dev` branch, where each commit is expected to @@ -77,7 +214,7 @@ gitGraph It will then wait for the CI checks to pass for the newly updated `next` branch. When the CI checks for the `next` branch pass, it will push the `main` branch -fast-forward to the `next` branch. +fast-forward to the `next` branch. We return to the top and start again. ```mermaid gitGraph @@ -93,7 +230,7 @@ gitGraph ``` If the CI checks should fail for the `next` branch, the developer should -**amend** that commit in the history of their `dev` branch. +**amend** that commit **in the history of their `dev` branch**. They should then force-push their rebased `dev` branch. ```mermaid @@ -114,27 +251,38 @@ gitGraph ``` `git-next` will then detect that the `next` branch is no longer part of the -`dev` branch ancestory, and reset `next` back to `main`. +`dev` branch ancestory, and will reset `next` back to `main`. We then return to the top, where `git-next` sees that `dev` is ahead of `next`. +When the `dev` branch is on the same commit as the `main` branch, then there +are no pending commits and `git-next` will wait until it receives a webhook +indicating that there has been a push to one of the branches. At which point +it will start at the top again. + ### Important The `dev` branch _should_ have the `next` branch as an ancestor. -If the `git-next` server finds that this isn't the case, it will **force-push** -the `next` branch back to the same commit as the `main` branch. +However, when the commit on tip of the `next` branch has failed CI and is +amended, this will not be the case. When this happens `git-next` will +**force-push** the `next` branch back to the same commit as the `main` branch. -In short, the `next` branch **belongs** to `git-next`. +This is the only time a force-push will happen in `git-next`. + +In short, the `next` branch **belongs** to `git-next`. Don't try to update it +yourself. `git-next` will update the `next` it as it sees fit. ## Getting Started To use `git-next` for trunk-based development, follow these steps: -### Initialise the repo +### Initialise the repo (optional) -You need to specify which branches you are using +You need to specify which branches you are using. You can do this in the repo, +or in the server configuration. -To create the default config file, run this command in the root of your repo: +To create a default config file for the repo, run this command in the root of +your repo: ```shell git next init @@ -147,7 +295,8 @@ three branches _must_ exist in your repo. ### Initialise the server -The server uses the file `git-next-server.toml` for configuration. +The server uses the file `git-next-server.toml` for configuration. It expects +to find this file the the current directory when executed. The create the default config file, run this command: @@ -157,12 +306,7 @@ git next server init This will create a `git-next-server.toml` file. [Default](./server-default.toml) -Edit this file to your needs. - -Specify the access token. - -The `branch` parameter for the repo identies the branch where the -`.git-next.toml` file should be found. +Edit this file to your needs. See the [Configuration](#configuration) section above. ### Run the server @@ -174,7 +318,10 @@ git next server start ### Forges -The following forges are supported: [ForgeJo](https://forgejo.org) and [GitHub](https://github.com/). +The following forges are supported: + +- [ForgeJo](https://forgejo.org) +- [GitHub](https://github.com/) #### ForgeJo @@ -192,7 +339,9 @@ hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch ``` -The token is created `/user/settings/applications` and requires the `write:repository` permission. +The token is created on your ForgeJo instance at (for example) +`https://git.myforgejo.com/user/settings/applications` +and requires the `write:repository` permission. #### GitHub @@ -217,7 +366,7 @@ The token is created [here](https://github.com/settings/tokens/new) and requires Contributions to `git-next` are welcome! If you find a bug or have a feature request, please [create an issue](https://git.kemitix.net/kemitix/git-next/issues/new). -If you'd like to contribute code, feel free to submit a merge request. +If you'd like to contribute code, feel free to submit changes. Before you start committing, run the `just install-hooks` command to setup the Git Hooks. ([Get Just](https://just.systems/man/en/chapter_3.html)) diff --git a/server-default.toml b/server-default.toml index 885881e..c5258fb 100644 --- a/server-default.toml +++ b/server-default.toml @@ -8,6 +8,8 @@ url = "https://localhost:8080" [storage] path = "./data" +[forge] + [forge.default] forge_type = "ForgeJo" hostname = "git.example.net"