GitHub Actions: Best Practices


Dieses lebende Dokument dient als Sammlung von Best Practices für die Nutzung von GitHub Actions. Wenn du Vorschläge oder Ergänzungen hast, eröffne bitte einen Pull Request auf GitHub!

Sammlung von Best Practices

Timeouts für Workflows festlegen

Standardmäßig beendet GitHub Actions Workflows nach 6 Stunden, wenn sie bis dahin nicht fertig sind. Viele Workflows brauchen längst nicht so viel Zeit, aber manchmal treten unerwartete Fehler auf oder ein Job hängt, bis der Workflow-Lauf 6 Stunden nach seinem Start abgebrochen wird. Deshalb ist es empfehlenswert, einen kürzeren Timeout festzulegen.

Der ideale Timeout hängt vom einzelnen Workflow ab, aber 30 Minuten sind für die Workflows in Exercism-Repos normalerweise mehr als genug.

Das hat folgende Vorteile:

  • PRs hängen nicht den halben Tag in der CI fest, Probleme lassen sich früh erkennen oder Workflow-Läufe können neu gestartet werden.
  • Die Gesamtzahl paralleler Builds ist begrenzt; hängende Jobs verursachen keine Probleme für andere PRs, wenn sie früh abgebrochen werden.

Beispiel

jobs:
  configlet:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    steps:
      - [...]

Überlege, ob (Drittanbieter-)Actions wirklich nötig sind

Actions sollte man wie Abhängigkeiten in deiner Lieblingsprogrammiersprache1 behandeln: Sie sind Code, der von Dritten geschrieben wurde, außerhalb der Kontrolle von Exercism. Selbst wenn du den Autoren der Action vertraust, kann es zu einer feindlichen Übernahme des Repositories kommen, die diesen Leuten indirekt Zugriff auf Exercism-Repos verschafft, einschließlich Schreibzugriff.

Deshalb solltest du sorgfältig abwägen, ob eine neue Action wirklich sinnvoll ist oder ob es besser ist, den Code in eine (neue) Action unter der Kontrolle von Exercism zu verschieben.

Überlege auch, ob die Action aktiv gepflegt wird, z. B. indem du die aktuelle Repo-Aktivität prüfst oder sicherstellst, dass die Action zu einer Organisation und nicht zu einem einzelnen Account gehört.

Actions, die von GitHub oder der Exercism-Organisation veröffentlicht wurden, kann man in der Regel als (ziemlich) sicher einstufen und ohne besondere Bedenken einbinden.

Den Geltungsbereich des Workflow-Tokens einschränken

Standardmäßig hat das Zugriffstoken, das der Workflow erhält, weitreichende Berechtigungen, sowohl zum Lesen als auch zum Schreiben.

Das Prinzip der geringsten Berechtigung solltest du auch auf Workflows anwenden.

Du kannst für jeden Workflow einzeln festlegen, welche Berechtigungen er benötigt.

Beispiel

Wenn ein Workflow nur den Inhalt eines Repos lesen, aber nicht schreiben muss, z. B. weil er eine normale CI-Prüfung ist, kannst du das Token so einschränken:

permissions:
  contents: read

Die vollständige Liste der Berechtigungen findest du in den GitHub-Docs.

Actions an SHAs binden

Wenn du andere Actions verwendest, binde sie an einen Commit (über dessen SHA), nicht an einen Branch oder Tag. So wird jedes Mal derselbe Code ausgeführt, was beim Binden an einen Branch oder Tag nicht garantiert ist.

Das hat zwei Vorteile:

  1. Es macht deinen Build stabil
  2. Es hindert einen Angreifer daran, einen Branch/Tag so zu ändern, dass er auf bösartigen Code zeigt

Die einzige Ausnahme von dieser Regel könnten Actions sein, die wir (Exercism) selbst gebaut haben.

Den Commit-SHA finden

Normalerweise willst du an den Commit-SHA eines bestimmten Releases binden. Um den Commit-SHA eines Releases zu finden, gehst du auf die Releases-Seite des Action-Repositories (z. B. https://github.com/actions/checkout/releases). Suche das Release, das du verwenden willst, und klicke auf den Kurz-SHA (z. B. a12a394), der im Zusammenfassungsbereich links neben dem Release aufgeführt ist. Du wirst dann auf die Seite mit den Release-Details weitergeleitet, auf der der vollständige Commit-SHA steht, den du verwenden kannst.

Beispiel

- name: Checkout code
  uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846

Test-Runner an eine Version binden

Die meisten Workflows laufen auf den von GitHub unterstützten Runnern. Wenn du einen dieser Runner verwendest, nutze eine bestimmte Version statt der neuesten Version.

So läuft der Workflow immer auf demselben Runner, was deinen Build stabil macht.

Beispiel

Verwende:

runs-on: ubuntu-22.04

statt:

runs-on: ubuntu-latest

Überlege, ob du eine Concurrency-Strategie einrichten solltest

Oft ist es weder nötig noch sinnvoll, die CI auf Zwischen-Commits laufen zu lassen, wenn zwischenzeitlich ein neuerer Commit gepusht wurde.

Du kannst eine Concurrency-Strategie konfigurieren, um laufende Workflows im selben Kontext automatisch abzubrechen.

Beispiel

Um Zwischen-Builds in einem PR abzubrechen, kannst du die folgenden Concurrency-Einstellungen verwenden:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
Hinweis zu Drittanbietern

Das obige Beispiel basiert auf dem CI-Workflow von PkgTemplates.jl, veröffentlicht unter der MIT-Lizenz:

MIT License

Copyright (c) 2017-2020 Chris de Graaf, Invenia Technical Computing Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Überlege, welche Trigger wirklich nötig sind

Lies den Leitfaden „Security hardening for GitHub Actions“

Die oben genannten Praktiken sind keineswegs vollständig. Einen umfassenden Leitfaden zu guten Sicherheitspraktiken für die sichere Nutzung von GitHub Actions findest du in GitHubs Sicherheitsleitfaden.

Workflow-Checkliste

Mit der folgenden Checkliste kannst du prüfen, ob ein Workflow den Best Practices folgt. Die Checkliste erhebt keinen Anspruch auf Vollständigkeit, sondern konzentriert sich auf die wichtigsten Punkte.

Zum Kopieren und Einfügen, z. B. für PRs

  1. es sei denn, die Sprache nutzt das npm-Ökosystem. ↩