Skip to main content

Gitea and Forgejo

Runesmith works with Gitea and Forgejo servers through an official plugin that ships with it, Gitea and Forgejo (runesmith.gitea), developed in RunesmithHub/plugin-gitea. It starts with gitea.com and Codeberg and takes any self-hosted Gitea or Forgejo server by its address. Once you are signed in, the clone dialog has a tab for each of your accounts, Pull Requests lists the open repository's pull requests, and Open on and Copy Link point at the server's pages. Git itself, with the Commit and Git windows, comes from the Git plugin; this plugin only adds the server's side.

Gitea and Forgejo​

The plugin keeps Gitea and Forgejo apart: each has its own settings page, accounts and setting, and a server is added under the service it runs. Everything else on this page works the same for both.

GiteaForgejo
Settings pageSettings › GiteaSettings › Forgejo
Default servergitea.comCodeberg (codeberg.org)
Clone dialog tabsgitea.com, Gitea (git.example.com)Codeberg, Forgejo (git.example.com)
Secret store keysrunesmith.gitea/gitea.com/alicerunesmith.gitea/forgejo/codeberg.org/alice
OAuth2 client IDsgitea.oauthClientIdsforgejo.oauthClientIds
Made-up servers for testsRUNESMITH_GITEA_FAKERUNESMITH_FORGEJO_FAKE

Forgejo used to have its own plugin, runesmith.forgejo. Its list of accounts carries over; sign in to each account again.

Sign in​

Open Settings › Gitea or Settings › Forgejo. Before the first account, it offers Sign in to gitea.com or Sign in to Codeberg; Add Account signs in to another server.

Runesmith signs in one of two ways:

WayWhenWhat happens
Through the browserAn OAuth2 application for Runesmith is registered on the server, and its client ID is in the settingsRunesmith opens the server's approval page in your browser and waits. When you approve, the browser comes back to Runesmith and you are signed in.
With an access tokenAlwaysYou create a token on the server and paste it. Runesmith checks it with the server before keeping it.

Through the browser​

  1. Select Sign in to gitea.com or Sign in to Codeberg, or Sign In next to an account.
  2. The dialog says Waiting for the browser... and your browser opens the server's page. Sign in there if you are not, and approve Runesmith.
  3. The browser shows Signed in; close the tab. The dialog closes and a notification says which account signed in.

While it waits, the dialog offers Open the page again, Use a token instead and Cancel. Nothing you type in the browser reaches Runesmith: the server sends back a one-time code, which Runesmith exchanges for a token. The exchange uses PKCE and a redirect to http://127.0.0.1 on a port chosen for each sign-in, so no client secret is involved.

Browser tokens expire after an hour. Runesmith renews them a couple of minutes before they expire; if the server refuses, Runesmith signs out and a notification offers Sign In.

With an access token​

When the server has no OAuth2 application for Runesmith, the dialog asks for a token at once; otherwise select Use a token instead.

  1. Select Create a token on the server. It opens Settings › Applications on the server, at /user/settings/applications.
  2. Under Manage access tokens, give the token a name such as Runesmith, choose All under repository and organization access, and set the permissions in the table below.
  3. Select Generate token, copy it, paste it into Runesmith and select Sign In.
PermissionAccessWhat Runesmith does with it
repositoryRead and writeClone, fetch, pull and push, list pull requests and create them
userReadYour login and avatar, and your own repositories
organizationReadThe organizations whose repositories the clone dialog lists

When a token lacks a permission, Runesmith says which one the server asked for. Access tokens do not expire unless you delete them on the server.

Several servers and accounts​

Add Account asks for a server's address, such as gitea.com, codeberg.org, git.example.com, git.example.com:3000 or example.com/git when the server lives under a path. Runesmith checks the address before signing in: a Gitea server answers /api/v1/version, and a Forgejo server also answers /api/forgejo/v1/version. When the address runs the other service, Runesmith says so and points at its settings page, such as Settings › Forgejo.

Each account has its own row on its service's settings page, with its server, how it signed in, Manage Tokens, which opens the server's applications page, and Sign Out. A signed-out account keeps its row with Sign In and a button that removes it. You can sign in to several accounts on the same server; Git uses the account named in a remote's URL, such as https://alice@gitea.com/..., and otherwise the first one.

In the clone dialog, the default servers' tabs are called gitea.com and Codeberg, and other servers' tabs are called Gitea (git.example.com) or Forgejo (git.example.com).

Tokens and Git​

Runesmith keeps the tokens in the system's secret store, one entry per server and account, under keys such as runesmith.gitea/gitea.com/alice and runesmith.gitea/forgejo/codeberg.org/alice. Where no secret store is available, they go in a file only you can read, and the sign-in dialog says so. The list of accounts, without tokens, is in Runesmith's state folder. Sign Out deletes the account's token.

Git receives the token for the account's https:// remotes on its server, for the one command that needs it. The token never appears in command lines, logs or Git's configuration. SSH remotes, and remotes on servers you are not signed in to, use your own Git setup.

Open on and Copy Link work for HTTPS and SSH remotes on the server, with any port or path, such as git@gitea.com:alice/notes.git or ssh://git@git.example.com:2222/alice/notes.git. Files link to the branch, or to the commit when the revision is one, with the selected lines, such as https://gitea.com/alice/notes/src/branch/main/README.md#L4-L9.

Pull Requests shows each open pull request with its author, branches, review state and checks state; Checkout fetches its refs/pull/<number>/head ref. A pull request created as a draft gets the WIP: prefix in its title, which is how Gitea and Forgejo mark work in progress.

Settings​

SettingDefaultWhat it does
gitea.oauthClientIdsemptyThe client ID of the OAuth2 application registered for Runesmith on each Gitea server, as server=ID pairs separated by commas, such as gitea.com=1a2b3c4d, git.example.com=5e6f7a8b. An ID without a server is for gitea.com. Servers without an ID sign in with an access token.
forgejo.oauthClientIdsemptyThe same for Forgejo servers, such as codeberg.org=1a2b3c4d. An ID without a server is for Codeberg.

The sign-in dialog fills the setting in for you: without a client ID it offers Set up browser sign-in, which shows the steps and takes the client ID.

Register an OAuth2 application​

Browser sign-in needs an OAuth2 application for Runesmith on the server, registered once. Any account can register one for itself, and a server administrator can register one for every account in the site administration's Applications page.

  1. On the server, open Settings › Applications (/user/settings/applications) and find Manage OAuth2 applications.
  2. Set Application name to Runesmith and Redirect URIs to http://127.0.0.1/.
  3. Clear Confidential client: Runesmith is a desktop app and keeps no secret.
  4. Select Create application and copy the Client ID. Runesmith does not need the client secret.
  5. In Runesmith, paste the client ID in the sign-in dialog's Set up browser sign-in, or add server=ID to gitea.oauthClientIds or forgejo.oauthClientIds.

Gitea and Forgejo accept any port for a loopback redirect URI of a public client, so the one URI covers every sign-in. Use 127.0.0.1, not localhost. The detailed steps, including what each error means, are in Registering an OAuth2 application on Forgejo and Gitea.

Screenshots and tests​

Setting the environment variable RUNESMITH_GITEA_FAKE or RUNESMITH_FORGEJO_FAKE to signed-in or signed-out replaces every server of that service with made-up answers and accounts, so its screens can be shown and tested without a network or a real account. Browser sign-in then waits forever, and nothing is kept in the secret store. Never set it for real work: nothing reaches a server while it is set.