🐸 Frogue(Fed)

~ololduck/Frogue

Raw

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 ?

  • Repositories and their PatchTracker/IssueTracker are 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:

  1. Clone this repository; cd into it

  2. run make. This will download the internet and produce a binary at target/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. Running sudo make install will put this binary at /usr/local/bin/frogue.

  3. Run this binary with the appropriate envvars: See lib.rs. One setup i'd recommend is running via systemd with a Service unit 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.env could 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
    
  4. 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 #frogue channel 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 Patch support, 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.