如何将文档与Github页面同步?

时间:2013-03-05 02:26:32

标签: git github github-pages webhooks

我和一些人一起有一个项目,我们有一个README.md文件,其中有一堆GitHub Flavored Markdown,它们在我们的GitHub页面上呈现。我们还设置了一个GitHub Pages分支,该分支托管在我们的GitHub组织的子域下,并在我们创建页面时使用Automatic Page Generator简单地加载到README.md文件中。但是,我注意到当我更新README.md文件时,它不会更新项目页面。相反,我们必须转到GitHub设置选项卡并重新创建项目页面,在我们这样做时重新加载README.md文件。

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

换句话说,我的问题是:

  • 有没有办法让我的README.md文件在我的Github页子域上自动更新?
    • [编辑]:如果使用自动页面生成器,似乎没有答案。您必须转到回购的设置页面,并在每次更改时重新加载它以便更新它
  • 有没有办法可以将我的README.md文件上的文档的相关链接放在我的Github页面上,也许我会以某种方式将我的/docs/*.md同步到我的Github页面并以某种方式呈现和/或主题化它们?
    • [编辑]:从写完这个问题后我学到的东西看来,只有在GitHub页面才能通过使用像{3}}这样的红宝石宝石来static site generator 3}}以及下面评论中提到的Jekyll的一些用法。我正在尝试寻找最佳解决方案
  • 更好的是,有没有更简单的方法可以做到这一点,也许只有一份我的README.md和文档,用于gh-pages和我的主分支,并使一切最简单?
    • [编辑]:看来这个几乎肯定是不行的。我正在考虑GitHub中内置的东西的可能性。似乎未来可能会在GitHub页面中构建对此类事物的更好支持,或者至少我绝对希望它会如此。

10 个答案:

答案 0 :(得分:37)

我将发布一个我设置的解决方案,它利用了GitHub Pages使用Jekyll已经使用自动页面生成器这一事实。

  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
  7. ---
    layout: index
    ---
    

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

    1. README.md文件的markdown中删除呈现的HTML。这通常位于<section><article>标记之间。将此HTML替换为文本{{ content }},这将允许我们将此文件用作jekyll。我们应用布局的文件将放置在内容标记所在的位置。

    2. 找到项目页面主题的CSS。对我来说,这是一个如下所示的行:

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

      这需要更改为

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

    3. 您网站上存储的将用于此布局的任何其他资源也需要以{{ site.path }}为前缀。
    4. 通过这样做,Jekyll将markdown文件呈现为index.html目录中_layouts布局的内容。为了使这个过程不仅自动化README.md文件,而且还有你的主分支中可能有的其他文档,我采取了以下步骤:

      创建名为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函数,以便从.md分支上的锚点中剥离gh-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。为了解决这个问题,我将其更新为以下脚本,该脚本会更仔细地检出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设置了一个示例回购,其中有project page here,如果您想了解所有这些是如何协同工作的。

答案 1 :(得分:5)

我将README与Github页面同步的问题的解决方案与上述略有不同。可以使用Github API返回呈现为HTML的Markdown文件,而不是使用单独的JavaScript Markdown引擎。

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

     {
       "text": "<README>",
       "mode": "markdown",
       "context": "<owner>/<repo>"
     }
    
  5. 将呈现的HTML插入到DOM元素中,如Brad Rhodes所示。

  6. 这种方法有两点需要注意:

    1. 执行两个串行请求会减慢页面加载速度。
    2. 访问Github API时可能会遇到速率限制。
    3. 对于负载时间不重要(约1-2秒)的低流量页面,上述方法运行良好。

答案 2 :(得分:4)

您可以使用DocumentUp呈现README.md。

答案 3 :(得分:3)

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

  1. 您只能使用包含代码和jekyll文档站点的单个gh-pages分支。您的存储库可能会变得有点混乱,您需要在自述文件的顶部放置一个YAML标头。 几乎支持相对链接。问题是,如果你想让jekyll渲染你的降价,它会给它一个.html扩展名。也许有一种方法可以配置它。 Here's an example I threw together to see if it works.

  2. 您可以在文档站点中使用AJAX调用来读取主分支中的自述文件,然后使用Javascript Markdown renderer进行渲染。这需要更长的时间来加载,如果没有你编写一些聪明的Javascript,它将不支持相对链接。与想法1相比,实施起来也更多。

答案 4 :(得分:3)

另一个需要考虑的方法是设置pre-commit hook来构建相关页面。我在one of my repositories中执行此操作。您可能不得不放弃自动页面生成器,只是自己推送到gh-pages分支,以及做一些花哨的事情,将您的文档转换为HTML或Jekyll网站Nathan suggests。< / p>

在该存储库I push like this中保持gh-pagesmaster相同。还有很多other ways可以做到这一点。这可能不适合您的情况(您可能不希望它们相同)。

无论如何,我在这个问题上提供赏金的原因是因为我希望有人有更好的工作流程。这种方法有点复杂且不灵活,需要每个人保持同步。

答案 5 :(得分:2)

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

  1. 使用Github API和JSONP从Github
  2. 获取文档
  3. 解码来自Github API的响应中的base64内容
  4. 使用javascript markdown引擎
  5. 渲染降价
  6. 显示呈现的html
  7. 内森对表现表示了一些担忧,但根据我的经验,它似乎立即加载,所以我不认为这实际上是一个问题。

    优势在于它易于设置,即使您只是直接在github上的浏览器中编辑markdown,它也会始终更新您的文档。

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

答案 6 :(得分:2)

Nathan和Brand Rhodes描述的方法的另一种可能性是使用Rico Sta创建的一个很棒的工具FlatDoc。克鲁兹。

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

它在api中构建了一个帮助方法来从GitHub repo master加载文件(但也可以从Web上的任何其他地方加载)。

<强>说明

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

  • 用您的GitHub用户名替换“USER”
  • 用您的GitHub回购名称替换“REPO”
  • 用您的项目名称替换“您的项目”

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

如果默认主题不适合您,您可以使用自己的CSS重新设置它。

答案 7 :(得分:1)

我还想在master中编辑文档并在gh-pages中发布 - 我喜欢让文档与源代码保持同步,这似乎是最好的方法。这对我来说正在进行中,但是我以Cory's script作为起点并进行了扩展,只要有一个带有_layouts的gh-pages分支就可以开箱即用(即一个jekyll网站)。它转换反引号样式的防护(对于代码块),它在github源代码浏览中很好地工作,但不在gh-pages中。我使用带有项目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在服务器上构建它。

答案 8 :(得分:0)

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

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

我正在使用herehere

答案 9 :(得分:0)

不难,两次复制并粘贴到终端中,您就已经完成了设置。

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

值得查看how to setup a super barebones Jekyll site on 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

自动化

然后我们只需要在每次推送之前自动执行将所有更改从master复制到gh-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

就是这样。完成。