介绍
Cedar & Common 正在筹备社区活动日。正式活动安排已经上线,两个候选方案则需要独立预览。Jenkins 可以构建这两个分支,但它们当前的 Pipeline 会发布到同一个位置。仅有构建成功,并不能让两个方案同时可用。
你将发现这些分支,观察发布冲突,修改它们的 Jenkinsfile,并发布两个可用的预览。随后,你将更改一个集合时间,确认其预览得到更新,而另一个方案保持不变。
前置要求是基本终端输入和路径知识、Jenkins 页面操作,以及能看懂一段简短的声明式流水线。实验会在使用前解释 Git 分支、提交、推送、索引扫描和新的 Pipeline 设置。仓库、Java 构建程序、发布程序和 Jenkins 插件都已准备好;你不需要安装它们或编写网站。这是同一台 VM 上的本地训练源服务和预览服务,并非 GitHub 或生产部署平台。预计用时由作者估算,未经初学者实测。
发现方案及其分支构建
在这一步中,你将检查正常的活动安排和候选方案源文件,然后发现对应的分支任务,并观察共享预览冲突。请从 Preview Desk 开始。
选择 Open the official program。确认 Common Ground Day 和 09:30。选择 Explore this plan,检查三项活动和路线插图。选择 Download the activities 获取真实的 CSV,选择 Read visitor notes 获取完整文本。使用浏览器的 Back 操作返回概览,再使用一次 Back 返回预览台。另外,打开 Read the courtyard notes 并确认 Courtyard Stories。这两个现有活动安排必须在整个操作过程中始终可用。
切换到 Source。这个终端中是一个 Git 工作副本:每次你能编辑的文件都属于当前选中的一个分支。分支是一条有名称的源代码历史线。切换分支会将工作文件改为该分支的版本,不会改变另一个分支。提交是仓库内容的一个已记录版本,由哈希值标识;这个标识会将 Jenkins 构建与其源代码关联起来。
终端打开时位于 /home/labex/project/community-site。pwd 打印当前目录。git --no-pager branch --list 列出本地分支,以 * 标记选中的分支。--no-pager 让结果直接显示在终端中。不使用这个选项时,Git 可能打开交互式查看器;如果你看到的是 (END) 而不是 shell 提示符,请按 q 退出查看器。运行:
pwd
git --no-pager branch --list
列表包含 main、courtyard-notes、garden-plan 和 river-plan。预先选中的是 garden-plan。如果不慎更改了目录,请先用 cd /home/labex/project/community-site 返回,再继续。
cat 打印文件内容,不会修改文件。event.properties 每行存储一个 key=value 设置,描述标题、集合详情和活动。阅读这个小型数据文件:
cat event.properties
它描述的是 Garden Gathering,于 10:00 在 Glasshouse gate 集合。meeting_time 行是提供的构建程序所使用的数据;该程序会一起生成页面、CSV 和须知。
git switch 在此工作副本中选择分支。比较第二个候选方案,然后切换回来:
git switch river-plan
cat event.properties
git switch garden-plan
第二个方案是 Riverside Picnic,于 14:00 在 River steps 集合。这些确实是不同的源文件,而不是仅更换分支标记的同一个页面。
可编辑范围是候选分支的 Jenkinsfile,以及稍后要求的 meeting_time 更改,该设置位于 event.properties 中。保持模板、路线图片、构建程序和发布程序不变。不要编辑、删除、重命名或重新创建已准备好的 Jenkins 项目或分支任务。保留所有 Git 和 Jenkins 历史、每个已保留的预览归档、main 和 courtyard-notes 分支、正式活动安排及庭院预览。本练习不需要 Docker 或管理员命令。
此时,请辨认哪个候选方案于 10:00 开始,哪个于 14:00 开始。目前还没有发布任何候选方案预览。
现在运行 Jenkins 原生分支发现,并将成功构建与其实际发布结果比较。切换到 Jenkins,从 Dashboard 打开 community-previews。
这个已准备好的父项目是一个多分支流水线(Multibranch Pipeline)。它扫描 Git 仓库中包含 Jenkinsfile 的分支,并为每个分支创建一个子 Pipeline 任务。源代码使用训练环境内的小型只读 Git 服务;工作副本预先配置的 origin 是你稍后推送源代码变更的目标仓库。不需要外部账户或凭据。
等待 Jenkins 页面加载完成,然后选择 Scan Multibranch Pipeline Now。打开 Scan Multibranch Pipeline Log,等待 Finished: SUCCESS。扫描会发现 garden-plan 和 river-plan;main 和 courtyard-notes 不包含 Jenkinsfile,因此不是候选任务。通过 community-previews 面包屑导航返回。等待两个子构建结束。
打开 garden-plan,再打开其带编号的构建和 Console Output。输出应标识 Garden Gathering、10:00 和检出的源代码修订版本。通过 community-previews 返回,打开 river-plan,检查其带编号构建的控制台。它应标识 Riverside Picnic、14:00 和自己的源代码修订版本。两者都应以 SUCCESS 结束。在这个已准备好的环境中,成功检出前可能出现 Using Default Git 工具消息;请阅读实际修订版本和最终结果,判断检出是否完成。
切换到 Source。阅读提供的 Pipeline:
cat Jenkinsfile
options { skipDefaultCheckout() } 关闭声明式流水线隐式执行的源代码检出,让可见的 Check out this branch 阶段显式执行它。checkout scm 使用提供此 Jenkinsfile 的特定分支修订版本。不要将它替换为固定分支的检出。
提供的 Build preview 阶段将检出的源代码转换成真实的访客文件。Archive preview 在 Jenkins 中保留 preview.zip,然后 Publish preview 将同样的字节发送到本地预览台。最后的 post 块使用 deleteDir() 清空该构建的工作区。请保留这些阶段和清理操作。
environment 块为各阶段提供值。两个分支目前都包含相同的设置:
PREVIEW_KEY = 'shared'
PREVIEW_KEY 选择预览台的发布地址。字面字符串 'shared' 会将两个构建发送到同一位置,尽管它们检出的源代码不同。返回 Preview Desk 并刷新。此时只有一个 shared 候选卡片,显示最后发布的那个分支。选择它的 Open preview 链接,将标题与两个成功的源构建比较。你无法通过这一个地址分享两个独立预览。
使用浏览器的 Back 操作返回预览台。正式活动安排和庭院须知必须仍然可用。你现在已经观察到,为什么独立分支任务并不会自动带来独立的发布结果。
为每个分支提供独立预览
在这一步中,你将修改并推送每个分支的 Jenkinsfile,然后构建两个独立预览。请从 Source 开始,工作目录为 /home/labex/project/community-site。
Jenkins 在多分支构建中提供 env.BRANCH_NAME。它是当前分支名称,例如 garden-plan。将共享值替换为这个原生分支身份:
PREVIEW_KEY = "${env.BRANCH_NAME}"
Groovy 双引号允许 ${...} 插入变量的值。如果将该表达式放在单引号中,则会保留其字面字符。本练习中的分支名已经采用适合预览地址的简单小写字母和连字符;这不是针对任意分支名的通用安全处理规则。
首先选择花园候选方案。git status --short 以简洁形式显示尚未提交的更改;M 表示文件已修改,无输出则表示工作副本干净。nano 是编辑指定文件的终端编辑器;在你保存并退出之前,它会一直占用这个终端。
git switch garden-plan
git status --short
nano Jenkinsfile
nano 在此终端中编辑指定文件。使用方向键移到 PREVIEW_KEY 行。按 Home 移到行首,然后按一次 Ctrl+K 剪切这一行。输入上面展示的完整替换行,包括缩进,并按 Enter,确保后面的 RECEIVER_URL 行保持独立。不要剪切其他行。用 Ctrl+O 保存,按 Enter 确认 Jenkinsfile,然后用 Ctrl+X 退出。这里的 Ctrl 表示按住 Control 键,在 macOS 上也一样。
在将编辑结果保存到 Git 历史前先检查它。git diff 比较工作文件与已提交版本。与之前一样,--no-pager 让结果直接显示在终端中;-- 分隔选项与文件路径。运行:
git --no-pager diff -- Jenkinsfile
差异应只显示删除旧的 PREVIEW_KEY 行并添加新行。- 和 + 前缀描述删除和添加的文本,并不是要输入文件的字符。如果差异中包含意外更改,请重新打开 nano Jenkinsfile,修正、保存、退出后再次检查。如果出现找不到文件的错误,请运行 pwd,返回上面给出的工作目录。
提交(commit)将已暂存的源代码更改记录到所选分支。git add 暂存这个文件;git commit -m 使用提供的消息记录它;git push origin garden-plan 将该分支推送到预先准备好的 origin 仓库,让 Jenkins 能发现新提交。在这些提交命令中,双引号将包含多个单词的消息保持为一个参数。这些命令修改源代码历史,不会直接改变线上预览:
git add Jenkinsfile
git commit -m "Give the garden plan its own preview"
git push origin garden-plan
现在将相同设置应用到另一个候选方案:
git switch river-plan
git status --short
nano Jenkinsfile
仅替换其 PREVIEW_KEY 行,使用相同的 nano 操作和完全相同的双引号表达式。保存并退出。检查、提交并推送这个分支:
git --no-pager diff -- Jenkinsfile
git add Jenkinsfile
git commit -m "Give the river plan its own preview"
git push origin river-plan
如果 Git 因尚未提交的更改而拒绝切换分支,请先运行 git status --short 并检查当前分支的差异。在切换前完成或修正该预期编辑;不要丢弃文件或重置仓库。如果你已经提交了预期编辑,随后 git commit 提示没有可提交的内容,请检查 git --no-pager log -1 --oneline,然后继续推送该分支。-1 将显示范围限制为一次提交;--oneline 显示简短标识和提交消息。
切换到 Jenkins,通过面包屑导航返回 community-previews,再次选择 Scan Multibranch Pipeline Now。本地练习没有 webhook,因此仅推送源代码不会发起扫描请求。等待扫描和两个新的子构建成功完成。每个控制台都必须显示自己的分支预览键。如果构建报告 Groovy 语法错误,请在 Source 中修正该分支 Jenkinsfile 的引号和花括号,在该分支提交并推送修正,然后再次扫描。不要通过编辑生成的子任务来代替修改源文件。
切换到 Preview Desk 并刷新。现在必须分别存在 garden-plan 和 river-plan 卡片。旧的共享卡片可能仍保留,作为之前观察到的结果。打开每个候选方案的 Open preview 链接,检查其正确标题、集合时间、三项活动、路线图片、CSV 和访客须知。查看一个方案后,使用浏览器的 Back 操作返回其概览,再使用一次 Back 返回预览台,然后再打开另一张卡片。两个预览地址必须不同,且能同时正常使用。

查看各自标题和原始集合时间上方的 garden-plan 和 river-plan 键。保留的 shared 卡片展示了之前的冲突,不能替代任何一个独立预览。
在 Jenkins 中,打开每个分支最新成功构建的状态页面,从 Build Artifacts 下载 preview.zip。将每个 ZIP 分别解压到不同的新文件夹,并打开 index.html。将全部七个文件保持在一起。页面和附件必须能在本地正常使用;文本附件可能直接打开,而不是再次触发下载。build.json 标识实际源分支和提交。完整预览才是成果,仅有两个绿色构建标签还不够。
更新一个方案并保留另一个
在这一步中,你将更改花园集合时间,再次扫描以仅更新该分支的预览。请从 Jenkins 开始,记下最新成功的 river-plan 构建编号。保持其预览打开,以便比较。
切换到 Source。选择花园分支,并编辑它的小型数据文件:
git switch garden-plan
git status --short
nano event.properties
仅将完整的 meeting_time 行从 meeting_time=10:00 改为:
meeting_time=10:30
使用编辑 Pipeline 行时的相同操作:方向键、Home、一次 Ctrl+K、替换文本和 Enter。用 Ctrl+O、Enter 保存,再用 Ctrl+X 退出。构建程序读取这一个值,使页面、CSV 和须知保持一致;你不需要编辑生成的访客文件。
检查并推送这次源代码更新:
git --no-pager diff -- event.properties
git add event.properties
git commit -m "Move the garden meeting to 10:30"
git push origin garden-plan
差异应仅改变这个集合时间。否则,请在提交前修正文件。河畔分支不应收到任何源代码更改。
切换到 Jenkins,返回 community-previews,选择 Scan Multibranch Pipeline Now。索引扫描之后,花园任务应为更改后的修订版本运行一次新构建;未更改的河畔分支应保留你记下的构建编号。等待花园构建以 SUCCESS 结束。打开其 Console Output,将新提交和 10:30 与源代码更改对应起来。
如果扫描显示没有更改,且花园预览仍是旧版本,请返回 Source。检查 git status --short 和 git --no-pager log -1 --oneline,确认预期更改已在 garden-plan 上提交,并在再次扫描前推送该分支。尚未到达 origin 的本地文件编辑或提交,还不是 Jenkins 能发现的源代码。如果构建失败,请阅读控制台,并通过另一次提交和推送修正其指出的源代码错误。不要重置 VM 或替换提供的构建程序。
切换到 Preview Desk 并刷新。打开 garden-plan:Garden Gathering 现在必须于 10:30 集合。检查 Explore this plan、下载的活动 CSV 和完整访客须知,各处集合时间必须一致。打开 river-plan:Riverside Picnic 必须仍于 14:00 集合,保留原始活动和正常工作的附件。其 build.json 必须保留之前的源提交和原生构建编号。在这次最终更新中,不要重新运行未更改的子任务。
返回 Jenkins 并下载最新的花园 preview.zip。将它解压到另一个新文件夹,重复本地页面、图片、CSV 和须知检查。它必须标识新的花园提交;之前下载的河畔资料包应仍能独立使用。
最后返回 Preview Desk,打开 Open the official program 和 Read the courtyard notes,确认两个完整的活动安排都保持完整。保留原始分支和构建历史。如果继续编辑任何源文件,请先提交、推送并完成相应的 Jenkins 构建,再检查是否完成。现在你拥有两个线上预览,并有证据表明更新其中一个没有覆盖或重新构建另一个。
总结
你使用了原生多分支发现及各 Jenkinsfile 对应的源代码修订版本,然后依据 Jenkins 的分支身份将发布位置分开。两个方案现在都在独立地址上拥有可用的页面、图片和附件。之后的花园提交只更新了自己的预览,而河畔构建、正式活动安排和庭院预览都保持不变。



