回到我最初作为开发人员开始时,测试应用程序通常涉及将应用程序代码文件压缩到ZIP存档中或将它们放置在共享的网络文件服务器上,将它们传输到测试环境中,将其解压缩或复制到正确的位置,然后进行编译如有必要,请手动运行各种测试。 不用说,这是一个耗时,令人沮丧且容易出错的过程,并不是很多人喜欢的过程。
时至今日,事情变得如此简单。 有了随时可用的新的连续交付工具,只要进行更改,就会从其存储库中提取应用程序代码,并自动安全地将其部署到测试或生产环境中。 无需手动摆弄ZIP文件,网络共享或配置文件,并且很容易检查部署的当前状态或将其回滚到以前的版本。
“ IBM Bluemix Continuous Delivery提供了一种安全,自动化的方式,以一致且无错误的方式构建,测试和部署PHP应用程序。 ”
IBMBluemix®Continuous Delivery服务非常有用,因为您可以使用它进行设置,以便GitHub存储库中的每个新提交或成功的请求请求都可以自动构建,测试并将修订后的应用程序代码部署到IBM Bluemix。 让我告诉你怎么做。
您将需要什么
本文的目的是向您介绍–一个希望向在Bluemix上托管PHP应用程序中添加持续交付PHP开发人员– Bluemix持续交付服务及其可以添加到PHP应用程序的功能。 我将使用一个基本PHP应用程序(包括单元测试)和一个简单的工具链,将应用程序从GitHub迁移到Bluemix。 在这种情况下,目标Bluemix部署将始终反映PHP应用程序开发分支的最新测试通过版本。
本文概述的基本过程如下:
- 每次在GitHub源存储库中创建拉取请求时,Travis CI都会使用PHPUnit自动对源代码进行测试,以确保所有单元测试都能通过。
- 如果单元测试通过,则拉取请求将被手动或自动合并到存储库的开发分支中。 该合并将使用Bluemix Continuous Delivery工具链自动触发该应用程序在Bluemix上的新部署。
- 如果单元测试失败,那么拉取请求将不会合并,并且Bluemix上的当前部署将不受影响。
这个简单的过程应该可以使您的Bluemix部署与最新的开发分支保持最新。 一旦了解了此过程,就可以毫无问题地对其进行调整以满足更复杂的要求。
请注意,本文中描述的方法主要旨在确保您的测试和开发环境始终反映应用程序代码的未开发分支中的最新更改。 尽管您也可以使用此处描述的方法来自动将其部署到应用程序的生产环境中,但是如果您不首先考虑所涉及的固有风险(然后,采取适当的控制措施来管理此类风险),就不希望这样做。 。
这是您需要的:
- 一个Bluemix帐户( 在此处注册 )
- 一个GitHub帐户( 在此处注册 )和一个带有一些PHPUnit单元测试PHP应用程序
- 基本了解PHP和PHPUnit
- 使用Apache的本地或托管PHP开发环境(具有mod_rewrite和.htaccess文件支持)
- PHP依赖管理器Composer
- Cloud Foundry命令行工具
- Git命令行工具 (或任何其他Git客户端)
- 文本编辑器或IDE
创建PHP应用程序
要按照本文中的步骤进行操作,您将需要在本地开发环境中使用带有PHPUnit单元测试PHP应用程序。 这是创建此类应用程序的说明。 如果您在本地环境或GitHub存储库中已经有一个满足这些要求PHP应用程序,则可以跳过此步骤。 如果不这样做,则可以按照以下说明进行操作,或在GitHub上克隆示例应用程序的源代码。
从此Composer配置文件开始,应将其保存到$ APP_ROOT / composer.json($ APP_ROOT指向您的项目目录)。 处理器类和名称空间尚不存在,但是您很快就会创建它们。
{
"require": {
"slim/slim": "^3.8",
"slim/php-view": "^2.2",
"phpunit/phpunit": "^5.7",
"ext-mbstring": "*"
},
"autoload": {
"psr-4": {
"App\\Processor\\": "src/app/processors"
}
}
}
使用Composer通过以下命令安装配置文件
shell> php composer.phar install
接下来,为应用程序设置主控制脚本。 该脚本将加载Slim框架并初始化Slim应用程序。 它还将包含每个应用程序路由的回调。 每个回调都定义了当路由与传入请求匹配时要执行的代码。 使用以下内容在$ APP_ROOT / public / index.php中创建此脚本:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
// autoload files
require '../vendor/autoload.php';
// configure Slim application instance
// initialize application
$app = new \Slim\App();
// initialize dependency injection container
$container = $app->getContainer();
// configure processor in DI container
$container['processor'] = function ($container) {
return new \App\Processor\MyProcessor();
};
// "hello world" controller
$app->get('/hello[/{name}]', function (Request $request, Response $response) {
$name = $request->getAttribute('name');
if ($name) {
$processedName = $this->processor->process($name);
$response->getBody()->write("Hello, $processedName!");
} else {
$response->getBody()->write("Sorry, we haven't been introduced yet.");
}
return $response;
});
$app->run();
该代码是Slim框架的官方“ Hello world”脚本的变体。 它设置了应用程序路由/ hello / $ NAME,当您浏览到该路由并提供名称时,它会向您发送欢迎消息。 如果未提供名称,则显示礼貌错误。
此版本的脚本将处理器类添加到Slim依赖项注入容器中,以对输入名称执行一些基本的字符串处理。 包含此处理器类仅是为了在PHPUnit单元测试的基础上增加一些内容,它看起来像这样(将其保存到$ APP_ROOT / src / app / processors / MyProcessor.php中):
<?php
namespace App\Processor;
class MyProcessor
{
public function process($string)
{
return ucfirst(strtolower($string));
}
}
最后,将推荐的Apache重写规则添加到$ APP_ROOT / public / .htaccess中:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
</IfModule>
通过浏览到http:// localhost / hello / james来检查应用程序是否正常运行(根据需要更新此URL以反映您的本地Apache环境),您应该会看到类似的输出:
图1.示例PHP应用程序
创建PHPUnit测试套件和GitHub存储库
现在为您的应用程序添加一些真实的和虚拟PHPUnit测试,以在$ APP_ROOT / tests / AppTest.php中使用:
<?php
use PHPUnit\Framework\TestCase;
class AppTest extends TestCase
{
public function testTrue()
{
$value = true;
$this->assertTrue($value);
}
public function testEmpty()
{
$arr = [];
$this->assertEmpty($arr);
}
public function testProcessor()
{
$processor = new \App\Processor\MyProcessor();
$this->assertEquals('John', $processor->process('john'));
$this->assertEquals('John', $processor->process('JOHN'));
}
}
?>
在$ APP_ROOT / phpunit.xml中创建一个最小PHPUnit配置文件,其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnFailure="false" syntaxCheck="false">
<testsuites>
<testsuite name="Test suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
运行PHPUnit并确保所有测试都通过:
图2. PHPUnit测试运行器
最后,通过GitHub网站创建一个存储库,并使用以下代码清单中所示的命令将代码推送到该存储库。 创建两个分支: master
生产代码库和dev-master
的开发代码库。
shell> git init
shell> git add .
shell> git commit -a
shell> git remote add origin https://github.com/$GITHUB-USERNAME/$GITHUB-REPOSITORY-NAME.git
shell> git push origin master
shell> git checkout -b dev-master
shell> git push origin dev-master
记下GitHub存储库URL,因为下一步将需要它。
图3. GitHub存储库URL
部署到Bluemix
现在是时候从本地开发环境将应用程序部署到Bluemix了。 如果由于在GitHub中已经有一个PHP应用程序存储库而跳过了前两个步骤,请在继续之前将存储库克隆到本地开发环境。
创建应用程序清单文件,记住通过在文件名后附加一个随机字符串(例如您的姓名首字母)来使用唯一的主机名和应用程序名称。
---
applications:
- name: myapp-dev-[initials]
memory: 256M
instances: 1
host: myapp-dev-[initials]
buildpack: https://github.com/cloudfoundry/php-buildpack.git
stack: cflinuxfs2
您还必须配置构建包以将应用程序的public /目录用作Web服务器目录。 创建一个包含以下内容的$ APP_ROOT / .bp-config / options.json文件:
{
"WEB_SERVER": "httpd",
"COMPOSER_VENDOR_DIR": "vendor",
"WEBDIR": "public",
"PHP_VERSION": "{PHP_56_LATEST}"
}
现在,继续并将该应用程序推送到Bluemix:
shell> cf api https://api.ng.bluemix.net
shell> cf login
shell> cf push
现在,您应该能够在http:// myapp-dev- [initials] .mybluemix.net / hello / james上浏览到该应用程序,并看到在创建PHP应用程序的第1步结束时看到的欢迎消息。 如果您没有看到此消息,请使用调试日志找出问题所在 。
创建Bluemix持续交付工具链
在Bluemix控制台中,单击左上角的菜单图标,然后选择Services-> DevOps子菜单。 在服务详细信息页面上,单击“ 创建工具链”,然后选择“ Simple Cloud Foundry”工具链。
图4.工具链的创建
该工具链模板已预先配置为使用GitHub和Delivery Pipeline服务。 在工具链配置页面上,输入工具链的名称。 选择GitHub图标并授权Bluemix访问您的GitHub帐户。 一旦完成一次性授权过程,请选择一个现有存储库,并在创建GitHub存储库的步骤2中输入GitHub上的源存储库URL。
图5.仓库集成
单击创建以创建工具链。 现在,将使用一些默认的默认值初始化工具链和交付管道服务,并将一个Webhook添加到您的GitHub存储库中,以便自动将有关存储库更改的通知通知交付管道服务。 您应该在Bluemix仪表板的工具链概述页面中看到类似图6的内容。
图6.工具链概述
单击交付管道图标,您应该看到管道已经配置了两个阶段:构建和部署。
图7.工具链阶段
尽管这些阶段对于大多数设置都使用合理的默认设置,但是您仍然需要按照以下步骤检查一次:
- 在“构建阶段”面板中,单击“ 配置阶段”图标。 在“ 输入”选项卡中,检查GitHub存储库详细信息是否正确以及“ 分支”字段是否设置为
dev-master
。图8.构建阶段配置
- 在“部署阶段”面板中,单击“ 配置阶段”图标。 在“ 作业”选项卡中,检查部署详细信息(区域,组织,空间和应用程序名称)是否正确。 请注意,应用程序名称将被存储库中应用程序清单文件中的设置覆盖。
图9.部署阶段配置
保存对阶段所做的任何更改。
通过对GitHub存储库的dev-master
分支进行较小更改来测试工具链,例如,将欢迎消息从“ Hello ...”更改为“ Aloha ...”。如果工具链配置正确,则更改应该由Bluemix Delivery Pipeline服务检测到,这又应依次触发Build和Deploy阶段。 在构建新版本的应用程序并将其部署到Bluemix时,您应该能够实时看到更改。
图10.运行中的工具链
如果发生错误,则可以在每个阶段使用“ 查看日志和历史记录”链接来获取详细记录出问题的日志。
图11.工具链日志
此时,您的工具链已在运行,并且对指定GitHub存储库和分支的每次提交都会触发Bluemix上应用程序代码的新部署。 但是您还没有完成。
配置Travis CI以构建和测试拉取请求
如果您在分布式团队中工作,则可能不会直接提交到主存储库分支。 在大多数情况下,您将创建请求请求,这些请求将被手动或自动检查,测试和合并。
这就是Travis CI的用处。Travis CI是一个持续集成引擎,可用于所有GitHub存储库,并且可以配置为针对每个新的请求请求构建和运行测试(包括PHPUnit测试),并将构建标记为通过或拒绝。失败。 然后,审阅者可以将合并请求手动合并到存储库中,或者可以将Travis CI配置为通过自定义脚本自动执行此任务。
我确定您可以看到我要去的地方。 您可以进行设置,以便Travis CI可以自动测试通过拉取请求对应用程序提出的更改,然后将其合并到dev-master
分支中。 请记住,该分支已经由Delivery Pipeline服务监视,因此每次成功合并将导致新版本的应用程序被步骤4中配置的工具链自动部署到Bluemix。
首先使用您的GitHub帐户凭据登录Travis CI网站 ,然后授予Travis CI访问您的GitHub帐户的权限。
图12. Travis CI-GitHub集成
在您的Travis CI配置文件页面上,为GitHub存储库打开Travis CI引擎。 为存储库启用Travis CI后,请在Travis CI界面中单击存储库的“设置”图标以配置构建设置。
图13. Travis CI引擎激活
在“ 常规”部分中,确保“ 构建拉取请求更新”处于打开状态。
图14. Travis CI配置
在$ APP_ROOT / .travis.yml中创建一个最小的Travis CI配置文件,其内容如下:
language: php
php:
- 5.6
install:
- composer install --no-interaction
branches:
only:
- "dev-master"
script:
- vendor/bin/phpunit
简而言之,此配置文件告诉Travis CI仅构建dev-master
分支,并使用vendor / bin / phpunit脚本测试构建。 如果成功,Travis CI将标记生成为通过,以便可以手动合并。
通过在GitHub存储库的dev-master
分支中创建新的请求请求来测试配置。 Travis CI应该注册拉取请求,然后进行构建和测试。 您将能够从Travis CI配置文件页面跟踪构建进度。
图15.正在运行的Travis CI
如果代码可以构建并通过测试,则将其合并到GitHub存储库的dev-master
分支中。
图16. GitHub合并操作
如我在创建Bluemix Continuous Delivery工具链的步骤4中所述,IBM Continuous Delivery工具链现在将接管并将修订的代码库部署到Bluemix。
如果您不耐烦而又不想等待手动合并成功的构建,或者如果您有大量正在进行的请求请求,则可以让Travis CI自动将成功的构建合并到您的存储库中。 这种类型的无人值守的自动合并会带来风险,因此您只应在您的开发部门考虑这一点。
Travis CI不包含用于自动合并的任何内置功能,因此您将需要自定义脚本来执行此操作。 有关某些自动合并脚本的示例,请参考本文结尾处的链接。 您也可以创建自己的脚本来执行此操作以及其他相关任务,例如发布通知或更新项目面板。
创建自定义脚本后,请记住,必须通过在$ APP_ROOT / .travis.yml文件中添加类似于示例的块,来指示Travis CI在成功的构建上调用它:
after_success:
- chmod +x ./do-merge.sh
- ./do-merge.sh
结论
在本文中,我演示了如何使用Bluemix Continuous Delivery服务使Bluemix应用程序部署与GitHub代码存储库保持同步。 通过提供现成的工具链模板,该模板已配置为可以与GitHub一起使用,Bluemix Continuous Delivery提供了一种安全,自动化的方式,以一致且无错误的方式构建,测试和部署PHP应用程序。
Bluemix提供了许多现成的工具集成,因此您还可以将工具链与其他流行的工具结合使用,例如,用于通知的Slack或用于问题跟踪的JIRA。 试试看,自己看看!
致谢
感谢Chris Down提供的Travis自动合并脚本,在撰写本文时使用了该脚本的修改版本。