# OneDev Abschließen möchte ich meinen Test mit einer weitgehend unbekannten Plattform, die erst 2019 als Hobbyprojekt von zwei Entwicklern veröffentlicht wurde, sich aber in Sachen Funktionalität nicht vor den anderen Plattformen verstecken muss: OneDev. ![OneDev homepage](./assets/onedev/homepage.png) OneDev ist in Java geschrieben und verwendet das Webframework Apache Wicket. Das Projekt wird hauptächlich von Robin Shen und Steve Luo entwickelt, insgesamt gibt es ca. 30 Beitragende. Das Projekt ist unter der MIT-Lizenz veröffentlicht. Der [erste Commit](https://code.onedev.io/onedev/server/~commits/6be8e3f97c97e44cf6b5a9b8360c299cc55388f6) erfolgte im April 2012, die erste in Git getaggte Version (2.0.0) wurde 2019 veröffentlicht. Rechnet man mit dem Datum des ersten Release, ist OneDev die jüngste der vier Plattformen, die ich getestet habe. OneDev besteht aus einer einzigen Java-Anwendung und erfordert bei Verwendung der eingebetteten HSQL-Datenbank keine zusätzlichen Dienste zum Betrieb. Es werden auch externe Datenbanken (MySQL, MariaDB, Postgres, MS SQL, Oracle) unterstützt. Getestet wurde die Version 8.5.2. ## Installation Die OneDev-Entwickler stellen Container-Images für OneDev zur Verfügung (`docker.io/1dev/server`), mit denen sich OneDev einfach mittels Docker installieren lässt. Alternativ gibt es auch die Möglichkeit, die Java-Anwendung direkt auf seinem System zu installieren oder OneDev in einem Kubernetes-Cluster zu betreiben. Für den Installationsprozess gibt es eine Schritt-für-Schritt-Anleitung auf der Dokumentationsseite des Projekts. Allerdings bin ich hiervon abgewichen, da in der Installationsanleitung empfohlen wird, den Docker-Socket (`/var/run/docker.sock`) im OneDev-Container als Volume einzubinden. Dies ist nur dann erforderlich, wenn der eingebaute _Server Docker Executor_ anstelle eines externen Agents für CI-Jobs verwendet wird. Da Container mit Docker-Zugriff effektiv über Root-Rechte auf dem Hostsystem verfügen, ist dies jedoch mit einem Sicherheitsrisiko verbunden. Deswegen empfehle ich, den eingebauten Agent nicht zu nutzen und stattdessen den seperaten Agent-Container (`docker.io/1dev/agent`) zu verwenden. Der CI-Agent sollte bei einem Produktionssetup auf einem anderen Server bzw. einer anderen VM laufen, auf der sich keine wertvollen oder sensiblen Daten befinden - insbesondere wenn nicht vertrauenswürdige Nutzer Zugriff auf das CI-System haben. [Hier](./assets/onedev/docker-compose.yml) ist die Docker-Compose-Datei, die ich für meine Testinstallation verwendet habe. Nach dem Start des Servers kann man auf der Weboberfläche den ersten Benutzeraccount anlegen und die URL des Servers konfigurieren. Anschließend muss noch das CI-System eingerichtet werden. Hierzu öffnet man den Menüpunkt _Administration_ \> _Agents_, klickt auf _Tokens_ und generiert sich einen neuen Agent Token. Dieser Token muss dem Agent als Umgebungsvariable übergeben werden (also z.B. in die Docker-Compose-Datei eintragen). Nach dem Start des Agents muss dieser in der Tabelle sichtbar sein. ![Agent setup](./assets/onedev/add_agent.png) Danach öffnet man den Menüpunkt _Job Executors_ und erstellt einen _Remote Docker Executor_. Damit ist die Einrichtung des CI-Systems abgeschlossen und man kann den ersten Build starten (siehe im Abschnitt [Continuous Integration](#continous-integration)). Standardmäßig erlaubt OneDev nur angemeldeten Benutzern den Zugriff auf die Instanz. Um seine Projekte öffentlich verfügbar zu machen, muss noch die Option _Security Settings_ \> _Enable Anonymous Access_ aktiviert werden. ## Systemanforderungen OneDev ist auf jedem System mit Java-Unterstützung lauffähig. Das offizielle Docker-Image wird für die 64bit Interl/AMD und ARM-Architektur angeboten. Der Server benötigte auf meinem System ca. 1.2GB Arbeitsspeicher, der CI-Agent ca. 180MB. Die CPU-Auslastung im Leerlauf beträgt auf meinem System (AMD Ryzen 5700G) ca. 1%, mit gelegentlichen Spitzen auf 5-10%. Aufwändige Git-Operationen (History/Blame in großen Repositories) können Lastspitzen von bis zu 100% mit einer Dauer von max. 2 Sekunden verursachen. Bei Nutzung der Suchfunktion habe ich bis zu 50% Auslastung gemessen. ## Bedienung OneDev verfügt über eine modern gestaltete Weboberfläche, die mit dem Webframework Apache Wicket realisiert wurde. Das Framework lädt beim Navigieren nur die Teile der Website vom Server, die sich durch den entsprechenden Navigationsschritt geändert haben (also z.B. die Dateiliste). Dadurch geht das Navigieren durch die Repositories sehr flüssig vonstatten, ohne dass die gesamte Seite neu geladen werden muss. Ein Alleinstellungsmerkmal von OneDev ist die Suchfunktion. OneDev verwendet nicht nur eine Textsuchmaschine, sondern analysiert den Code im Repository und bietet so die Möglichkeit, nach Klassen und Funktionen zu suchen. Die Suchergebnisse werden während dem Tippen angezeigt. Auf diese Weise kann man schnell durch komplexe Softwareprojekte navigieren. ![Suche](./assets/onedev/search.png) Die Suche kann auch über ein Kontextmenü in der Code-Ansicht aufgrufen werden. Auf diese Weise kann man nach Definitionen oder Verwendungen von Funktionen suchen. Es gibt auch eine Übersicht aller Klassen und Funktionen einer Datei auf der rechten Seite. Die Code-Analyse ist für die Sprachen Java, JavaScript, C, C++, CSharp, Go, PHP, Python, CSS, SCSS, LESS und R verfügbar. Rust wird leider nicht unterstützt. ![Code-Navigation](./assets/onedev/code_navigation.png) OneDev kann auf der Weboberfläche Code, Markdown-Dokumente und Bilder darstellen. Es gibt keine Unterstützung für alternative Markupsprachen wie RST. ## Import bestehender Projekte OneDev bietet einen Import-Assistenten mit Unterstützung für GitHub, Gitlab, BitBucket, und Gitea. Neben dem Git-Repository werden auch Metadaten und Issues übertragen. Der Importer erlaubt es auch, nach einer Authentifizierung per API-Key sämtliche Projekte eines Nutzers oder einer Organisation zu übertragen, was beim Umstieg viel Zeit sparen kann. Es gibt jedoch nicht die Möglichkeit, Projekte aus anderen OneDev-Instanzen zu übertragen. ## Zusatzfeatures OneDev verfügt über umfangreiche Tools zum Projektmanagement. Es gibt die Möglichkeit, Issues zu Meilensteinen zuzuordnen (z.B. _Sprint 14_ oder _Version 2.0_). Zudem verfügt OneDev über Issue Boards, um Issues je nach Status in mehreren Spalten anzuzeigen. ![OneDev Issue Board](./assets/onedev/kanban.png) Issues können bestimmten Entwicklern zugewiesen werden und es gibt die Möglichkeit, Abhängigkeiten zwischen Issues zu definieren (z.B. Issue A muss vor Issue B erledigt werden). Was allerdings fehlt ist die Möglichkeit, einem Issue mehrere Labels zuzuordnen. OneDev bietet auch die Möglichkeit, statische Webseiten zu hosten. Hierfür ist im Gegensatz zu Gitlab Pages keine separate Domain nötig. Stattdessen wird die Webseite im Unterverzeichnis `~site` des Repositorys (z.B. `https://example.com/user/repo/~site`) veröffentlicht. Als einzige getestete Plattform verfügt OneDev über ein Plugin-System. Auf diese Weise lassen sich neue Features implementieren, ohne die Software verändern zu müssen. Beispielsweise gibt es ein Plugin zum [Import von Issues](https://github.com/DevCharly/onedev-plugin-import-redmine/) aus der Projektmanagement-Anwendung Redmine. Weitere Zusatzfeatures wie Paketmanagement bietet OneDev nicht. Darüber hinaus fehlt die Möglichkeit, Releases seiner Software hochzuladen und mit Git-Tags zu verknüpfen. Dieses Feature beherrschen ansonsten alle getesteten Plattformen. ## Continous Integration OneDev bietet ein eingebautes CI-System um Projekte zu kompilieren und zu testen. Die Jobs können in Docker-Containern, Kubernetes-Pods oder bare metal ausgeführt werden. Jobs werden in einer yml-Datei definiert, die als `.onedev-buildspec.yml` im Wurzelverzeichnis des Repositories abgelegt werden muss. OneDev bietet jedoch auch eine Weboberfläche, um Builds zu erstellen und zu bearbeiten. Auf diese Weise muss man nicht zuerst die yaml-Syntax erlernen, um das CI-System zu nutzen. Über die Weboberfläche lassen sich bestimmte Aktionen (z.B. "Befehle ausführen", "Docker Image bauen", "Webseite veröffentlichen") auswählen und konfigurieren. ![CI-Editor](./assets/onedev/ci_editor.png) ```yml version: 23 jobs: - name: test steps: - !CheckoutStep name: checkout cloneCredential: !DefaultCredential {} withLfs: false withSubmodules: false condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL - !CommandStep name: build runInContainer: true image: rust:latest interpreter: !DefaultInterpreter commands: - rustup component add rustfmt clippy - cargo fmt --all --check - cargo clippy --all --features=rss -- -D warnings - cargo test --features=rss --workspace useTTY: false condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL triggers: - !BranchUpdateTrigger {} - !PullRequestUpdateTrigger {} retryCondition: never maxRetries: 3 retryDelay: 30 timeout: 3600 ``` Die Builds können durch Branch Updates oder neue Pull Requests ausgelöst werden. Es gibt auch die Möglichkeit, Builds zeitgesteuert oder manuell zu starten. ## Öffentliche Instanzen Das OneDev-Team betreibt ihre eigene Instanz unter [code.onedev.io](https://code.onedev.io). Allerdings verbietet diese Instanz das erstellen eigener Projekte und dient nur der Entwicklung und Demonstration der Plattform. Darüber hinaus habe ich außer einer kleinen privaten Instanz names ["Winux Projects"](https://projects.winux.it/) keine öffentlichen Instanzen gefunden, was sicher auch daran liegt, dass das Projekt momentan noch relativ unbekannt ist. ## Fazit Obwohl OneDev noch relativ jung und weitgehend unbekannt ist, kann es funktional durchaus mit den Konkurrenten mithalten. Insbesondere die intelligente Suchfunktion und das einfach zu bedienende CI-System haben mir im Test sehr gut gefallen. Allerdings ist OneDev immer noch ein Hobbyprojekt von 2 Entwicklern und hat keine Firma oder größere Organisation hinter sich. Wer OneDev beispielsweise in einem Unternehmen einsetzen möchte, muss die Einrichtung und den Support selbst übernehmen, da es im Gegensatz zu GitLab und Gitea keine öffentlichen Instanzen oder SaaS-Angebote gibt. Wer sich hieran nicht stört, erhält mit OneDev eine leichtgewichtige, einfach zu installierende und moderne Git-Hosting-Plattform. ## Quellen - Projektseite - Repository