From 7387d7c8712a2442974f93d21b8693ed2fbef662 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 26 Jan 2025 08:04:39 +0000 Subject: [PATCH] refactor: flatten into single crate --- Cargo.toml | 64 +- README.md | 662 ++++++++++++++++- crates/cli/Cargo.toml | 124 ---- crates/cli/README.md | 672 ------------------ crates/cli/default.toml => default.toml | 0 {crates/cli/src => src}/alerts/desktop.rs | 0 {crates/cli/src => src}/alerts/email.rs | 0 .../cli/src => src}/alerts/handlers/mod.rs | 0 .../alerts/handlers/notify_user.rs | 0 .../alerts/handlers/update_shout.rs | 0 {crates/cli/src => src}/alerts/history.rs | 0 {crates/cli/src => src}/alerts/messages.rs | 0 {crates/cli/src => src}/alerts/mod.rs | 0 .../cli/src => src}/alerts/tests/history.rs | 0 {crates/cli/src => src}/alerts/tests/mod.rs | 0 {crates/cli/src => src}/alerts/webhook.rs | 0 {crates/cli/src => src}/base_actor.rs | 0 .../cli/src => src}/core/config/api_token.rs | 0 .../src => src}/core/config/branch_name.rs | 0 .../src => src}/core/config/commit_count.rs | 0 {crates/cli/src => src}/core/config/common.rs | 0 .../src => src}/core/config/forge_alias.rs | 0 .../src => src}/core/config/forge_config.rs | 0 .../src => src}/core/config/forge_details.rs | 0 .../cli/src => src}/core/config/forge_type.rs | 0 .../cli/src => src}/core/config/git_dir.rs | 0 {crates/cli/src => src}/core/config/graphs.rs | 0 .../cli/src => src}/core/config/host_name.rs | 0 {crates/cli/src => src}/core/config/mod.rs | 0 .../core/config/registered_webhook.rs | 0 .../cli/src => src}/core/config/remote_url.rs | 0 .../cli/src => src}/core/config/repo_alias.rs | 0 .../src => src}/core/config/repo_branches.rs | 0 .../src => src}/core/config/repo_config.rs | 0 .../core/config/repo_config_source.rs | 0 .../cli/src => src}/core/config/repo_path.rs | 0 {crates/cli/src => src}/core/config/server.rs | 0 .../core/config/server_repo_config.rs | 0 {crates/cli/src => src}/core/config/tests.rs | 0 .../cli/src => src}/core/config/tests/url.rs | 0 {crates/cli/src => src}/core/config/user.rs | 0 .../cli/src => src}/core/config/webhook.rs | 0 .../src => src}/core/config/webhook/auth.rs | 0 .../core/config/webhook/forge_notification.rs | 0 .../cli/src => src}/core/config/webhook/id.rs | 0 .../src => src}/core/config/webhook/push.rs | 0 .../src => src}/core/config/webhook/tests.rs | 0 {crates/cli/src => src}/core/git/commit.rs | 0 {crates/cli/src => src}/core/git/file.rs | 0 .../cli/src => src}/core/git/forge/commit.rs | 0 {crates/cli/src => src}/core/git/forge/mod.rs | 0 .../cli/src => src}/core/git/forge/trait.rs | 0 .../cli/src => src}/core/git/forge/webhook.rs | 0 .../cli/src => src}/core/git/generation.rs | 0 {crates/cli/src => src}/core/git/git_ref.rs | 0 .../cli/src => src}/core/git/git_remote.rs | 0 {crates/cli/src => src}/core/git/graph.rs | 0 {crates/cli/src => src}/core/git/mod.rs | 0 {crates/cli/src => src}/core/git/push.rs | 0 .../cli/src => src}/core/git/repo_details.rs | 0 .../core/git/repository/factory.rs | 0 .../src => src}/core/git/repository/mod.rs | 0 .../core/git/repository/open/mod.rs | 0 .../core/git/repository/open/oreal.rs | 0 .../core/git/repository/open/otest.rs | 0 .../git/repository/open/tests/commit_log.rs | 0 .../core/git/repository/open/tests/fetch.rs | 0 .../open/tests/find_default_remote.rs | 0 .../git/repository/open/tests/forge_config.rs | 0 .../core/git/repository/open/tests/mod.rs | 0 .../git/repository/open/tests/read_file.rs | 0 .../git/repository/open/tests/repo_config.rs | 0 .../open/tests/server_repo_config.rs | 0 .../src => src}/core/git/repository/test.rs | 0 .../core/git/repository/tests/factory.rs | 0 .../core/git/repository/tests/mod.rs | 0 .../core/git/repository/tests/validate.rs | 0 {crates/cli/src => src}/core/git/tests.rs | 0 .../src => src}/core/git/user_notification.rs | 0 .../src => src}/core/git/validation/mod.rs | 0 .../core/git/validation/positions.rs | 0 .../core/git/validation/remotes.rs | 0 .../src => src}/core/git/validation/tests.rs | 0 .../cli/src => src}/core/macros/message.rs | 0 {crates/cli/src => src}/core/macros/mod.rs | 0 .../cli/src => src}/core/macros/newtype.rs | 0 .../src => src}/core/macros/owned_string.rs | 0 {crates/cli/src => src}/core/mod.rs | 0 {crates/cli/src => src}/file_watcher.rs | 0 {crates/cli/src => src}/forge/mod.rs | 0 {crates/cli/src => src}/forge/tests.rs | 0 {crates/cli/src => src}/forges/forgejo/mod.rs | 0 .../cli/src => src}/forges/forgejo/tests.rs | 0 .../forges/forgejo/webhook/list.rs | 0 .../src => src}/forges/forgejo/webhook/mod.rs | 0 .../forges/forgejo/webhook/parser.rs | 0 .../forges/forgejo/webhook/register.rs | 0 .../forges/forgejo/webhook/unregister.rs | 0 .../cli/src => src}/forges/github/commit.rs | 0 .../src => src}/forges/github/message.json | 0 {crates/cli/src => src}/forges/github/mod.rs | 0 .../src => src}/forges/github/tests/mod.rs | 0 .../forges/github/webhook/authorisation.rs | 0 .../src => src}/forges/github/webhook/list.rs | 0 .../src => src}/forges/github/webhook/mod.rs | 0 .../forges/github/webhook/parser.rs | 0 .../forges/github/webhook/register.rs | 0 .../forges/github/webhook/unregister.rs | 0 {crates/cli/src => src}/forges/mod.rs | 0 {crates/cli/src => src}/init.rs | 0 {crates/cli/src => src}/macros/actor.rs | 0 {crates/cli/src => src}/macros/mod.rs | 0 {crates/cli/src => src}/macros/send.rs | 0 {crates/cli/src => src}/macros/spawn.rs | 0 {crates/cli/src => src}/main.rs | 0 {crates/cli/src => src}/repo/MESSAGES.md | 0 {crates/cli/src => src}/repo/branch.rs | 0 .../src => src}/repo/handlers/advance_main.rs | 0 .../src => src}/repo/handlers/advance_next.rs | 0 .../repo/handlers/check_ci_status.rs | 0 .../src => src}/repo/handlers/clone_repo.rs | 0 .../repo/handlers/load_config_from_repo.rs | 0 {crates/cli/src => src}/repo/handlers/mod.rs | 0 .../repo/handlers/receive_ci_status.rs | 0 .../repo/handlers/receive_repo_config.rs | 0 .../repo/handlers/register_webhook.rs | 0 .../repo/handlers/unregister_webhook.rs | 0 .../repo/handlers/validate_repo.rs | 0 .../repo/handlers/webhook_notification.rs | 0 .../repo/handlers/webhook_registered.rs | 0 {crates/cli/src => src}/repo/load.rs | 0 {crates/cli/src => src}/repo/messages.rs | 0 {crates/cli/src => src}/repo/mod.rs | 0 {crates/cli/src => src}/repo/notifications.rs | 0 .../repo/tests/branch/advance_main.rs | 0 .../repo/tests/branch/advance_next.rs | 0 .../cli/src => src}/repo/tests/branch/mod.rs | 0 {crates/cli/src => src}/repo/tests/expect.rs | 0 {crates/cli/src => src}/repo/tests/given.rs | 0 .../repo/tests/handlers/advance_main.rs | 0 .../repo/tests/handlers/advance_next.rs | 0 .../repo/tests/handlers/check_ci_status.rs | 0 .../repo/tests/handlers/clone_repo.rs | 0 .../tests/handlers/load_config_from_repo.rs | 0 .../repo/tests/handlers/loaded_config.rs | 0 .../src => src}/repo/tests/handlers/mod.rs | 0 .../repo/tests/handlers/receive_ci_status.rs | 0 .../repo/tests/handlers/register_webhook.rs | 0 .../repo/tests/handlers/validate_repo.rs | 0 .../tests/handlers/webhook_notification.rs | 0 .../repo/tests/handlers/webhook_registered.rs | 0 {crates/cli/src => src}/repo/tests/load.rs | 0 {crates/cli/src => src}/repo/tests/mod.rs | 0 {crates/cli/src => src}/repo/tests/when.rs | 0 {crates/cli/src => src}/root.rs | 0 .../cli/src => src}/server/actor/MESSAGES.md | 0 .../server/actor/handlers/file_updated.rs | 0 .../src => src}/server/actor/handlers/mod.rs | 0 .../actor/handlers/receive_app_config.rs | 0 .../handlers/receive_valid_app_config.rs | 0 .../server/actor/handlers/server_update.rs | 0 .../server/actor/handlers/shutdown.rs | 0 .../server/actor/handlers/shutdown_trigger.rs | 0 .../cli/src => src}/server/actor/messages.rs | 0 {crates/cli/src => src}/server/actor/mod.rs | 0 .../src => src}/server/actor/tests/given.rs | 0 .../cli/src => src}/server/actor/tests/mod.rs | 0 .../server/actor/tests/receive_app_config.rs | 0 {crates/cli/src => src}/server/mod.rs | 0 .../src => src}/server/server-default.toml | 0 {crates/cli/src => src}/server/tests.rs | 0 {crates/cli/src => src}/tests.rs | 0 {crates/cli/src => src}/tui/README.md | 0 .../cli/src => src}/tui/actor/handlers/mod.rs | 0 .../tui/actor/handlers/server_update.rs | 0 .../src => src}/tui/actor/handlers/tick.rs | 0 {crates/cli/src => src}/tui/actor/messages.rs | 0 {crates/cli/src => src}/tui/actor/mod.rs | 0 {crates/cli/src => src}/tui/actor/model.rs | 0 {crates/cli/src => src}/tui/actor/tests.rs | 0 .../tui/components/configured_app.rs | 0 .../tui/components/forge/collapsed.rs | 0 .../tui/components/forge/expanded.rs | 0 .../src => src}/tui/components/forge/mod.rs | 0 .../cli/src => src}/tui/components/history.rs | 0 .../src => src}/tui/components/key_focus.rs | 0 {crates/cli/src => src}/tui/components/mod.rs | 0 .../tui/components/repo/identity.rs | 0 .../src => src}/tui/components/repo/mod.rs | 0 {crates/cli/src => src}/tui/logging.rs | 0 {crates/cli/src => src}/tui/mod.rs | 0 {crates/cli/src => src}/webhook/mod.rs | 0 {crates/cli/src => src}/webhook/router.rs | 0 {crates/cli/src => src}/webhook/server.rs | 0 194 files changed, 701 insertions(+), 821 deletions(-) delete mode 100644 crates/cli/Cargo.toml delete mode 100644 crates/cli/README.md rename crates/cli/default.toml => default.toml (100%) rename {crates/cli/src => src}/alerts/desktop.rs (100%) rename {crates/cli/src => src}/alerts/email.rs (100%) rename {crates/cli/src => src}/alerts/handlers/mod.rs (100%) rename {crates/cli/src => src}/alerts/handlers/notify_user.rs (100%) rename {crates/cli/src => src}/alerts/handlers/update_shout.rs (100%) rename {crates/cli/src => src}/alerts/history.rs (100%) rename {crates/cli/src => src}/alerts/messages.rs (100%) rename {crates/cli/src => src}/alerts/mod.rs (100%) rename {crates/cli/src => src}/alerts/tests/history.rs (100%) rename {crates/cli/src => src}/alerts/tests/mod.rs (100%) rename {crates/cli/src => src}/alerts/webhook.rs (100%) rename {crates/cli/src => src}/base_actor.rs (100%) rename {crates/cli/src => src}/core/config/api_token.rs (100%) rename {crates/cli/src => src}/core/config/branch_name.rs (100%) rename {crates/cli/src => src}/core/config/commit_count.rs (100%) rename {crates/cli/src => src}/core/config/common.rs (100%) rename {crates/cli/src => src}/core/config/forge_alias.rs (100%) rename {crates/cli/src => src}/core/config/forge_config.rs (100%) rename {crates/cli/src => src}/core/config/forge_details.rs (100%) rename {crates/cli/src => src}/core/config/forge_type.rs (100%) rename {crates/cli/src => src}/core/config/git_dir.rs (100%) rename {crates/cli/src => src}/core/config/graphs.rs (100%) rename {crates/cli/src => src}/core/config/host_name.rs (100%) rename {crates/cli/src => src}/core/config/mod.rs (100%) rename {crates/cli/src => src}/core/config/registered_webhook.rs (100%) rename {crates/cli/src => src}/core/config/remote_url.rs (100%) rename {crates/cli/src => src}/core/config/repo_alias.rs (100%) rename {crates/cli/src => src}/core/config/repo_branches.rs (100%) rename {crates/cli/src => src}/core/config/repo_config.rs (100%) rename {crates/cli/src => src}/core/config/repo_config_source.rs (100%) rename {crates/cli/src => src}/core/config/repo_path.rs (100%) rename {crates/cli/src => src}/core/config/server.rs (100%) rename {crates/cli/src => src}/core/config/server_repo_config.rs (100%) rename {crates/cli/src => src}/core/config/tests.rs (100%) rename {crates/cli/src => src}/core/config/tests/url.rs (100%) rename {crates/cli/src => src}/core/config/user.rs (100%) rename {crates/cli/src => src}/core/config/webhook.rs (100%) rename {crates/cli/src => src}/core/config/webhook/auth.rs (100%) rename {crates/cli/src => src}/core/config/webhook/forge_notification.rs (100%) rename {crates/cli/src => src}/core/config/webhook/id.rs (100%) rename {crates/cli/src => src}/core/config/webhook/push.rs (100%) rename {crates/cli/src => src}/core/config/webhook/tests.rs (100%) rename {crates/cli/src => src}/core/git/commit.rs (100%) rename {crates/cli/src => src}/core/git/file.rs (100%) rename {crates/cli/src => src}/core/git/forge/commit.rs (100%) rename {crates/cli/src => src}/core/git/forge/mod.rs (100%) rename {crates/cli/src => src}/core/git/forge/trait.rs (100%) rename {crates/cli/src => src}/core/git/forge/webhook.rs (100%) rename {crates/cli/src => src}/core/git/generation.rs (100%) rename {crates/cli/src => src}/core/git/git_ref.rs (100%) rename {crates/cli/src => src}/core/git/git_remote.rs (100%) rename {crates/cli/src => src}/core/git/graph.rs (100%) rename {crates/cli/src => src}/core/git/mod.rs (100%) rename {crates/cli/src => src}/core/git/push.rs (100%) rename {crates/cli/src => src}/core/git/repo_details.rs (100%) rename {crates/cli/src => src}/core/git/repository/factory.rs (100%) rename {crates/cli/src => src}/core/git/repository/mod.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/mod.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/oreal.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/otest.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/commit_log.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/fetch.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/find_default_remote.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/forge_config.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/mod.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/read_file.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/repo_config.rs (100%) rename {crates/cli/src => src}/core/git/repository/open/tests/server_repo_config.rs (100%) rename {crates/cli/src => src}/core/git/repository/test.rs (100%) rename {crates/cli/src => src}/core/git/repository/tests/factory.rs (100%) rename {crates/cli/src => src}/core/git/repository/tests/mod.rs (100%) rename {crates/cli/src => src}/core/git/repository/tests/validate.rs (100%) rename {crates/cli/src => src}/core/git/tests.rs (100%) rename {crates/cli/src => src}/core/git/user_notification.rs (100%) rename {crates/cli/src => src}/core/git/validation/mod.rs (100%) rename {crates/cli/src => src}/core/git/validation/positions.rs (100%) rename {crates/cli/src => src}/core/git/validation/remotes.rs (100%) rename {crates/cli/src => src}/core/git/validation/tests.rs (100%) rename {crates/cli/src => src}/core/macros/message.rs (100%) rename {crates/cli/src => src}/core/macros/mod.rs (100%) rename {crates/cli/src => src}/core/macros/newtype.rs (100%) rename {crates/cli/src => src}/core/macros/owned_string.rs (100%) rename {crates/cli/src => src}/core/mod.rs (100%) rename {crates/cli/src => src}/file_watcher.rs (100%) rename {crates/cli/src => src}/forge/mod.rs (100%) rename {crates/cli/src => src}/forge/tests.rs (100%) rename {crates/cli/src => src}/forges/forgejo/mod.rs (100%) rename {crates/cli/src => src}/forges/forgejo/tests.rs (100%) rename {crates/cli/src => src}/forges/forgejo/webhook/list.rs (100%) rename {crates/cli/src => src}/forges/forgejo/webhook/mod.rs (100%) rename {crates/cli/src => src}/forges/forgejo/webhook/parser.rs (100%) rename {crates/cli/src => src}/forges/forgejo/webhook/register.rs (100%) rename {crates/cli/src => src}/forges/forgejo/webhook/unregister.rs (100%) rename {crates/cli/src => src}/forges/github/commit.rs (100%) rename {crates/cli/src => src}/forges/github/message.json (100%) rename {crates/cli/src => src}/forges/github/mod.rs (100%) rename {crates/cli/src => src}/forges/github/tests/mod.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/authorisation.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/list.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/mod.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/parser.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/register.rs (100%) rename {crates/cli/src => src}/forges/github/webhook/unregister.rs (100%) rename {crates/cli/src => src}/forges/mod.rs (100%) rename {crates/cli/src => src}/init.rs (100%) rename {crates/cli/src => src}/macros/actor.rs (100%) rename {crates/cli/src => src}/macros/mod.rs (100%) rename {crates/cli/src => src}/macros/send.rs (100%) rename {crates/cli/src => src}/macros/spawn.rs (100%) rename {crates/cli/src => src}/main.rs (100%) rename {crates/cli/src => src}/repo/MESSAGES.md (100%) rename {crates/cli/src => src}/repo/branch.rs (100%) rename {crates/cli/src => src}/repo/handlers/advance_main.rs (100%) rename {crates/cli/src => src}/repo/handlers/advance_next.rs (100%) rename {crates/cli/src => src}/repo/handlers/check_ci_status.rs (100%) rename {crates/cli/src => src}/repo/handlers/clone_repo.rs (100%) rename {crates/cli/src => src}/repo/handlers/load_config_from_repo.rs (100%) rename {crates/cli/src => src}/repo/handlers/mod.rs (100%) rename {crates/cli/src => src}/repo/handlers/receive_ci_status.rs (100%) rename {crates/cli/src => src}/repo/handlers/receive_repo_config.rs (100%) rename {crates/cli/src => src}/repo/handlers/register_webhook.rs (100%) rename {crates/cli/src => src}/repo/handlers/unregister_webhook.rs (100%) rename {crates/cli/src => src}/repo/handlers/validate_repo.rs (100%) rename {crates/cli/src => src}/repo/handlers/webhook_notification.rs (100%) rename {crates/cli/src => src}/repo/handlers/webhook_registered.rs (100%) rename {crates/cli/src => src}/repo/load.rs (100%) rename {crates/cli/src => src}/repo/messages.rs (100%) rename {crates/cli/src => src}/repo/mod.rs (100%) rename {crates/cli/src => src}/repo/notifications.rs (100%) rename {crates/cli/src => src}/repo/tests/branch/advance_main.rs (100%) rename {crates/cli/src => src}/repo/tests/branch/advance_next.rs (100%) rename {crates/cli/src => src}/repo/tests/branch/mod.rs (100%) rename {crates/cli/src => src}/repo/tests/expect.rs (100%) rename {crates/cli/src => src}/repo/tests/given.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/advance_main.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/advance_next.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/check_ci_status.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/clone_repo.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/load_config_from_repo.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/loaded_config.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/mod.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/receive_ci_status.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/register_webhook.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/validate_repo.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/webhook_notification.rs (100%) rename {crates/cli/src => src}/repo/tests/handlers/webhook_registered.rs (100%) rename {crates/cli/src => src}/repo/tests/load.rs (100%) rename {crates/cli/src => src}/repo/tests/mod.rs (100%) rename {crates/cli/src => src}/repo/tests/when.rs (100%) rename {crates/cli/src => src}/root.rs (100%) rename {crates/cli/src => src}/server/actor/MESSAGES.md (100%) rename {crates/cli/src => src}/server/actor/handlers/file_updated.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/mod.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/receive_app_config.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/receive_valid_app_config.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/server_update.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/shutdown.rs (100%) rename {crates/cli/src => src}/server/actor/handlers/shutdown_trigger.rs (100%) rename {crates/cli/src => src}/server/actor/messages.rs (100%) rename {crates/cli/src => src}/server/actor/mod.rs (100%) rename {crates/cli/src => src}/server/actor/tests/given.rs (100%) rename {crates/cli/src => src}/server/actor/tests/mod.rs (100%) rename {crates/cli/src => src}/server/actor/tests/receive_app_config.rs (100%) rename {crates/cli/src => src}/server/mod.rs (100%) rename {crates/cli/src => src}/server/server-default.toml (100%) rename {crates/cli/src => src}/server/tests.rs (100%) rename {crates/cli/src => src}/tests.rs (100%) rename {crates/cli/src => src}/tui/README.md (100%) rename {crates/cli/src => src}/tui/actor/handlers/mod.rs (100%) rename {crates/cli/src => src}/tui/actor/handlers/server_update.rs (100%) rename {crates/cli/src => src}/tui/actor/handlers/tick.rs (100%) rename {crates/cli/src => src}/tui/actor/messages.rs (100%) rename {crates/cli/src => src}/tui/actor/mod.rs (100%) rename {crates/cli/src => src}/tui/actor/model.rs (100%) rename {crates/cli/src => src}/tui/actor/tests.rs (100%) rename {crates/cli/src => src}/tui/components/configured_app.rs (100%) rename {crates/cli/src => src}/tui/components/forge/collapsed.rs (100%) rename {crates/cli/src => src}/tui/components/forge/expanded.rs (100%) rename {crates/cli/src => src}/tui/components/forge/mod.rs (100%) rename {crates/cli/src => src}/tui/components/history.rs (100%) rename {crates/cli/src => src}/tui/components/key_focus.rs (100%) rename {crates/cli/src => src}/tui/components/mod.rs (100%) rename {crates/cli/src => src}/tui/components/repo/identity.rs (100%) rename {crates/cli/src => src}/tui/components/repo/mod.rs (100%) rename {crates/cli/src => src}/tui/logging.rs (100%) rename {crates/cli/src => src}/tui/mod.rs (100%) rename {crates/cli/src => src}/webhook/mod.rs (100%) rename {crates/cli/src => src}/webhook/router.rs (100%) rename {crates/cli/src => src}/webhook/server.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index cbd6e61..ebe1426 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,36 +1,41 @@ -[workspace] -resolver = "2" -members = ["crates/*"] - -[workspace.package] +[package] +name = "git-next" version = "0.14.1" - edition = "2021" license = "MIT" repository = "https://git.kemitix.net/kemitix/git-next" +description = "trunk-based development manager" authors = ["Paul Campbell "] rust-version = "1.76" -description = "trunk-based development manager" documentation = "https://git.kemitix.net/kemitix/git-next/src/branch/main/README.md" keywords = ["git", "cli", "server", "tool"] categories = ["development-tools"] -# [workspace.lints.clippy] -# pedantic = { level = "warn", priority = -1 } -# nursery = { level = "warn", priority = -1 } -# unwrap_used = "warn" -# expect_used = "warn" +[features] +# default = ["forgejo", "github"] +default = ["forgejo", "github", "tui"] +forgejo = [] +github = [] +tui = [ + "ratatui", + "directories", + "lazy_static", + "tui-scrollview", + "regex", + "chrono", +] -[workspace.dependencies] +[dependencies] + +color-eyre = "0.6" # TUI -ratatui = "0.29" -directories = "6.0" -lazy_static = "1.5" -color-eyre = "0.6" -tui-scrollview = "0.5" -regex = "1.10" -chrono = "0.4" +ratatui = { version = "0.29", optional = true } +directories = { version = "6.0", optional = true } +lazy_static = { version = "1.5", optional = true } +tui-scrollview = { version = "0.5", optional = true } +regex = { version = "1.10", optional = true } +chrono = { version = "0.4", optional = true } # CLI parsing clap = { version = "4.5", features = ["cargo", "derive"] } @@ -41,7 +46,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-error = "0.2.0" # base64 decoding -base64 = "0.22" +# base64 = { version = "0.22", optional = true } # sha256 encoding (e.g. verify github webhooks) hmac = "0.12" @@ -110,10 +115,21 @@ sendmail = "2.0" # desktop notifications notifica = "3.0" -# Testing +mockall = "0.13" + +[dev-dependencies] assert2 = "0.3" + pretty_assertions = "1.4" rand = "0.8" -mockall = "0.13" -test-log = "0.2" rstest = { version = "0.24", features = ["async-timeout"] } +test-log = "0.2" + +[lints.clippy] +nursery = { level = "warn", priority = -1 } +pedantic = { level = "warn", priority = -1 } +unwrap_used = "warn" +expect_used = "warn" + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] } diff --git a/README.md b/README.md index 6992bbf..991cb6a 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,671 @@ ## Trunk-based developement manager. +> A source-control branching model, where developers collaborate on code in a single branch +> called ‘trunk’, resist any pressure to create other long-lived development branches by +> employing documented techniques. They therefore avoid merge hell, do not break the build, +> and live happily ever after. - [source](https://trunkbaseddevelopment.com) + `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. +## Features + +- Allows enforcing the requirement for each commit to pass the CI pipeline before being + included in the main branch +- Provides a server component that manages the trunk-based development process +- Ensure a consistent, high-quality codebase by preventing untested changes + from being added to main +- Requires each commit uses conventional commit format. + +See [Behaviour](#behaviour) to learn how we do this. + ![Demo](./demo.gif) +## Prerequisits -See [README.md](https://git.kemitix.net/kemitix/git-next/src/branch/main/crates/cli/README.md) for more information. +- Rust 1.76.0 or later - https://www.rust-lang.org +- pgk-config +- libssl-dev +- libdbus-1-dev (ubuntu/debian) +- dbus-devel (fedora) + +See `.cargo/config.toml` for how they are configured. + +## Installation + +You can install `git-next` from : + +```shell +cargo install git-next +``` + +If you use [mise](https://mise.jdx.dev): + +```shell +mise use -g cargo:git-next +``` + +Or you can install `git-next` from source after cloning: + +```shell +cargo install --path crates/cli +``` + +## Roadmap + +- [x] cli +- [x] server +- [x] notifications - notify user when intervention required (e.g. to rebase) +- [x] tui overview +- [ ] webui overview + +## 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 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. + +#### listen + +The server should listen for webhook notifications from each forge. + +```toml +[listen] +http = { addr = "0.0.0.0", port = 8080 } +url = "https://localhost:8080" +``` + +##### 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 + +##### url + +The HTTPS URL for forges to send webhooks to. + +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. + +#### shout + +The server should be able to notify the user when manual intervention is required. + +```toml +[shout] +desktop = true + +[shout.webhook] +url = "https//localhost:9090" +secret = "secret-password" + +[shout.email] +from = "git-next@example.com" +to = "developer@example.com" + +[shout.email.smtp] +hostname = "smtp.example.com" +username = "git-next@example.com" +password = "MySecretEmailPassword42" +``` + +##### desktop + +When specified as `true`, desktop notifications will be sent for some events. + +##### webhook + +Will send a POST request for some events. + +- **url** - the URL to POST the notification to and the +- **secret** - the sync key used to sign the webhook payload + +See [Notifications](#notifications) for more details. + +##### email + +Will send an email for some events. + +- **from** - the email address to send the email from +- **to** - the email address to send the email to + +With just `from` and `to` specified, `git-next` will attempt to send emails +with `sendmail` if it is configured. + +Alternativly, you can use an SMTP relay. + +###### smtp + +Will send emails using an SMTP relay. + +- **hostname** - the SMTP relay server +- **username** - the account to authenticate as +- **password** - the password to authenticate with + +#### storage + +```toml +[storage] +path = "./data" +``` + +`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 monitor 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" +max_dev_commits = 25 +``` + +- **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 [Forges](#forges) below for the permissions required for each forge. +- **max_dev_commits** - [optional] the maximum number of commits allowed between `dev` and `main`. Defaults to 25. + +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 `my-repo`'s `owner/repo` +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 if needed +- **gitdir** - (optional) you can use a 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 cloned in that directory 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, nor 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 and repo is the +same one specified as the `origin` remote. Otherwise the behaviour is +untested and undefined. + +## Webhook Notifications + +When sending a Webhook Notification to a user they are sent using the +Standard Webhooks format. That means all POST messages have the +following headers: + +- `Webhook-Id` +- `Webhook-Signature` +- `Webhook-Timestamp` + +### Events + +#### Dev Not Based on Main + +This message `type` indicates that the `dev` branch is not based on `main`. + +**Action Required**: Rebase the `dev` branch onto the `main` branch. + +Sample payload: + +```json +{ + "data": { + "branches": { + "dev": "dev", + "main": "main" + }, + "forge_alias": "jo", + "repo_alias": "kxio", + "log": [ + "* 9bfce91 (origin/dev) fix: add log graph to notifications", + "| * c37bd2c (origin/next, origin/main) feat: add log graph to notifications", + "|/", + "* 8c19680 refactor: macros use a more common syntax" + ] + }, + "timestamp": "1721760933", + "type": "branch.dev.not-on-main" +} +``` + +#### CI Check Failed + +This message `type` indicates that the commit on the tip of the `next` branch has failed the +configured CI checks. + +**Action Required**: Either update the commit to correct the issue CI raised, or, if the issue +is transient (e.g. a network issue), re-run/re-start the job in your CI. + +Sample payload: + +```json +{ + "data": { + "commit": { + "sha": "c37bd2caf6825f9770d725a681e5cfc09d7fd4f2", + "message": "feat: add log graph to notifications (1 of 2)" + }, + "forge_alias": "jo", + "repo_alias": "kxio", + "log": [ + "* 9bfce91 (origin/dev) feat: add log graph to notifications (2 of 2)", + "* c37bd2c (origin/next) feat: add log graph to notifications (1 of 2)", + "* 8c19680 (origin/main) refactor: macros use a more common syntax" + ] + }, + "timestamp": "1721760933", + "type": "cicheck.failed" +} +``` + +#### Repo Config Load Failed + +This message `type` indicates that `git-next` wasn't able to load the configuration for the +repo from the `git-next.toml` file in the repository. + +**Action Required**: Review the `reason` provided. + +Sample payload: + +```json +{ + "data": { + "reason": "File not found: .git-next.toml", + "forge_alias": "jo", + "repo_alias": "kxio" + }, + "timestamp": "1721760933", + "type": "config.load.failed" +} +``` + +#### Webhook Registration Failed + +This message `type` indicates that `git-next` wasn't able to register it's webhook with the +forge repository, so will not receive updates when the branches in the repo are updated. + +**Action Required**: Review the `reason` provided. + +Sample payload: + +```json +{ + "data": { + "reason": "repo config not loaded", + "forge_alias": "jo", + "repo_alias": "kxio" + }, + "timestamp": "1721760933", + "type": "webhook.registration.failed" +} +``` + +## Behaviour + +The branch names are configurable, but we will talk about `main`, `next` and `dev`. + +Development happens on the `dev` branch, where each commit is expected to +be able to pass the CI checks. + +(Note: in the diagrams, mermaid isn't capable of showing `main` and `next` on +the same commit, so we show `next` as empty) + +```mermaid +gitGraph + commit + commit + + branch next + + branch dev + commit + commit + commit +``` + +When the `git-next` server sees that the `dev` branch is ahead of the `next` +branch, it will push the `next` branch fast-forward one commit along the `dev` +branch. + +```mermaid +gitGraph + commit + commit + + branch next + commit + + branch dev + commit + commit +``` + +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. We return to the top and start again. + +```mermaid +gitGraph + commit + commit + commit + + branch next + + branch dev + commit + commit +``` + +If the CI checks should fail for the `next` branch, the developer should +**amend** that commit **in the history of their `dev` branch**. +They should then force-push their rebased `dev` branch. + +```mermaid +gitGraph + commit + commit + + branch next + commit + + checkout main + + branch dev + commit + + commit + commit +``` + +`git-next` will then detect that the `next` branch is no longer part of the +`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. + +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. + +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 (optional) + +You need to specify which branches you are using. You can do this in the repo, +or in the server configuration. + +To create a default config file for the repo, run this command in the root of +your repo: + +```shell +git next init +``` + +This will create a `.git-next.toml` file. [Default](./crates/cli/default.toml) + +By default the expected branches are `main`, `next` and `dev`. Each of these +three branches _must_ exist in your repo. + +### Initialise the server + +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: + +```shell +git next server init +``` + +This will create a `git-next-server.toml` file. [Default](./crates/server/server-default.toml) + +Edit this file to your needs. See the [Configuration](#configuration) section above. + +### Run the server + +In the directory with your `git-next-server.toml` file, run the command: + +```shell +git next server start +``` + +### Forges + +The following forges are supported: + +- [ForgeJo](https://forgejo.org) (probably compatible with Gitea, but not tested) +- [GitHub](https://github.com/) + +Note: ForgeJo is a hard fork of Gitea, but currently they are largely compatible. +For now using a `forge_type` of `ForgeJo` with a Gitea instance will probably work +okay. The only API calls we make are around registering and unregistering webhooks. +So, as long as those APIs remain the same, they should be compatible. + +#### ForgeJo + +Configure the forge in `git-next-server.toml` like: + +```toml +[forge.jo] +forge_type = "ForgeJo" +hostname = "git.myforgejo.com" +user = "bob" +token = "..." + +[forge.jo.repos] +hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user/hello.git" } # maps to https://git.example.net/user/hello on the branch 'main' +world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch +``` + +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 + +Configure the forge in `git-next-server.toml` like: + +```toml +[forge.gh] +forge_type = "GitHub" +hostname = "github.com" # required even for GitHub +user = "bob" +token = "..." + +[forge.gh.repos] +hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user/hello.git" } # maps to https://github.com/user/hello on the branch 'main' +world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch +``` + +The token is created [here](https://github.com/settings/tokens/new) and requires the `repo` and `admin:repo_hook` permissions. + +## Docker + +`git-next` is available as a [Docker image](https://git.kemitix.net/kemitix/-/packages/container/git-next/). + +```shell +docker pull docker pull git.kemitix.net/kemitix/git-next:latest +``` + +### Docker Compose + +Here is an example `docker-compose.yml`: + +```yaml +services: + server: + image: git.kemitix.net/kemitix/git-next:latest + container_name: git-next-server + restart: unless-stopped + environment: + RUST_LOG: "hyper=warn,info" + ports: + - 8080:8092 + volumes: + - ./:/app/ +``` + +Note: this assumes the `git-next-server.toml` has a `listen.http.port` of +`8092` and that you are using a reverse proxy to route traffic arriving at +`listen.url` to port `8080`. + +### Docker Run + +This will run with the `server start` options: + +```shell +docker run -it -p "8080:8092" -v .:/app/ git.kemitix.net/kemitix/git-next:latest +``` + +To perform `server init`: + +```shell +docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest server init +``` + +To perform repo `init`: + +```shell +docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest init +``` + +TUI support is not available in the docker container. See [kemitix/git-next#154](https://git.kemitix.net/kemitix/git-next/issues/154). + +## Contributing + +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 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)) + +## Crate Dependency + +The following diagram shows the dependency between the crates that make up `git-next`: + +```mermaid +stateDiagram-v2 + + cli --> core + cli --> forge_forgejo + cli --> forge_github + + forge_forgejo --> core + + forge_github --> core +``` + +## Actor Supervision Tree + +```mermaid +mindmap + Root + Alerts + FileWatcher + Server + Repo 1 + Repo 2 +``` + +## License + +`git-next` is released under the [MIT License](./LICENSE). diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml deleted file mode 100644 index 5f053b8..0000000 --- a/crates/cli/Cargo.toml +++ /dev/null @@ -1,124 +0,0 @@ -[package] -name = "git-next" -version = { workspace = true } -edition = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -description = "git-next, the trunk-based development manager" -authors = { workspace = true } -rust-version = { workspace = true } -documentation = { workspace = true } -keywords = { workspace = true } -categories = { workspace = true } - -[features] -# default = ["forgejo", "github"] -default = ["forgejo", "github", "tui"] -forgejo = [] -github = [] -tui = [ - "ratatui", - "directories", - "lazy_static", - "tui-scrollview", - "regex", - "chrono", -] - -[dependencies] - -# TUI -ratatui = { workspace = true, optional = true } -directories = { workspace = true, optional = true } -lazy_static = { workspace = true, optional = true } -color-eyre = { workspace = true } -tui-scrollview = { workspace = true, optional = true } -regex = { workspace = true, optional = true } -chrono = { workspace = true, optional = true } - -# CLI parsing -clap = { workspace = true } - -# fs/network -kxio = { workspace = true } - -# logging -tracing = { workspace = true } -tracing-subscriber = { workspace = true } -tracing-error.workspace = true - -# Conventional Commit check -git-conventional = { workspace = true } - -# TOML parsing -toml = { workspace = true } -serde = { workspace = true } - -# Actors -kameo = { workspace = true } -tokio = { workspace = true } - -# boilerplate -bon = { workspace = true } -derive_more = { workspace = true } -derive-with = { workspace = true } -anyhow = { workspace = true } -thiserror = { workspace = true } - -# Webhooks -serde_json = { workspace = true } -ulid = { workspace = true } -time = { workspace = true } -secrecy = { workspace = true } -standardwebhooks = { workspace = true } -bytes = { workspace = true } -warp = { workspace = true } - -# file watcher (linux) -notify = { workspace = true } - -# email -lettre = { workspace = true } -sendmail = { workspace = true } - -# desktop notifications -notifica = { workspace = true } - -# git -async-trait = { workspace = true } - -# sha256 encoding (e.g. verify github webhooks) -hmac = { workspace = true } -sha2 = { workspace = true } -hex = { workspace = true } - -# Git -gix = { workspace = true } -git-url-parse = { workspace = true } - -# boilerplate -pike = { workspace = true } - - -mockall = { workspace = true } - -#iters -take-until = { workspace = true } - -[dev-dependencies] -# Testing -assert2 = { workspace = true } -test-log = { workspace = true } -rand = { workspace = true } -pretty_assertions = { workspace = true } -mockall = { workspace = true } -rstest = { workspace = true } - -[lints.clippy] -nursery = { level = "warn", priority = -1 } -pedantic = { level = "warn", priority = -1 } -unwrap_used = "warn" -expect_used = "warn" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] } diff --git a/crates/cli/README.md b/crates/cli/README.md deleted file mode 100644 index 1215823..0000000 --- a/crates/cli/README.md +++ /dev/null @@ -1,672 +0,0 @@ -# git-next - -## Trunk-based developement manager. - -> A source-control branching model, where developers collaborate on code in a single branch -> called ‘trunk’, resist any pressure to create other long-lived development branches by -> employing documented techniques. They therefore avoid merge hell, do not break the build, -> and live happily ever after. - [source](https://trunkbaseddevelopment.com) - -- Status: **BETA** - 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. - -## Features - -- Allows enforcing the requirement for each commit to pass the CI pipeline before being - included in the main branch -- Provides a server component that manages the trunk-based development process -- Ensure a consistent, high-quality codebase by preventing untested changes - from being added to main -- Requires each commit uses conventional commit format. - -See [Behaviour](#behaviour) to learn how we do this. - -## Prerequisits - -- Rust 1.76.0 or later - https://www.rust-lang.org -- pgk-config -- libssl-dev -- libdbus-1-dev (ubuntu/debian) -- dbus-devel (fedora) - -See `.cargo/config.toml` for how they are configured. - -## Installation - -You can install `git-next` from : - -```shell -cargo install git-next -``` - -If you use [mise](https://mise.jdx.dev): - -```shell -mise use -g cargo:git-next -``` - -Or you can install `git-next` from source after cloning: - -```shell -cargo install --path crates/cli -``` - -## Roadmap - -- [x] cli -- [x] server -- [x] notifications - notify user when intervention required (e.g. to rebase) -- [x] tui overview -- [ ] webui overview - -## 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 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. - -#### listen - -The server should listen for webhook notifications from each forge. - -```toml -[listen] -http = { addr = "0.0.0.0", port = 8080 } -url = "https://localhost:8080" -``` - -##### 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 - -##### url - -The HTTPS URL for forges to send webhooks to. - -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. - -#### shout - -The server should be able to notify the user when manual intervention is required. - -```toml -[shout] -desktop = true - -[shout.webhook] -url = "https//localhost:9090" -secret = "secret-password" - -[shout.email] -from = "git-next@example.com" -to = "developer@example.com" - -[shout.email.smtp] -hostname = "smtp.example.com" -username = "git-next@example.com" -password = "MySecretEmailPassword42" -``` - -##### desktop - -When specified as `true`, desktop notifications will be sent for some events. - -##### webhook - -Will send a POST request for some events. - -- **url** - the URL to POST the notification to and the -- **secret** - the sync key used to sign the webhook payload - -See [Notifications](#notifications) for more details. - -##### email - -Will send an email for some events. - -- **from** - the email address to send the email from -- **to** - the email address to send the email to - -With just `from` and `to` specified, `git-next` will attempt to send emails -with `sendmail` if it is configured. - -Alternativly, you can use an SMTP relay. - -###### smtp - -Will send emails using an SMTP relay. - -- **hostname** - the SMTP relay server -- **username** - the account to authenticate as -- **password** - the password to authenticate with - -#### storage - -```toml -[storage] -path = "./data" -``` - -`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 monitor 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" -max_dev_commits = 25 -``` - -- **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 [Forges](#forges) below for the permissions required for each forge. -- **max_dev_commits** - [optional] the maximum number of commits allowed between `dev` and `main`. Defaults to 25. - -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 `my-repo`'s `owner/repo` -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 if needed -- **gitdir** - (optional) you can use a 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 cloned in that directory 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, nor 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 and repo is the -same one specified as the `origin` remote. Otherwise the behaviour is -untested and undefined. - -## Webhook Notifications - -When sending a Webhook Notification to a user they are sent using the -Standard Webhooks format. That means all POST messages have the -following headers: - -- `Webhook-Id` -- `Webhook-Signature` -- `Webhook-Timestamp` - -### Events - -#### Dev Not Based on Main - -This message `type` indicates that the `dev` branch is not based on `main`. - -**Action Required**: Rebase the `dev` branch onto the `main` branch. - -Sample payload: - -```json -{ - "data": { - "branches": { - "dev": "dev", - "main": "main" - }, - "forge_alias": "jo", - "repo_alias": "kxio", - "log": [ - "* 9bfce91 (origin/dev) fix: add log graph to notifications", - "| * c37bd2c (origin/next, origin/main) feat: add log graph to notifications", - "|/", - "* 8c19680 refactor: macros use a more common syntax" - ] - }, - "timestamp": "1721760933", - "type": "branch.dev.not-on-main" -} -``` - -#### CI Check Failed - -This message `type` indicates that the commit on the tip of the `next` branch has failed the -configured CI checks. - -**Action Required**: Either update the commit to correct the issue CI raised, or, if the issue -is transient (e.g. a network issue), re-run/re-start the job in your CI. - -Sample payload: - -```json -{ - "data": { - "commit": { - "sha": "c37bd2caf6825f9770d725a681e5cfc09d7fd4f2", - "message": "feat: add log graph to notifications (1 of 2)" - }, - "forge_alias": "jo", - "repo_alias": "kxio", - "log": [ - "* 9bfce91 (origin/dev) feat: add log graph to notifications (2 of 2)", - "* c37bd2c (origin/next) feat: add log graph to notifications (1 of 2)", - "* 8c19680 (origin/main) refactor: macros use a more common syntax" - ] - }, - "timestamp": "1721760933", - "type": "cicheck.failed" -} -``` - -#### Repo Config Load Failed - -This message `type` indicates that `git-next` wasn't able to load the configuration for the -repo from the `git-next.toml` file in the repository. - -**Action Required**: Review the `reason` provided. - -Sample payload: - -```json -{ - "data": { - "reason": "File not found: .git-next.toml", - "forge_alias": "jo", - "repo_alias": "kxio" - }, - "timestamp": "1721760933", - "type": "config.load.failed" -} -``` - -#### Webhook Registration Failed - -This message `type` indicates that `git-next` wasn't able to register it's webhook with the -forge repository, so will not receive updates when the branches in the repo are updated. - -**Action Required**: Review the `reason` provided. - -Sample payload: - -```json -{ - "data": { - "reason": "repo config not loaded", - "forge_alias": "jo", - "repo_alias": "kxio" - }, - "timestamp": "1721760933", - "type": "webhook.registration.failed" -} -``` - -## Behaviour - -The branch names are configurable, but we will talk about `main`, `next` and `dev`. - -Development happens on the `dev` branch, where each commit is expected to -be able to pass the CI checks. - -(Note: in the diagrams, mermaid isn't capable of showing `main` and `next` on -the same commit, so we show `next` as empty) - -```mermaid -gitGraph - commit - commit - - branch next - - branch dev - commit - commit - commit -``` - -When the `git-next` server sees that the `dev` branch is ahead of the `next` -branch, it will push the `next` branch fast-forward one commit along the `dev` -branch. - -```mermaid -gitGraph - commit - commit - - branch next - commit - - branch dev - commit - commit -``` - -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. We return to the top and start again. - -```mermaid -gitGraph - commit - commit - commit - - branch next - - branch dev - commit - commit -``` - -If the CI checks should fail for the `next` branch, the developer should -**amend** that commit **in the history of their `dev` branch**. -They should then force-push their rebased `dev` branch. - -```mermaid -gitGraph - commit - commit - - branch next - commit - - checkout main - - branch dev - commit - - commit - commit -``` - -`git-next` will then detect that the `next` branch is no longer part of the -`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. - -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. - -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 (optional) - -You need to specify which branches you are using. You can do this in the repo, -or in the server configuration. - -To create a default config file for the repo, run this command in the root of -your repo: - -```shell -git next init -``` - -This will create a `.git-next.toml` file. [Default](./crates/cli/default.toml) - -By default the expected branches are `main`, `next` and `dev`. Each of these -three branches _must_ exist in your repo. - -### Initialise the server - -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: - -```shell -git next server init -``` - -This will create a `git-next-server.toml` file. [Default](./crates/server/server-default.toml) - -Edit this file to your needs. See the [Configuration](#configuration) section above. - -### Run the server - -In the directory with your `git-next-server.toml` file, run the command: - -```shell -git next server start -``` - -### Forges - -The following forges are supported: - -- [ForgeJo](https://forgejo.org) (probably compatible with Gitea, but not tested) -- [GitHub](https://github.com/) - -Note: ForgeJo is a hard fork of Gitea, but currently they are largely compatible. -For now using a `forge_type` of `ForgeJo` with a Gitea instance will probably work -okay. The only API calls we make are around registering and unregistering webhooks. -So, as long as those APIs remain the same, they should be compatible. - -#### ForgeJo - -Configure the forge in `git-next-server.toml` like: - -```toml -[forge.jo] -forge_type = "ForgeJo" -hostname = "git.myforgejo.com" -user = "bob" -token = "..." - -[forge.jo.repos] -hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user/hello.git" } # maps to https://git.example.net/user/hello on the branch 'main' -world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch -``` - -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 - -Configure the forge in `git-next-server.toml` like: - -```toml -[forge.gh] -forge_type = "GitHub" -hostname = "github.com" # required even for GitHub -user = "bob" -token = "..." - -[forge.gh.repos] -hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user/hello.git" } # maps to https://github.com/user/hello on the branch 'main' -world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch -``` - -The token is created [here](https://github.com/settings/tokens/new) and requires the `repo` and `admin:repo_hook` permissions. - -## Docker - -`git-next` is available as a [Docker image](https://git.kemitix.net/kemitix/-/packages/container/git-next/). - -```shell -docker pull docker pull git.kemitix.net/kemitix/git-next:latest -``` - -### Docker Compose - -Here is an example `docker-compose.yml`: - -```yaml -services: - server: - image: git.kemitix.net/kemitix/git-next:latest - container_name: git-next-server - restart: unless-stopped - environment: - RUST_LOG: "hyper=warn,info" - ports: - - 8080:8092 - volumes: - - ./:/app/ -``` - -Note: this assumes the `git-next-server.toml` has a `listen.http.port` of -`8092` and that you are using a reverse proxy to route traffic arriving at -`listen.url` to port `8080`. - -### Docker Run - -This will run with the `server start` options: - -```shell -docker run -it -p "8080:8092" -v .:/app/ git.kemitix.net/kemitix/git-next:latest -``` - -To perform `server init`: - -```shell -docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest server init -``` - -To perform repo `init`: - -```shell -docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest init -``` - -TUI support is not available in the docker container. See [kemitix/git-next#154](https://git.kemitix.net/kemitix/git-next/issues/154). - -## Contributing - -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 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)) - -## Crate Dependency - -The following diagram shows the dependency between the crates that make up `git-next`: - -```mermaid -stateDiagram-v2 - - cli --> core - cli --> forge_forgejo - cli --> forge_github - - forge_forgejo --> core - - forge_github --> core -``` - -## Actor Supervision Tree - -```mermaid -mindmap - Root - Alerts - FileWatcher - Server - Repo 1 - Repo 2 -``` - -## License - -`git-next` is released under the [MIT License](./LICENSE). diff --git a/crates/cli/default.toml b/default.toml similarity index 100% rename from crates/cli/default.toml rename to default.toml diff --git a/crates/cli/src/alerts/desktop.rs b/src/alerts/desktop.rs similarity index 100% rename from crates/cli/src/alerts/desktop.rs rename to src/alerts/desktop.rs diff --git a/crates/cli/src/alerts/email.rs b/src/alerts/email.rs similarity index 100% rename from crates/cli/src/alerts/email.rs rename to src/alerts/email.rs diff --git a/crates/cli/src/alerts/handlers/mod.rs b/src/alerts/handlers/mod.rs similarity index 100% rename from crates/cli/src/alerts/handlers/mod.rs rename to src/alerts/handlers/mod.rs diff --git a/crates/cli/src/alerts/handlers/notify_user.rs b/src/alerts/handlers/notify_user.rs similarity index 100% rename from crates/cli/src/alerts/handlers/notify_user.rs rename to src/alerts/handlers/notify_user.rs diff --git a/crates/cli/src/alerts/handlers/update_shout.rs b/src/alerts/handlers/update_shout.rs similarity index 100% rename from crates/cli/src/alerts/handlers/update_shout.rs rename to src/alerts/handlers/update_shout.rs diff --git a/crates/cli/src/alerts/history.rs b/src/alerts/history.rs similarity index 100% rename from crates/cli/src/alerts/history.rs rename to src/alerts/history.rs diff --git a/crates/cli/src/alerts/messages.rs b/src/alerts/messages.rs similarity index 100% rename from crates/cli/src/alerts/messages.rs rename to src/alerts/messages.rs diff --git a/crates/cli/src/alerts/mod.rs b/src/alerts/mod.rs similarity index 100% rename from crates/cli/src/alerts/mod.rs rename to src/alerts/mod.rs diff --git a/crates/cli/src/alerts/tests/history.rs b/src/alerts/tests/history.rs similarity index 100% rename from crates/cli/src/alerts/tests/history.rs rename to src/alerts/tests/history.rs diff --git a/crates/cli/src/alerts/tests/mod.rs b/src/alerts/tests/mod.rs similarity index 100% rename from crates/cli/src/alerts/tests/mod.rs rename to src/alerts/tests/mod.rs diff --git a/crates/cli/src/alerts/webhook.rs b/src/alerts/webhook.rs similarity index 100% rename from crates/cli/src/alerts/webhook.rs rename to src/alerts/webhook.rs diff --git a/crates/cli/src/base_actor.rs b/src/base_actor.rs similarity index 100% rename from crates/cli/src/base_actor.rs rename to src/base_actor.rs diff --git a/crates/cli/src/core/config/api_token.rs b/src/core/config/api_token.rs similarity index 100% rename from crates/cli/src/core/config/api_token.rs rename to src/core/config/api_token.rs diff --git a/crates/cli/src/core/config/branch_name.rs b/src/core/config/branch_name.rs similarity index 100% rename from crates/cli/src/core/config/branch_name.rs rename to src/core/config/branch_name.rs diff --git a/crates/cli/src/core/config/commit_count.rs b/src/core/config/commit_count.rs similarity index 100% rename from crates/cli/src/core/config/commit_count.rs rename to src/core/config/commit_count.rs diff --git a/crates/cli/src/core/config/common.rs b/src/core/config/common.rs similarity index 100% rename from crates/cli/src/core/config/common.rs rename to src/core/config/common.rs diff --git a/crates/cli/src/core/config/forge_alias.rs b/src/core/config/forge_alias.rs similarity index 100% rename from crates/cli/src/core/config/forge_alias.rs rename to src/core/config/forge_alias.rs diff --git a/crates/cli/src/core/config/forge_config.rs b/src/core/config/forge_config.rs similarity index 100% rename from crates/cli/src/core/config/forge_config.rs rename to src/core/config/forge_config.rs diff --git a/crates/cli/src/core/config/forge_details.rs b/src/core/config/forge_details.rs similarity index 100% rename from crates/cli/src/core/config/forge_details.rs rename to src/core/config/forge_details.rs diff --git a/crates/cli/src/core/config/forge_type.rs b/src/core/config/forge_type.rs similarity index 100% rename from crates/cli/src/core/config/forge_type.rs rename to src/core/config/forge_type.rs diff --git a/crates/cli/src/core/config/git_dir.rs b/src/core/config/git_dir.rs similarity index 100% rename from crates/cli/src/core/config/git_dir.rs rename to src/core/config/git_dir.rs diff --git a/crates/cli/src/core/config/graphs.rs b/src/core/config/graphs.rs similarity index 100% rename from crates/cli/src/core/config/graphs.rs rename to src/core/config/graphs.rs diff --git a/crates/cli/src/core/config/host_name.rs b/src/core/config/host_name.rs similarity index 100% rename from crates/cli/src/core/config/host_name.rs rename to src/core/config/host_name.rs diff --git a/crates/cli/src/core/config/mod.rs b/src/core/config/mod.rs similarity index 100% rename from crates/cli/src/core/config/mod.rs rename to src/core/config/mod.rs diff --git a/crates/cli/src/core/config/registered_webhook.rs b/src/core/config/registered_webhook.rs similarity index 100% rename from crates/cli/src/core/config/registered_webhook.rs rename to src/core/config/registered_webhook.rs diff --git a/crates/cli/src/core/config/remote_url.rs b/src/core/config/remote_url.rs similarity index 100% rename from crates/cli/src/core/config/remote_url.rs rename to src/core/config/remote_url.rs diff --git a/crates/cli/src/core/config/repo_alias.rs b/src/core/config/repo_alias.rs similarity index 100% rename from crates/cli/src/core/config/repo_alias.rs rename to src/core/config/repo_alias.rs diff --git a/crates/cli/src/core/config/repo_branches.rs b/src/core/config/repo_branches.rs similarity index 100% rename from crates/cli/src/core/config/repo_branches.rs rename to src/core/config/repo_branches.rs diff --git a/crates/cli/src/core/config/repo_config.rs b/src/core/config/repo_config.rs similarity index 100% rename from crates/cli/src/core/config/repo_config.rs rename to src/core/config/repo_config.rs diff --git a/crates/cli/src/core/config/repo_config_source.rs b/src/core/config/repo_config_source.rs similarity index 100% rename from crates/cli/src/core/config/repo_config_source.rs rename to src/core/config/repo_config_source.rs diff --git a/crates/cli/src/core/config/repo_path.rs b/src/core/config/repo_path.rs similarity index 100% rename from crates/cli/src/core/config/repo_path.rs rename to src/core/config/repo_path.rs diff --git a/crates/cli/src/core/config/server.rs b/src/core/config/server.rs similarity index 100% rename from crates/cli/src/core/config/server.rs rename to src/core/config/server.rs diff --git a/crates/cli/src/core/config/server_repo_config.rs b/src/core/config/server_repo_config.rs similarity index 100% rename from crates/cli/src/core/config/server_repo_config.rs rename to src/core/config/server_repo_config.rs diff --git a/crates/cli/src/core/config/tests.rs b/src/core/config/tests.rs similarity index 100% rename from crates/cli/src/core/config/tests.rs rename to src/core/config/tests.rs diff --git a/crates/cli/src/core/config/tests/url.rs b/src/core/config/tests/url.rs similarity index 100% rename from crates/cli/src/core/config/tests/url.rs rename to src/core/config/tests/url.rs diff --git a/crates/cli/src/core/config/user.rs b/src/core/config/user.rs similarity index 100% rename from crates/cli/src/core/config/user.rs rename to src/core/config/user.rs diff --git a/crates/cli/src/core/config/webhook.rs b/src/core/config/webhook.rs similarity index 100% rename from crates/cli/src/core/config/webhook.rs rename to src/core/config/webhook.rs diff --git a/crates/cli/src/core/config/webhook/auth.rs b/src/core/config/webhook/auth.rs similarity index 100% rename from crates/cli/src/core/config/webhook/auth.rs rename to src/core/config/webhook/auth.rs diff --git a/crates/cli/src/core/config/webhook/forge_notification.rs b/src/core/config/webhook/forge_notification.rs similarity index 100% rename from crates/cli/src/core/config/webhook/forge_notification.rs rename to src/core/config/webhook/forge_notification.rs diff --git a/crates/cli/src/core/config/webhook/id.rs b/src/core/config/webhook/id.rs similarity index 100% rename from crates/cli/src/core/config/webhook/id.rs rename to src/core/config/webhook/id.rs diff --git a/crates/cli/src/core/config/webhook/push.rs b/src/core/config/webhook/push.rs similarity index 100% rename from crates/cli/src/core/config/webhook/push.rs rename to src/core/config/webhook/push.rs diff --git a/crates/cli/src/core/config/webhook/tests.rs b/src/core/config/webhook/tests.rs similarity index 100% rename from crates/cli/src/core/config/webhook/tests.rs rename to src/core/config/webhook/tests.rs diff --git a/crates/cli/src/core/git/commit.rs b/src/core/git/commit.rs similarity index 100% rename from crates/cli/src/core/git/commit.rs rename to src/core/git/commit.rs diff --git a/crates/cli/src/core/git/file.rs b/src/core/git/file.rs similarity index 100% rename from crates/cli/src/core/git/file.rs rename to src/core/git/file.rs diff --git a/crates/cli/src/core/git/forge/commit.rs b/src/core/git/forge/commit.rs similarity index 100% rename from crates/cli/src/core/git/forge/commit.rs rename to src/core/git/forge/commit.rs diff --git a/crates/cli/src/core/git/forge/mod.rs b/src/core/git/forge/mod.rs similarity index 100% rename from crates/cli/src/core/git/forge/mod.rs rename to src/core/git/forge/mod.rs diff --git a/crates/cli/src/core/git/forge/trait.rs b/src/core/git/forge/trait.rs similarity index 100% rename from crates/cli/src/core/git/forge/trait.rs rename to src/core/git/forge/trait.rs diff --git a/crates/cli/src/core/git/forge/webhook.rs b/src/core/git/forge/webhook.rs similarity index 100% rename from crates/cli/src/core/git/forge/webhook.rs rename to src/core/git/forge/webhook.rs diff --git a/crates/cli/src/core/git/generation.rs b/src/core/git/generation.rs similarity index 100% rename from crates/cli/src/core/git/generation.rs rename to src/core/git/generation.rs diff --git a/crates/cli/src/core/git/git_ref.rs b/src/core/git/git_ref.rs similarity index 100% rename from crates/cli/src/core/git/git_ref.rs rename to src/core/git/git_ref.rs diff --git a/crates/cli/src/core/git/git_remote.rs b/src/core/git/git_remote.rs similarity index 100% rename from crates/cli/src/core/git/git_remote.rs rename to src/core/git/git_remote.rs diff --git a/crates/cli/src/core/git/graph.rs b/src/core/git/graph.rs similarity index 100% rename from crates/cli/src/core/git/graph.rs rename to src/core/git/graph.rs diff --git a/crates/cli/src/core/git/mod.rs b/src/core/git/mod.rs similarity index 100% rename from crates/cli/src/core/git/mod.rs rename to src/core/git/mod.rs diff --git a/crates/cli/src/core/git/push.rs b/src/core/git/push.rs similarity index 100% rename from crates/cli/src/core/git/push.rs rename to src/core/git/push.rs diff --git a/crates/cli/src/core/git/repo_details.rs b/src/core/git/repo_details.rs similarity index 100% rename from crates/cli/src/core/git/repo_details.rs rename to src/core/git/repo_details.rs diff --git a/crates/cli/src/core/git/repository/factory.rs b/src/core/git/repository/factory.rs similarity index 100% rename from crates/cli/src/core/git/repository/factory.rs rename to src/core/git/repository/factory.rs diff --git a/crates/cli/src/core/git/repository/mod.rs b/src/core/git/repository/mod.rs similarity index 100% rename from crates/cli/src/core/git/repository/mod.rs rename to src/core/git/repository/mod.rs diff --git a/crates/cli/src/core/git/repository/open/mod.rs b/src/core/git/repository/open/mod.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/mod.rs rename to src/core/git/repository/open/mod.rs diff --git a/crates/cli/src/core/git/repository/open/oreal.rs b/src/core/git/repository/open/oreal.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/oreal.rs rename to src/core/git/repository/open/oreal.rs diff --git a/crates/cli/src/core/git/repository/open/otest.rs b/src/core/git/repository/open/otest.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/otest.rs rename to src/core/git/repository/open/otest.rs diff --git a/crates/cli/src/core/git/repository/open/tests/commit_log.rs b/src/core/git/repository/open/tests/commit_log.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/commit_log.rs rename to src/core/git/repository/open/tests/commit_log.rs diff --git a/crates/cli/src/core/git/repository/open/tests/fetch.rs b/src/core/git/repository/open/tests/fetch.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/fetch.rs rename to src/core/git/repository/open/tests/fetch.rs diff --git a/crates/cli/src/core/git/repository/open/tests/find_default_remote.rs b/src/core/git/repository/open/tests/find_default_remote.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/find_default_remote.rs rename to src/core/git/repository/open/tests/find_default_remote.rs diff --git a/crates/cli/src/core/git/repository/open/tests/forge_config.rs b/src/core/git/repository/open/tests/forge_config.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/forge_config.rs rename to src/core/git/repository/open/tests/forge_config.rs diff --git a/crates/cli/src/core/git/repository/open/tests/mod.rs b/src/core/git/repository/open/tests/mod.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/mod.rs rename to src/core/git/repository/open/tests/mod.rs diff --git a/crates/cli/src/core/git/repository/open/tests/read_file.rs b/src/core/git/repository/open/tests/read_file.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/read_file.rs rename to src/core/git/repository/open/tests/read_file.rs diff --git a/crates/cli/src/core/git/repository/open/tests/repo_config.rs b/src/core/git/repository/open/tests/repo_config.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/repo_config.rs rename to src/core/git/repository/open/tests/repo_config.rs diff --git a/crates/cli/src/core/git/repository/open/tests/server_repo_config.rs b/src/core/git/repository/open/tests/server_repo_config.rs similarity index 100% rename from crates/cli/src/core/git/repository/open/tests/server_repo_config.rs rename to src/core/git/repository/open/tests/server_repo_config.rs diff --git a/crates/cli/src/core/git/repository/test.rs b/src/core/git/repository/test.rs similarity index 100% rename from crates/cli/src/core/git/repository/test.rs rename to src/core/git/repository/test.rs diff --git a/crates/cli/src/core/git/repository/tests/factory.rs b/src/core/git/repository/tests/factory.rs similarity index 100% rename from crates/cli/src/core/git/repository/tests/factory.rs rename to src/core/git/repository/tests/factory.rs diff --git a/crates/cli/src/core/git/repository/tests/mod.rs b/src/core/git/repository/tests/mod.rs similarity index 100% rename from crates/cli/src/core/git/repository/tests/mod.rs rename to src/core/git/repository/tests/mod.rs diff --git a/crates/cli/src/core/git/repository/tests/validate.rs b/src/core/git/repository/tests/validate.rs similarity index 100% rename from crates/cli/src/core/git/repository/tests/validate.rs rename to src/core/git/repository/tests/validate.rs diff --git a/crates/cli/src/core/git/tests.rs b/src/core/git/tests.rs similarity index 100% rename from crates/cli/src/core/git/tests.rs rename to src/core/git/tests.rs diff --git a/crates/cli/src/core/git/user_notification.rs b/src/core/git/user_notification.rs similarity index 100% rename from crates/cli/src/core/git/user_notification.rs rename to src/core/git/user_notification.rs diff --git a/crates/cli/src/core/git/validation/mod.rs b/src/core/git/validation/mod.rs similarity index 100% rename from crates/cli/src/core/git/validation/mod.rs rename to src/core/git/validation/mod.rs diff --git a/crates/cli/src/core/git/validation/positions.rs b/src/core/git/validation/positions.rs similarity index 100% rename from crates/cli/src/core/git/validation/positions.rs rename to src/core/git/validation/positions.rs diff --git a/crates/cli/src/core/git/validation/remotes.rs b/src/core/git/validation/remotes.rs similarity index 100% rename from crates/cli/src/core/git/validation/remotes.rs rename to src/core/git/validation/remotes.rs diff --git a/crates/cli/src/core/git/validation/tests.rs b/src/core/git/validation/tests.rs similarity index 100% rename from crates/cli/src/core/git/validation/tests.rs rename to src/core/git/validation/tests.rs diff --git a/crates/cli/src/core/macros/message.rs b/src/core/macros/message.rs similarity index 100% rename from crates/cli/src/core/macros/message.rs rename to src/core/macros/message.rs diff --git a/crates/cli/src/core/macros/mod.rs b/src/core/macros/mod.rs similarity index 100% rename from crates/cli/src/core/macros/mod.rs rename to src/core/macros/mod.rs diff --git a/crates/cli/src/core/macros/newtype.rs b/src/core/macros/newtype.rs similarity index 100% rename from crates/cli/src/core/macros/newtype.rs rename to src/core/macros/newtype.rs diff --git a/crates/cli/src/core/macros/owned_string.rs b/src/core/macros/owned_string.rs similarity index 100% rename from crates/cli/src/core/macros/owned_string.rs rename to src/core/macros/owned_string.rs diff --git a/crates/cli/src/core/mod.rs b/src/core/mod.rs similarity index 100% rename from crates/cli/src/core/mod.rs rename to src/core/mod.rs diff --git a/crates/cli/src/file_watcher.rs b/src/file_watcher.rs similarity index 100% rename from crates/cli/src/file_watcher.rs rename to src/file_watcher.rs diff --git a/crates/cli/src/forge/mod.rs b/src/forge/mod.rs similarity index 100% rename from crates/cli/src/forge/mod.rs rename to src/forge/mod.rs diff --git a/crates/cli/src/forge/tests.rs b/src/forge/tests.rs similarity index 100% rename from crates/cli/src/forge/tests.rs rename to src/forge/tests.rs diff --git a/crates/cli/src/forges/forgejo/mod.rs b/src/forges/forgejo/mod.rs similarity index 100% rename from crates/cli/src/forges/forgejo/mod.rs rename to src/forges/forgejo/mod.rs diff --git a/crates/cli/src/forges/forgejo/tests.rs b/src/forges/forgejo/tests.rs similarity index 100% rename from crates/cli/src/forges/forgejo/tests.rs rename to src/forges/forgejo/tests.rs diff --git a/crates/cli/src/forges/forgejo/webhook/list.rs b/src/forges/forgejo/webhook/list.rs similarity index 100% rename from crates/cli/src/forges/forgejo/webhook/list.rs rename to src/forges/forgejo/webhook/list.rs diff --git a/crates/cli/src/forges/forgejo/webhook/mod.rs b/src/forges/forgejo/webhook/mod.rs similarity index 100% rename from crates/cli/src/forges/forgejo/webhook/mod.rs rename to src/forges/forgejo/webhook/mod.rs diff --git a/crates/cli/src/forges/forgejo/webhook/parser.rs b/src/forges/forgejo/webhook/parser.rs similarity index 100% rename from crates/cli/src/forges/forgejo/webhook/parser.rs rename to src/forges/forgejo/webhook/parser.rs diff --git a/crates/cli/src/forges/forgejo/webhook/register.rs b/src/forges/forgejo/webhook/register.rs similarity index 100% rename from crates/cli/src/forges/forgejo/webhook/register.rs rename to src/forges/forgejo/webhook/register.rs diff --git a/crates/cli/src/forges/forgejo/webhook/unregister.rs b/src/forges/forgejo/webhook/unregister.rs similarity index 100% rename from crates/cli/src/forges/forgejo/webhook/unregister.rs rename to src/forges/forgejo/webhook/unregister.rs diff --git a/crates/cli/src/forges/github/commit.rs b/src/forges/github/commit.rs similarity index 100% rename from crates/cli/src/forges/github/commit.rs rename to src/forges/github/commit.rs diff --git a/crates/cli/src/forges/github/message.json b/src/forges/github/message.json similarity index 100% rename from crates/cli/src/forges/github/message.json rename to src/forges/github/message.json diff --git a/crates/cli/src/forges/github/mod.rs b/src/forges/github/mod.rs similarity index 100% rename from crates/cli/src/forges/github/mod.rs rename to src/forges/github/mod.rs diff --git a/crates/cli/src/forges/github/tests/mod.rs b/src/forges/github/tests/mod.rs similarity index 100% rename from crates/cli/src/forges/github/tests/mod.rs rename to src/forges/github/tests/mod.rs diff --git a/crates/cli/src/forges/github/webhook/authorisation.rs b/src/forges/github/webhook/authorisation.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/authorisation.rs rename to src/forges/github/webhook/authorisation.rs diff --git a/crates/cli/src/forges/github/webhook/list.rs b/src/forges/github/webhook/list.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/list.rs rename to src/forges/github/webhook/list.rs diff --git a/crates/cli/src/forges/github/webhook/mod.rs b/src/forges/github/webhook/mod.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/mod.rs rename to src/forges/github/webhook/mod.rs diff --git a/crates/cli/src/forges/github/webhook/parser.rs b/src/forges/github/webhook/parser.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/parser.rs rename to src/forges/github/webhook/parser.rs diff --git a/crates/cli/src/forges/github/webhook/register.rs b/src/forges/github/webhook/register.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/register.rs rename to src/forges/github/webhook/register.rs diff --git a/crates/cli/src/forges/github/webhook/unregister.rs b/src/forges/github/webhook/unregister.rs similarity index 100% rename from crates/cli/src/forges/github/webhook/unregister.rs rename to src/forges/github/webhook/unregister.rs diff --git a/crates/cli/src/forges/mod.rs b/src/forges/mod.rs similarity index 100% rename from crates/cli/src/forges/mod.rs rename to src/forges/mod.rs diff --git a/crates/cli/src/init.rs b/src/init.rs similarity index 100% rename from crates/cli/src/init.rs rename to src/init.rs diff --git a/crates/cli/src/macros/actor.rs b/src/macros/actor.rs similarity index 100% rename from crates/cli/src/macros/actor.rs rename to src/macros/actor.rs diff --git a/crates/cli/src/macros/mod.rs b/src/macros/mod.rs similarity index 100% rename from crates/cli/src/macros/mod.rs rename to src/macros/mod.rs diff --git a/crates/cli/src/macros/send.rs b/src/macros/send.rs similarity index 100% rename from crates/cli/src/macros/send.rs rename to src/macros/send.rs diff --git a/crates/cli/src/macros/spawn.rs b/src/macros/spawn.rs similarity index 100% rename from crates/cli/src/macros/spawn.rs rename to src/macros/spawn.rs diff --git a/crates/cli/src/main.rs b/src/main.rs similarity index 100% rename from crates/cli/src/main.rs rename to src/main.rs diff --git a/crates/cli/src/repo/MESSAGES.md b/src/repo/MESSAGES.md similarity index 100% rename from crates/cli/src/repo/MESSAGES.md rename to src/repo/MESSAGES.md diff --git a/crates/cli/src/repo/branch.rs b/src/repo/branch.rs similarity index 100% rename from crates/cli/src/repo/branch.rs rename to src/repo/branch.rs diff --git a/crates/cli/src/repo/handlers/advance_main.rs b/src/repo/handlers/advance_main.rs similarity index 100% rename from crates/cli/src/repo/handlers/advance_main.rs rename to src/repo/handlers/advance_main.rs diff --git a/crates/cli/src/repo/handlers/advance_next.rs b/src/repo/handlers/advance_next.rs similarity index 100% rename from crates/cli/src/repo/handlers/advance_next.rs rename to src/repo/handlers/advance_next.rs diff --git a/crates/cli/src/repo/handlers/check_ci_status.rs b/src/repo/handlers/check_ci_status.rs similarity index 100% rename from crates/cli/src/repo/handlers/check_ci_status.rs rename to src/repo/handlers/check_ci_status.rs diff --git a/crates/cli/src/repo/handlers/clone_repo.rs b/src/repo/handlers/clone_repo.rs similarity index 100% rename from crates/cli/src/repo/handlers/clone_repo.rs rename to src/repo/handlers/clone_repo.rs diff --git a/crates/cli/src/repo/handlers/load_config_from_repo.rs b/src/repo/handlers/load_config_from_repo.rs similarity index 100% rename from crates/cli/src/repo/handlers/load_config_from_repo.rs rename to src/repo/handlers/load_config_from_repo.rs diff --git a/crates/cli/src/repo/handlers/mod.rs b/src/repo/handlers/mod.rs similarity index 100% rename from crates/cli/src/repo/handlers/mod.rs rename to src/repo/handlers/mod.rs diff --git a/crates/cli/src/repo/handlers/receive_ci_status.rs b/src/repo/handlers/receive_ci_status.rs similarity index 100% rename from crates/cli/src/repo/handlers/receive_ci_status.rs rename to src/repo/handlers/receive_ci_status.rs diff --git a/crates/cli/src/repo/handlers/receive_repo_config.rs b/src/repo/handlers/receive_repo_config.rs similarity index 100% rename from crates/cli/src/repo/handlers/receive_repo_config.rs rename to src/repo/handlers/receive_repo_config.rs diff --git a/crates/cli/src/repo/handlers/register_webhook.rs b/src/repo/handlers/register_webhook.rs similarity index 100% rename from crates/cli/src/repo/handlers/register_webhook.rs rename to src/repo/handlers/register_webhook.rs diff --git a/crates/cli/src/repo/handlers/unregister_webhook.rs b/src/repo/handlers/unregister_webhook.rs similarity index 100% rename from crates/cli/src/repo/handlers/unregister_webhook.rs rename to src/repo/handlers/unregister_webhook.rs diff --git a/crates/cli/src/repo/handlers/validate_repo.rs b/src/repo/handlers/validate_repo.rs similarity index 100% rename from crates/cli/src/repo/handlers/validate_repo.rs rename to src/repo/handlers/validate_repo.rs diff --git a/crates/cli/src/repo/handlers/webhook_notification.rs b/src/repo/handlers/webhook_notification.rs similarity index 100% rename from crates/cli/src/repo/handlers/webhook_notification.rs rename to src/repo/handlers/webhook_notification.rs diff --git a/crates/cli/src/repo/handlers/webhook_registered.rs b/src/repo/handlers/webhook_registered.rs similarity index 100% rename from crates/cli/src/repo/handlers/webhook_registered.rs rename to src/repo/handlers/webhook_registered.rs diff --git a/crates/cli/src/repo/load.rs b/src/repo/load.rs similarity index 100% rename from crates/cli/src/repo/load.rs rename to src/repo/load.rs diff --git a/crates/cli/src/repo/messages.rs b/src/repo/messages.rs similarity index 100% rename from crates/cli/src/repo/messages.rs rename to src/repo/messages.rs diff --git a/crates/cli/src/repo/mod.rs b/src/repo/mod.rs similarity index 100% rename from crates/cli/src/repo/mod.rs rename to src/repo/mod.rs diff --git a/crates/cli/src/repo/notifications.rs b/src/repo/notifications.rs similarity index 100% rename from crates/cli/src/repo/notifications.rs rename to src/repo/notifications.rs diff --git a/crates/cli/src/repo/tests/branch/advance_main.rs b/src/repo/tests/branch/advance_main.rs similarity index 100% rename from crates/cli/src/repo/tests/branch/advance_main.rs rename to src/repo/tests/branch/advance_main.rs diff --git a/crates/cli/src/repo/tests/branch/advance_next.rs b/src/repo/tests/branch/advance_next.rs similarity index 100% rename from crates/cli/src/repo/tests/branch/advance_next.rs rename to src/repo/tests/branch/advance_next.rs diff --git a/crates/cli/src/repo/tests/branch/mod.rs b/src/repo/tests/branch/mod.rs similarity index 100% rename from crates/cli/src/repo/tests/branch/mod.rs rename to src/repo/tests/branch/mod.rs diff --git a/crates/cli/src/repo/tests/expect.rs b/src/repo/tests/expect.rs similarity index 100% rename from crates/cli/src/repo/tests/expect.rs rename to src/repo/tests/expect.rs diff --git a/crates/cli/src/repo/tests/given.rs b/src/repo/tests/given.rs similarity index 100% rename from crates/cli/src/repo/tests/given.rs rename to src/repo/tests/given.rs diff --git a/crates/cli/src/repo/tests/handlers/advance_main.rs b/src/repo/tests/handlers/advance_main.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/advance_main.rs rename to src/repo/tests/handlers/advance_main.rs diff --git a/crates/cli/src/repo/tests/handlers/advance_next.rs b/src/repo/tests/handlers/advance_next.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/advance_next.rs rename to src/repo/tests/handlers/advance_next.rs diff --git a/crates/cli/src/repo/tests/handlers/check_ci_status.rs b/src/repo/tests/handlers/check_ci_status.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/check_ci_status.rs rename to src/repo/tests/handlers/check_ci_status.rs diff --git a/crates/cli/src/repo/tests/handlers/clone_repo.rs b/src/repo/tests/handlers/clone_repo.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/clone_repo.rs rename to src/repo/tests/handlers/clone_repo.rs diff --git a/crates/cli/src/repo/tests/handlers/load_config_from_repo.rs b/src/repo/tests/handlers/load_config_from_repo.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/load_config_from_repo.rs rename to src/repo/tests/handlers/load_config_from_repo.rs diff --git a/crates/cli/src/repo/tests/handlers/loaded_config.rs b/src/repo/tests/handlers/loaded_config.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/loaded_config.rs rename to src/repo/tests/handlers/loaded_config.rs diff --git a/crates/cli/src/repo/tests/handlers/mod.rs b/src/repo/tests/handlers/mod.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/mod.rs rename to src/repo/tests/handlers/mod.rs diff --git a/crates/cli/src/repo/tests/handlers/receive_ci_status.rs b/src/repo/tests/handlers/receive_ci_status.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/receive_ci_status.rs rename to src/repo/tests/handlers/receive_ci_status.rs diff --git a/crates/cli/src/repo/tests/handlers/register_webhook.rs b/src/repo/tests/handlers/register_webhook.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/register_webhook.rs rename to src/repo/tests/handlers/register_webhook.rs diff --git a/crates/cli/src/repo/tests/handlers/validate_repo.rs b/src/repo/tests/handlers/validate_repo.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/validate_repo.rs rename to src/repo/tests/handlers/validate_repo.rs diff --git a/crates/cli/src/repo/tests/handlers/webhook_notification.rs b/src/repo/tests/handlers/webhook_notification.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/webhook_notification.rs rename to src/repo/tests/handlers/webhook_notification.rs diff --git a/crates/cli/src/repo/tests/handlers/webhook_registered.rs b/src/repo/tests/handlers/webhook_registered.rs similarity index 100% rename from crates/cli/src/repo/tests/handlers/webhook_registered.rs rename to src/repo/tests/handlers/webhook_registered.rs diff --git a/crates/cli/src/repo/tests/load.rs b/src/repo/tests/load.rs similarity index 100% rename from crates/cli/src/repo/tests/load.rs rename to src/repo/tests/load.rs diff --git a/crates/cli/src/repo/tests/mod.rs b/src/repo/tests/mod.rs similarity index 100% rename from crates/cli/src/repo/tests/mod.rs rename to src/repo/tests/mod.rs diff --git a/crates/cli/src/repo/tests/when.rs b/src/repo/tests/when.rs similarity index 100% rename from crates/cli/src/repo/tests/when.rs rename to src/repo/tests/when.rs diff --git a/crates/cli/src/root.rs b/src/root.rs similarity index 100% rename from crates/cli/src/root.rs rename to src/root.rs diff --git a/crates/cli/src/server/actor/MESSAGES.md b/src/server/actor/MESSAGES.md similarity index 100% rename from crates/cli/src/server/actor/MESSAGES.md rename to src/server/actor/MESSAGES.md diff --git a/crates/cli/src/server/actor/handlers/file_updated.rs b/src/server/actor/handlers/file_updated.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/file_updated.rs rename to src/server/actor/handlers/file_updated.rs diff --git a/crates/cli/src/server/actor/handlers/mod.rs b/src/server/actor/handlers/mod.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/mod.rs rename to src/server/actor/handlers/mod.rs diff --git a/crates/cli/src/server/actor/handlers/receive_app_config.rs b/src/server/actor/handlers/receive_app_config.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/receive_app_config.rs rename to src/server/actor/handlers/receive_app_config.rs diff --git a/crates/cli/src/server/actor/handlers/receive_valid_app_config.rs b/src/server/actor/handlers/receive_valid_app_config.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/receive_valid_app_config.rs rename to src/server/actor/handlers/receive_valid_app_config.rs diff --git a/crates/cli/src/server/actor/handlers/server_update.rs b/src/server/actor/handlers/server_update.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/server_update.rs rename to src/server/actor/handlers/server_update.rs diff --git a/crates/cli/src/server/actor/handlers/shutdown.rs b/src/server/actor/handlers/shutdown.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/shutdown.rs rename to src/server/actor/handlers/shutdown.rs diff --git a/crates/cli/src/server/actor/handlers/shutdown_trigger.rs b/src/server/actor/handlers/shutdown_trigger.rs similarity index 100% rename from crates/cli/src/server/actor/handlers/shutdown_trigger.rs rename to src/server/actor/handlers/shutdown_trigger.rs diff --git a/crates/cli/src/server/actor/messages.rs b/src/server/actor/messages.rs similarity index 100% rename from crates/cli/src/server/actor/messages.rs rename to src/server/actor/messages.rs diff --git a/crates/cli/src/server/actor/mod.rs b/src/server/actor/mod.rs similarity index 100% rename from crates/cli/src/server/actor/mod.rs rename to src/server/actor/mod.rs diff --git a/crates/cli/src/server/actor/tests/given.rs b/src/server/actor/tests/given.rs similarity index 100% rename from crates/cli/src/server/actor/tests/given.rs rename to src/server/actor/tests/given.rs diff --git a/crates/cli/src/server/actor/tests/mod.rs b/src/server/actor/tests/mod.rs similarity index 100% rename from crates/cli/src/server/actor/tests/mod.rs rename to src/server/actor/tests/mod.rs diff --git a/crates/cli/src/server/actor/tests/receive_app_config.rs b/src/server/actor/tests/receive_app_config.rs similarity index 100% rename from crates/cli/src/server/actor/tests/receive_app_config.rs rename to src/server/actor/tests/receive_app_config.rs diff --git a/crates/cli/src/server/mod.rs b/src/server/mod.rs similarity index 100% rename from crates/cli/src/server/mod.rs rename to src/server/mod.rs diff --git a/crates/cli/src/server/server-default.toml b/src/server/server-default.toml similarity index 100% rename from crates/cli/src/server/server-default.toml rename to src/server/server-default.toml diff --git a/crates/cli/src/server/tests.rs b/src/server/tests.rs similarity index 100% rename from crates/cli/src/server/tests.rs rename to src/server/tests.rs diff --git a/crates/cli/src/tests.rs b/src/tests.rs similarity index 100% rename from crates/cli/src/tests.rs rename to src/tests.rs diff --git a/crates/cli/src/tui/README.md b/src/tui/README.md similarity index 100% rename from crates/cli/src/tui/README.md rename to src/tui/README.md diff --git a/crates/cli/src/tui/actor/handlers/mod.rs b/src/tui/actor/handlers/mod.rs similarity index 100% rename from crates/cli/src/tui/actor/handlers/mod.rs rename to src/tui/actor/handlers/mod.rs diff --git a/crates/cli/src/tui/actor/handlers/server_update.rs b/src/tui/actor/handlers/server_update.rs similarity index 100% rename from crates/cli/src/tui/actor/handlers/server_update.rs rename to src/tui/actor/handlers/server_update.rs diff --git a/crates/cli/src/tui/actor/handlers/tick.rs b/src/tui/actor/handlers/tick.rs similarity index 100% rename from crates/cli/src/tui/actor/handlers/tick.rs rename to src/tui/actor/handlers/tick.rs diff --git a/crates/cli/src/tui/actor/messages.rs b/src/tui/actor/messages.rs similarity index 100% rename from crates/cli/src/tui/actor/messages.rs rename to src/tui/actor/messages.rs diff --git a/crates/cli/src/tui/actor/mod.rs b/src/tui/actor/mod.rs similarity index 100% rename from crates/cli/src/tui/actor/mod.rs rename to src/tui/actor/mod.rs diff --git a/crates/cli/src/tui/actor/model.rs b/src/tui/actor/model.rs similarity index 100% rename from crates/cli/src/tui/actor/model.rs rename to src/tui/actor/model.rs diff --git a/crates/cli/src/tui/actor/tests.rs b/src/tui/actor/tests.rs similarity index 100% rename from crates/cli/src/tui/actor/tests.rs rename to src/tui/actor/tests.rs diff --git a/crates/cli/src/tui/components/configured_app.rs b/src/tui/components/configured_app.rs similarity index 100% rename from crates/cli/src/tui/components/configured_app.rs rename to src/tui/components/configured_app.rs diff --git a/crates/cli/src/tui/components/forge/collapsed.rs b/src/tui/components/forge/collapsed.rs similarity index 100% rename from crates/cli/src/tui/components/forge/collapsed.rs rename to src/tui/components/forge/collapsed.rs diff --git a/crates/cli/src/tui/components/forge/expanded.rs b/src/tui/components/forge/expanded.rs similarity index 100% rename from crates/cli/src/tui/components/forge/expanded.rs rename to src/tui/components/forge/expanded.rs diff --git a/crates/cli/src/tui/components/forge/mod.rs b/src/tui/components/forge/mod.rs similarity index 100% rename from crates/cli/src/tui/components/forge/mod.rs rename to src/tui/components/forge/mod.rs diff --git a/crates/cli/src/tui/components/history.rs b/src/tui/components/history.rs similarity index 100% rename from crates/cli/src/tui/components/history.rs rename to src/tui/components/history.rs diff --git a/crates/cli/src/tui/components/key_focus.rs b/src/tui/components/key_focus.rs similarity index 100% rename from crates/cli/src/tui/components/key_focus.rs rename to src/tui/components/key_focus.rs diff --git a/crates/cli/src/tui/components/mod.rs b/src/tui/components/mod.rs similarity index 100% rename from crates/cli/src/tui/components/mod.rs rename to src/tui/components/mod.rs diff --git a/crates/cli/src/tui/components/repo/identity.rs b/src/tui/components/repo/identity.rs similarity index 100% rename from crates/cli/src/tui/components/repo/identity.rs rename to src/tui/components/repo/identity.rs diff --git a/crates/cli/src/tui/components/repo/mod.rs b/src/tui/components/repo/mod.rs similarity index 100% rename from crates/cli/src/tui/components/repo/mod.rs rename to src/tui/components/repo/mod.rs diff --git a/crates/cli/src/tui/logging.rs b/src/tui/logging.rs similarity index 100% rename from crates/cli/src/tui/logging.rs rename to src/tui/logging.rs diff --git a/crates/cli/src/tui/mod.rs b/src/tui/mod.rs similarity index 100% rename from crates/cli/src/tui/mod.rs rename to src/tui/mod.rs diff --git a/crates/cli/src/webhook/mod.rs b/src/webhook/mod.rs similarity index 100% rename from crates/cli/src/webhook/mod.rs rename to src/webhook/mod.rs diff --git a/crates/cli/src/webhook/router.rs b/src/webhook/router.rs similarity index 100% rename from crates/cli/src/webhook/router.rs rename to src/webhook/router.rs diff --git a/crates/cli/src/webhook/server.rs b/src/webhook/server.rs similarity index 100% rename from crates/cli/src/webhook/server.rs rename to src/webhook/server.rs