Wie kann ich die Dokumentation mit Github Pages synchronisieren?

81

Ich habe ein Projekt zusammen mit mehreren Personen und wir haben eine README.mdDatei mit einer Reihe von GitHub Flavored Markdown, die auf unserer GitHub-Seite gerendert wird. Wir haben auch einen GitHub Pages-Zweig eingerichtet, der unter der Subdomain unserer GitHub-Organisation gehostet wird, und den automatischenREADME.md Seitengenerator verwendet, der beim Erstellen unserer Seite einfach in unsere Datei geladen wird. Ich stelle jedoch fest, dass beim Aktualisieren unserer README.mdDatei die Projektseite nicht aktualisiert wird. Stattdessen müssen wir zur Registerkarte GitHub-Einstellungen gehen und die Projektseite neu erstellen und die README.mdDatei dabei neu laden .

Nachdem Sie die relative Verknüpfung zwischen Dokumentationsdateien auf den GitHub-Projektverzeichnisseiten gelesen haben . Ich mag den Abschlag sehr, da er viel Zeit spart, da wir nicht den gesamten HTML-Code für unsere Dokumentation von Hand schreiben müssen. Was ich jedoch möchte, ist, dass ich eine README.mdDatei haben kann, die relative Links zu anderen Dokumentationsdateien enthält, die sich unter befinden docs/*.md. Ich hatte gehofft, dass es eine einfache Lösung gibt, damit meine anderen Dokumentationsdateien auch in meinem Gh-Pages-Zweig enthalten sind und unter meiner GitHub Pages-Subdomain gehostet und gerendert und / oder thematisiert werden.

Mit anderen Worten, meine Fragen sind:

  • Gibt es eine Möglichkeit, meine README.md-Datei automatisch auf meiner Github Page-Subdomain zu aktualisieren?
    • [BEARBEITEN]: Nein scheint die Antwort zu sein, wenn der automatische Seitengenerator verwendet wird. Sie müssen die Einstellungsseite für das Repo aufrufen und es bei jeder Änderung neu laden, um es zu aktualisieren.
       
  • Gibt es eine Möglichkeit, meine relativen Links zu meiner Dokumentation in meiner README.md-Datei auf meinen Github-Seiten funktionieren zu lassen, vielleicht meine /docs/*.mdmit meinen Github-Seiten zu synchronisieren und sie irgendwie zu rendern und / oder zu thematisieren?
    • [EDIT]: Von dem, was ich da schreibt diese Frage gelernt habe , scheint es , dass dies auf GitHub Seiten durch die Verwendung eines nur möglich ist , statische Website - Generator wie die Ruby Gem Jekyll und wahrscheinlich einige Verwendungen der webhooks von GitHub unterstützt , die erwähnt werden in den Kommentaren unten. Ich versuche gerade, eine optimale Lösung zu finden.
       
  • Besser noch, gibt es eine noch einfachere Möglichkeit, dies zu tun und vielleicht nur eine Kopie meiner README.md und Dokumentation zu haben, die sowohl auf gh-Seiten als auch in meinem Hauptzweig verwendet wird und alles einfacher macht?
    • [EDIT]: Es scheint, dass dies fast definitiv ein Nein ist. Ich habe über die Möglichkeit nachgedacht, etwas in GitHub zu integrieren, um dies zu ermöglichen. Es scheint, dass in Zukunft eine bessere Unterstützung für solche Dinge in GitHub Pages eingebaut werden könnte, oder zumindest hoffe ich definitiv, dass dies der Fall sein wird.
       
Cory Gross
quelle
3
GitHub unterstützt Webhooks nach dem Empfang. Haben Sie darüber nachgedacht, einen Hook hinzuzufügen, der ein Remote-Skript aufruft, das die neue README.mdVersion in GitHub-Seiten überträgt?
Ubik
7
Vielen Dank, dass Sie großartig sind und Ihre Ergebnisse bearbeitet haben. Nicht genug Leute machen das auf dieser Seite.
Matt Kantor
Für die erste Frage ist hier ein manueller Ansatz , nicht automatisch, aber er ist einfach und funktioniert. Für den HTML-Generierungsteil kann man dillinger.io verwenden . Ich habe diese automatische Methode auch gefunden , obwohl ich sie ausprobiert, aber nicht zum Laufen gebracht habe.
iled
1
GitHub hat gerade die Verwendung eines beliebigen Zweigs und Verzeichnisses als Quelle für die Dokumente aktiviert . Sie müssen nicht mehr verwenden gh-pages.
Dan Dascalescu

Antworten:

37

Ich werde eine von mir eingerichtete Lösung veröffentlichen, die die Tatsache ausnutzt, dass GitHub Pages Jekyll bereits mit dem automatischen Seitengenerator verwendet.

  1. git checkout gh-pages
  2. mkdir _layouts
  3. mv index.html _layouts
  4. git checkout master -- README.md
  5. mv README.md index.md
  6. Stellen Sie den folgenden Text vor index.md

 

---
layout: index
---

Sie müssen die index.htmlDatei auch öffnen und die folgenden Änderungen vornehmen:

  1. Entfernen Sie den gerenderten HTML-Code aus dem Markdown in Ihrer README.mdDatei. Dies ist normalerweise zwischen <section>oder <article>Tags. Ersetzen Sie diesen HTML- {{ content }}Code durch den Text, mit dem wir diese Datei als Jekyll verwenden können. Die Datei, auf die wir das Layout anwenden, wird dort platziert, wo sich das Inhalts-Tag befindet.

  2. Suchen Sie das CSS für Ihr Projektseitenthema. Für mich war dies eine Zeile wie die folgende:

    <link rel='stylesheet' href='stylesheets/stylesheet.css' />

    Dies muss geändert werden in

    <link rel='stylesheet' href='{{ site.path }}/stylesheets/stylesheet.css' />

  3. Allen anderen auf Ihrer Site gespeicherten Assets, die in diesem Layout verwendet werden, muss ebenfalls ein Präfix vorangestellt werden {{ site.path }}.

Auf diese Weise rendert Jekyll die Markdown-Datei als Inhalt des index.htmlLayouts im _layoutsVerzeichnis. Um diesen Prozess nicht nur für die Datei README.md, sondern auch für andere Dokumente in Ihrem Hauptzweig zu automatisieren, habe ich die folgenden Schritte ausgeführt:

Erstellt die aufgerufene Datei post-commitmit den folgenden Angaben :

 

#!/bin/bash
###
### The following block runs after commit to "master" branch
###
if [ `git rev-parse --abbrev-ref HEAD` == "master" ]; then

    # Layout prefix is prepended to each markdown file synced
    ###################################################################
    LAYOUT_PREFIX='---\r\nlayout: index\r\n---\r\n\r\n'

    # Switch to gh-pages branch to sync it with master
    ###################################################################
    git checkout gh-pages

    # Sync the README.md in master to index.md adding jekyll header
    ###################################################################
    git checkout master -- README.md
    echo -e $LAYOUT_PREFIX > index.md
    cat README.md >> index.md
    rm README.md
    git add index.md
    git commit -a -m "Sync README.md in master branch to index.md in gh-pages"

    # Sync the markdown files in the docs/* directory
    ###################################################################
    git checkout master -- docs
    FILES=docs/*
    for file in $FILES
    do
        echo -e $LAYOUT_PREFIX | cat - "$file" > temp && mv temp "$file"
    done

    git add docs
    git commit -a -m "Sync docs from master branch to docs gh-pages directory"

    # Uncomment the following push if you want to auto push to
    # the gh-pages branch whenever you commit to master locally.
    # This is a little extreme. Use with care!
    ###################################################################
    # git push origin gh-pages

    # Finally, switch back to the master branch and exit block
    git checkout master
fi

BEARBEITEN: Ich habe das obige Skript sowohl für die README.mdDatei als auch für den Abschlag aktualisiert docs/*, damit beide dieselbe Layoutdatei verwenden. Dies ist ein viel besseres Setup als das, was ich vorher hatte. Dieses Skript befindet sich in Ihrem .git/hooks/Verzeichnis. Bash muss auf deinem Weg sein.

Erstellen Sie die Datei wie _config.ymlfolgt

markdown: redcarpet
path: http://username.github.io/reponame

Das obige Skript synchronisiert auch Markdown-Dateien, die sich im docs/*Verzeichnis des masterZweigs befinden, damit sie auch auf der GitHub Pages-Site angezeigt werden können. Die relative Verknüpfung mit diesen Dokumenten funktioniert, wenn Sie die folgende jQuery-Funktion einschließen, um die .mdErweiterung von den Ankern auf dem gh-pagesZweig zu entfernen. Sie können das folgende Skript index.htmlim _layoutsVerzeichnis hinzufügen :

$(document).on('ready', function () {
    $('a').each(function (i, e) {
        var href = e.href;
        if (href.search('.md') > 0)
            $(this).attr('href', href.split('.md')[0]);
    });
});

BEARBEITEN: Ich habe den obigen Code in meinem Repository geändert. Dies war eine schnelle und schmutzige Methode, aber es funktioniert nicht in allen Fällen richtig, wenn Sie wissen, was ich meine. Beispielsweise company.mdata.mdwürde die Markdown-Datei nicht verarbeitet korrekt. Um dies zu beheben, habe ich dies auf das folgende Skript aktualisiert, das die href genauer überprüft und die Erweiterung entfernt, wenn sie gefunden wird. Ich habe das Skript auch allgemeiner gestaltet, sodass andere Erweiterungen durch Ändern der extVariablen entfernt werden können. Hier ist der Code:

$(function () {
    $('a').each(function () {
        var ext = '.md';
        var href = $(this).attr('href');
        var position = href.length - ext.length;
        if (href.substring(position) === ext)
            $(this).attr('href', href.substring(0, position));
    });
});

Ich habe ein Beispiel-Repo unter CoryG89 / docsync eingerichtet , das hier eine Projektseite enthält , wenn Sie sehen möchten , wie dies alles zusammenarbeitet.

Cory Gross
quelle
4
Ich vergebe Ihnen mein Kopfgeld für eine so gründliche Antwort, aber ich hoffe immer noch, dass jemand eine einfachere Lösung findet.
Matt Kantor
1
Ich schätze das, Matt. Ich werde weitermachen und die 50 Wiederholungen verwenden, um ein weiteres Kopfgeld darauf zu setzen, in der Hoffnung auf eine andere einfachere / einfachere Lösung, um dies zu tun. Diese Lösung ist nützlich, da die relative Verknüpfung zwischen Ihrer README-Datei und anderen Markdown-Dokumenten auf Ihrer Website sowie in Ihrem Repo erwartungsgemäß fortgesetzt werden kann.
Cory Gross
1
Wäre es nicht einfacher, einfach .md-Erweiterungen im Post-Commit-Hook zu entfernen? Oder gibt es sogar eine Möglichkeit, Jenkins selbst zu verwenden?
jjmerelo
Ich denke, dass Sie die Dateien mit der Erweiterung .md im Speicher behalten müssen, sonst würden sie nicht als Markdown gerendert. Nicht zu 100%.
Cory Gross
2
Gibt es 2016 etwas Einfacheres?
Peter Krauss
5

Meine Lösung für das Problem der Synchronisierung einer README-Datei mit einer Github-Seite weicht geringfügig von der oben genannten ab. Anstatt eine separate JavaScript-Markdown-Engine zu verwenden, kann die Github-API verwendet werden, um eine als HTML gerenderte Markdown-Datei zurückzugeben.

  1. Holen Sie sich die README.mdvon https://api.github.com/repos/<owner>/<repo>/contents/README.md.
  2. Dekodieren Sie die Base64-Antwort: window.atob( JSON.parse( blob ).content );
  3. Das entschlüsselte Beitrag READMEzu https://api.github.com/markdownin einem JSON Körper

     {
       "text": "<README>",
       "mode": "markdown",
       "context": "<owner>/<repo>"
     }
    
  4. Fügen Sie den gerenderten HTML-Code wie von Brad Rhodes in ein DOM-Element ein .

Zwei Vorbehalte zu diesem Ansatz:

  1. Das Durchführen von zwei seriellen Anforderungen verlangsamt das Laden der Seite.
  2. Beim Zugriff auf die Github-API können Ratenbeschränkungen auftreten.

Für eine Seite mit wenig Verkehr, auf der die Ladezeit nicht kritisch ist (~ 1-2 Sekunden), funktioniert die obige Methode gut genug.

kgryte
quelle
atob () funktioniert gut in Chrome und FF, aber nicht in IE 11. Sagt ungültiges Zeichen. Seite ist unter joymon.github.io/joyful-visualstudio
Joy George Kunjikkuru
3

Ich habe ein paar Ideen, wie Sie eine einzelne Readme-Datei zwischen Ihrer Dokumentationssite und dem Haupt-Github-Repo teilen können:

  1. Sie können nur einen einzigen Gh-Seiten-Zweig verwenden, der sowohl Ihren Code als auch eine Jekyll-Dokumentationssite enthält. Ihr Repository könnte etwas überladen sein und Sie müssen einen YAML-Header oben in die Readme-Datei einfügen. Es unterstützt fast die relative Verknüpfung. Das Problem ist, dass wenn Sie möchten, dass Jekyll Ihren Markdown rendert, es eine .html-Erweiterung erhält. Vielleicht gibt es aber eine Möglichkeit, dies zu konfigurieren. Hier ist ein Beispiel, das ich zusammengeschmissen habe, um zu sehen, ob es funktioniert.

  2. Sie können AJAX-Aufrufe auf Ihrer Dokumentationssite verwenden, um die Readme-Datei aus Ihrem Hauptzweig zu lesen und sie dann mit einem Javascript Markdown-Renderer zu rendern . Das Laden dauert etwas länger und unterstützt keine relativen Links, ohne dass Sie ein cleveres Javascript schreiben. Es ist auch mehr Arbeit zu implementieren als Idee 1.

Nathan Breit
quelle
3

Ein weiterer zu berücksichtigender Weg ist das Einrichten eines Pre-Commit-Hooks, der die relevanten Seiten erstellt. Ich mache das in einem meiner Repositories . Sie müssten wahrscheinlich den automatischen Seitengenerator über Bord werfen und einfach selbst in den gh-pagesZweig gehen und etwas Besonderes tun, um Ihre Dokumente in HTML oder eine Jekyll-Site umzuwandeln, wie Nathan vorschlägt .

In diesem Repository drücke ich so , um gh-pagesidentisch zu bleiben master. Es gibt auch viele andere Möglichkeiten , dies zu tun. Dies ist jedoch möglicherweise nicht ideal für Ihre Situation (Sie möchten möglicherweise nicht, dass sie identisch sind).

Der Grund, warum ich für diese Frage ein Kopfgeld angeboten hatte, war, dass ich gehofft hatte, jemand hätte einen besseren Workflow. Diese Methode ist kompliziert und unflexibel und erfordert, dass jeder seine Hooks synchron hält.

Matt Kantor
quelle
2

Eine andere Methode, mit der ich ziemlich erfolgreich arbeiten konnte, ist die Verwendung von Ajax zum Abrufen der Dokumente mithilfe der Github-API und einer Javascript-Markdown-Engine zum Rendern des HTML-Codes (wie auch von Nathan vorgeschlagen).

  1. Verwenden Sie die Github-API und JSONP, um das Dokument von Github abzurufen
  2. Dekodieren Sie den base64-Inhalt in der Antwort von der Github-API
  3. Rendern Sie den Markdown mit einer Javascript-Markdown-Engine
  4. Zeigen Sie das gerenderte HTML an

Nathan äußerte sich besorgt über die Leistung, aber meiner Erfahrung nach wird sie scheinbar sofort geladen, sodass ich nicht denke, dass dies tatsächlich ein Problem ist.

Der Vorteil ist, dass es einfach einzurichten ist und Ihre Dokumente immer aktualisiert werden, selbst wenn Sie den Markdown nur direkt in einem Browser auf github bearbeiten.

Ich habe ein Beispiel auf Github-Seiten unter http://bradrhodes.github.io/GithubDocSync/ eingerichtet, um zu zeigen, dass es funktioniert.

Brad Rhodes
quelle
Ich habe die Methode mit dem Klonen kombiniert , um mein project.wiki auf GitHub-Seiten anzuzeigen .
Chetabahana
2

Eine andere Möglichkeit für die von Nathan und Brand Rhodes beschriebene Methode ist die Verwendung eines großartigen Tools: FlatDoc, erstellt von Rico Sta. Cruz.

FlatDoc lädt die Dokumentation (README.md oder eine andere Markdown-Datei) per Ajax, analysiert sie und zeigt sie mit allen Extras und sogar einem Seitenleistenmenü für die Navigation an!

Es hat in seiner API eine Hilfsmethode zum Laden von Dateien vom GitHub-Repo-Master erstellt (kann aber auch überall im Web geladen werden).

Anleitung

Beginnen Sie mit dem Kopieren der folgenden HTML-Vorlage in Ihre index.html in Ihrem gh-pages-Zweig. Weitermachen mit:

  • Ersetzen Sie "USER" durch Ihren GitHub-Benutzernamen
  • Ersetzen Sie "REPO" durch Ihren GitHub-Repo-Namen
  • Ersetzen Sie "Ihr Projekt" durch Ihren Projektnamen

in der Datei. Probieren Sie es lokal in Ihrem Browser aus. Übernehmen Sie dann die Änderungen und übertragen Sie sie. Jetzt wird Ihre Github-Seite immer mit Ihrer README.md-Datei in Ihrem Hauptzweig aktualisiert.

Wenn das Standarddesign für Sie nicht zufriedenstellend ist, können Sie es mit Ihrem eigenen CSS neu gestalten.

Khalid Salomão
quelle
1

Ich möchte auch Dokumente in Master bearbeiten und in Gh-Seiten veröffentlichen. Ich möchte die Dokumente mit dem Quellcode auf dem neuesten Stand halten, und das scheint der beste Weg zu sein. Für mich ist dies in Arbeit, aber ich habe Corys Skript als Ausgangspunkt genommen und es ein wenig erweitert, damit es _layoutssofort funktioniert, solange es einen Gh-Pages-Zweig mit (dh einer Jekyll-Site) gibt. Es konvertiert Fencing im Backtick-Stil (für Codeblöcke), die beim Durchsuchen von Github-Quellen gut funktionieren, jedoch nicht bei Gh-Seiten. Ich verwende ein index.mdmit einem Include für das Projekt, README.mddamit ich einen Header und einige andere Dekorationen hinzufügen kann. Diese Version behandelt auch die Dokumentation in verschachtelten Verzeichnissen namens "docs", die ich in einem Projekt mit mehreren Modulen nützlich finde (keine Git-Submodule, nur Unterverzeichnisse):

.git/hooks/post-commit

#!/bin/bash
###
### The following block runs after commit to "master" branch
###
if [ `git rev-parse --abbrev-ref HEAD` == "master" ]; then

    # function to convert a plain .md file to one that renders nicely in gh-pages
    function convert {
        # sed - convert links with *.md to *.html (assumed relative links in local pages)
        # awk - convert backtick fencing to highlights (script from bottom of file)
        sed -e 's/(\(.*\)\.md)/(\1.html)/g' "$1" | awk -f <(sed -e '0,/^#!.*awk/d' $0) > _temp && mv _temp "$1"
    } 

    if ! git show-ref --verify --quiet refs/heads/gh-pages; then
        echo "No gh-pages, so not syncing"
        exit 0
    fi

    # Switch to gh-pages branch to sync it with master
    ###################################################################
    git checkout gh-pages

    mkdir -p _includes

    # Sync the README.md in master to index.md adding jekyll header
    ###################################################################
    git checkout master -- README.md
    if [ -f README.md ]; then
        cp README.md _includes/
        convert _includes/README.md
        git add README.md
        git add _includes/README.md
    fi

    # Generate index if there isn't one already
    ###################################################################
    if [ ! -f index.md ]; then
        echo -e '---\ntitle: Docs\nlayout: default\n---\n\n{% include README.md %}' > index.md
        git add index.md
    fi

    # Generate a header if there isn't one already
    ###################################################################
    if [ ! -f _includes/header.txt ]; then
        echo -e '---\ntitle: Docs\nlayout: default\nhome: \n---\n\n' > _includes/header.txt
        git add _includes/header.txt
    fi

    # Sync the markdown files in all docs/* directories
    ###################################################################
    for file in `git ls-tree -r --name-only master | grep 'docs/.*\.md'`
    do
        git checkout master -- "$file"
        dir=`echo ${file%/*} | sed -e "s,[^/]*,..,g"`
        cat _includes/header.txt | sed -e "s,^home: .*$,home: ${dir}/," > _temp
        cat "$file" >> _temp && mv _temp "$file"
        convert "$file"
        git add "$file"
    done

    git commit -a -m "Sync docs from master branch to docs gh-pages directory"

    # Uncomment the following push if you want to auto push to
    # the gh-pages branch whenever you commit to master locally.
    # This is a little extreme. Use with care!
    ###################################################################
    # git push origin gh-pages

    # Finally, switch back to the master branch and exit block
    git checkout master
fi

exit $?

#!/usr/bin/awk
{
   # Replace backtick fencing (renders well when browsing github) with jekyll directives
   if (/```/) {
      IN = IN?0:1 # Are we already in a fenced section? Toggle.
      if (IN) { # If we are starting a fenced section
         if (/```\s*$/) {
           $0 = $0"text" # empty language is OK for backticks but not for jekyll
         }
         gsub(/```/, "{% highlight ")
         print $0" %}"
      } else { # ending a fenced section
        print "{% endhighlight %}" 
      }
    } else { # not a fencing line
      if (IN) { # but in a fenced section, so add indent to make sure code is rendered with <pre>
        print "    "$0
      } else {
        print
      }
    }
}

Eine weitere Abweichung vom Original besteht darin, dass page.homeauf allen Seiten eine Variable festgelegt wird . Dies kann verwendet werden, um den relativen Pfad des Stammverzeichnisses zu lokalisieren, sodass statische Ressourcen wie CSS gefunden werden können. In habe _layouts/.default.htmlich:

<link rel="stylesheet" href="{{ page.home }}css/main.css">

Auf diese Weise kann ich das CSS bearbeiten, die Jekyll-Site lokal erstellen und das Ergebnis in einem Browser anzeigen, ohne darauf warten zu müssen, dass Github es auf dem Server erstellt.

Dave Syer
quelle
0

Ich habe kürzlich ein Paket gh-pages-generator erstellt , um dieses Problem zu lösen. Es generiert eine mehrseitige Site mit mehreren MD-Dateien und einer Konfigurationsdatei.

Alle Links zwischen den Seiten werden korrekt aktualisiert. Es ist relativ einfach, es zu einem Teil von CI zu machen, Änderungen wieder in den gh-pages-Zweig zu übernehmen.

Ich benutze es hier und hier .

insb
quelle
0

Es ist nicht schwer , zwei Kopien und Pasten in das Terminal und Sie sind fertig.

JekyllMit dieser Option können Sie Ihre Markdown-Datei importieren und anschließend in HTML konvertieren. Der Trick besteht darin, Ihre mit README.mdin Ihre index.mdDatei zu importieren {% include_relative README.md %}. So können wir das machen:

Es lohnt sich herauszufinden, wie man eine Super-Barebone- JekyllSite auf Github einrichtet (es sind nur zwei Dateien! )

Die Einrichtung

Sie können die beiden Dateien kopieren und Ihre Seite mit Ihrer aktuellen Readme-Datei versehen, indem Sie nur dieses einmalige Setup ausführen ( kopieren Sie den gesamten Codeblock und fügen Sie ihn in das Terminal ein ):

# Copy our two files to the gh-pages branch
git checkout -b gh-pages &&
wget https://raw.githubusercontent.com/lazamar/barebones-jekyll-project-readme/master/_config.yml &&
wget https://raw.githubusercontent.com/lazamar/barebones-jekyll-project-readme/master/index.md &&
#
# Commit and publish our page on github
git add -A && git commit -m "Create project github page" &&
git push --set-upstream origin gh-pages |
#
git checkout master # go back to master branch

Automatisieren

Dann müssen wir nur noch die Aufgabe automatisieren, alle Änderungen vor jedem Push von masterin den gh-pagesZweig zu kopieren . Wir können dies tun, indem wir dieses Skript ausführen ( Sie können es kopieren und in das Terminal einfügen ).

$(cat > .git/hooks/pre-push << EOF
#!/bin/sh
we_are_in_gh_pages="\$(git branch | grep -G "* gh-pages")"

if [ ! "\$we_are_in_gh_pages" ];
  then
    git checkout gh-pages &&
    git rebase master &&
    git push -f &&
    git checkout master # go back to master branch
fi
EOF
) && chmod 775 .git/hooks/pre-push

Es wird ein Push-Hook erstellt, der alle Änderungen aus dem masterZweig bei gh-pagesjeder Ausführung kopiert git push.

Das ist es. Erledigt.

Marcelo Lazaroni
quelle