<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>持续集成/持续部署（CI/CD） on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/%E6%8C%81%E7%BB%AD%E9%83%A8%E7%BD%B2ci/cd/</link><description>Recent content in 持续集成/持续部署（CI/CD） on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 23 Oct 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/%E6%8C%81%E7%BB%AD%E9%83%A8%E7%BD%B2ci/cd/index.xml" rel="self" type="application/rss+xml"/><item><title>持续集成/持续部署（CI/CD）</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/engineering/engineering-009/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/engineering/engineering-009/</guid><description>&lt;h2 id="传统应用发布模式"&gt;传统应用发布模式&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;开发人员&lt;/strong&gt;：在开发环境完成代码编写，单元测试，测试通过后提交到代码仓库&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;运维人员&lt;/strong&gt;：把项目部署到测试环境，供QA团队测试，测试通过后，部署生成环境&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;测试人员&lt;/strong&gt;：进行测试，测试完成后通知运维部署生产环境&lt;/p&gt;
&lt;h3 id="缺点"&gt;缺点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;项目在早期就存在错误，但到最后集成的时候才发现&lt;/li&gt;
&lt;li&gt;需要手动操作，易错率高&lt;/li&gt;
&lt;li&gt;开发与运维需要及时沟通 有了以上缺点，那么就有了CI/CD&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="cicd"&gt;CI/CD&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;持续集成&lt;/em&gt;(CI):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;合并开发人员正在编写的所有代码&lt;/li&gt;
&lt;li&gt;一天内进行多次合并和提交代码&lt;/li&gt;
&lt;li&gt;从存储库或生产环境中进行构建和自动化测试，确保没有集成问题并及早发现任何问题&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;持续交付&lt;/em&gt;(CD):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;可以通过将更改自动推送到发布系统来随时将软件发布到生产环境中&lt;/li&gt;
&lt;li&gt;持续部署，并自动将更改推送到生产中&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="gitlab内置cicd"&gt;GitLab内置CI/CD&lt;/h2&gt;
&lt;h3 id="运行流水线任务"&gt;运行流水线任务&lt;/h3&gt;
&lt;p&gt;Job&lt;/p&gt;
&lt;p&gt;在文件中可以定义一个或多个作业，每个作业具有唯一的名称，每个作业是独立执行的，&lt;em&gt;每个作业至少包含一个script&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;stages：&lt;/p&gt;
&lt;p&gt;用于定义作业可以使用的阶段，并且是全局定义，同一个阶段的作业并行运行，不同阶段按顺序运行&lt;/p&gt;
&lt;p&gt;only：&lt;/p&gt;
&lt;p&gt;用分支策略来限制jobs构建&lt;/p&gt;
&lt;p&gt;script:&lt;/p&gt;
&lt;p&gt;项目中package中的脚本&lt;/p&gt;
&lt;p&gt;environment：&lt;/p&gt;
&lt;p&gt;定义此作业完成部署的环境名称&lt;/p&gt;
&lt;p&gt;下面是每个jobs的详细变量名&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Keyword&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;script&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;Runner执行的命令或脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;image&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;所使用的docker镜像，查阅&lt;a href="https://docs.gitlab.com/ce/ci/docker/using_docker_images.html#define-image-and-services-from-gitlab-ciyml"&gt;使用docker镜像&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;services&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;所使用的docker服务，查阅&lt;a href="https://docs.gitlab.com/ce/ci/docker/using_docker_images.html#define-image-and-services-from-gitlab-ciyml"&gt;使用docker镜像&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stage&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义job stage（默认：&lt;code&gt;test&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stage&lt;/code&gt;的别名（已弃用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;variables&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义job级别的变量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;only&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义一列git分支，并为其创建job&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;except&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义一列git分支，不创建job&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tags&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义一列tags，用来指定选择哪个Runner（同时Runner也要设置tags）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;allow_failure&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;允许job失败。失败的job不影响commit状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;when&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义何时开始job。可以是&lt;code&gt;on_success&lt;/code&gt;，&lt;code&gt;on_failure&lt;/code&gt;，&lt;code&gt;always&lt;/code&gt;或者&lt;code&gt;manual&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dependencies&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义job依赖关系，这样他们就可以互相传递artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cache&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义应在后续运行之间缓存的文件列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;before_script&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;重写一组在作业前执行的命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;after_script&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;重写一组在作业后执行的命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;environment&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义此作业完成部署的环境名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coverage&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;定义给定作业的代码覆盖率设置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="配置gitlab-ciyml"&gt;配置.gitlab-ci.yml&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;stages:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; deploy_dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; deploy_test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; deploy_production
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deploy_dev:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stage: deploy_dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; only:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; script:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; rsync &lt;span style="color:#f92672"&gt;-&lt;/span&gt;av &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#f92672"&gt;$&lt;/span&gt;{WORKSPACE_PATH} &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cd &lt;span style="color:#f92672"&gt;$&lt;/span&gt;{WORKSPACE_PATH}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; npm run build:dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;playbook ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;deploy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;yml &lt;span style="color:#f92672"&gt;--&lt;/span&gt;extra&lt;span style="color:#f92672"&gt;-&lt;/span&gt;vars &lt;span style="color:#e6db74"&gt;&amp;#34;hosts=cloud_ui_test projectDir=${WORKSPACE_DIST_PATH} projectName=${PROJECT_NAME} webRootPath=/opt/devroot/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deploy_test:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stage: deploy_test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; only:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; script:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; rsync &lt;span style="color:#f92672"&gt;-&lt;/span&gt;av &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#f92672"&gt;$&lt;/span&gt;{WORKSPACE_PATH} &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cd &lt;span style="color:#f92672"&gt;$&lt;/span&gt;{WORKSPACE_PATH}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; npm run build:stage
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;playbook ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;deploy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;yml &lt;span style="color:#f92672"&gt;--&lt;/span&gt;extra&lt;span style="color:#f92672"&gt;-&lt;/span&gt;vars &lt;span style="color:#e6db74"&gt;&amp;#34;hosts=cloud_ui_test projectDir=${WORKSPACE_DIST_PATH} projectName=${PROJECT_NAME} webRootPath=${WEB_ROOT_PATH}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deploy_production:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stage: deploy_production
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; only:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; production
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; when: manual
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; script:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; npm install
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; npm run build:prod
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;playbook ansible&lt;span style="color:#f92672"&gt;-&lt;/span&gt;deploy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;yml &lt;span style="color:#f92672"&gt;--&lt;/span&gt;extra&lt;span style="color:#f92672"&gt;-&lt;/span&gt;vars &lt;span style="color:#e6db74"&gt;&amp;#34;hosts=dvs-front-prod projectDir=${PROJECT_PATH} projectName=xianglin-cloud-ui/${PROJECT_NAME} webRootPath=/opt/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面这个.yml文件,我们首先定义了三个阶段，deploy_dev部署到dev环境，并且拉去的是dev分支代码; deploy_test部署到test环境，拉去的是master分支代码，deploy_production拉取production分支代码，执行完后需要手动操作&lt;/p&gt;</description></item></channel></rss>