Blog @ herzog.network

Jekyll und GitHub Actions: Source Code in private Repository auslagern

“Ich denke, dass jede allgemein nützliche Information frei sein sollte. Mit ‘frei’ beziehe ich mich nicht auf den Preis, sondern auf die Freiheit, Informationen zu kopieren und für die eigenen Zwecke anpassen zu können. Wenn Informationen allgemein nützlich sind, wird die Menschheit durch ihre Verbreitung reicher, ganz egal, wer sie weiter gibt und wer sie erhält.”

- Richard Stallman

Wer sein Wissen teilt, verschenkt nichts und muss nicht befürchten, dass andere ihn dadurch überholen. Manchmal ist es allerdings notwendig Informationen zu schützen. Diese Informationen sind in der Softwareentwicklung unter anderem der Source Code, den man aus verschiedenen Gründen schützen möchte.

  • Entwürfe oder “WiP Code” sollen nicht veröffentlich werden
  • Material Dritter / Lizenzierter Code muss geschützt werden

Dieses Vorgehen schützt unseren Source Code nicht vor Wiederverwendung. Bei clientseitigen Skriptsprachen, die von Jekyll verwendet werden, muss die Sprache vom Webbrowser interpretiert werden. Die Daten müssen beim Webbrowser ankommen. Diese Daten kann man auf mehrere Arten und Weisen abfangen, manchmal bietet der Browser sogar Möglichkeiten an, auf den Quellcode zuzugreifen. Um seinen Code effizient zu schützen nutzt man das Urheberrecht und entsprechende Lizenzierungen.

Wichtig zu wissen ist auch, dass GitHub bereits die Funktionalität bietet, seine über GitHub Pages gehostete Webseite, in einer privaten Repository zu erstellen. Dadurch ist der Source Code privat und GitHub Pages wird ausschließlich die Webseite bauen und veröffentlichen. Diese Funktionalität bietet allerdings nur der Pro Plan von GitHub. Die hier beschriebene Vorgehensweise kann auch im Free Plan eingesetzt werden. Da wir unsere Webseite über GitHub Actions, mit einem selbst konfigurierten Build Agent, generieren lassen, unterliegen wir auch nicht den Beschränkungen, denen durch GitHub Pages generierte Webseiten unterliegen.

GitHub Pages cannot build sites using unsupported plugins. If you want to use unsupported plugins, generate your site locally and then push your site’s static files to GitHub.

Abhängigkeiten

Jekyll Projekt

Dieser Beitrag setzt voraus, dass ein vorhandenes Jekyll Projekt existiert. Sollte solch ein Projekt nicht bestehen, dann kann man aus meinem Blogeintrag - Jekyll und GitHub Pages: Deine erste Webseite entsprechende Informationen beziehen, wie ein Jekyll Projekt initialisiert wird.

GitHub Token

Um die durch Jekyll generierten Daten aus unserem Source Code von der privaten zur öffentlichen Repository zu übertragen benötigen wir einen Token mit Schreibrechten auf unsere Repositories und Rechten auf den Workflow zuzugreifen. Wie solch ein Token erstellt wird kann den GitHub Docs entnommen werden. Den erhaltenen Token brauchen wir um im nächsten Schritt ein sogenanntes Secret für die private Repository zu erstellen. Die Rechte für den Token sehen wie folgt aus:

github-access-token.png

Private GitHub Repository

Die Repository für den Source Code wird als private Repository erstellt.

create-private-repository

Und das lokal vorliegende Jekyll Projekt mit der erstellten Repository initalisiert.

cd dir/of/your/jekyll/site
git init
git add .
git commit -m "first commit"
git branch -M master
git remote add origin https://github.com/herzog-network/jekyll_source.git
git push -u origin master

Abschließend muss noch ein Secret für die Respository erstellt werden. Der Name des Secret lautet JEKYLL_TOKEN und der Inhalt ist der Token, der im Abschnitt GitHub Token, erstellt wurde. Mit diesem Secret können wir uns im Workflow, nachdem die Webseite generiert wurde, gegenüber der öffentlichen Repository authentifizieren und die generierten Daten übertragen. Unser Token wird als Secret verschlüsselt und ist in den Build Logs des Workflow nicht zu sehen. Weitere Informationen zu den GitHub Action Secrets.

github-repo-secret

Public GitHub Repository

Die durch Jekyll generierte Webseite wird in einer öffentlichen Repository abgelegt. Die Voraussetzungen für die Erstellung dieser Repository habe ich bereits in diesem Beitrag beschrieben. Abweichend von dieser Beschreibung wird die Source Directory für die GitHub Page angepasst und auf docs/ festgelegt.

github-pages-repo-source

GitHub Actions

Aktuell weist der beschriebene Aufbau noch keine Logik auf, die unser Jekyll Projekt, innerhalb der privaten Repository, baut und in die öffentliche Repository überträgt. Zu diesem Zweck kommen GitHub Actions zum Einsatz.

GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.

Um einen Job innerhalb eines GitHub Workflow auszuführen benötigen wir in unserem Projekt eine entsprechende Workflow Struktur und eine YAML Datei die die Schritte, zur Ausführung innerhalb des Job, beschreibt.

cd dir/of/your/jekyll/site
mkdir -p .github/workflows
touch .github/workflows/jekyll-build.yml

Untenstehend habe ich den Code meiner jekyll-build.yml Datei bereitgestellt. Diese kann nach Belieben angepasst werden. Zwingend angepasst werden müssen die Werte REPO_URL, REPO_NAME, USER und E_MAIL, die als Environment Variablen für den Job gesetzt sind. REPO_URL und REPO_NAME müssen mit den Werten der öffentlichen Repository angepasst werden.

name: jekyll-build

on:
  push:
    branches:
      - master

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - name: Check out
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Install
        run: |
          sudo gem install jekyll
          sudo gem install bundler -v '2.1.4'
          sudo bundle -v
          sudo bundle install
      - name: Clean up
        run: |
          if [ -d "_site" ]; then
            rm -rf _site/*
          fi
      - name: Build
        run:
          bundle exec jekyll build -d _site
      - name: Deploy
        env:
          JEKYLL_TOKEN: ${{ secrets.JEKYLL_TOKEN }}
          REPO_URL: github.com/herzog-network/herzog-network.github.io.git
          REPO_NAME: herzog-network.github.io
          USER: herzog-network
          E_MAIL: 75946937+herzog-network@users.noreply.github.com
        run: |
          mkdir build && cd build
          git clone https://$USER:$JEKYLL_TOKEN@$REPO_URL
          cd $REPO_NAME && cp -r ../../_site/* docs/
          git config user.name "${GITHUB_ACTOR}"
          git config user.email "$E_MAIL"
          git add .
          git commit -m "jekyll-build: ${{ github.event.head_commit.message }}"
          git push https://$USER:$JEKYLL_TOKEN@$REPO_URL

Sobald die lokale Repository vorbereitet ist und in die private GitHub Repository übertragen wird, generiert der definierte Workflow unsere Jekyll Webseite und überträgt alle Daten in unsere öffentliche Repository, über die GitHub Pages unsere finale Webseite bereitstellt. In dem öffentlichen Repository befindet sich nun ein Ordner Docs, mit allen durch Jekyll generierten Daten. Der Source Code bleibt in der privaten Repository und ist somit vor ungewollten Einblicken geschützt.


So long -
herzog


Hast du Fragen oder Anregungen?
Erstelle ein Ticket auf GitHub, frag mich auf Twitter oder
schreib mir eine E-Mail.