Введение
Pine & Path готовит прогулку по саду. Один редактор просит перенести начало на более позднее время; затем другой меняет место встречи. Jenkins может подготовить и опубликовать любое из объявлений, но старый запуск, ожидающий согласования, может перезаписать более новое объявление после того, как оно уже стало доступно посетителям.
Вы увидите такую перезапись, затем измените Pipeline, чтобы новый запуск автоматически замещал старый ожидающий запуск. Ваш результат — настоящее объявление для посетителей и скачиваемый комплект из семи файлов, в котором маршрут, расписание и памятка соответствуют последнему запросу.
Необходимы базовые навыки навигации по страницам Jenkins и умение распознать короткий Declarative Pipeline. Параметры, паузы для согласования и настройка параллельного выполнения объясняются здесь. Jenkins, два исполнителя контроллера, инструменты объявлений и локальный Notice Desk подготовлены. Устанавливать ПО или писать сайт не нужно. Оба интерфейса работают на одной учебной виртуальной машине; это контролируемое локальное средство публикации, а не промышленная платформа развёртывания. Продолжительность — авторская оценка, а не измеренное время для начинающих.
Наблюдайте перезапись объявления после запоздалого согласования
На этом шаге вы опубликуете последнее объявление, затем увидите, как старый ожидающий запуск перезаписывает его. Начните в Notice Desk. Оставьте этот интерфейс открытым; переключение интерфейсов не перезапускает сборку и не сбрасывает объявление.
Изучите обычный путь посетителя
Первое мероприятие — прогулка по саду. Выберите её ссылку View notice. Предоставленное объявление указывает начало в 10:00 у Community Gate. Откройте Open the route и изучите три остановки. Действием браузера Back вернитесь к объявлению. Откройте Read visitor notes, прочитайте инструкции о встрече, затем снова используйте Back. Schedule table — CSV-файл: простая таблица, поля которой разделены запятыми. Notice details — JSON: именованные значения, описывающие то же мероприятие. Preparation record указывает, как подготовлен этот комплект. Сейчас он честно сообщает PROVIDED BASELINE; подготовка среды не запускала задание Jenkins за вас.
Действием браузера Back вернитесь на главную страницу Notice Desk. Выберите Download notice pack для прогулки по саду и сохраните ZIP-архив. ZIP держит несколько файлов вместе. Полностью распакуйте архив в новую папку архиватором вашего компьютера, затем откройте его index.html. Держите все семь соседних файлов вместе. Маршрут, таблица стилей, расписание, памятка, JSON и запись подготовки — настоящие локальные файлы; перенос одного index.html сломает ссылки на соседние файлы. Браузер может открыть CSV/текстовый файл или скачать его; оба варианта подходят для чтения сохранённых байтов.
Вернитесь на главную страницу Notice Desk. Изучите отдельное объявление Seed Swap и его скачиваемый комплект. Оно начинается в 11:00 у Potting Shed и должно остаться неизменным. Предстоящие запросы редакторов касаются только прогулки по саду.
Выберите Read the editor requests. Более ранний запрос использует значение UPDATE later-start: 10:30, всё ещё Community Gate. Последний запрос — new-meeting-point: сохранить 10:30, встречаться у Glasshouse Gate. Здесь «последний» означает более поздний запрос редактора, а не сборку, которой случилось завершиться последней.
Прочитайте подготовленный Pipeline
Переключитесь в Jenkins. Откройте publish-walk-notice, затем Configure. Найдите раздел Pipeline и редактор Script. Это Declarative Pipeline: внешний блок pipeline { ... } описывает работу, а парные фигурные скобки группируют настройки и этапы.
Задание использует agent any, который выделяет исполнителя и рабочий каталог на доступном подготовленном узле. Исполнитель — место Jenkins для выполнения работы; рабочий каталог — каталог конкретного запуска. У этого учебного контроллера два исполнителя, поэтому два запуска задания могут выполняться с перекрытием во времени. У них отдельные рабочие каталоги, но они публикуют в одно объявление прогулки по саду.
Блок parameters определяет значения, выбираемые для каждой сборки. choice предлагает два запроса редакторов как UPDATE. booleanParam делает HOLD_FOR_REVIEW флажком: установленный означает true, снятый — false. params.HOLD_FOR_REVIEW читает значение, выбранное для этого запуска. Условие when выполняет свой этап только тогда, когда выражение истинно.
У трёх этапов разные цели:
- Prepare notice очищает рабочий каталог запуска через
deleteDir(), вызывает предоставленную программу подготовки черезshи сохраняет архивnotice-pack.zip.archiveArtifactsхранит именно этот файл вместе с собственной сборкой Jenkins.fingerprint: trueфиксирует идентичность содержимого и связанную сборку. Подготовка и архивирование не меняют объявление для посетителей. - Review notice использует
input, чтобы при установленном флажке приостановить запуск перед публикацией. Ссылка Proceed разрешает следующий этап; Abort отменяет этот запуск. Это намеренная пауза, а не сбой соединения. - Publish notice отправляет подготовленный комплект в локальный Notice Desk. Блок
post { always { ... } }очищает рабочий каталог при завершении запуска, включая прерывание. Собственные архивные файлы Jenkins остаются доступны после очистки рабочего каталога.
Предоставленные программы подготовки и публикации читают параметры и архив фактической сборки. Сохраните эти программы, все этапы, условие согласования, регистрацию отпечатков и обе операции очистки. На следующем шаге вы измените только обработку перекрывающихся запусков. Пока оставьте Script без изменений. Выберите Save, чтобы вернуться к заданию.
Запустите старый запрос и оставьте его ждать
На странице задания publish-walk-notice выберите Build with Parameters. Укажите later-start для UPDATE и установите HOLD_FOR_REVIEW, щёлкнув его подпись или флажок. Один раз выберите Build.
Откройте только что начатый запуск в Build History; в нетронутом задании это #1. Откройте Console Output. Дождитесь Release this selected notice? со ссылками Proceed и Abort. Оставьте его ждать. Консоль уже сообщила о подготовке и архивировании. Общее объявление задания для посетителей пока остаётся исходным, потому что Publish notice не выполнялся.
Через publish-walk-notice в навигационной цепочке вверху вернитесь на страницу задания. Это переход внутри Jenkins; он отличается от переключения на интерфейс Notice Desk. Запишите номер старого запуска, чтобы вернуться к его ожидающей консоли.
Снова выберите Build with Parameters. На этот раз укажите new-meeting-point и оставьте HOLD_FOR_REVIEW снятым. Один раз выберите Build. Откройте Console Output этого нового запуска и дождитесь Finished: SUCCESS. В нетронутом задании это #2.
Переключитесь в Notice Desk и перезагрузите его главную страницу. Откройте объявление прогулки по саду: теперь должны отображаться 10:30 и Glasshouse Gate. Откройте маршрут и памятку для посетителей и подтвердите то же место встречи. Последний запрос редактора действительно опубликован.
Продолжите старый запуск
Вернитесь в Jenkins. Вернитесь к заданию, откройте записанный старый запуск и его Console Output, затем выберите его ссылку Proceed. Дождитесь Finished: SUCCESS. Если открыта устаревшая консоль, перезагрузите консоль этого запуска перед выбором ссылки; не запускайте ещё одну сборку только ради обновления страницы.
Переключитесь в Notice Desk, перезагрузите и снова изучите объявление прогулки. Теперь оно указывает 10:30 у Community Gate. Это ожидаемый ошибочный результат: старый запуск завершился позднее и перезаписал новый запрос. Оба запуска Jenkins успешны, но результат для посетителей устарел.
Скачайте текущий комплект в другую папку. Его publication.txt называет старый запуск Jenkins; маршрут, расписание и памятка соответствуют более раннему запросу. Вернитесь в Jenkins и откройте ссылку Build Artifacts той старой сборки, чтобы скачать её собственный notice-pack.zip. Notice Desk предоставил этот фактически подготовленный архив, а не незаметно создал другое объявление.
Если запуск неожиданно ожидает, изучите выбранные Parameters и консоль. Можно выбрать Abort в его запросе input, чтобы отменить случайный ожидающий запуск, затем снова запустить нужные параметры. Сохраните всю историю сборок. Сообщение об ошибке до запроса отличается от ожидаемой паузы согласования; прочитайте консоль и вернитесь в Configure, чтобы восстановить предоставленные этапы, если вы случайно изменили их.
Самопроверка: вы сохранили обе настоящие успешные сборки, реальное согласование старого запуска и устаревший результат для посетителей. Отдельное объявление Seed Swap и его скачивание по-прежнему работают. Последующие исправления не сотрут эти свидетельства.
Позвольте новым запускам замещать старые ожидающие
На этом шаге вы не дадите старому согласованию перезаписать последний запрос. Начните в Jenkins на странице задания publish-walk-notice.
Добавьте политику перекрытия запусков одного задания
Блок options Pipeline управляет поведением запусков. Сам по себе disableConcurrentBuilds() заставляет новые запуски ждать в очереди завершения текущего. Это оставило бы управление за старым согласованием. Настройка abortPrevious: true вместо этого прерывает старый запуск, когда начинается новый запуск того же задания. true — логическое значение, а не текст в кавычках. Двоеточие передаёт этот именованный параметр настройке.
Выберите Configure, найдите Pipeline → Script и вставьте следующую строку сразу после agent any, внутри внешнего блока pipeline и перед parameters:
options { disableConcurrentBuilds(abortPrevious: true) }
Теперь начало должно выглядеть так:
pipeline {
agent any
options { disableConcurrentBuilds(abortPrevious: true) }
parameters {
Этот небольшой фрагмент показывает расположение; не заменяйте им весь Script. Сохраните существующие параметры, этапы, архивирование и очистку. Выберите Save. Сохранение меняет будущие запуски; для демонстрации эффекта нужно выполнить новую пару.
Наблюдайте автоматическое замещение
На странице задания выберите Build with Parameters, укажите later-start, установите HOLD_FOR_REVIEW и выберите Build. Откройте Console Output только что начатого запуска раннего запроса — он будет старшим в новой паре. Дождитесь настоящего запроса Proceed / Abort. При прохождении без дополнительных действий это #3. Оставьте его ждать; не прерывайте и не продолжайте его вручную.
Вернитесь к заданию через навигационную цепочку. Выберите Build with Parameters, укажите new-meeting-point, оставьте HOLD_FOR_REVIEW снятым, затем выберите Build. Откройте консоль этого более нового запуска и дождитесь Finished: SUCCESS. При прохождении без дополнительных действий это #4.
Откройте консоль старого ожидающего запуска и перезагрузите её. В подготовленной версии Jenkins запуск имеет статус NOT_BUILT, а Superseded by #... называет более новый запуск. Старый этап Publish notice пропущен, а очистка всё же выполнена. Одного серого статуса недостаточно: прочитайте причину замещения и сравните номер новой сборки. Старый input больше не ожидает вашего согласования. Исторический консольный вывод может по-прежнему показывать прежний текст Proceed/Abort; не используйте эти старые ссылки после замещения.

Прочитайте Superseded by #... и пропущенный этап публикации, затем сравните итоговый результат NOT_BUILT.
NOT_BUILT здесь не означает, что никакой работы не было. Старый запуск подготовил и сохранил архив комплекта до паузы. Откройте его Build Artifacts и убедитесь, что notice-pack.zip по-прежнему можно скачать. Политика предотвратила именно последующую публикацию этого устаревшего комплекта. Очистка рабочих каталогов обоих запусков оставляет эти архивные файлы нетронутыми.
Переключитесь в Notice Desk, перезагрузите и откройте объявление прогулки. Оно должно показывать 10:30 у Glasshouse Gate. Прочитайте маршрут, памятку и расписание.

Вместе проверьте 10:30, Glasshouse Gate и первую остановку маршрута. Вернитесь на главную страницу и убедитесь, что Seed Swap по-прежнему начинается в 11:00 у Potting Shed.
Потренируйтесь отменять случайную паузу согласования
Переключитесь в Jenkins. Запустите ещё одну сборку later-start с установленным HOLD_FOR_REVIEW. Дождитесь запроса input в консоли, затем выберите Abort. Это намеренная ручная отмена, которая завершается с ABORTED. Она отличается от уже наблюдавшегося автоматического замещения и не заменяет его свидетельства. Действующее объявление остаётся у Glasshouse Gate, потому что этот запуск ничего не публиковал.
Запустите итоговую сборку new-meeting-point со снятым HOLD_FOR_REVIEW и дождитесь SUCCESS. Это действие восстановления, если вы случайно приостановили или отменили не тот запрос: изучите страницу редакторских запросов, выберите последний запрос и соберите его без ожидания. Сохраните старые запуски; удаление истории убрало бы свидетельства поведения политики.
Если после сохранения Script появляется FAILURE с синтаксическим сообщением, проверьте парность фигурных скобок и убедитесь, что строка options находится внутри pipeline, а не внутри stages или steps этапа. Исправьте в Configure, сохраните и снова запустите нужную пару. Не сбрасывайте виртуальную машину и не меняйте предоставленные инструменты. Дополнительные неуспешные попытки могут оставаться в истории.
Сохраните и изучите итоговый результат
Переключитесь в Notice Desk. Перезагрузите, затем скачайте notice pack прогулки по саду. Сохраните в новую папку, не смешивая файлы с предыдущими скачиваниями. Полностью распакуйте ZIP и откройте index.html. Подтвердите Glasshouse Gate, 10:30, иллюстрированный маршрут и все три остановки. Откройте Read visitor notes, Schedule table, Notice details и Preparation record. CSV и JSON должны соответствовать странице; publication.txt называет итоговые успешные задание Jenkins и сборку. Полная папка работает локально без Jenkins или Notice Desk. Между просмотрами локальных файлов используйте действие браузера Back.
В Jenkins откройте соответствующую успешную сборку и Build Artifacts, затем скачайте notice-pack.zip. Его семь распакованных файлов должны совпадать со скачанными из Notice Desk. Собственные архивы Jenkins фиксируют то, что подготовила сборка; Notice Desk показывает то, что действительно опубликовано.
Самопроверка: сохранённая политика действует, настоящий новый запуск автоматически заместил старый, приостановленный на input, и посетители получают реальные файлы последнего запроса. Пара приостановленного и нового запусков должна выполнять этот сохранённый Script. Самый новый завершённый запуск должен сам быть успешной публикацией последнего запроса; после ошибочной или пропущенной публикации восстановите Script и запустите снова. Если вы снова измените его поведение, продемонстрируйте новую пару приостановленного и нового запусков. Вся история сборок, предыдущие архивы, поведение подготовки, согласования, публикации и очистки и отдельное мероприятие остаются нетронутыми.
Эта настройка влияет на перекрытие в одном задании. Она не может отменить публикацию, произошедшую до прерывания, координировать разные задания или сделать любое промышленное развёртывание безопасным для прерывания. Здесь старый запуск приостанавливается до единственного шага публикации, что делает границу ясной.
Резюме
Вы связали реальный результат для посетителей с поведением запусков Jenkins. Вы воспроизвели перезапись нового объявления после согласования старого, затем с помощью disableConcurrentBuilds(abortPrevious: true) настроили новые запуски на прерывание старых ожидающих запусков того же задания. Вы различили подготовку и публикацию, встроенное замещение и ручную отмену, сохранённые архивные файлы и файлы рабочего каталога.
Ваш итоговый продукт — последнее объявление прогулки по саду с соответствующими автономными маршрутом, расписанием и памяткой. Сохранённая история показывает, почему успешная сборка означает, что нужное обновление действительно дошло до посетителей.



