对于每次提交,在单独的repo或分支中创建等效的编译提交

时间:2017-02-04 21:32:09

标签: git githooks post-commit-hook

我正在使用Jekyll构建网站,它编译ERB,SASS和& c。简单的HTML& CSS。

在大多数提交之后,我想编译站点并将编译后的版本提交到单独的存储库或分支中,以便可以将其推送到静态服务器。

最好的方法是什么?

我已经有a solution,但我希望有人可能会更优雅。

5 个答案:

答案 0 :(得分:5)

  

在大多数提交之后,我想编译站点并将编译后的版本提交到单独的存储库或分支中,以便可以将其推送到静态服务器。

您的正确关键字是“持续集成”。

您可以使用像Jenkins这样的CI软件在每次提交后,在创建或修改拉取请求之后构建您的系统,或者只是每晚。

您在CI软件中配置的构建脚本负责将构建的工件(在这种情况下是您的编译版本)部署到目标系统,如s3存储桶。您还可以将您的人工制品程序化提交到不同的git仓库。

看看这里:https://jenkins.io/doc/

答案 1 :(得分:2)

您的解决方案会将混合在同一个回购"来源提交"和#34;交付提交" (_site编译版本),最佳实践(并且会不必要地增加Git仓库的大小)

我会创建一个单独的回购" site"我会在名为_site/的路径中将 submodule 添加到您当前的仓库。

cd /path/to/current/repo
git rm -R _site
git submodule add -- /url/repo/site _site

这样,每次使用bundle exec jekyll build构建交付时,都会在一个单独的仓库(_site)中完成,您可以在其中添加,提交甚至直接推送到您想要的位置测试它。
然后你回到你的主仓库,在那里添加并提交 gitlink special entry in the index),在源的确切版本与确切版本之间建立强大的链接交付版本(建成网站)。

答案 2 :(得分:2)

根据您的要求

我不建议您使用相同的repo存储已编译的代码。因为它可以从任何源代码状态获得,所以它将是不必要的信息发布。

因此,在这种情况下,您希望使用git作为CI工具。您应该为已编译的站点创建另一个repo,并在每次需要时进行提交。

我建议你为代码的“生产”状态选择分支。当你提交那个分支时 - 代码应该被重建。让我们把它命名为“生产”。

  1. 为构建的代码单独创建git repo。
  2. 将此代码放入src repo中的post-commit挂钩。 它将处理生产分支中的所有提交,将代码签出到临时目录,进行构建并提交更改。
  3. srcDir='../srcWorkTree'
    buildedRepo='../buildedRepo'
    
    if [ `git rev-parse --abbrev-ref HEAD` == "production" ]; then
        echo "making builded code commit..."
        mkdir -p $srcDir
        # http://stackoverflow.com/questions/4479960/git-checkout-to-a-specific-folder
        git checkout-index -a -f --prefix=$srcDir/
    
        bundle exec jekyll build --source $srcDir --destination $buildedRepo
    
        cd $buildedRepo
        git add -A
        commitInfo=$( git log -1 --pretty="%h %B" )
        git commit -m "autobuild for $commitInfo"
        # git push
    fi
    

    另一种变体

    正如我可以想象的那样,您可以访问您的生产服务器。至少你提到你在那里有git repo。因此,使用post-receive hook将代码构建到目标目录是合理的。它将更清晰简单,而不是像我所描述的那样在本地机器上进行。

    我认为这个回购是“裸露的”,因为你不应该在服务器上进行更改。

    收到后挂钩:

    #!/bin/sh
    
    siteDir='/var/www/site'
    tmpSrcDir='/var/www/site'
    
    echo "**** [builder's post-receive hook]"
    
    while read oldrev newrev refname
    do
        if [ $refname = refs/heads/production ]
        then
            GIT_WORK_TREE=$tmpSrcDir git checkout --detach $newrev
    
            bundle exec jekyll build --source $tmpSrcDir --destination $siteDir
        fi
    done
    
    exit 0
    

    几条评论

    我知道,您尝试使用子模块来存储您构建的网站。我不推荐。没有任何意义,因为您的源代码不依赖于构建的代码。

答案 3 :(得分:2)

我只是建议另一种选择:不要将编译后的版本存储在git中,将它们存储在其他地方。

以您的工作流程为例:

  • 当我们需要测试特定提交时,我们通过CI流程运行它,生成.tar.gz存档,我们使用部署工具在登台服务器上测试它;

    < / LI>
  • 当我们为发布版本选择提交时,我们在git中标记此提交,我们通过CI流程运行它,.tar.gz标记有版本号并存储在某些{{1}中我们的部署服务器上的目录。

我们有releases/文件夹的备份,但是如果我们放弃它,我们也可以从源代码重建任何特定版本(基于标记)。

答案 4 :(得分:1)

_site/初始化一个Git仓库,然后添加一个Git post-commit hook .git/hooks/post-commit

echo -n "Add commit to compiled version? (y/N) "
read answer < /dev/tty
if [ "$answer" != "y" ]; then exit; fi

message=$( git log -1 --pretty=%B )

git stash --all
bundle exec jekyll build

cd _site
    git add --all
    git commit -m "$message"
cd ..

git stash pop

现在,每次提交时,都会询问您是否要为已编译的版本添加提交。