feat: add Gitea account authentication in integrations settings#12901
feat: add Gitea account authentication in integrations settings#12901javery556 wants to merge 3 commits intogitbutlerapp:masterfrom
Conversation
|
@javery556 is attempting to deploy a commit to the GitButler Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks for giving it a shot. I think @estib-vega should decide if reviewing this makes sense for him. A cursory look shows new crates without any docs, so I don't think it's there just yet and needs quite some work. In any case, could @javery556 provide demo videos that show all the functionality? |
|
Follow-up is pushed in I addressed the reviewability gaps Byron called out:
I also re-tested this against a real local Gitea 1.25.5 instance rather than synthetic-only data:
Window-only demo video: |
|
Thanks a lot! Let's see what Esteban thinks when he gets to it. @codex review |
There was a problem hiding this comment.
Pull request overview
Adds first-pass Gitea (e.g., Codeberg) authentication/account management support across the Rust backend, server/tauri command surfaces, and the Desktop Settings UI, including token persistence via OS keychain and forge-storage metadata.
Changes:
- Introduces
but-giteacrate for validating PATs, fetching/api/v1/user, and persisting account/token data. - Wires new Gitea commands into
but-api,but-serverroutes, and Tauri command registration; extendsbut-forge-storagesettings/controller for Gitea accounts. - Adds Desktop-side Gitea user service + Settings integration components, plus generated TS types.
Reviewed changes
Copilot reviewed 21 out of 25 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/generated/index.ts | Re-exports generated Gitea API/token types for frontend consumption. |
| packages/core/src/generated/gitea/token.ts | Adds generated GiteaAccountIdentifier TS type. |
| packages/core/src/generated/gitea/index.ts | Adds generated sensitive response/user TS types for Gitea auth flows. |
| crates/gitbutler-tauri/src/main.rs | Registers new Tauri commands for Gitea account management. |
| crates/but-server/src/lib.rs | Adds but-server HTTP routes for Gitea account management commands. |
| crates/but-gitea/src/token.rs | Implements Gitea account identifier + token persistence/removal/listing. |
| crates/but-gitea/src/lib.rs | Exposes high-level Gitea auth/account-management API + JSON transport types. |
| crates/but-gitea/src/client.rs | Adds minimal reqwest-based Gitea client for /api/v1/user. |
| crates/but-gitea/README.md | Documents scope and manual verification steps for the new crate. |
| crates/but-gitea/Cargo.toml | Defines new crate, features (ts/schema export), and deps. |
| crates/but-forge-storage/src/settings.rs | Extends forge settings with gitea settings + persisted account metadata. |
| crates/but-forge-storage/src/controller.rs | Adds controller CRUD helpers for Gitea known accounts. |
| crates/but-api/src/lib.rs | Exposes new but_api::gitea module. |
| crates/but-api/src/gitea.rs | Implements API entrypoints/commands for storing/listing/forgetting/clearing Gitea accounts and fetching user. |
| crates/but-api/Cargo.toml | Adds but-gitea dependency. |
| apps/desktop/src/lib/state/tags.ts | Adds ReduxTag.GiteaUserList for RTK Query caching. |
| apps/desktop/src/lib/forge/gitea/giteaUserService.test.ts | Adds helper tests for identifier (de)serialization/comparison. |
| apps/desktop/src/lib/forge/gitea/giteaUserService.svelte.ts | Adds RTK Query endpoint wiring + DI service wrapper for Gitea. |
| apps/desktop/src/lib/bootstrap/deps.ts | Registers GiteaUserService in dependency injection bootstrap. |
| apps/desktop/src/components/profileSettings/IntegrationsSettings.svelte | Adds the Gitea integration card to Settings. |
| apps/desktop/src/components/GiteaUserLoginState.svelte | Renders per-account login state with forget action + user fetch. |
| apps/desktop/src/components/GiteaIntegration.svelte | Implements Settings UI flow for adding/removing/clearing Gitea accounts. |
| apps/desktop/src/components/GiteaAccountBadge.svelte | Adds badge/tooltip for displaying the normalized Gitea instance host. |
| Cargo.toml | Adds crates/but-gitea to workspace members and workspace deps. |
| Cargo.lock | Adds lockfile entries for the new crate and dependency edges. |
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53e774babf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Pushed a follow-up in
Re-verified with:
|
|
@codex review |
There was a problem hiding this comment.
Pull request overview
Adds a first-pass Gitea authentication + account-management integration across the Rust backend, server/Tauri command surfaces, and the desktop Settings UI.
Changes:
- Introduces
but-giteafor validating PATs against a Gitea host, persisting account metadata, and storing tokens in secure storage. - Wires new Gitea commands into
but-api,but-server, and the Tauri invoke handler. - Adds a desktop Settings integration card + service layer to store/list/forget Gitea accounts.
Reviewed changes
Copilot reviewed 21 out of 25 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/generated/index.ts | Exports generated Gitea SDK types from @gitbutler/core/api. |
| packages/core/src/generated/gitea/token.ts | Adds generated TS type for GiteaAccountIdentifier. |
| packages/core/src/generated/gitea/index.ts | Adds generated TS response types exposing tokens for UI handoff. |
| crates/gitbutler-tauri/src/main.rs | Registers new Gitea Tauri commands. |
| crates/but-server/src/lib.rs | Adds HTTP routes for Gitea account/token management commands. |
| crates/but-gitea/src/token.rs | Implements persisted account identifiers + secure token storage helpers. |
| crates/but-gitea/src/lib.rs | Provides the high-level Gitea auth/account API used by but-api. |
| crates/but-gitea/src/client.rs | Implements minimal Gitea /api/v1/user client for auth validation/user fetch. |
| crates/but-gitea/README.md | Documents scope, layout, and manual verification steps for but-gitea. |
| crates/but-gitea/Cargo.toml | Adds new crate manifest + feature flags (ts/schema export). |
| crates/but-forge-storage/src/settings.rs | Extends forge settings schema with Gitea settings/accounts. |
| crates/but-forge-storage/src/controller.rs | Adds CRUD helpers for Gitea accounts in forge settings storage. |
| crates/but-api/src/lib.rs | Exposes new gitea API module. |
| crates/but-api/src/gitea.rs | Adds Gitea API commands for store/get/list/forget/clear. |
| crates/but-api/Cargo.toml | Adds but-gitea dependency. |
| apps/desktop/src/lib/state/tags.ts | Adds ReduxTag.GiteaUserList for cache tagging. |
| apps/desktop/src/lib/forge/gitea/giteaUserService.test.ts | Adds unit tests for Gitea account identifier helpers. |
| apps/desktop/src/lib/forge/gitea/giteaUserService.svelte.ts | Adds RTK Query endpoints + service wrapper for Gitea auth/account management. |
| apps/desktop/src/lib/bootstrap/deps.ts | Registers GiteaUserService in dependency injection. |
| apps/desktop/src/components/profileSettings/IntegrationsSettings.svelte | Adds the Gitea integration card to Settings. |
| apps/desktop/src/components/GiteaUserLoginState.svelte | Renders per-account user state and forget action. |
| apps/desktop/src/components/GiteaIntegration.svelte | Implements Settings UI flow to add/list Gitea accounts. |
| apps/desktop/src/components/GiteaAccountBadge.svelte | Adds host badge rendering/normalization for Gitea accounts. |
| Cargo.toml | Adds but-gitea to workspace members and workspace dependencies. |
| Cargo.lock | Locks new crate and its dependency graph. |
You can also share your feedback on Copilot code review. Take the survey.
| let _one_at_a_time_to_prevent_races = FAIR_QUEUE.lock().unwrap(); | ||
| secret::persist( | ||
| &secret_key, | ||
| &account.access_token(), | ||
| secret::Namespace::BuildKind, | ||
| )?; | ||
|
|
||
| if let Err(err) = storage.add_gitea_account(&account.into()) { | ||
| let _ = secret::delete(&secret_key, secret::Namespace::BuildKind); |
| impl GiteaAccountIdentifier { | ||
| /// Build an identifier from the authenticated username and host. | ||
| pub fn new(username: &str, host: &str) -> Self { | ||
| Self { | ||
| username: username.to_string(), | ||
| host: host.to_string(), | ||
| } | ||
| } | ||
|
|
||
| /// Recreate a client for this stored account. | ||
| pub fn client(&self, access_token: &Sensitive<String>) -> Result<GiteaClient> { | ||
| crate::client::client_for(self, access_token) | ||
| } | ||
| } |
| if settings.gitea.known_accounts.iter().any(|a| a == account) { | ||
| return Ok(()); | ||
| } | ||
|
|
||
| settings.gitea.known_accounts.push(account.to_owned()); |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a08386e220
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| token::persist_gitea_access_token( | ||
| &token::GiteaAccountIdentifier::new(&user.username, host), | ||
| access_token, |
There was a problem hiding this comment.
Canonicalize Gitea hosts before persisting account IDs
normalize_api_base_url() already treats https://codeberg.org, https://codeberg.org/, and https://codeberg.org/api/v1 as the same API root, but this path stores the raw textbox value in the account identifier. As a result, the same Gitea account can be added multiple times under equivalent URLs, and the settings UI then renders those duplicates with the same normalized badge text while keeping separate stored secrets.
Useful? React with 👍 / 👎.
| query: (args) => args, | ||
| invalidatesTags: [providesList(ReduxTag.GiteaUserList)], |
There was a problem hiding this comment.
Invalidate cached Gitea user queries after storing a token
This mutation only invalidates GiteaUserList, even though getGiteaUser caches each account separately. Because RTK Query serves existing cached query results on remount by default, saving the same host+username again (for example after rotating a PAT, or re-adding an account you just removed) can leave the card showing a stale success/error state instead of fetching /get_gitea_user with the new credentials until the cache expires or the app restarts.
Useful? React with 👍 / 👎.
Summary
Adds a small Gitea authentication/settings slice to GitButler.
This PR lets users store a personal access token for Codeberg or another Gitea-compatible host, fetch the authenticated account, list saved Gitea accounts, and remove individual or all stored accounts from Settings.
Related to #2904.
What’s included
but-giteacrate for Gitea auth requests and account token persistencestore_gitea_accountget_gitea_userforget_gitea_accountlist_known_gitea_accountsclear_all_gitea_tokensbut-serverWhat’s not included
This PR does not add:
The goal here is just the auth and account-management foundation as a small focused slice.
Validation
Repo checks:
cargo test -p but-gitea -p but-forge-storagecargo test -p but-server -p but-api -p gitbutler-tauri --no-runnpx --yes pnpm@10.20.0 --filter @gitbutler/core checknpx --yes pnpm@10.20.0 --filter @gitbutler/desktop checknpx --yes pnpm@10.20.0 --filter @gitbutler/desktop exec vitest run --mode development src/lib/forge/gitea/giteaUserService.test.tsReal Gitea smoke test:
1.25.5instance/api/v1/useragainst the live instancestore_account,list_known_gitea_accounts,get_gitea_user, andforget_gitea_access_tokenNotes
I kept this intentionally narrow so it can be reviewed independently from broader Gitea forge support work.