Skip to main content

Von CircleCI zu GitHub-Aktionen migrieren

GitHub Actions und CircleCI weisen mehrere Ähnlichkeiten in Bezug auf die Konfiguration auf, was die Migration zu GitHub Actions relativ einfach macht.

Einführung

CircleCI und GitHub Actions ermöglichen es Dir, Workflows zu erstellen, die Code automatisch bauen, testen, veröffentlichen, freigeben und bereitstellen. CircleCI und GitHub Actions haben einige Ähnlichkeiten in der Workflow-Konfiguration:

  • Workflow-Konfigurationsdateien werden in YAML geschrieben und im Repository gespeichert.
  • Workflows umfassen einen oder mehrere Jobs.
  • Jobs beinhalten einen oder mehrere Schritte oder einzelne Befehle.
  • Schritte oder Aufgaben können wiederverwendet und in der Community gemeinsam genutzt werden.

Weitere Informationen finden Sie unter Grundlegendes zu GitHub Actions.

Wesentliche Unterschiede

Betrachte bei der Migration von CircleCI folgende Unterschiede:

  • Die automatische Testparallelität des CircleCI gruppiert die Tests automatisch nach benutzerdefinierten Regeln oder historischen Zeitinformationen. Diese Funktionalität ist in GitHub Actions nicht eingebaut.
  • Aktionen, die in Docker-Containern ausgeführt werden, sind sensibel für Berechtigungsprobleme, da Container eine andere Zuordnung von Benutzern haben. Viele dieser Probleme lassen sich vermeiden, indem die USER-Anweisung nicht in Dockerfile verwendet wird. Weitere Informationen über das Docker-Dateisystem auf von GitHub gehosteten Runnern findest du unter Verwenden von auf GitHub gehosteten Runnern.

Workflows und Jobs migrieren

Bei CircleCI werden Workflows (workflows) in der Datei config.yml definiert. Dadurch lassen sich mehrere Workflows konfigurieren. Da GitHub eine Workflowdatei pro Workflow benötigt, müssen keine Workflows (workflows) deklariert werden. Für jeden in config.yml konfigurierten Workflow muss eine neue Workflowdatei erstellt werden.

Sowohl bei CircleCI als auch bei GitHub Actions werden Aufträge (jobs) in der Konfigurationsdatei mit einer ähnlichen Syntax konfiguriert. Wenn du Abhängigkeiten zwischen Aufträgen mithilfe von requires in deinem CircleCI-Workflow konfigurierst, kannst du die entsprechende needs-Syntax von GitHub Actions verwenden. Weitere Informationen finden Sie unter Workflowsyntax für GitHub Actions.

„Orbs“ (Gestirne) zu Aktionen migrieren

Sowohl CircleCI als auch GitHub Actions bieten einen Mechanismus, um Aufgaben in einem Workflow wiederzuverwenden und weiterzugeben. CircleCI verwendet ein Konzept namens „Orbs“ (Gestirne), das in YAML geschrieben ist, um Aufgaben bereitzustellen, die man in einem Workflow wiederverwenden kann. GitHub Actions hat mächtige und flexible wiederverwendbare Komponenten namens Aktionen, die man entweder mit JavaScript-Dateien oder mit Docker-Images erstellt. Um Aktionen zu erstellen, kannst du eigenen Code schreiben, der mit deinem Repository auf die gewünschte Weise interagiert und dabei beispielsweise in die APIs von GitHub und beliebige öffentlich zugänglichen Drittanbieter-APIs integriert. Beispielsweise kann eine Aktion npm-Module veröffentlichen, SMS-Warnungen senden, wenn dringende Probleme erstellt werden, oder produktionsbereiten Code bereitstellen. Weitere Informationen finden Sie unter Freigeben von Automatisierungen.

CircleCI kann Workflows mit YAML-Ankern und Aliasen wiederverwenden. GitHub Actions unterstützt die gängigsten Anforderungen im Hinblick auf die Wiederverwendbarkeit durch den Einsatz von Matrizen. Weitere Informationen zu Matrizen findest du unter Ausführen von Variationen von Aufträgen in einem Workflow.

Docker-Images verwenden

Sowohl CircleCI als auch GitHub Actions können Schritte innerhalb eines Docker-Images ausführen.

CircleCI stellt eine Reihe von vordefinierten Images mit üblichen Abhängigkeiten zur Verfügung. Bei diesen Images ist USER auf circleci festgelegt. Dies führt zu Berechtigungskonflikten mit GitHub Actions.

Wir empfehlen Dir, von vordefinierten CircleCI-Images zu wegzugehen, wenn du zu GitHub Actions migrierst. In vielen Fällen kannst du die zusätzlich benötigten Abhängigkeiten mithilfe von Aktionen installieren.

Weitere Informationen zum Docker-Dateisystem findest du unter Verwenden von auf GitHub gehosteten Runnern.

Weitere Informationen zu den Tools und Paketen, die in von GitHub gehosteten Runnerimages verfügbar sind, findest du unter Verwenden von auf GitHub gehosteten Runnern.

Variablen und Geheimnisse verwenden

CircleCI und GitHub Actions unterstützen das Setzen von Variablen in der Konfigurationsdatei und das Erstellen von Geheimnissen mit der Benutzeroberfläche von entweder CircleCI oder GitHub.

Weitere Informationen findest du unter Speichern von Informationen in Variablen und Verwenden von Geheimnissen in GitHub-Aktionen.

Caching

CircleCI und GitHub Actions bieten in der Konfigurationsdatei eine Methode an, um Dateien manuell im Cache zwischenzuspeichern.

Nachfolgend ein Beispiel für die Syntax in jedem System.

CircleCI-Syntax für das Zwischenspeichern

- restore_cache:
    keys:
      - v1-npm-deps-{{ checksum "package-lock.json" }}
      - v1-npm-deps-

GitHub Actions-Syntax für das Zwischenspeichern

- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}
    restore-keys: v1-npm-deps-

GitHub Actions hat kein Äquivalent zum „Docker Layer Caching“ („DLC“, im Cache auf Docker-Ebene zwischenspeichern).

Daten zwischen Jobs persistieren

Sowohl CircleCI als auch GitHub Actions bieten Mechanismen für die Persistierung von Daten zwischen Jobs.

Nachfolgend siehst du ein Beispiel in der Konfigurationssyntax von CircleCI und GitHub Actions.

CircleCI-Syntax zum Beibehalten von Daten zwischen Aufträgen

- persist_to_workspace:
    root: workspace
    paths:
      - math-homework.txt

...

- attach_workspace:
    at: /tmp/workspace

GitHub Actions-Syntax zum Beibehalten von Daten zwischen Aufträgen

- name: Upload math result for job 1
  uses: actions/upload-artifact@v4
  with:
    name: homework
    path: math-homework.txt

...

- name: Download math result for job 1
  uses: actions/download-artifact@v4
  with:
    name: homework

Weitere Informationen finden Sie unter Speichern und Freigeben von Daten aus einem Workflow.

Datenbanken und Service-Container verwenden

Mit beiden Systemen kannst du zusätzliche Container für Datenbanken, Zwischenspeicherung im Cache oder andere Abhängigkeiten einbinden.

In CircleCI ist das erste in der Datei config.yaml aufgelistete Image das primäre Image, welches benutzt wird, um Befehle auszuführen. GitHub Actions verwendet explizite Abschnitte: verwende container für den primären Container, und liste zusätzliche Container in services auf.

Nachfolgend siehst du ein Beispiel in der Konfigurationssyntax von CircleCI und GitHub Actions.

CircleCI-Syntax für die Verwendung von Datenbanken und Dienstcontainern

---
version: 2.1

jobs:

  ruby-26:
    docker:
      - image: circleci/ruby:2.6.3-node-browsers-legacy
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby26
          POSTGRES_PASSWORD: ""

    working_directory: ~/administrate

    steps:
      - checkout

      # Bundle install dependencies
      - run: bundle install --path vendor/bundle

      # Wait for DB
      - run: dockerize -wait tcp://localhost:5432 -timeout 1m

      # Setup the environment
      - run: cp .sample.env .env

      # Setup the database
      - run: bundle exec rake db:setup

      # Run the tests
      - run: bundle exec rake

workflows:
  version: 2
  build:
    jobs:
      - ruby-26
...

- attach_workspace:
    at: /tmp/workspace

GitHub Actions-Syntax für die Verwendung von Datenbanken und Dienstcontainern

name: Containers

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    container: circleci/ruby:2.6.3-node-browsers-legacy

    env:
      PGHOST: postgres
      PGUSER: administrate
      RAILS_ENV: test

    services:
      postgres:
        image: postgres:10.1-alpine
        env:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""
        ports:
          - 5432:5432
        # Add a health check
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      # This Docker file changes sets USER to circleci instead of using the default user, so we need to update file permissions for this image to work on GH Actions.
      # See https://docs.github.com/actions/using-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem

      - name: Setup file system permissions
        run: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: bundle install --path vendor/bundle
      - name: Setup environment configuration
        run: cp .sample.env .env
      - name: Setup database
        run: bundle exec rake db:setup
      - name: Run tests
        run: bundle exec rake

Weitere Informationen finden Sie unter Informationen zu Service-Containern.

Vollständiges Beispiel

Nachfolgend siehst du ein Beispiel aus der realen Welt. Auf der linken Seite ist die tatsächliche CircleCI-Datei config.yml für das Repository thoughtbot/administrator gezeigt. Die rechte Seite zeigt das Äquivalent unter GitHub Actions.

Vollständiges Beispiel für CircleCI

---
version: 2.1

commands:
  shared_steps:
    steps:
      - checkout

      # Restore Cached Dependencies
      - restore_cache:
          name: Restore bundle cache
          key: administrate-{{ checksum "Gemfile.lock" }}

      # Bundle install dependencies
      - run: bundle install --path vendor/bundle

      # Cache Dependencies
      - save_cache:
          name: Store bundle cache
          key: administrate-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      # Wait for DB
      - run: dockerize -wait tcp://localhost:5432 -timeout 1m

      # Setup the environment
      - run: cp .sample.env .env

      # Setup the database
      - run: bundle exec rake db:setup

      # Run the tests
      - run: bundle exec rake

default_job: &default_job
  working_directory: ~/administrate
  steps:
    - shared_steps
    # Run the tests against multiple versions of Rails
    - run: bundle exec appraisal install
    - run: bundle exec appraisal rake

jobs:
  ruby-25:
    <<: *default_job
    docker:
      - image: circleci/ruby:2.5.0-node-browsers
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""

  ruby-26:
    <<: *default_job
    docker:
      - image: circleci/ruby:2.6.3-node-browsers-legacy
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby26
          POSTGRES_PASSWORD: ""

workflows:
  version: 2
  multiple-rubies:
    jobs:
      - ruby-26
      - ruby-25

Vollständiges Beispiel für GitHub Actions

# Dieser Workflow verwendet Aktionen, die nicht von GitHub zertifiziert sind.
# Sie werden von einem Drittanbieter bereitgestellt und unterliegen
# separaten Nutzungsbedingungen, Datenschutzbestimmungen und Support
# Onlinedokumentation.

# GitHub empfiehlt, Aktionen an einen Commit-SHA anzuheften.
# Um eine neuere Version zu erhalten, musst du den SHA aktualisieren.
# Du kannst auch auf ein Tag oder einen Branch verweisen, aber die Aktion kann sich ohne Vorwarnung ändern.

name: Containers

on: [push]

jobs:
  build:

    strategy:
      matrix:
        ruby: ['2.5', '2.6.3']

    runs-on: ubuntu-latest

    env:
      PGHOST: localhost
      PGUSER: administrate
      RAILS_ENV: test

    services:
      postgres:
        image: postgres:10.1-alpine
        env:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""
        ports:
          - 5432:5432
        # Add a health check
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      - uses: actions/checkout@v4
      - name: Setup Ruby
        uses: eregon/use-ruby-action@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
        with:
          ruby-version: ${{ matrix.ruby }}
      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: administrate-${{ matrix.image }}-${{ hashFiles('Gemfile.lock') }}
      - name: Install postgres headers
        run: |
          sudo apt-get update
          sudo apt-get install libpq-dev
      - name: Install dependencies
        run: bundle install --path vendor/bundle
      - name: Setup environment configuration
        run: cp .sample.env .env
      - name: Setup database
        run: bundle exec rake db:setup
      - name: Run tests
        run: bundle exec rake
      - name: Install appraisal
        run: bundle exec appraisal install
      - name: Run appraisal
        run: bundle exec appraisal rake