如何将文档与Github Pages同步?


81

我有一个与几个人在一起的项目,我们README.md在GitHub页面上呈现了一个带有一堆GitHub Flavored Markdown的文件。我们还建立了一个GitHub Pages分支,该分支托管在GitHub Organization的子域下,并在创建页面时使用了自动页面生成器,只需将其加载到README.md文件中即可。但是,我注意到当我更新README.md文件时,它不会更新项目页面。相反,我们必须转到GitHub设置选项卡并重新创建项目页面,并README.md在执行时重新加载文件。

此外,在阅读了有关GitHub项目目录页面上文档文件之间的相对链接的信息之后。我非常喜欢markdown,因为它省了很多时间,而不必为我们的文档手工编写所有HTML。但是,我希望有一个README.md文件能够包含位于的其他文档文件的相对链接docs/*.md。我希望有一个简单的解决方案,以便其他文档文件也可以包含在gh-pages分支中,并托管在GitHub Pages子域下并进行呈现和/或主题化。

换句话说,我的问题是:

  • 有没有办法让我的README.md文件在我的Github Page子域上自动更新?
    • [编辑]:如果使用自动页面生成器,似乎没有答案。您必须转到存储库的设置页面,并在每次更改时都重新加载它以进行更新。
       
  • 有没有一种方法可以使我的README.md文件上的文档的相对链接在Github Pages上起作用,也许以某种方式将其同步/docs/*.md到Github Pages并以某种方式呈现和/或主题化?
    • [编辑]:从我写这个问题以来所学到的内容来看,这似乎只有通过使用静态网站生成器(如ruby gem Jekyll)才能在GitHub页面上实现,并且可能还提到了GitHub支持webhooks的某些用法在下面的评论中。我目前正在尝试寻找最佳解决方案。
       
  • 更好的是,有没有一种更简便的方法可以执行此操作,并且也许只有gh页和主分支上使用的README.md和文档的一个副本,使一切变得最简单?
    • [编辑]:看来这几乎是肯定的。我正在考虑将某些内置于GitHub的东西允许的可能性。似乎将来可以在GitHub Pages中内置对此类事物的更好支持,或者至少我绝对希望如此。
       

3
GitHub支持接收后的Webhooks。您是否考虑过添加一个钩子,该钩子调用一些将新README.md版本推送到GitHub页面的远程脚本?
2013年

7
感谢您的出色表现和修改结果。没有足够的人在此站点上执行此操作。
马特·坎托

对于第一个问题,这是一种手动方法,而不是自动方法,但它很简单并且有效。对于HTML生成部分,可以使用dillinger.io。我也找到了这种自动方法,尽管我尝试了一下,但没有成功。
直到2016年

1
GitHub刚刚启用了使用任何分支和目录作为文档源的功能。您不再需要使用gh-pages
Dan Dascalescu

Answers:


37

我将发布一个我设置的解决方案,该解决方案利用GitHub Pages已使用Jekyll的事实,而该公司已经在使用Automatic Page Generator。

  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. 将以下文本添加到 index.md

 

---
layout: index
---

您还需要打开index.html文件并进行以下更改:

  1. README.md文件的Markdown中删除呈现的HTML 。通常在<section><article>标签之间。将该HTML替换为文本,{{ content }}这将使我们可以将该文件用作jekyll。我们将布局应用到的文件将放置在content标签所在的位置。

  2. 找到您的项目页面主题的CSS。对我来说,这是一条类似于以下内容的行:

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

    这需要更改为

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

  3. 您网站上存储的任何其他资产(将用于此布局)也都需要加上前缀{{ site.path }}

这样,Jekyll将markdown文件呈现为目录中index.html布局的内容_layouts。为了不仅针对README.md文件而且还对您在master分支中可能具有的其他文档进行此过程自动化,我采取了以下步骤:

创建名为的文件,post-commit其中包含以下内容:

 

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

编辑:我为README.md文件和降价更新了上面的脚本,docs/*以都使用相同的布局文件。这是一个比以前更好的设置。该脚本位于您的.git/hooks/目录中。bash必须在您的道路上。

_config.yml使用以下内容创建文件

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

上面的脚本还同步docs/*了在master分支目录中找到的markdown文件,以便它们也可以在GitHub Pages站点上查看。如果您包含以下jQuery函数,以便.mdgh-pages分支的锚点剥离扩展名,则可以相对链接到这些文档。您可以index.html_layouts目录中添加以下脚本:

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

编辑:我在存储库中更改了上面的代码,这是一种快速而肮脏的方法,但是,如果您了解我的意思,它将无法在所有情况下正常工作。例如,company.mdata.md不会处理markdown文件正确地。为了解决这个问题,我将其更新为以下脚本,该脚本会更仔细地检出href并删除扩展名(如果找到)。我还使脚本更加通用,允许通过更改ext变量来删除其他扩展名。这是代码:

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

我想在CoryG89 / docsync上设置一个示例存储库,如果您想了解所有这些功能如何协同工作,可以在此处找到项目页面


4
我会因提供如此详尽的答案而奖励您,但我仍然希望有人能提出更简单的解决方案。
马特·坎托

1
我很感谢马特。我将继续使用这50个代表来悬赏,以期希望有另一个更简单的解决方案。这个解决方案很好,因为它允许相对链接继续在您的自述文件与站点以及您的回购中的其他降价文档之间按预期进行。
科里·格罗斯

1
仅在提交后的钩子中剥离.md扩展名会更容易吗?也许甚至有一种使用Jenkins本身的方法?
jjmerelo

我认为您必须使用.md扩展名保存文件,否则它将不会呈现为Markdown。虽然不是100%。
Cory Gross

2
2016年会有更简单的事情吗?
彼得·克劳斯

5

我对将自述文件与Github页面同步的问题的解决方案与上面略有不同。除了使用单独的JavaScript Markdown引擎外,还可以使用Github API返回以HTML格式呈现的Markdown文件。

  1. README.md从获取https://api.github.com/repos/<owner>/<repo>/contents/README.md
  2. 解码Base64响应: window.atob( JSON.parse( blob ).content );
  3. 将解码后的内容发布READMEhttps://api.github.com/markdownJSON正文中

     {
       "text": "<README>",
       "mode": "markdown",
       "context": "<owner>/<repo>"
     }
    
  4. Brad Rhodes一样,将呈现的HTML插入DOM元素。

此方法有两个警告:

  1. 执行两个串行请求会减慢页面加载速度。
  2. 访问Github API时可能会遇到速率限制。

对于加载时间不是很关键的低流量页面(约1-2秒),则上述方法效果很好。


atob()在Chrome和FF中可以正常工作,但在IE 11中却不能。网站位于joymon.github.io/joyful-visualstudio
Joy George Kunjikkuru 2015年


3

对于在您的文档站点和主要github存储库之间共享一个自述文件,我有一些想法:

  1. 您只能使用一个包含代码和jekyll文档站点的gh-pages分支。您的存储库可能会有些混乱,您需要在自述文件的顶部放置一个YAML标头。它几乎支持相对链接。问题是,如果您希望jekyll渲染markdown,则会为其添加.html扩展名。也许有一种方法可以配置它。这是我放在一起查看它是否有效的示例。

  2. 您可以在文档站点中使用AJAX调用从主分支读取自述文件,然后使用Javascript Markdown呈现器对其进行呈现。这将花费更长的时间来加载,并且如果不编写一些精巧的Javascript,它将不支持相对链接。实施比构思1还要多的工作。


3

要考虑的另一种方法是设置一个预先提交的挂钩,以构建相关的页面。我在我的一个存储库中执行此操作。但是,您可能不得不抛弃自动页面生成器,然后gh-pages自己推送到分支,并做一些花哨的操作,以将文档转换为HTML或Nathan建议的Jekyll站点。

在该存储库中,我像这样推动与保持gh-pages一致master。还有很多其他方法可以做到这一点。但是,这对于您的情况可能并不理想(您可能不希望它们相同)。

无论如何,我之所以悬赏这个问题,是因为我希望有人能拥有更好的工作流程。这种方法有点复杂且不灵活,它要求每个人都保持同步。


2

我已经非常成功地工作的另一种方法是使用Github API和Javascript markdown引擎使用Ajax来获取文档以呈现HTML(Nathan也建议)。

  1. 使用Github API和JSONP从Github获取文档
  2. 在Github API的响应中解码base64内容
  3. 使用JavaScript Markdown引擎渲染Markdown
  4. 显示渲染的HTML

内森(Nathan)对性能表示了一些担忧,但是根据我的经验,它似乎是立即加载的,因此我认为这实际上不是问题。

优点是设置简单,即使您直接在github的浏览器中直接编辑markdown,它也将始终更新您的文档。

我在http://bradrhodes.github.io/GithubDocSync/的Github页面上设置了一个示例,以显示其工作原理。


我将方法与克隆结合起来,以我的project.wiki显示到GitHub页面中
Chetabahana '16

2

内森(Nathan)和布兰德·罗德斯(Brand Rhodes)描述的方法的另一种可能性是使用一个很棒的工具:由里科·斯塔(Rico Sta)创建的FlatDoc。克鲁兹

FlatDoc将通过ajax加载文档(README.md或任何其他markdown文件),进行解析并显示所有功能,甚至显示侧边栏菜单进行导航!

它在其api中内置了一个帮助程序方法,可从GitHub repo master加载文件(但也可以从Web的其他任何位置加载文件)。

使用说明

首先将以下html模板复制到gh-pages分支的index.html中。继续:

  • 用您的GitHub用户名替换“ USER”
  • 用您的GitHub存储库名称替换“ REPO”
  • 用您的项目名称替换“您的项目”

在文件中。在浏览器中本地尝试。然后提交并推送更改。现在,您的github页面将始终通过master分支中的README.md文件进行更新。

如果您不满意默认主题,则可以使用自己的CSS重新设置其样式。


1

我也想在master中编辑文档并在gh-pages中发布-我想使文档与源代码保持最新,这似乎是最好的方法。对于我来说,这是正在进行的工作,但是我以Cory的脚本为起点,并对其进行了扩展,以使其可以立即使用,只要有gh-pages分支_layouts(即jekyll网站)即可。它转换了反勾号样式围栏(用于代码块),该样式在github源浏览中很好用,但在gh页中却没有。我index.md在项目中使用带有include的,README.md因此可以添加标题和其他装饰。此版本还处理称为“ docs”的任何嵌套目录中的文档,在具有多个模块(不是git子模块,仅是子目录)的项目中,我发现它很有用:

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

与原始版本的另一个不同之处在于,它page.home在所有页面中设置了一个变量。这可用于定位根目录的相对路径,因此可用于定位诸如CSS之类的静态资源。在_layouts/.default.html我有:

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

这样,我可以编辑css,在本地构建jekyll站点,并在浏览器中查看结果,而不必等待github在服务器上构建它。


0

我最近制作了一个gh-pages-generator软件包来解决此问题-它使用多个MD文件和一个配置文件生成多页站点。

它将正确更新页面之间的所有链接。使其成为CI的一部分将更改提交回gh-pages分支相对容易。

我在这里这里使用它。


0

这并不难,将两个副本粘贴到终端中就可以了。

Jekyll允许您导入markdown文件,然后将其转换为HTML。诀窍是使用导入您README.mdindex.md文件{% include_relative README.md %}。这是我们可以做到的:

值得一试的是如何Jekyll在github上建立一个超级准系统网站(只有两个文件!

设置

您可以复制这两个文件,只需运行一次设置即可将页面与当前的自述文件保持一致(将整个代码块复制并插入到终端中):

# 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

自动化

然后,我们只需要在每次推送之前自动化将所有更改从复制mastergh-pages分支的任务即可。我们可以通过运行此脚本来做到这一点(您可以将其复制并粘贴到终端中

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

它将创建一个推钩,将所有更改从master分支复制到gh-pages每次运行时git push

而已。做完了

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.