news 2026/6/5 6:06:35

PHP自动化构建与持续交付流水线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP自动化构建与持续交付流水线

PHP自动化构建与持续交付流水线

自动化构建和持续交付是现代软件开发的基础设施。今天说说PHP项目的构建、测试、部署流水线的各个阶段。

构建阶段包括代码检查、依赖安装、静态分析和单元测试。

```php
// 构建状态追踪
class BuildPipeline
{
private string $buildId;
private string $branch;
private string $commit;
private array $stages = [];
private string $status = 'pending';
private ?string $error = null;

public function __construct(string $branch, string $commit)
{
$this->buildId = date('Ymd') . '_' . uniqid();
$this->branch = $branch;
$this->commit = $commit;
}

public function runStage(string $name, callable $stage): bool
{
echo "\n=== {$name} ===\n";
$startTime = microtime(true);

try {
$stage();
$duration = round((microtime(true) - $startTime) * 1000);
$this->stages[] = ['name' => $name, 'status' => 'success', 'duration' => $duration];
echo " 完成 ({$duration}ms)\n";
return true;
} catch (\Exception $e) {
$duration = round((microtime(true) - $startTime) * 1000);
$this->stages[] = ['name' => $name, 'status' => 'failed', 'duration' => $duration];
$this->error = $e->getMessage();
$this->status = 'failed';
echo " 失败: {$e->getMessage()}\n";
return false;
}
}

public function execute(array $stages): void
{
echo "构建 #{$this->buildId} 开始\n";
echo "分支: {$this->branch}, 提交: {$this->commit}\n";

foreach ($stages as $name => $stage) {
if (!$this->runStage($name, $stage)) {
echo "\n构建失败\n";
$this->status = 'failed';
return;
}
}

$this->status = 'success';
echo "\n构建成功\n";
}

public function getSummary(): array
{
$totalDuration = array_sum(array_column($this->stages, 'duration'));

return [
'build_id' => $this->buildId,
'branch' => $this->branch,
'commit' => $this->commit,
'status' => $this->status,
'stages' => $this->stages,
'total_duration_ms' => $totalDuration,
'error' => $this->error,
];
}
}

$build = new BuildPipeline('main', 'abc1234');

$build->execute([
'语法检查' => function () {
exec('php -l src/index.php 2>&1', $output, $code);
if ($code !== 0) throw new \RuntimeException(implode("\n", $output));
},
'依赖安装' => function () {
exec('composer install --no-dev --no-progress 2>&1', $output, $code);
if ($code !== 0) throw new \RuntimeException('Composer安装失败');
},
'单元测试' => function () {
exec('vendor/bin/phpunit --no-coverage 2>&1', $output, $code);
if ($code !== 0) throw new \RuntimeException('单元测试失败');
},
]);

print_r($build->getSummary());
?>
>

版本号管理和自动发布:

```php
class VersionManager
{
private string $versionFile;
private array $version;

public function __construct(string $versionFile = 'VERSION')
{
$this->versionFile = $versionFile;
$this->version = $this->load();
}

private function load(): array
{
if (file_exists($this->versionFile)) {
$content = trim(file_get_contents($this->versionFile));
$parts = explode('.', $content);
return [
'major' => (int)($parts[0] ?? 1),
'minor' => (int)($parts[1] ?? 0),
'patch' => (int)($parts[2] ?? 0),
];
}
return ['major' => 1, 'minor' => 0, 'patch' => 0];
}

public function getVersion(): string
{
return "{$this->version['major']}.{$this->version['minor']}.{$this->version['patch']}";
}

public function bumpMajor(): string
{
$this->version['major']++;
$this->version['minor'] = 0;
$this->version['patch'] = 0;
return $this->save();
}

public function bumpMinor(): string
{
$this->version['minor']++;
$this->version['patch'] = 0;
return $this->save();
}

public function bumpPatch(): string
{
$this->version['patch']++;
return $this->save();
}

private function save(): string
{
$version = $this->getVersion();
file_put_contents($this->versionFile, $version);
return $version;
}

public function generateChangelog(array $changes): string
{
$date = date('Y-m-d');
$version = $this->getVersion();

$log = "## [{$version}] - {$date}\n\n";
foreach ($changes as $type => $items) {
if (!empty($items)) {
$log .= "### {$type}\n";
foreach ($items as $item) {
$log .= "- {$item}\n";
}
$log .= "\n";
}
}

$changelogFile = 'CHANGELOG.md';
$existing = file_exists($changelogFile) ? file_get_contents($changelogFile) : '';
file_put_contents($changelogFile, $log . $existing);

return $version;
}
}

$version = new VersionManager();
echo "当前版本: {$version->getVersion()}\n";

$changes = [
'新增' => ['用户注册功能', '订单导出功能'],
'修复' => ['修复了分页bug', '修复了登录超时问题'],
];

$newVersion = $version->generateChangelog($changes);
echo "新版本: {$newVersion}\n";

// 自动打Tag
$tag = "v{$newVersion}";
exec("git tag -a {$tag} -m 'Release {$tag}'");
exec("git push origin {$tag}");
echo "Git Tag: {$tag}\n";
?>

构建产物管理和自动化部署脚本:

```php
class ArtifactManager
{
private string $artifactDir;

public function __construct(string $artifactDir = '/var/www/artifacts')
{
$this->artifactDir = rtrim($artifactDir, '/');
if (!is_dir($this->artifactDir)) mkdir($this->artifactDir, 0755, true);
}

public function build(string $sourceDir, string $version): string
{
$artifactName = "app-{$version}.tar.gz";
$artifactPath = "{$this->artifactDir}/{$artifactName}";

$exclude = ['--exclude=.git', '--exclude=node_modules', '--exclude=tests'];
$excludeStr = implode(' ', $exclude);

exec("tar -czf {$artifactPath} {$excludeStr} -C {$sourceDir} . 2>&1", $output, $code);

if ($code !== 0) {
throw new \RuntimeException("构建失败: " . implode("\n", $output));
}

echo "构建产物: {$artifactPath} (" . round(filesize($artifactPath) / 1024 / 1024, 2) . "MB)\n";
return $artifactPath;
}

public function deploy(string $artifact, string $targetDir): void
{
if (!file_exists($artifact)) {
throw new \RuntimeException("构建产物不存在: {$artifact}");
}

if (!is_dir($targetDir)) mkdir($targetDir, 0755, true);

exec("tar -xzf {$artifact} -C {$targetDir} 2>&1", $output, $code);

if ($code !== 0) {
throw new \RuntimeException("部署失败: " . implode("\n", $output));
}

$this->setPermissions($targetDir);
echo "部署完成: {$targetDir}\n";
}

private function setPermissions(string $dir): void
{
exec("chmod -R 755 {$dir}");
if (is_dir("{$dir}/storage")) {
exec("chmod -R 775 {$dir}/storage");
}
}
}
?>

自动化构建和持续交付是DevOps实践的核心。自动化流水线确保代码质量,减少人工操作,加快交付速度。构建、测试、部署的自动化程度越高,团队的交付效率也就越高。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 6:06:32

JoyAI-Image-Edit模型部署指南:从开发到生产的完整流程

JoyAI-Image-Edit模型部署指南:从开发到生产的完整流程 【免费下载链接】JoyAI-Image-Edit-Diffusers 项目地址: https://ai.gitcode.com/jd-x-opensource/JoyAI-Image-Edit-Diffusers 想要快速掌握先进的AI图像编辑技术吗?JoyAI-Image-Edit作为…

作者头像 李华
网站建设 2026/6/5 6:06:22

微信小程序逆向工程完全指南:Wedecode工具深度解析与实战应用

微信小程序逆向工程完全指南:Wedecode工具深度解析与实战应用 【免费下载链接】wedecode 全自动化,微信小程序 wxapkg 包 源代码还原工具, 线上代码安全审计,支持 Windows, Macos, Linux 项目地址: https://gitcode.com/gh_mirrors/we/wede…

作者头像 李华
网站建设 2026/6/5 6:06:20

PHP混沌工程与故障注入测试

PHP混沌工程与故障注入测试混沌工程通过主动引入故障来验证系统的容错能力。故障注入可以测试系统在异常情况下的表现。今天说说PHP中实现混沌工程和故障注入的方法。故障注入是在代码层面模拟各种异常情况,验证系统的容错逻辑。phpclass ChaosEngine { private arr…

作者头像 李华
网站建设 2026/6/5 6:06:13

5G速率上不去?从PDSCH码率控制算法入手,看懂调度器的‘小心思’

5G速率优化实战:解码PDSCH码率控制算法的底层逻辑当你在5G现网测试中盯着屏幕上始终无法突破的吞吐率曲线时,是否思考过调度器背后的决策机制?作为无线网络优化的核心战场,PDSCH码率控制算法直接决定了空口传输效率的天花板。本文…

作者头像 李华