自动化部署Git, Bitbucket和PHP


Automate Deployments with Git, Bitbucket and PHP

当我将git推送到我的bitbucket存储库时,我正在尝试设置自动部署。我有一个php部署脚本,我利用这个博客,但当脚本运行时,它是日志记录,它只是从以前的提交更新。

下面是一个例子。假设我登录到我的服务器并输入git pull。服务器将使用最新的更改进行更新,假设该提交的哈希值为001。然而,如果我做了几次提交,我们称它们为002、003和004,我的脚本应该每次都运行,假设我在每次提交后都将这些更改推送到bitbucket。脚本运行,但每次都会保留001的更改。只有当我登录到我的服务器并输入git pull时,服务器才会更新到004。你知道是什么引起的吗?

// Make sure we're in the right directory
exec('cd '.$this->_directory, $output);
$this->log('Changing working directory... '.implode(' ', $output));
// Discard any changes to tracked files since our last deploy
exec('git reset --hard HEAD', $output);
$this->log('Reseting repository... '.implode(' ', $output));
// Update the local repository
exec('git pull '.$this->_remote.' '.$this->_branch, $output);
$this->log('Pulling in changes... '.implode(' ', $output));
// Secure the .git directory
exec('chmod -R og-rx .git');
$this->log('Securing .git directory... ');
if (is_callable($this->post_deploy))
{
 call_user_func($this->post_deploy, $this->_data);
}
$this->log('Deployment successful.');

我的建议是不要根据你的主版中的最新版本发布,而是使用最新的标签。

/home/my-user/my-application/1.0.12/www
/home/my-user/my-application/1.0.13/www

等。这提供了回滚功能。您可以编写一个PHP脚本,通过SSH连接到服务器,并基于该标记创建一个新的克隆。如果您使用Composer,则可以使用它来执行命令。如果没有,你可以用makefile来完成。

编辑:我忘了说你是怎么链接的。

你有一个符号链接
/home/my-user/my-application/www -> /home/my-user/my-application/1.0.12/www

当整个部署脚本完成且没有错误时,将符号链接切换为:
/home/my-user/my-application/www -> /home/my-user/my-application/1.0.13/www

您的应用程序现在可以运行,没有停机时间。

一个非常简单而有效的方法是使用bitbucket管道,您可以创建一个YAML脚本来编译依赖项,并在每次提交时自动或手动将代码推送到服务器。

下面是一个Bitbucket pipes YAML脚本的例子:

image: php:7.1.1
pipelines:
  default:
    - step:
       caches:
         - composer
       script:
         - apt-get update && apt-get install -y unzip
         - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
         - composer install
    - step:
       deployment: staging
       name: Deploy to Staging Server
       script:
         - apt-get update
         - apt-get -qq install rsync 
         - echo "Upload Project files..."
         - rsync -avH * -e "ssh" root@$IP_SERVER:/var/www/html/

该脚本在Docker实例中安装Composer依赖项,并将项目文件推送到服务器。

问题是文件权限。

我一直在浏览那个博客的链接。我发现php和nginx进程使用的"www-data"用户没有对存储库代码的写入权限。它甚至不能使用git。

为了验证这一点,尝试在服务器上以'www-user'的身份执行'git pull'。你可以通过"sudo su www-data"切换到它。你会发现它甚至认不出这是一个有效的git repo,并且无法运行你的'deploy.php'脚本而不出错。

您需要为您的存储库设置适当的权限,以便www-data可以访问它。

或者你改变整个方法。跟随这个帖子http://toroid.org/ams/git-website-howto,我觉得这是一个比上面更好的方法。我最终使用了这个方法

您想要在您推送到的远程中设置post-update钩子。

在默认情况下,git不会检出你推送到远程的任何数据。这就是为什么默认的git配置拒绝推送到签出分支,因为当你推送到签出分支时,签出的文件已经不是最新的HEAD了。

当远程接收到一个分支的推送时,你可以在post-update钩子中对它做出反应。要查看发生了什么,您应该首先从一些日志开始:

echo "post update `date`: $*" >> /home/ingo/test/githooks.out

当我推到分支new时,例如,我得到一行

post update Mi 24. Jun 13:01:14 CEST 2015: refs/heads/new

,其中$*包含我推送到的分支。

有了这个,你可以简单地写一个脚本来签出那个分支。我更喜欢签出而不是分离头,因为将来自几个模块存储库(没有子模块)的工作合并到一个部署版本中要简单得多。关于如何在git存储库外签出代码并使用它,请参阅我对源代码部署的回答。

例如

for b in $*
do B=`basename $b`
if [ "$B" = "publish" ] # react on changes to the publish branch
then git --work-tree "PATH TO THE PUBLISHED WORK TREE" checkout publish
do_some_extra_work # to change permissions or inform your team leader
fi done

当然您也可以执行checkout步骤,这是在pull

上完成的。
if [ "`cat HEAD`" = "ref: refs/heads/master" ]
# only do that checkout if the repository is in a sane state
then git merge new # I assume you push to new
fi
最酷的是,您将在执行push的终端中看到远程钩子的输出:
# git push remote master:new
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 296 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Updating f81ba5b..a99a710
remote: Fast-forward
remote:  a.txt | 2 ++
remote:  1 file changed, 2 insertions(+)
To ../remote
    db48da1..a99a710  master -> new