До списку уроків
9 клас · Урок 15 з 16

Складання продукту: інтеграція артефактів, деплой, захист

виконано0%
Крок 1

Що робимо сьогодні

Модуль I · Хмарні сервіси й документи · тема 8, урок 2 з 2 · 120 хвилин

Після уроку ти вмієш

Слова «деплой» і «вебхук» поки нічого не означають. Розберемо їх на кроці 5.

Минулого уроку команда завела репозиторій, розібралася з гілками й зверстала каркас із чотирьох сторінок. Сьогодні цей каркас має стати продуктом — одним сайтом. Стороння людина відкриває його й розуміє: що це, хто це зробив і навіщо.

Урок складається з трьох частин, і кожна відповідає на своє питання.

ЧастинаПитанняРезультат
Інтеграція як чотири шматки від чотирьох людей зробити одним сайтом спільна навігація, один style.css, узгоджені імена
Деплой чому «в мене працює» ще не означає «працює в інтернеті» зелений прогін push → webhook → сайт
Захист як за 5 хвилин показати зроблене так, щоб зрозуміли виступ із ролями і CONTRIB.md

Хід уроку

ЕтапХвЩо робимо
Вхід у тему10Чотири сторінки від чотирьох людей: що з ними не так
Інтеграція20Спільне меню, один style.css, домовленість про імена файлів
Деплой20Ланцюжок push → вебхук → сайт, симулятор на сторінці
Розбір поламок15Чотири місця, де рветься публікація; читання журналу
Практика: складання сайту35Чотири сторінки, чек-ліст, media.html, CONTRIB.md
Захист15П’ять хвилин на команду, ролі у виступі
Здача5check 15 --why, підсумок модуля
Разом120
Що вже є в команди Репозиторій class9a/team-3 — підстав свою організацію і номер. Чотири сторінки з уроку 14 і налаштований вебхук-деплой на https://team<N>.<домен>/. У прикладах на цій сторінці адреса записана як team<N>.<домен> — підстав свій номер команди й адресу, яку дав учитель. Артефакти попередніх тем лежать у кожного в особистому кабінеті. Це історія з теми 1, розмітка коміксу з теми 4, дашборд із теми 6 і бот із теми 7.
Медіа на сервер не їде — і сьогодні теж Комікс і трейлер важать десятки мегабайтів, тому на командному сайті вони представлені текстом. Це сторінка media.html з описом, текстом субтитрів і посиланням на prompts.json. Сам трейлер і сам комікс команда показує з власного екрана під час захисту. Якщо залити .mp4 у репозиторій, файл відхилять, а критерій no_media лишиться незарахованим.

Що має бути на екрані наприкінці уроку

Крок 2

Чому чотири сторінки виглядають як чотири різні сайти

Коли кожен верстає свою сторінку окремо, він робить її красивою саму по собі. Проблема з’являється тільки в момент, коли ці сторінки ставлять поруч і людина переходить між ними.

Читач не бачить чотирьох авторів. Він бачить один сайт, який «стрибає». На кожній сторінці інший шрифт. Меню з’їжджає вбік. Кнопка тут синя, а на сусідній сторінці зелена. Це виглядає недоробленим — навіть якщо кожна сторінка окремо зроблена добре.

Що розходитьсяЯк це помічає читачЯк лікується
Шрифт і розміри«сторінка перезавантажилася на інший сайт» один style.css на всі сторінки
Набір посилань у менюзаблукав і не може повернутися на головну той самий блок <nav>, скопійований дослівно
Порядок пунктів менютицяє мимо: пункт «переїхав» порядок фіксується один раз і не міняється
Імена файлів404 на переході домовленість: усе малими, без пробілів і кирилиці
Структура текчастина посилань працює, частина ні одна схема тек на весь репозиторій

Один файл стилів замість чотирьох

Найчастіша поламка інтеграції — у кожного своя копія стилів. Формально сайт працює. А потім ви міняєте колір заголовка — і правити доводиться в чотирьох файлах. На четвертому хтось забуде.

знайти всі підключення стилів у репозиторії
$ grep -rn "stylesheet" --include="*.html" . ./index.html:7: <link rel="stylesheet" href="style.css"> ./team.html:7: <link rel="stylesheet" href="style.css"> ./media.html:6: <link rel="stylesheet" href="media.css"> ./dash/index.html:9: <link rel="stylesheet" href="style.css">

У цьому виводі — дві різні проблеми. Перша: media.html тягне власний файл стилів, його треба прибрати. Друга: dash/index.html лежить на рівень глибше. Для нього шлях style.css означає dash/style.css, а такого файлу немає. Правильно писати ../style.css. Сторінка відкриється, просто без оформлення.

один style.css + той самий <nav> index.html головна: що це і хто story.html інтерактивна історія media.html опис + субтитри, без файлів data.html дашборд і опитування team.html ролі й внесок кожного story/story.json — тема 1 автор: Оксана comic/, av/ — теми 4 і 5 Тарас: на сайті лише текст dash/data.json — тема 6 автор: Ніна CONTRIB.md звіряється з git log
Карта командного сайту. Головна — єдина точка входу; чотири сторінки живуть усередині спільної рамки стилів і навігації; праворуч — артефакт, який кожен приносить зі своєї теми. Імена учасників тут для прикладу.
Питання

Зібрали чотири сторінки в один репозиторій. На кожній свій шрифт, своє меню і свій набір кольорів. До захисту 40 хвилин. З чого починати?

Домовленість про імена — на п’ять хвилин, економить годину

На Windows файл Story.HTML відкриється за посиланням story.html. Помилки не буде. На сервері під Linux це два різні файли, і посилання дасть 404. Це найчастіша поламка, яку ми бачимо на цьому уроці з року в рік. Помилку не видно в автора — вона вилазить тільки після деплою.

Питання

Тарас поклав у репозиторій файл Comic.html, а в навігації написав <a href="comic.html">. У себе на Windows він відкрив сайт — усе працює. Що станеться після деплою?

Крок 3

Структура спільного репозиторію

Репозиторій — не «тека, куди все кидають». Його структура і є домовленістю команди. Коли вона записана, усі знають, де що лежить, і посилання не ламаються.

team-3/ ← корінь репозиторію, він же корінь сайту ├── index.html єдина точка входу, з неї починають усі ├── style.css один файл стилів на весь сайт ├── team.html хто ми і хто що робив ├── media.html опис коміксу й трейлера, субтитри ├── data.html дашборд і підсумки опитування ├── README.md для того, хто прийде після вас ├── CONTRIB.md внесок кожного, звіряється з git log ├── .gitignore що НІКОЛИ не потрапляє в git ├── assets/ спільні дрібні файли: логотип, іконки │ └── logo.svg ├── story/ артефакт теми 1 │ ├── index.html │ └── story.json ├── comic/ розмітка й підписи; зображень тут немає │ ├── index.html │ └── prompts.json └── dash/ дашборд теми 6 + data.json
Структура спільного репозиторію. Корінь репозиторію — це і є корінь сайту: файл team-3/story/index.html відкриється за адресою https://team3.<домен>/story/. Дерево записується в README.md, щоб домовленість не жила тільки в чиїйсь голові.

Навіщо .gitignore

Це список того, що git ігнорує назавжди. Туди пишуть тимчасові файли редактора, теку з локальними відео, файли з паролями.

Заводять його не заради охайності, а заради безпеки. Пароль, який одного разу потрапив у коміт, лишається в історії репозиторію. Видалити файл уже не досить.

.gitignore командного сайту
*.mp4 *.mov *.mp3 *.wav .env node_modules/ .DS_Store Thumbs.db
Зворотний бік .gitignore Він рятує від зайвого, але створює новий ризик. Файл, який ти справді хотів опублікувати, може мовчки не поїхати. Тому перед фінальним пушем завжди дивись git status: рядок Untracked files має бути порожній.
Питання

У репозиторії команди лежать style.css, styles.css і main.css — усі три робочі, у різних сторінках підключені різні. Що робити?

Крок 4

Що перетворює набір сторінок на продукт

Продукт — це коли людина, яка вас не знає, відкриває адресу і за 15 секунд розуміє, що це таке. Набір сторінок — це коли їй доводиться здогадуватися.

1. Головна, яка пояснює, що це

Типова головна сторінка командного сайту — це заголовок «Команда 3» і чотири посилання. Без автора поруч такий сайт не зрозуміти.

Замість цьогоНапиши це
«Команда 3. Наш проєкт.» «Ми опитали 62 учні 8–9 класів про те, скільки часу вони проводять у застосунках, і зробили сайт із результатами, історією й коміксом про цифрову звичку.»
«Тут наші роботи» «Чотири розділи: дані опитування, інтерактивна історія, комікс і трейлер, сторінка команди.»
порожній <title>Document</title> <title>Цифрова звичка — проєкт команди 3</title>

Заголовок вкладки — не дрібниця. Його видно у списку вкладок, у закладках і в результатах пошуку. Слово Document там означає одне: сторінку зробили з шаблону й не дочитали.

2. Навігація без «мертвих» посилань

Мертве посилання веде в нікуди. Це або <a href="gallery.html"> на сторінку, якої немає, або href="#", залишене «на потім». Читач читає це однаково: сайт зламаний.

Git Bash / macOS / Linux — обійти всі свої сторінки
$ for p in "" team.html media.html data.html story/ comic/ dash/; do $ printf "%s /%s\n" "$(curl -o /dev/null -s -w '%{http_code}' https://team<N>.<домен>/$p)" "$p" $ done 200 / 200 /team.html 404 /media.html 200 /data.html 200 /story/ 403 /comic/ 200 /dash/

Тут два різні діагнози. 404 — файлу немає: або його не закомічено, або ім’я інше. 403 у теці — файли в ній є, але серед них немає index.html. Показувати список файлів сервер не стане.

PowerShell 5.1: обережно зі словом curl У Windows PowerShell curl — це псевдонім Invoke-WebRequest, і ключі -o -s -w він не розуміє. Або пиши curl.exe явно, або користуйся рідною командою: (Invoke-WebRequest -Uri https://team<N>.<домен>/ -Method Head).StatusCode.

3. Сторінка команди з ролями

На team.html — по абзацу на людину. Що робив, який файл у репозиторії його, чого навчився.

«Допомагав з дизайном» не каже нічого. Пиши так: «зробив style.css і звів чотири сторінки до одного вигляду». І далі: «переверстав media.html, щоб на телефоні не було бічного скролу».

Той самий текст, тільки коротше, дублюється в CONTRIB.md. Звідти його читає чекер. Він звіряє імена з авторами комітів у git log. Учасника без жодного коміту видно одразу.

Питання

Учитель відкриває головну сторінку команди й бачить заголовок «Наш проєкт» і чотири посилання без жодного речення тексту. Команда каже: «ну ми ж зараз усе розкажемо». Чому це все одно недороблено?

4. README.md — для того, хто прийде після вас

Сайт відкривається в браузері — і здається, що цього досить. Але наступного року репозиторій візьме інша команда. Або ви самі через півроку. README.md відповідає на питання, на які код не відповідає.

Розділ READMEЩо там пишуть
Що це2–3 речення про продукт і для кого він
Як подивитисяадреса сайту + як відкрити локально (просто відкрити index.html, чи потрібен сервер)
Де що лежитьдерево тек із поясненням, як на схемі вище
Чого тут немаєвідео й зображення коміксу — локально в учасників, на сайті лише текстовий супровід
Хто робивпосилання на CONTRIB.md
Питання

Команда каже: «README нікому не потрібен, сайт же й так відкривається і все видно». Який найсильніший аргумент проти?

Крок 5

Деплой: що відбувається після git push

Ти дописав сторінку й зробив git push. Через кілька секунд її бачить будь-хто в інтернеті. Така публікація нової версії зветься деплоєм. Автоматичний деплой означає, що файли ніхто не копіює руками.

Ти лишаєш у магазині свій номер: «привезуть — набери мені». Дві програми домовляються так само: «станеться подія — постукай ось за цією адресою». Такий домовлений стук зветься вебхуком.

Gitea приймає твій push. Далі бере з налаштувань репозиторію адресу хука і шле на неї запит POST з описом події. За тією адресою чекає маленький скрипт. Він робить git pull у теку сайту.

твоя машина Gitea сервер сервер інтернет git push коміти їдуть у репозиторій webhook Gitea шле POST на адресу хука deploy.sh git pull у теку сайту команди перевірка сторінки віддають 200 сайт оновився нову версію видно всім 0 c ≈1 c ≈2 c ≈4 c ≈5 c секунди приблизні, для маленького сайту — щоб було видно масштаб
Шлях деплою. Увесь ланцюг після git push працює без людини. Саме тому опублікована версія завжди дорівнює тому, що лежить у гілці main.

Що всередині deploy.sh

Скрипт на сервері простіший, ніж здається. Головне в ньому — ключ --ff-only. Він забороняє серверу зливати гілки й розв’язувати конфлікти. Сервер або бере нову версію цілком, або не робить нічого. У другому випадку сайт лишається в робочому стані.

~/bin/deploy.sh на сервері (скорочено)
cd /srv/<команда> git pull --ff-only origin main find . -type f -name "*.html" -exec chmod 644 {} + echo "$(date -Is) deployed $(git rev-parse --short HEAD)" >> ~/deploy.log
Де шукати, коли сайт не оновився Ланцюг має чотири ланки, і кожна лишає слід. Push видно в git log origin/main. Спрацювання хука — у Gitea: Settings → Webhooks → Recent Deliveries, там видно код відповіді. Роботу скрипта — у ~/deploy.log. Результат — у браузері. Дивитися треба саме в такому порядку.
Питання

Оксана зробила git push, у Gitea коміт видно, а сайт показує стару версію навіть після Ctrl+F5. Куди дивитися першим?

Крок 6

Симулятор деплою: знайди поламку за логом

Тисни «Зробити push» і читай журнал очима того, у кого не оновився сайт. У кожному прогоні може трапитися типова помилка. Назви її раніше за вчителя.

Прогін деплою

Ланцюг проходить чотири ланки. Зелена — ланка відпрацювала, червона — обірвалася саме тут.

розгадано 0 з 0
журнал порожній — натисни «Зробити push»

Демонстраційний режим: журнал згенеровано на цій сторінці. Формат рядків і коди відповідей — такі самі, як у справжньому ~/deploy.log і виводі curl.

Як читають лог насправді Не згори вниз, а знизу вгору: шукають перший рядок, де щось пішло не так, і зупиняються. Усе, що після нього, — уже наслідки.
Крок 7

Чому «в мене працює» не аргумент

Локально сторінка відкривається з файлової системи твоєї машини. В інтернеті — з теки на сервері під Linux, з того, що потрапило в git. Це три різні набори правил, і вони розходяться завжди в тих самих місцях.

Сторінку з теки сервера браузеру віддає окрема програма. Вона приймає запит, знаходить потрібний файл і надсилає його назад. Цю програму звуть nginx — на схемі нижче вона остання ланка.

git push твоя машина webhook Gitea git pull сервер віддача сторінок nginx 1 2 3 4 1. Файл не в git створив, але не зробив git add — на сервер він не поїхав узагалі видно: git status Untracked files: style.css 2. Хук не дійшов push пройшов, але Gitea не достукалась до сервера деплою видно: Webhooks → Recent Deliveries відповідь не 200 3. pull відхилено хтось правив файли просто на сервері — git боїться їх стерти видно: deploy.log local changes would be overwritten 4. Шлях не той Images/hero.png ≠ images/hero.png, або немає index.html видно: 404 і 403 у DevTools → Network і у виводі curl
Чотири місця, де рветься деплой, і слід, за яким кожне впізнають. Поламки 1 і 4 — учнівські й трапляються майже щоразу; 2 і 3 — серверні, їх зазвичай лікує вчитель.

Три різниці, через які ламається саме твоя сторінка

ЛокальноНа серверіСимптом
Images/hero.png = images/hero.png це два різні шляхи порожні квадрати замість зображень, 404 у Network
відкривається будь-який файл у теці тека без index.html закрита 403 на переході в розділ
файл існує, бо він на диску файла немає, бо його немає в git 404 рівно на одному файлі, решта працює
file:///C:/Users/…/style.css працює такого шляху не існує сторінка без стилів, «як у 1998 році»

Звідси одне робоче правило на весь сайт: усі шляхи відносні. style.css, story/index.html, ../style.css — так, C:\…, file:///…, /home/oksana/… — ні. Відносний шлях однаково працює і на твоєму диску, і на сервері.

Питання

На головній сторінці команди три власні іконки у форматі SVG. Локально видно всі три, після деплою на їх місці порожні квадрати. Що перевіряєш першим?

Питання

Ніна підключила стилі так: <link rel="stylesheet" href="/home/nina/team-3/style.css">. Локально в редакторі все гарно, на сайті — гола сторінка без оформлення. Чому?

Крок 8

Чек-ліст готовності продукту

П’ятнадцять пунктів у п’яти групах. Відмічай виконане — сторінка рахує відсоток готовності. Окремо вона показує пункти, без яких чекер поки не зарахує роботу, скільки б решти не було зроблено.

Готовність до здачі
Готовність
0%
0 з 15 пунктів
Галочки зберігаються в браузері й переживають перезавантаження сторінки.
Чому пунктів саме стільки Кожен із них — це або окремий критерій автоперевірки check 15, або типова помилка, на якій команди спотикалися минулими роками. Чек-ліст не замінює перевірку, він робить її передбачуваною.
Питання

У коді сторінки лишився рядок const TOKEN = "a7f3…" — токен доступу до Gitea, який використовували для тесту. Репозиторій приватний, тому команда каже, що це не страшно. Хто має рацію?

Крок 9

Сторінка media.html: як показати те, чого немає на сервері

Трейлер і комікс лишаються на машинах учасників. Але сайт має чесно розповідати, що вони існують і що саме в них зроблено — інакше половина роботи модуля просто зникає з продукту.

Сторінка media.html — це текстовий супровід медіа. Її читають, коли команди немає поруч: наступного року, з телефона, з іншого міста. Вона має бути зрозумілою сама по собі.

Блок сторінкиЩо в ньомуЗвідки береться
Опис трейлера2–3 абзаци: про що, скільки триває, як зроблено власний текст + av.meta.json з теми 5
Субтитриповний текст репліками, з таймкодами trailer.vtt з теми 5
Як зроблено звукпосилання на music.strudel і sfx.jsonтема 5
Комікспанелі з підписами, бульбашки текстом comic.json з теми 4
Промптипосилання на prompts.json і позначка «зображення згенеровано AI»тема 4
Де подивитисячесний рядок: «відео показуємо з екрана, на сервері його немає»правило модуля

Субтитри як текст сторінки

Файл .vtt уже містить усе потрібне: таймкод і репліку. Перенести його на сторінку — хвилин десять роботи. Зате текст трейлера стає видно в пошуку, і його можна прочитати без відео.

trailer.vtt — фрагмент
WEBVTT 00:00:02.000 --> 00:00:05.400 Місто прокидається раніше за людей. 00:00:05.600 --> 00:00:09.100 І кожен ранок починається з того самого екрана.

На сторінці це стає таблицею з двох колонок: час і репліка. Або списком <dl>. Головне — щоб це був текст, а не картинка. Текст знайде пошук. А ще його прочитає вголос програма для незрячих — її звуть скрінрідером. І цитату з тексту можна скопіювати.

Чого на цій сторінці бути не може <video src="trailer.mp4"> і <audio src="music.mp3"> — файлів немає в репозиторії, тег дасть порожній плеєр і зламану сторінку. Так само не можна вставляти посилання на файл у своїй домашній теці: воно працює тільки на твоїй машині.
Питання

Трейлер команди важить 41 МБ. Тарас пропонує «просто закинути його в репозиторій, хай буде — сервер же наш». Що з цим не так і що робити натомість?

Крок 10

Захист: п’ять хвилин, щоб вас зрозуміли

Захист — не звіт про витрачений час. Це відповідь на чотири питання: яка була задача, що ви зробили, як воно працює, і що не вийшло. Останнє питання приносить більше балів, ніж здається.

5 хвилин команди, розділені між учасниками Задача 45 c Рішення 60 c Демонстрація живого сайту 150 c — найдовший блок Що не вийшло 45 c Питання решта часу хто говорить тимлід: навіщо це нам і кого ми питали фронтенд: як влаштований сайт, звідки беруться дані автор медіа: показує комікс і трейлер зі свого екрана QA: що ламалося, як лагодили, що лишилось недоробленим говорить кожен — мовчазний учасник на захисті виглядає так само, як учасник без комітів у git log: незрозуміло, що саме він зробив
Розкладка захисту. Найбільший блок — демонстрація: журі має побачити живий сайт, а не почути переказ. Хронометраж орієнтовний, учитель тримає таймер.

Що показувати з екрана, а що з сайту

ЩоЗвідки показуємоЧому так
Сайт командибраузер, публічна адреса це і є продукт; локальна копія не рахується
Комікссторінка comic/ на своєму ноутбуці з локальними зображеннямикартинки на сервер не заливаються
Трейлерплеєр на своєму ноутбуці, зі звуком відео на сервер не заливається
Внесок кожногоgit log --oneline на екрані історія комітів — це доказ, а не слова

Про «що не вийшло» — чесно і конкретно

Слабка відповідь: «нам не вистачило часу». Сильна звучить так: «Фільтр галереї працює тільки мишею. З клавіатури він не вмикається. Ми помітили це вчора, коли пройшли сторінку клавішею Tab. Переписати не встигли: треба обробляти keydown».

Друга відповідь показує, що команда розуміє свою роботу й бачить її межі. Саме це й оцінюють.

Питання

Команда п’ять хвилин показувала код у редакторі, жодного разу не відкривши сайт у браузері. Технічно все правда. Що з таким захистом не так?

Крок 11

Практика: зібрати і опублікувати

Кроки 1—4 робить уся команда разом за одним екраном, далі — кожен у своїй гілці. Галочки зберігаються, сторінку можна закрити.

Підстав своє У командах нижче class9a заміни на свою організацію (class9a або class9b), team-3 — на номер своєї команди, team<N>.<домен> — на адресу, яку дав учитель.
Останній push — не за хвилину до захисту Деплой іде кілька секунд, але поламка знаходиться десять хвилин. Зроби фінальний push за 15 хвилин до кінця практики і відкрий сайт із чужого телефона — це і є справжня перевірка.
Крок 12

Автоперевірка

Чекер відкриває ваш сайт так само, як стороння людина, і читає репозиторій через API Gitea. Він не знає, хто скільки старався, — він бачить коди відповідей і історію комітів. Спроби не обмежені.

Демонстраційний режим: результат згенеровано для показу. На сервері ця кнопка викликає POST /api/check, який запускає check 15 для репозиторію і сайту команди.

Що вчитель дивиться очно

Крок 13

Шкала виконання

Це те, що бачить учитель, коли виставляє оцінку.

СкладникВагаРезультат
Виконано
0%
Рекомендований бал за 12-бальною

П’ять речень, які варто запам’ятати

Де найчастіше помиляються

Домашнє завдання

Усунути зауваження після захисту й довести check 15 до зеленого. Окремо: дописати в README.md розділ «Що ми зробили б інакше» — 3—5 речень від команди, з конкретикою.

«Краще розподілили б час» — це ні про що. Пиши конкретно: «Домовилися б про імена файлів на першому уроці теми. Три людини назвали головні сторінки розділів по-різному. Ми втратили близько години, поки лагодили посилання».

Джерела

Звідки взяті правила й формулювання

Тексти помилок git, коди відповідей HTTP і вимоги доступності на цій сторінці — зі стандартів і офіційної документації. Перевіряти дозволено й корисно.

Повний список із поясненнями, що звідки взято, — у файлі urok-15-джерела.md поруч із цією сторінкою.