Skip to content

Contributing

Für Personen, die im Repository von dsslab-net-bench committen wollen, wurde sich auf folgende Prinzipien und Grundlagen geeinigt.

IMPORTANT: Comunicating changes in this repository

Communication is an important principle for us as it prevents backtracking decisions and frustrating developers along the way. To achieve this we collectively decided on the following usage of the tools provided through Git and Gitlab:

  • Issues are for either describing a problem or proposing a new feature. They should have a clear and understandable title. Their description can be short but should include a long enough text which should make the proposal understandable to all participants. Bug reports should contain a way of reproducing the error. Feature requests should contain a draft of the expected API and usage context.
  • Merge Requests are for discussing and introducing changes. Tracking your thought processes can be done in the description or in the comments. People are invited to leave their feedback and discuss the proposed changes. MRs should include a proposed design and a corresponding documentation. Commits inside MRs can be messy as long as it is set to draft. Clear up your Git history before setting it to "ready".
  • Commits are for communicating decisions. Commit description can and should be used to communicate the decisions from the MRs. Corresponding MRs can be referenced through the known notation (!xx). The merging person should take care to not squash said commits during the merge into main.

To prevent email spam from the repository, isolated changes that do not affect the work of others can be merged by those in a leading position. Minor things (like documentation, wording or formatting) can be directly merged as well by Shay or David. Henrik and Paula focus solely on development and not on the reviewing processes. In case review by junior developers is required it will be mentioned in a meeting beforehand and we will be specific about our tasks towards Henrik and Paula.

Issues

Issues sollten vorzugsweise einen englischen Titel erhalten, der Inhalt kann auf deutsch sein. Das hat den Zweck, dass falls MRs über die GUI von Gitlab erzeugt werden, dann die entsprechenden MR-Titel und Branches ebenfalls englische Titel erhalten.

Issues sollten nach Möglichkeit eine sinnvolle und zielführende Beschreibung enthalten. Falls möglich, ist ein kurzes Beispiel oder eine Lösungsvorschlag anzugeben.

Wer sich ein Issue zuweist oder zugewiesen ist, kümmert sich selbstständig um dieses. Bei Rückfragen oder Hilfe pingt die entsprechenden Leute an.

Merge requests

Hier gelten ähnliche Regeln wie für Issues. Bitte auf einen sinnvollen Titel auf Englisch achten ("Resolve XYZ" ist nicht aussagekräftig). Auch hier sollte eine kurze Beschreibung des Lösungsansatzes aufgeführt sein, entweder auf Deutsch oder Englisch.

Falls andere Personen beteiligt sind, bitte mit der @-Notation verlinken. Für ein Review bitte die entsprechende Person auswählen. Das Review wird durchgeführt, sobald ihr den Draft-Status auf eurem Issue entfernt habt.

Verwendung von Branches

Branches werden meist in Zusammenhang zu Issues angelegt. Branches sollten einen sinnvollen Namen haben. Die automatische Erzeugung einer MR mit einem Branch von Gitlab funktioniert dafür eigentlich sehr gut.

Git commits

Committet bitte regelmäßig (pimaldaumen einmal in der Stunde) und pusht am Ende eurer Arbeit, auch wenn eure Änderungen möglicherweise zu fehlschlagenden Tests führen. Das macht es anderen Entwickler:innen einfacher, Änderungsvorschläge zwischendurch zu machen oder bei Hilfe schnell zu unterstützen.

Git commit messages

Git commit messages werden transparent und zugänglich gestaltet. Details dazu lassen sich hier nachlesen: https://cbea.ms/git-commit/ Konkret listet der Artikel folgende Richtlinien (auf Englisch):

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how

Konkret sieht eine ausführliche Commit message dann wie folgt aus:

Summarize changes in around 50 characters or less

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like `log`, `shortlog`
and `rebase` can get confused if you run the two together.

Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.

Further paragraphs come after blank lines.

 - Bullet points are okay, too

 - Typically a hyphen or asterisk is used for the bullet, preceded
   by a single space, with blank lines in between, but conventions
   vary here

If you use an issue tracker, put references to them at the bottom,
like this:

Resolves: #123
See also: #456, #789

Bitte haltet euch daran, ansonsten kann eure MR abgelehnt werden.

Git rebase

Gewisse Grundkenntnisse von Git werden vorausgesetzt. Dazu gehören insbesondere der Umgang mit Branches (s.o.), Commit/Staging und Rebasing.

Rebasing sollte immer gegenüber Merges für das Updaten von Branches vorgezogen werden. Zum Thema Rebasing findet ihr für die IDE (und allgemein) hier einen guten Überblick zu Konzepten und der Verwendung: https://www.jetbrains.com/help/pycharm/apply-changes-from-one-branch-to-another.html#rebase-branch

Rebasing ermöglicht auch mit dem interactive rebasing ein Umschreiben der eigenen Historie. Verwendet dies bitte nur in eurem lokalen Branch, da das schnell zu Problemen führen kann, wenn andere auf eurem Branch arbeiten: https://www.jetbrains.com/help/pycharm/apply-changes-from-one-branch-to-another.html#interactive-rebase

Personen, die kein PyCharm nutzen, lesen sich bitte selbst in Rebasing und interactive rebase ein.

Bei Fragen oder auftretenden Problemen steht David gerne zur Verfügung.

Entwicklungsumgebung

Es gibt für die Entwicklung zwei Möglichkeiten, wie die Abhängigkeiten installiert werden können. Das ist deshalb kompliziert, weil wir auf Graphviz als separate Abhängigkeit zugreifen. Graphviz ist nicht in Python als Package vorhanden, sondern muss über das Paketmanagement des jeweiligen Betriebssystems installiert werden. Entweder kann also Graphviz global installiert werden oder wir installieren es in die jeweilige Ordnerumgebung. Erstere Variante ist die einfachere, zweitere ist deutlich komplizierter. In beiden Fällen muss das Repository geclont werden.

Variante 1

Für das Management der Abhängigkeiten nutzen wir Poetry. Falls du das Tool noch nicht kennst, lies bitte zuerst den Abschnitt für die grundlegende Nutzung. Für die Installation auf deinem System siehe bitte hier. Nachdem das erledigt ist, manövriere im Terminal deiner Wahl in das geclonte Verzeichnis von dsslab-net-bench. Darin führe Folgendes aus:

poetry install --all-extras --with=dev

Das installiert neben den standardmäßigen Abhängigkeiten auch pygraphviz und alle für die Tests nötigen Abhängigkeiten in deine lokale Umgebung. Danach sollte folgender Befehl im Terminal euch eine Version für pytest wiedergeben:

poetry run pytest --version
> pytest 7.2.1

Danach hast du alle nötigen Tools, um mit der Entwicklung zu beginnen. Sollte irgendetwas nicht funktionieren, wende dich bitte an David. Viel Erfolg!

Variante 2

Dafür nutzen wir experimentell devenv, ein Tool zur Erzeugung deklarativer und reproduzierbarer Umgebungen über die Grenzen einer Programmiersprache hinaus. Im Inneren umschließt es aber ebenso den Poetry Package Manager.

Warnung: Für Einsteiger:innen empfiehlt sich diese Methode eher weniger. Vorhandene Kenntnisse in der Kommandozeile sind für diese Methode Voraussetzung.

  1. Zuerst den Nix Paketmanager installieren (https://nixos.org/download/).
  2. Relevante Konfiguration für Flakes aktivieren:
    mkdir -p ~/.config/nix
    echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
    
  3. Repository von dsslab-net-bench clonen
  4. cd <repository> und dann nix develop --impure. Das installiert alle benötigten Abhängigkeiten.
  5. [OPTIONAL] Nutze direnv für die automatische Aktivierung der Umgebung.

Type hinting

We use type hinting in this project to provide clarity for both users and developers. For Users, type hinting helps to understand what kind of information is expected when calling methods from our project. We, as developers, utilize type hinting to avoid bugs due to type errors.

Formatting and Linting

We adhere to the recommendations set by PEP8 and PEP257. Several tools are helping us in achieving this: Pylint, docformatter and Black. Pylint and docformatter are installed with the dev group through Poetry, Black needs to be globally installed through your local package manager.

Pylint

Running pylint on a file returns hints about improvements or problems with the given code (Doc). Executing is rather straightforward and will give you a list of recommendations:

# Inside the root of the repository
pylint dsslab/net_bench
# Executing single modules is also possible
pylint dsslab/net_benchinputs.py

Integrations for IDEs are available.

Docformatter

Black does not touch docstrings so these require a separate tool: docformatter. The configuration is already done through the pyproject.toml. Running it is as easy as:

docformatter dsslab/net_benchinputs.py
# Using the -i flag will apply the configuration
docformatter -i dsslab/net_benchinputs.py

Achtung: An integration for PyCharm exists: https://docformatter.readthedocs.io/en/latest/usage.html#use-as-a-pycharm-file-watcher

Black

Running Black on a file will reformat the file or directory:

black path/to/file_or_directory
# Setting the flag --check will show a preview of potential changes
black --check path/to/file_or_directory

Please put Black changes in a separate commit after everything else is done.

Dokumentation

Falls die Dokumentation geändert werden soll, so muss dafür mkdocs installiert sein (Das sollte ohnehin der Fall sein, wenn die Gruppe dev über poetry installiert wurde. Danach in der Kommandozeile im Repo einfach Folgendes eingeben:

mkdocs serve

Das sollte die Dokumentation erstellen und sie unter localhost:8000 bereitstellen. Normalerweise öffnet sich der Browser mit der Seite automatisch. Sollte das nicht der Fall sein, einfach http://127.0.0.1:8000 ansteuern. Die Seite hat einen automatischen Reload, Änderungen in den .md-Dateien sollten also sofort sichtbar sein.

Tests

Tests mit Abbildungen

Für Tests mit Abbildungen nutzen wir pytest-mpl, ein Plugin von Pytest von Matplotlib. Damit können automatisiert Bilder mit einer sogenannten "baseline" verglichen werden.

Wenn das Projekt bereits mittels Poetry installiert wurde (mit --with=dev), sollte das Plugin bereits zur Verfügung stehen.

Um eine neue Abbildung zu der bestehenden Baseline hinzuzufügen, muss folgender Befehl ausgeführt werden:

poetry run pytest --mpl-generate-path=tests/baseline tests/test_draw.py::test_draw_labels

Dies erzeugt eine neue Abbildung für die Funktion test_draw_labels in der Datei ./test/test_draw.py. Natürlich kann auch eine vollständiges Modul für die Baseline angegeben werden, indem das Suffix für die Methode weggelassen wird. Unveränderte Abbildungen werden nicht überschrieben.

Zum Debugging wird nach Abschluss der Tests (unabhängig vom Erfolg) ein Abschlussbericht in Form einer HTML-Datei erstellt. Diese stehen im Gitlab-Interface über Build - Pipelines - rechts unter dem Knopf "Artefakte herunterladen" zum Download als .zip zur Verfügung und können lokal eingesehen werden.

Sollen derlei Reports lokal erstellt werden, ist das über folgenden Befehl möglich:

poetry run pytest --mpl --mpl-results-path=results --mpl-generate-summary=basic-html

Damit werden alle Tests durchlaufen und der Bericht im Unterordner ./results/ im Repo abgelegt. Darin die HTML-Datei einfach im Browser öffnen.

Tokens

Für die Verschlüsselung bevorzugen wir age, eine moderne und sichere Implementierung vom ehemaligen Hauptverantwortlichen für Kryptografie bei Google.

Die Passwortdateien werden dabei mit dem öffentlichen SSH-Schlüssel verschlüsselt. Den jeweils aktuelle SSH-Schlüssel erhaltet ihr via Gitlab Keys. Bei mir ist das dann unter folgender Adresse zu finden: https://gitlab.rrz.uni-hamburg.de/bax8491.keys

Bitte hinterlegt dazu eure SSH-Schlüssel in Gitlab.

Installation

Ist in der README von Age für alle Betriebssysteme verlinkt.

Vorgehensweise

Verschlüsselung

Erstellt eine Textdatei, die Zugangsdaten enthalten. Ich mache das hier über die Kommandozeile, aber denkt daran, dass die Logs also eure Passwörter enthalten.

echo hunter3 > password-file.txt

Jetzt wollen wir diese Datei für David verschlüsseln:

curl "https://gitlab.rrz.uni-hamburg.de/bax8491.keys" | age -R - --output password.age password.txt

password.age könnt ihr jetzt verschicken.

Entschlüsselung

Jetzt kann David die Datei mit seinem SSH-Schlüssel entschlüsseln:

age -i ~/.ssh/id_ed25519 -d password.age
Und erhält den Output direkt ins Terminal. Übertragt die enthaltenen Daten bitte in euren Passwordmanager (Ihr nutzt doch einen, oder? ;)

Verschlüsselung an mehrere

Age erlaubt mit der -R Flagge, dass eine Empfängerliste übergeben werden kann. Empfängerliste sollten pro Zeile einen SSH-Schlüssel enthalten, mit # beginnende Zeilen werden ignoriert.

age -R recipients.txt --output password.age password.txt

Möglicher Inhalt der recipients.txt:

# Davids Schlüssel
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDagPDACR7SyPSt8WCXy9RG2eT6kTrRryFLVVxLeUjh5

Weiteres

Richtet einen SSH-Key auf Gitlab ein, falls noch nicht vorhanden, sodass euch andere verschlüsselte Dateien schicken können.

Bitte lest die sehr informative Man-Page von age für weitere Anwendungsfragen. Für Intergrationen in Yubikeys und GUIs siehe hier: https://github.com/FiloSottile/awesome-age