Jak mogę zsynchronizować dokumentację ze stronami Github?

81

Mam projekt razem z kilkoma osobami i mamy README.mdplik z zestawem GitHub Flavored Markdown, który jest renderowany na naszej stronie GitHub. Skonfigurowaliśmy również gałąź GitHub Pages, która jest hostowana w subdomenie naszej organizacji GitHub i użyliśmy automatycznego generatora stron po prostu ładującego się do naszego README.mdpliku podczas tworzenia naszej strony. Jednak zauważam, że kiedy aktualizuję nasz README.mdplik, nie aktualizuje on strony projektu. Zamiast tego musimy przejść do zakładki ustawień GitHub i odtworzyć stronę projektu, przeładowując README.mdplik, gdy to zrobimy.

Ponadto po przeczytaniu o relatywnym łączeniu pracy między plikami dokumentacji na stronach katalogu projektu GitHub. Bardzo podoba mi się przecena, ponieważ oszczędza mnóstwo czasu od konieczności ręcznego pisania całego kodu HTML do naszej dokumentacji. Chciałbym jednak mieć jeden README.mdplik, który może zawierać względne linki do innych plików dokumentacji znajdujących się pod adresem docs/*.md. Miałem nadzieję, że istnieje proste rozwiązanie, dzięki któremu moje inne pliki dokumentacji mogą również zostać włączone do mojej gałęzi gh-pages i być hostowane w mojej subdomenie GitHub Pages oraz renderowane i / lub tematyczne.

Innymi słowy, moje pytania to:

  • Czy istnieje sposób, aby mój plik README.md był automatycznie aktualizowany w subdomenie mojej strony Github?
    • [EDYTUJ]: Nie wydaje się być odpowiedzią, jeśli używasz automatycznego generatora stron. Musisz przejść do strony ustawień repozytorium i ponownie ją załadować za każdym razem, gdy nastąpi zmiana, aby ją zaktualizować.
       
  • Czy istnieje sposób, aby moje względne linki do mojej dokumentacji w moim pliku README.md działały na moich stronach Github, być może w jakiś sposób zsynchronizuję moje /docs/*.mdz moimi stronami Github i w jakiś sposób je wyrenderuję i / lub wykorzystam w temacie?
    • [EDYTUJ]: Z tego, czego się nauczyłem od czasu napisania tego pytania, wynika, że ​​jest to możliwe tylko na stronach GitHub za pomocą statycznego generatora witryn, takiego jak ruby ​​gem Jekyll i prawdopodobnie niektóre zastosowania webhooków obsługiwanych przez GitHub , o których wspomniano w komentarzach poniżej. Obecnie próbuję znaleźć optymalne rozwiązanie.
       
  • A jeszcze lepiej, czy istnieje jeszcze łatwiejszy sposób, w jaki mogę to zrobić i być może mam tylko jedną kopię mojego pliku README.md i dokumentacji, która jest używana zarówno na stronach gh, jak i w mojej głównej gałęzi i sprawia, że ​​wszystko jest łatwiejsze?
    • [EDYCJA]: Wygląda na to, że ten jest prawie na pewno nie. Myślałem o możliwości wprowadzenia czegoś wbudowanego w GitHub, aby to umożliwić. Wygląda na to, że w przyszłości można by wbudować w GitHub Pages lepsze wsparcie dla tego typu rzeczy, a przynajmniej mam taką nadzieję.
       
Cory Gross
źródło
3
GitHub obsługuje elementy webhook po odbiorze. Czy myślałeś o dodaniu haka, który wywołuje zdalny skrypt, który wypycha nową README.mdwersję na strony GitHub?
ubik
7
Dziękujemy za wsparcie i edytowanie wyników. Za mało ludzi robi to na tej stronie.
Matt Kantor
Pierwsze pytanie dotyczy podejścia ręcznego , a nie automatycznego, ale jest proste i działa. Do części generującej HTML można użyć dillinger.io . Znalazłem również tę automatyczną metodę , chociaż spróbowałem, ale nie udało mi się.
iled
1
GitHub właśnie włączył używanie dowolnej gałęzi i katalogu jako źródła dokumentów . Nie musisz już używać gh-pages.
Dan Dascalescu

Odpowiedzi:

37

Zamierzam opublikować rozwiązanie, które skonfigurowałem, które wykorzystuje fakt, że GitHub Pages korzysta z Jekyll już przy użyciu automatycznego generatora stron.

  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. Dołącz następujący tekst do index.md

 

---
layout: index
---

Musisz także otworzyć index.htmlplik i wprowadzić następujące zmiany:

  1. Usuń wyrenderowany kod HTML z przeceny w README.mdpliku. Zwykle jest to między tagami <section>lub <article>. Zastąp ten kod HTML tekstem, {{ content }}który pozwoli nam użyć tego pliku jako jekyll. Plik, do którego zastosujemy układ, zostanie umieszczony w miejscu znacznika treści.

  2. Znajdź kod CSS dla motywu strony projektu. dla mnie była to następująca linijka:

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

    Należy to zmienić na

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

  3. Wszelkie inne zasoby przechowywane w Twojej witrynie, które będą używane w tym układzie, również muszą być poprzedzone przedrostkiem {{ site.path }}.

W ten sposób Jekyll wyrenderuje plik przeceny jako zawartość index.htmlukładu w _layoutskatalogu. Aby zautomatyzować ten proces nie tylko dla pliku README.md, ale także innych dokumentów, które możesz mieć w swojej gałęzi głównej, wykonałem następujące kroki:

Utworzono plik o nazwie post-commitzawierający:

 

#!/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

EDYCJA: Zaktualizowałem powyższy skrypt zarówno dla README.mdpliku, jak i dla przeceny, docs/*aby używać tego samego pliku układu. To znacznie lepsza konfiguracja niż wcześniej. Ten skrypt trafia do twojego .git/hooks/katalogu. bash musi być na twojej drodze.

Utwórz plik _config.ymlz następującym

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

Powyższy skrypt synchronizuje również pliki markdown znalezione w docs/*katalogu masteroddziału, aby można je było przeglądać również w witrynie GitHub Pages. Względne łączenie do tych dokumentów działa, jeśli dołączysz następującą funkcję jQuery w celu usunięcia .mdrozszerzenia z kotwic w gh-pagesgałęzi. Możesz dodać poniższy skrypt index.htmlw _layoutskatalogu:

$(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]);
    });
});

EDYCJA: Zmieniłem powyższy kod w moim repozytorium, był to szybki i brudny sposób na zrobienie tego, ale nie zadziała to we wszystkich przypadkach, jeśli wiesz, co mam na myśli ... Na przykład plik przeceny company.mdata.mdnie zostałby przetworzony prawidłowo. Aby to naprawić, zaktualizowałem to do następującego skryptu, który dokładniej sprawdza href i usuwa rozszerzenie, jeśli zostanie znalezione. Skrypt stał się też bardziej ogólny, umożliwiając usuwanie innych rozszerzeń poprzez zmianę extzmiennej. Oto kod:

$(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));
    });
});

Skonfigurowałem przykładowe repozytorium w CoryG89 / docsync , który ma tutaj stronę projektu , jeśli chcesz zobaczyć, jak to wszystko działa.

Cory Gross
źródło
4
Przyznaję ci moją nagrodę za udzielenie tak dokładnej odpowiedzi, ale nadal mam nadzieję, że ktoś znajdzie prostsze rozwiązanie.
Matt Kantor
1
Doceniam to Matt. Mam zamiar użyć 50 powtórzeń, aby wyznaczyć kolejną nagrodę w nadziei na inne łatwiejsze / prostsze rozwiązanie, aby to zrobić. To rozwiązanie jest fajne, ponieważ umożliwia względne linkowanie, aby kontynuować pracę zgodnie z oczekiwaniami między plikiem README a innymi dokumentami przeceny w witrynie, a także w repozytorium.
Cory Gross
1
Czy nie byłoby łatwiej po prostu usunąć rozszerzenia .md z haka po zatwierdzeniu? A może jest nawet sposób na zrobienie tego za pomocą samego Jenkinsa?
jjmerelo
Myślę, że musisz przechowywać pliki w pamięci z rozszerzeniem .md, w przeciwnym razie nie zostanie wyrenderowany jako Markdown. Jednak nie w 100%.
Cory Gross
2
jest coś prostszego w 2016 roku?
Peter Krauss
5

Moje rozwiązanie problemu z synchronizacją pliku README ze stroną Github różni się nieco od powyższego. Zamiast używać oddzielnego silnika JavaScript Markdown, można użyć interfejsu API Github do zwrócenia pliku Markdown renderowanego jako HTML.

  1. Pobierz README.mdzhttps://api.github.com/repos/<owner>/<repo>/contents/README.md .
  2. Dekoduj odpowiedź Base64: window.atob( JSON.parse( blob ).content );
  3. Opublikuj zdekodowane READMEdo https://api.github.com/markdownw treści JSON

     {
       "text": "<README>",
       "mode": "markdown",
       "context": "<owner>/<repo>"
     }
    
  4. Wstaw wyrenderowany kod HTML do elementu DOM, tak jak zrobił to Brad Rhodes .

Dwa zastrzeżenia do tego podejścia:

  1. Wykonanie dwóch żądań szeregowych spowalnia ładowanie strony.
  2. Może napotkać ograniczenia szybkości podczas uzyskiwania dostępu do interfejsu API Github.

W przypadku strony o małym natężeniu ruchu, na której czas wczytywania nie jest krytyczny (~ 1-2 sekundy), powyższa metoda działa wystarczająco dobrze.

kgryte
źródło
atob () działa dobrze w Chrome i FF, ale nie w IE 11. Mówi, że nieprawidłowy znak. strona jest poniżej joymon.github.io/joyful-visualstudio
Joy George Kunjikkuru
3

Mam kilka pomysłów na udostępnienie pojedynczego pliku readme między witryną z dokumentacją a głównym repozytorium github:

  1. Możesz użyć tylko jednej gałęzi gh-pages, która zawiera zarówno twój kod, jak i witrynę dokumentacji jekyll. Twoje repozytorium może być trochę zagracone i będziesz musiał umieścić nagłówek YAML na początku pliku readme. To prawie obsługuje względną linkowanie. Problem polega na tym, że jeśli chcesz, aby jekyll wyrenderował Twoją przecenę, nada mu rozszerzenie .html. Może jest jednak sposób, aby to skonfigurować. Oto przykład, który zrzuciłem razem, aby sprawdzić, czy działa.

  2. Możesz użyć wywołań AJAX w swojej witrynie dokumentacji, aby przeczytać plik readme z głównej gałęzi, a następnie wyrenderować go za pomocą mechanizmu renderującego Javascript Markdown . Ładowanie zajmie trochę więcej czasu i nie będzie obsługiwać linków względnych bez napisania sprytnego JavaScript. Wdrożenie wymaga też więcej pracy niż pomysł 1.

Nathan Breit
źródło
3

Inną drogą do rozważenia jest ustawienie punktu zaczepienia przed zatwierdzeniem, który buduje odpowiednie strony. Robię to w jednym z moich repozytoriów . Prawdopodobnie musiałbyś jednak zrezygnować z automatycznego generatora stron i po prostu samodzielnie przesłać do gh-pagesgałęzi, a także zrobić coś wymyślnego, aby zamienić swoje dokumenty w HTML lub witrynę Jekyll, jak sugeruje Nathan .

W tym repozytorium naciskam w ten sposób, aby zachować gh-pagesidentyczność master. Można to zrobić na wiele innych sposobów . Może to jednak nie być idealne dla Twojej sytuacji (możesz nie chcieć, aby były identyczne).

W każdym razie powodem, dla którego zaoferowałem nagrodę za to pytanie, było to, że miałem nadzieję, że ktoś ma lepszy przepływ pracy. Ta metoda jest trochę zawiła i nieelastyczna i wymaga od wszystkich synchronizacji haków.

Matt Kantor
źródło
2

Inną metodą, którą udało mi się całkiem pomyślnie, jest użycie Ajax do pobierania dokumentów przy użyciu interfejsu API Github i silnika znaczników JavaScript do renderowania HTML (co również zasugerował Nathan).

  1. Użyj Github API i JSONP, aby pobrać dokument z Github
  2. Zdekoduj zawartość base64 w odpowiedzi z interfejsu API Github
  3. Renderuj przecenę za pomocą silnika znaczników javascript
  4. Wyświetl renderowany kod HTML

Nathan wyraził pewne zaniepokojenie wydajnością, ale z mojego doświadczenia wynika, że ​​ładuje się natychmiast, więc nie sądzę, aby to faktycznie był problem.

Zaletą jest to, że jest łatwy w konfiguracji i zawsze zaktualizuje Twoje dokumenty, nawet jeśli edytujesz przecenę bezpośrednio w przeglądarce na github.

Ustawiłem przykład na stronach Github pod adresem http://bradrhodes.github.io/GithubDocSync/, aby pokazać, że działa.

Brad Rhodes
źródło
Połączyłem tę metodę z klonowaniem, aby pokazać mój project.wiki na stronach GitHub .
Chetabahana,
2

Inną możliwością dla metody opisanej przez Nathana i Brand Rhodesa jest użycie świetnego narzędzia: FlatDoc stworzonego przez Rico Sta. Cruz.

FlatDoc załaduje przez Ajax dokumentację (README.md lub jakikolwiek inny plik markdown), przeanalizuje ją i wyświetli ze wszystkimi dodatkami, a nawet menu na pasku bocznym do nawigacji!

Ma wbudowaną w swoim api metodę pomocniczą do ładowania plików z repozytorium GitHub (ale może również ładować gdziekolwiek indziej z sieci).

Instrukcje

Zacznij od skopiowania następującego szablonu HTML do swojego index.html w gałęzi gh-pages. Kontynuować:

  • Zastąpienie „USER” nazwą użytkownika GitHub
  • Zastąpienie „REPO” nazwą repozytorium GitHub
  • Zastąpienie „Your Project” nazwą swojego projektu

w pliku. Wypróbuj lokalnie w swojej przeglądarce. Następnie zatwierdź i prześlij zmiany. Teraz twoja strona github będzie zawsze aktualizowana twoim plikiem README.md w twojej gałęzi głównej.

Jeśli domyślny motyw nie jest dla Ciebie satysfakcjonujący, możesz zmienić jego styl za pomocą własnego CSS.

Khalid Salomão
źródło
1

Chcę również edytować dokumenty w trybie głównym i publikować na stronach gh - lubię aktualizować dokumenty z kodem źródłowym i wydaje się, że to najlepszy sposób. Dla mnie to jest w toku, ale wziąłem skrypt Cory'ego jako punkt wyjścia i rozszerzyłem go trochę, aby działał po wyjęciu z pudełka, o ile istnieje gałąź gh-pages z _layouts(tj. Witryna jekyll). Konwertuje szermierkę w stylu backtick (dla bloków kodu), która działa dobrze podczas przeglądania źródeł github, ale nie na stronach gh. Używam index.mdz dołączeniem do projektu, README.mdwięc mogę dodać nagłówek i kilka innych dekoracji. Ta wersja obsługuje również dokumentację w dowolnych zagnieżdżonych katalogach zwanych „docs”, które uważam za przydatne w projekcie z wieloma modułami (nie pod modułami git, tylko podkatalogami):

.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
      }
    }
}

Inną odmianą oryginału jest ustawienie zmiennej page.homena wszystkich stronach. Można to wykorzystać do zlokalizowania względnej ścieżki katalogu głównego, dzięki czemu można go użyć do zlokalizowania zasobów statycznych, takich jak css. W _layouts/.default.htmlmam:

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

W ten sposób mogę edytować css, lokalnie budować witrynę jekyll i zobaczyć wynik w przeglądarce bez konieczności czekania, aż Github zbuduje ją na serwerze.

Dave Syer
źródło
0

Niedawno stworzyłem pakiet gh-pages-generator, aby rozwiązać ten problem - generuje on wielostronicową witrynę przy użyciu wielu plików MD i pliku konfiguracyjnego.

Prawidłowo aktualizuje wszystkie łącza między stronami. Wprowadzanie zmian z powrotem do gałęzi gh-pages jest stosunkowo łatwe.

Używam go tu i tutaj .

zwł
źródło
0

To nie jest trudne , dwie kopie i wklejanie do terminala i gotowe.

Jekyllpozwala zaimportować plik markdown, a następnie zajmie się konwersją do formatu HTML. Sztuczka polega na zaimportowaniu pliku README.mddo index.mdpliku z rozszerzeniem {% include_relative README.md %}. Oto jak możemy to zrobić:

Warto sprawdzić, jak skonfigurować Jekyllwitrynę super szkieletową na githubie (to tylko dwa pliki! )

Ustawić

Możesz skopiować oba pliki i uruchomić swoją stronę z aktualnym plikiem readme, uruchamiając tę jednorazową konfigurację ( skopiuj cały blok kodu i przejdź do terminala ):

# 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

Automatyzacja

Następnie wystarczy zautomatyzować zadanie kopiowania wszystkich zmian z masterdo gh-pagesgałęzi przed każdym wypchnięciem. Możemy to zrobić, uruchamiając ten skrypt ( możesz go skopiować i wkleić do terminala )

$(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

Utworzy hak push, który będzie kopiował wszystkie zmiany z mastergałęzi do gh-pageskażdego uruchomienia git push.

Otóż ​​to. Gotowe.

Marcelo Lazaroni
źródło