使用Git、Bitbucket和PHP自动化部署

4
我正在尝试在将代码推送到我的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.');

你也有子模块吗?如果有,请不要忘记 git submodule update - halfer
我真的不知道什么是子模块。我刚开始使用Bitbucket和Git。 - Jason Biondo
子模块是指向标签的存储库,位于您的存储库中。建议尽可能不使用它。如果您有多个内部应用程序使用相同的插件/库,则可能会出现这种情况。他们为此发明了Composer ;) - Anyone
如果您使用了一个具有git仓库的外部库,您可以设置一个子模块(submodule),它指向该远程库中的特定提交(commit)。如果您在工作库中更新了子模块(例如,您将库升级到较新版本),那么您需要在远程库上发出上述命令,以使子模块与其当前提交保持最新状态。Git手册会更详细地解释,并通过示例引导您理解。:) - halfer
4个回答

5
我建议的是根据最新的tag而不是在你的主分支中发布最新版本。
例如:
/home/my-user/my-application/1.0.12/www
/home/my-user/my-application/1.0.13/www
这样可以提供回滚功能。您可以编写一个连接到服务器并基于该tag创建镜像的PHP脚本。如果您使用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
这样,您的应用程序就可以在没有停机时间的情况下上线了。

1
一个非常简单而高效的方法是使用Bitbucket Pipelines,您可以创建一个YAML脚本来编译您的依赖项并在每次提交时将代码推送到服务器,自动或手动进行。
以下是Bitbucket Pipelines 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/

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


0

你想在推送到远程仓库时设置一个post-update钩子。

默认情况下,git不会检出您推送到远程仓库的任何数据。这就是为什么默认的git配置拒绝将内容推送到已检出分支,因为当您将内容推送到已检出分支时,检出的文件与HEAD不再是最新的。

但是,当远程仓库接收到对分支的推送时,您可以在post-update钩子中做出反应。为了查看发生了什么,您应该首先进行一些日志记录:

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

当我推送到新分支时,例如我会得到这行代码。
post update Mi 24. Jun 13:01:14 CEST 2015: refs/heads/new

在这里,$* 包含我推送到的分支。

有了这个,你可以简单地编写一个脚本来检出该分支。我更喜欢检出到分离的HEAD,因为它更容易将多个模块存储库(没有子模块)中的工作组合成部署版本。查看我的 answer 以获取有关如何在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

当然你也可以完成结账步骤,这是在拉取时完成的

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

0

问题在于文件权限。

我按照同样的链接查看了那篇博客文章。我发现,php和nginx进程使用的“www-data”用户没有对您的存储库代码进行写入权限。它甚至无法使用git。

为了验证这一点,请尝试在服务器上以“www-user”的身份执行“git pull”。您可以通过“sudo su www-data”切换到该用户。您会发现它甚至无法将其识别为有效的git存储库,并且无法在没有错误的情况下运行您的“deploy.php”脚本。

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

或者您可以改变整个方法。请遵循此帖子http://toroid.org/ams/git-website-howto,我认为这是比上述方法更好的方法。我最终采用了这种方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接