~ololduck/Frogue
Frogue 🐸
Frogue is destined to be a ForgeFed-enabled software forge.
It doesn't have the all the blingy stuff ForgeJo/Gitea have, but it's pretty fast and low-cpu. It's also very alpha-stage software (did you know that the existence of alpha software stems in fact from observation of non-free software? Modern science postulates that free software doesn't exhibit the same behaviour, making the whole alpha software theory possibly moot).
There was once IronBridge, which was a pretty advanced unreleased ForgeFed project, but it became too messy and undocumented to really be viable. But then i still wanted to create a software forge for my own use. So i started Frogue as a rewrite with many copy-pasting from this earlier project. But then i thought that it would still be great to be able to use the forge with ForgeFed, so i started implementing the ForgeFed concepts on top of what i already did.
Forge features
- Host public/private git repositories;
- Browse files;
- SSH interface to push commits;
- Show commits history;
- Propose/Merge sets of changes (Patch Proposals);
- Report bugs;
- Teams/groups;
- Permissions (current model: owner has all rights, logged-in users some rights, guest users no rights);
- Repository Activity feed;
- Notifications;
- Deploy keys;
Out of scope
These are features that are not considered planned, either at the moment or ever.
- CI/CD (hooks are still planned so you can notify your favorite CI system)
- Releases: use tags.
- Pages: no web hosting.
- ???
Federation status
So, it's still heavily a work in progress but when Federation support is enabled you:
- Have a fediverse handle (e.g.,
@alice@forge.example.org) - Publish notes that appear in their followers' feeds
- Receive follows, likes, and announces from other ActivityPub-compatible platforms
- Create and federate tickets across ForgeFed-compatible forges
- Submit patches (merge requests) via federation from remote repositories
- Federate ticket and patch discussions as ActivityPub conversations
You enable Federation by setting FROGUE_PUBLIC_URL. So in the previous example, FROGUE_PUBLIC_URL=https://forge.example.org.
Honestly i'm not sure what happens if you don't enable federation. I started without the idea of requiring Federation to use the forge but i've spent so much time re-implementing ForgeFed i'm not entirely sure it works without.
There's lots of tests but as everybody knows, even having 100% coverage doesn't guarantee anything.
Current limitations
Mhhhhh phew that's kind of a hard one. Basically everything apart from the stuff specified ?
Repositoriesand theirPatchTracker/IssueTrackerare kinda implemented- No moderation: you can't block/silence/defederate users/instances for now
- mentions and stuff beyond basic Like/Announce are not yet supported
- ForgeFed & ActivityPub's integration tests work and AP successfully interacts in the real world but it's still a bit early. I have no doubt i'll see some really weird stuff.
- I'll make a more complete precise list of supported actors/activities later.
Installation
For now, it's very roots:
-
Clone this repository;
cdinto it -
run
make. This will download the internet and produce a binary attarget/release/frogue. It is heavily recommended you copy this binary to a "static" path: it should not change, as this path is also used by git hooks when receiving commits. Runningsudo make installwill put this binary at/usr/local/bin/frogue. -
Run this binary with the appropriate envvars: See lib.rs. One setup i'd recommend is running via systemd with a
Serviceunit file that looks like this:# /etc/systemd/system/frogue.service [Unit] Description=Frogue ForgeFed server After=network-online.target Wants=network-online.target [Service] Type=exec # of course, you need to create the UNIX user User=git Group=git WorkingDirectory=/var/lib/frogue EnvironmentFile=/etc/frogue/frogue.env ExecStart=/usr/local/bin/frogue Restart=on-failure RestartSec=5 # /var/lib/frogue, created and chowned to git: automatically. StateDirectory=frogue StateDirectoryMode=0750 # Hardening NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictNamespaces=yes RestrictRealtime=yes RestrictSUIDSGID=yes LockPersonality=yes MemoryDenyWriteExecute=yes [Install] WantedBy=multi-user.target/etc/frogue/frogue.envcould look like this:# /etc/frogue/frogue.env # Federation / public identity FROGUE_PUBLIC_URL=https://forge.example.com # HTTP, localhost only; use nginx/certbot to terminate TLS connections FROGUE_BIND_ADDR=127.0.0.1:6565 # SSH — bound directly, advertised as git@example.com:2222 FROGUE_SSH_BIND_ADDR=0.0.0.0:2222 FROGUE_SSH_HOST=example.com:2222 FROGUE_SSH_USER=git FROGUE_SSH_HOST_KEY=/var/lib/frogue/ssh_host_ed25519_key # Storage FROGUE_REPO_ROOT=/var/lib/frogue/repos FROGUE_DATABASE_URL=sqlite:///var/lib/frogue/frogue.sqlite?mode=rwc # Generate once: openssl rand -hex 32 # Without it, every restart invalidates all browser sessions. FROGUE_SESSION_SECRET=changemechangemechangemechangemechangemechangemechangeme # Invite-only registration FROGUE_REGISTRATION_MODE=invite_only # Optional tuning: #FROGUE_INVITES_VALIDITY_SECONDS=172800 #FROGUE_INVITES_ALLOWED_PER_DAY=5 # Telemetry that can be useful if you want to inspect traces. i use jaeger. no personal data saved. # OTEL_TRACES_EXPORTER=otlp # OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 # example if you use local jaeger # OTEL_SERVICE_NAME=frogue # OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production -
check everything works.
Configuration is done via envvar, you can view a list of them and their defaults in the first lines of frogue/src/lib.rs.
As a side note: there's currently no way to proxy ssh connections.
Contributing
Well, frankly, i need help. I'm no graphic designer, i have Chaotic Brain Syndrome (that's when oh a squirrel) and so there's probably lots of bugs and inconsistencies. I try to note them down in TODO.md when i notice them but sometimes i'm too into the zone to think of it, or i've seen it so many times already that i don't notice it anymore.
The code is a bit of a mess, but as <pe> on Libera.chat said: You can always deslop your human slop later
. So i still publish it.
So. You can contribute by:
- Filing issue reports (if the issue filing is broken, you can also contact me on the Fediverse at
@ololduck@vit.am) or you can find me in the#froguechannel on Libera.Chat. - You can contribute code! (Well, in theory. It's possible you can't contribute code because registrations are closed and that i haven't yet implemented ForgeFed's
Patchsupport, or myriad of other reasons). This project especially needs a graphical identity/consistency, but every code contribution is welcome. - Documentation! Docs are great and this early i don't have much. To be honest i'm not sure writing heavy docs is such a good idea at the moment since it's still very early.
- Just being interested a talking about this project, it's a great motivator!
FAQ
Why the name Frogue?
Because i like frogs 🐸, that "forge" and "frog" are similar and that the combination of a frog and the style of the Vogue magazine was hilarious to me at the time.
As for why not 🦆 ducks, since i am also fond of them: it's simply because the duck emoji 🦆 is way less cute than the frog one 🐸.
Are LLMs ("AI") used in this project?
TL;DR: Yes they are.
A local LLM (llama3.2, via llama-cpp) has been used for commits messages and many docstrings (/// comments in Rust), as well as some comments. I'm not the most orderly of people and LLMs have helped me make a bit of sense in this chaotic brain of mine. Or at least help me remember stuff by putting it in context.
I've long pondered the ethical and political considerations of LLMs, and i've come to the (admitedly self-indulgent) opinion that local LLM use of "small" models was "kind of OK for natural language/descriptive stuff". I've also pondered about energy consumption and did some math and realised that boiling the water for my morning coffee was still more expensive (as raw energy) than running llama3.2 on my graphic card at home. So yeah, in the end, i rationalized that using LLMs to make this project more accessible both for myself and potential contributors was the right thing to do.
That doesn't mean i don't wish for more ethical LLM creation and use or condone the current LLM ecosystem (capitalistic, neo-liberal society, really) as well as it doesn't solve the ecological considerations of widespread LLM use. Also, widespread public data use should produce public results.
And if you (who am i kidding? you will) spot non-sensical/convoluted/weird code, that's my fault. Sorry. (Legal) Drugs have been involved.