← До списку уроків
Заняття 13 з 13Реліз і день показу
курс 0% виконано0%
Заняття 13 · місяць 3

Реліз і день показу

90 хвилин

Довести бота до стану, який не соромно показати: написати README для незнайомої людини, випустити версію 1.0 з описом і шляхом назад, перевірити проєкт власним скриптом-аудитом, прибрати з екрана секрети — і за дві-три хвилини розповісти про свою роботу гостям.

Мій сайт
http://91.219.61.4/u/<логін>/
Мій сабдомен
https://<логін>.<домен>/
Мій кабінет
http://91.219.61.4/k/<логін>/
Вхід на сервер
ssh <логін>@91.219.61.4

Замість <логін> підставляєш свій логін виду bohdan.g9: ім’я, крапка, номер групи. Кутові дужки не пишуться. У прикладах на цій сторінці скрізь стоїть bohdan.g9 — читай це як свій логін і виправляй у кожній команді, яку копіюєш. Кабінет — сторінка, де проти кожного критерію стоїть відмітка, зарахований він чи ні.

<домен> — назва, яку ти записав у файл ~/app/project.yaml на занятті 10, розділ server, поле url. Сабдомен (із заняття 10) — це частина адреси перед доменом: в імені bohdan.g9.klub.example домен — klub.example, а сабдомен — bohdan.g9. Саме цю адресу ти сьогодні даєш гостям, тому перевір її першою справою.

Перші два рядки ведуть на одне й те саме: за обома адресами nginx віддає файли з твоєї теки ~/www. Бот у цьому не бере участі: він сам звертається до Telegram.

Що ти зробиш сьогодні

Це останнє заняття курсу. За кілька місяців ти зібрав бота, який відповідає, пам’ятає людей, питає ШІ, шукає у своїй базі знань, пише першим і ловить власні помилки через тести. Тепер його треба випустити: так, щоб незнайома людина відкрила сторінку проєкту, за пів хвилини зрозуміла, що це, і змогла його запустити.

До кінця заняття в тебе буде:

Якщо в тебе немає TelegramУсе, крім живого повідомлення, ти зробиш через try_bot.py. На виступі замість живого чату покажеш його (приклади є в кроці 13). Пункти, де потрібен живий бот, викладач оцінить окремо.

Теорія

1. Реліз: коли «воно працює» стає «версією»

Поки ти пишеш бота, код змінюється щодня. Але щоб сказати комусь «ось готова штука», треба вирізати з цього потоку одну мить і домовитися: ось це — версія 1.0. Така мить називається релізом (випуском), а її позначка в Git — тегом. Тег — це наклейка на конкретному коміті: гілка рухається вперед із кожним новим комітом, а тег лишається на місці.

Навіщо це? Через тиждень ти виправиш щось і зламаєш. Тоді git checkout v1.0 покаже тобі код тієї версії, яку ти колись показував гостям і яка працювала. Після такого перегляду поверни робочу гілку: git switch main (Git скаже про «detached HEAD» — це лише означає, що ти дивишся на старий коміт, а не працюєш на гілці). А щоб справді позбутися поганих змін, є git revert: вона додає новий коміт, що їх скасовує. Це й називається відкат. Ще корисне правило: тег ставлять на коміті, де вже проходять тести, інакше «версія 1.0» — це версія з відомою поломкою.

До тега додають короткий файл RELEASE.md із трьома відповідями: що в цій версії (мовою користувача: «бот відповідає на /ask», а не «переписав функцію»), які в неї слабкі місця («без підключення до ШІ-шлюзу бот відповідає ввічливою відмовою») і як відкотитися. Написати про слабкі місця самому — нормально: так роблять усі дорослі проєкти, і так ти сам вирішуєш, що гість почує першим.

Ти поставив тег v1.0, а наступного дня змінив текст /help і зробив ще один коміт. Куди тепер вказує тег v1.0?

2. README: обличчя проєкту

README — це перше, що бачить людина, відкривши репозиторій на GitHub. У неї є приблизно тридцять секунд. Якщо за цей час вона не зрозуміє, що це і чи їй це потрібно, — закриє вкладку. Тому README пишуть не для себе і не для викладача, а для незнайомої людини, яка про твій проєкт нічого не знає.

У шаблоні сім головних розділів, і кожен відповідає на одне питання:

РозділПитання, на яке він відповідає
Що цеЩо робить бот і яку проблему розв’язує?
Для когоХто ним користуватиметься і що йому стане зручніше?
Як запуститиЩо зробити по кроках, щоб воно заробило? (токен, .env, перша перевірка)
Команди ботаЩо можна написати боту?
Приклад розмовиЯк це виглядає в житті? (шматок діалогу або знімок екрана)
Що вмієГоловні можливості списком
Чого я навчивсяЩо було важко, що вийшло, що зробиш інакше

Тут можна попросити ШІ допомогти: «ось мій bot.py, запропонуй, як пояснити команди людині, що бачить бота вперше». Але розділ «Чого я навчився» мусить звучати твоїм голосом: його прочитають гості, і саме з нього видно, що проєкт зробив ти. До того ж автоперевірка шукає в розділах твій текст і справжні команди з твого bot.py, а не загальні фрази.

Пароль у README — ніколиУ README пишуть, що треба вписати в .env, але не самі значення. Токен бота у файлі, який лежить на GitHub, — це як лишити ключ від квартири в дверях.

Для кого ти пишеш README?

3. Чекліст готовності й аудит: перевіряти може програма

Чекліст — список справ, які треба перевірити перед важливою подією; так робить пілот перед зльотом. Перелік із десяти пунктів ми зробимо не на папері, а як програму — audit.py. Аудит — це перевірка за списком: програма проходить пункти й для кожного друкує ✔ (гаразд) або ✘ (є що виправити, і чому). Ось усі десять:

№ПунктЗвідки береться
1README: сім розділів з твоїм текстомвже написано
2RELEASE.md: що в релізі, обмеження, як відкотитисядопишеш ти
3тег v1.0 існує й стоїть на коміті з історії твоєї гілки mainвже написано
4.env не потрапляв у git ні зараз, ні в історіївже написано
5.env.example: усі змінні з .env, але без значеньдопишеш ти
6бекап бази не старший за добувже написано
7з бекапу вже відновлювалисьвже написано
8служба сама піднімається (Restart=always)допишеш ти
9ранковий звіт: таймер увімкненовже написано
10усі тести проходятьвже написано

Три пункти (2, 5 і 8) ти допишеш сам: у кожному стоїть заготовка «ще не написано», яку треба замінити своєю перевіркою. Правило одне: функція повертає "" (порожній рядок), якщо все гаразд, або речення про те, що не так.

Головна вимога до аудиту — правдивість. Аудит, який завжди каже ✔, гірший за відсутній: він дає хибний спокій, і ти йдеш на показ з відкритим токеном, думаючи, що все гаразд. Тому автоперевірка нижче на сторінці не просто запускає твій audit.py: вона перевіряє ті самі речі власним способом і порівнює. Якщо твій аудит каже ✔, а насправді не гаразд (або навпаки) — зараховано не буде.

audit.py друкує десять ✔, але команда git ls-files показує, що .env лежить у git. Що це означає?

4. Безпека перед показом

На дні показу твій екран бачать десятки людей, а ще його можуть сфотографувати чи записати. Тому перед показом пройдися по короткому списку:

Після показу — змінити токен бота. Відкрий у Telegram @BotFather, напиши /revoke, вибери свого бота: старий токен перестане працювати, а BotFather видасть новий. Новий впиши в ~/app/.env і перезапусти службу. Навіщо, якщо ніби ніхто нічого не помітив? Заміна токена займає хвилину, а витік — це небезпека для всіх, хто писав боту: чужа людина зможе писати від імені твого бота і читати, що йому надсилають. Тому токен міняють після показу завжди, а не лише коли здається, що він «мигнув».

Під час показу токен бота на секунду з’явився на екрані проєктора. Що зробити після показу?

5. Виступ і день показу

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

ЧастинаСкількиЩо сказати
1. Проблема30 с«Мене звати … Я зробив бота, який … Він потрібен, щоб …»
2. Демо60–90 сПоказуєш бота в дії (порядок нижче)
3. Як влаштовано30 с«Бот — програма на Python, що живе на сервері як служба. Повідомлення приходить у handle_update, дані лежать у SQLite, а бекап і ранковий звіт запускають таймери»
4. Чого навчився30 сОдна річ, що вийшла, і одна помилка, яку виправив

Порядок демо (п’ять кроків, щоб нічого не забути): 1) /start: бот вітається; 2) своя команда або /ask; 3) скрипт за розкладом або ранковий звіт; 4) відмова чужому: чужий номер пише /run privit і отримує «Ця команда лише для власника бота» — це видовищна частина, бо показує, що захист справжній; 5) /version: бот називає свою версію.

Правило виступу: репетируй уголос із секундоміром. Тихо прочитати в голові — це не репетиція; уголос ти одразу почуєш, де заплутався.

6. Що далі: куди рости і як зберегти бота

Куди рости. Ідеї для наступних проєктів, що спираються на те, що ти вже вмієш: бот-нагадувач про домашні завдання й контрольні; бот класу (розклад, оголошення, голосування); бот-вікторина з таблицею рекордів; моніторинг: бот пише, якщо твій сайт перестав відкриватись; бот-помічник з базою знань про твоє хобі (фільми, гра, спорт). Вчитися далі зручно з офіційної документації Python і Telegram Bot API, з безкоштовних курсів (Prometheus, Coursera), ютуб-каналів про Python, шкільних і студентських олімпіад та змагань з програмування.

Як зберегти бота після курсу. Важливо: акаунти й сервер школи можуть бути вимкнені, і бот на них зупиниться. Тому вже зараз у тебе є все, щоб його перенести:

Куди переносити:

Що робити на новому місці, завжди однаково: поставити Python і потрібні бібліотеки, зробити git clone, створити .env із токеном, відновити базу з бекапу, зробити службу з Restart=always (як у club-bot.service), написати боту /start. Один токен — один працюючий бот: перш ніж вмикати нового, вимкни старого, інакше Telegram буде видавати помилку конфлікту.

Репетиція переїздуУ кроці 12 ти перевіриш, що проєкт збирається з нуля з репозиторію. Якщо там тести проходять — переїзд буде нудним, а це якраз найкраще.

Слова цього уроку

СловоЩо означає
релізВипуск версії: момент, коли «воно працює» фіксують і кажуть «це версія 1.0»
версіяНомер випуску: v1.0, потім v1.1, v2.0 тощо
тегНаклейка в Git на конкретному коміті. Не рухається, коли з’являються нові коміти
відкатПовернення до попередньої справної версії: найчастіше git revert (скасувати поганий коміт). git checkout v1.0 лише показує старий код
RELEASE.mdФайл про версію: що в ній, які слабкі місця, як повернутися назад
READMEСторінка проєкту для людини, яка бачить його вперше
чеклістСписок справ, які перевіряють перед важливою подією
аудитПеревірка за списком. У нас — програма audit.py, що друкує ✔ чи ✘ для десяти пунктів
.env.exampleЗразок .env: ті самі змінні, але без значень. Його можна класти в Git
/revokeКоманда @BotFather, що скасовує старий токен і видає новий
демоКороткий показ проєкту в дії
VPSОрендований віртуальний сервер, на який можна перенести бота

Практика

1 Зайти на сервер і подивитися, з чого починаємо

ssh <логін>@91.219.61.4
cd ~/app
git status --short
systemctl --user is-active club-bot
/opt/club/venv/bin/python3 -m pytest -q
ls /opt/club/kurs/13/

Домовленість про Python: усе, що запускає pytest (тести та audit.py), запускай через /opt/club/venv/bin/python3: лише там стоять потрібні пакети. try_bot.py, backup.py і restore.py працюють і з простим python3.

2 Запустити заготовку аудиту й побачити, скільки роботи

cp /opt/club/kurs/13/audit.py ~/app/
cd ~/app
/opt/club/venv/bin/python3 audit.py

Програма надрукує десять рядків: ✔ 3. git-тег v1.0 … або ✘ 2. RELEASE.md … — ще не написано, а в кінці Готово: N з 10.. Наразі ✘ буде кілька: пункти 2, 5 і 8 завжди, бо це твої заготовки, плюс ті, до яких ми ще не дійшли (README, тег, можливо бекап). Це не помилка, а список роботи: до кінця заняття всі десять мають стати ✔. Іноді тести (пункт 10) йдуть пів хвилини — зачекай.

3 Навчити бота називати свою версію: команда /version

Відкрий ~/app/bot.py (nano ~/app/bot.py). Потрібні три невеликі вставки. Готовий зразок лежить у /opt/club/kurs/13/bot.py: це бот із заняття 11 плюс /version. Але не копіюй його поверх свого файлу: у твоєму bot.py є свої правки. Порівняй: diff ~/app/bot.py /opt/club/kurs/13/bot.py і дивись лише на рядки про version.

Вставка 1. Знайди в bot.py текст HELP. Новий рядок має стати останнім у ньому. Після заняття 10 останній рядок — про /forget: у ньому лишається \n" без закривної дужки, а дужка ) переходить на новий рядок:

        "/forget — видалити мої дані\n"
        "/version — яка версія бота працює")

Якщо в тебе інша остання команда, правило те саме: попередній рядок закінчується на \n", а ) стоїть лише після рядка про /version.

Вставка 2. У handle_update, одразу після гілки /whoami:

    if text.startswith("/version"):                    # заняття 13
        return version()

Вставка 3. Нова функція перед def answer. Вона питає в git, на якому ти тегу, і повертає це як відповідь на /version:

def version():
    """Яка версія працює — за найближчим git-тегом (v1.0, v1.1…)."""
    import subprocess
    try:
        r = subprocess.run(["git", "--no-optional-locks", "-C", str(BASE), "describe", "--tags", "--match", "v[0-9]*", "--always"],
                           capture_output=True, text=True, timeout=5)
        tag = r.stdout.strip() if r.returncode == 0 else ""
    except (OSError, subprocess.SubprocessError):
        tag = ""
    if not tag:
        return "Версію визначити не вдалося: у ~/app немає git-репозиторію."
    return f"Версія бота: {tag}"
cd ~/app
python3 try_bot.py "/version"

Тега ще немає, тому бот відповість коротким номером коміту, наприклад Версія бота: 1a2b3c4. Після тега в кроці 11 тут з’явиться v1.0. Бачиш Traceback — найчастіше пропущена дужка чи відступ у вставці; diff покаже, де.

4 Написати README за шаблоном

cd ~/app
cp README.md README.old.md
cp /opt/club/kurs/13/README.template.md README.md
nano README.md

Старий README збережено як README.old.md: бери з нього свої готові тексти (розділи «Що це» і «Як запустити» із заняття 03). У шаблоні в кожному розділі є рядок-підказка зі словом TODO. Правило: рядок із TODO видали й напиши замість нього своє. Вимоги такі:

Розділ ## Персональні дані із заняття 10, якщо ти його писав, не видаляй: перенеси його нижче, перед розділом «Версії».

Як користуватися ШІМожна попросити його переглянути, чи зрозуміло написано «Як запустити», і де лишилися складні слова. Писати розділ «Чого я навчився» за тебе — не можна: його читатимуть гості, і він має бути твоїм.

rm README.old.md
grep -c "TODO" README.md
/opt/club/venv/bin/python3 audit.py | head -1

Друга команда має надрукувати 0: це кількість рядків із TODO, що лишилися. Не нуль — відкрий файл і знайди їх. Третя покаже перший рядок аудиту: ✔ 1. README: сім розділів з твоїм текстом. Якщо там ✘, у кінці рядка видно причину: яка секція порожня чи якого розділу немає.

5 Зробити .env.example

Нова людина, яка завантажить твій код, не знає, які змінні вписувати в .env. Для цього є зразок без значень. Назви змінних візьмемо з твого .env, не показуючи значень:

cd ~/app
grep '=' .env | cut -d= -f1 | sed 's/$/=/' > .env.example
cat .env.example
git check-ignore .env && echo ".env у git не потрапить"
git add .env.example

Друга команда (cat) покаже щось на зразок BOT_TOKEN=, ADMIN_IDS=, LLM_BASE_URL= — назви з порожнім місцем після =. Третя (git check-ignore) друкує .env і наш напис — отже, .gitignore справді приховує файл. Не надрукувалось — додай рядок .env у .gitignore. Четверта додала зразок до наступного коміту.

6 Написати RELEASE.md

cp /opt/club/kurs/13/RELEASE.template.md ~/app/RELEASE.md
date +%d.%m.%Y
nano ~/app/RELEASE.md

Заміни ДД.ММ.РРРР на дату (її показала друга команда), а в кожному розділі видали рядки з TODO і напиши своє:

grep -c "TODO" ~/app/RELEASE.md

Знову має бути 0.

7 Дописати три перевірки в audit.py

Відкрий nano ~/app/audit.py і знайди функції, де стоїть return "ще не написано (ЗАПОВНИ)". Подивись, як написана перевірка tag() чи backup_fresh(): вона бере факт, порівнює його з вимогою й повертає "" або причину. За тим самим зразком напиши свої три. Перша, пункт 8, розібрана повністю — перенеси її:

@check("служба сама піднімається: Restart=always")
def restart_always():
    unit = UNITS / "club-bot.service"
    if not unit.exists():
        return "немає файлу club-bot.service"
    # рядок цілком: закоментований «# Restart=always» не годиться
    if not re.search(r"^\s*Restart\s*=\s*always\s*$", unit.read_text(encoding="utf-8"), re.M):
        return "у club-bot.service немає рядка Restart=always"
    return ""

Дві інші перевірки — за тим самим зразком. Значення змінних із .env не друкуй і не повертай у причині.

Застряг — подивись розв’язки в розділі «Якщо щось не працює» внизу, після спроби самому.

cd ~/app
/opt/club/venv/bin/python3 audit.py

Після виправлення пункти 2, 5 і 8 мають стати ✔, а на місці «ще не написано» не лишитись нічого. Якщо перевірка «впала» — з’явиться перевірка впала: NameError (чи інша назва): значить, у твоїй функції описка.

8 Свіжий бекап і перевірене відновлення

cd ~/app
python3 backup.py
python3 restore.py
ls -l ~/backups | tail -3
ls -l ~/restore-test/
systemctl --user is-enabled club-backup.timer

backup.py друкує шлях нового файлу app-ДАТА.db; restore.py розгортає найсвіжіший бекап у ~/restore-test/app.db й перелічує таблиці (це не чіпає робочу базу). Остання команда має сказати enabled. Інакше: systemctl --user enable --now club-backup.timer (заняття 08). Бекап, з якого жодного разу не відновлювались, — не бекап; тому обидва кроки в одному місці.

9 Служба і ранковий звіт піднімаються самі

grep -n Restart ~/.config/systemd/user/club-bot.service
systemctl --user is-enabled club-morning.timer
systemctl --user list-timers club-morning.timer

Перша команда має показати рядок Restart=always («завжди перезапускай службу, якщо вона впала»). Друга — enabled. Третя показує, коли таймер спрацює наступного разу: стовпець NEXT (час за сервером, а не за Києвом — це та сама мить, що о 08:00 у Києві). Чого бракує — зроби кроки із занять 08–09, наприклад: systemctl --user enable --now club-morning.timer.

10 Довести аудит до десяти ✔ (крім тега)

cd ~/app
/opt/club/venv/bin/python3 audit.py

Тепер усі пункти, крім 3 (тег), мають бути ✔. Дивись на причину біля кожного ✘ і виправляй. Якщо пункт 4 (.env не потрапляв у git) ✘ через історію git, самому його не виправити (див. нижче «Якщо щось не працює», L13.5): скажи викладачеві.

11 Коміт, тег v1.0 і оновлення служби

cd ~/app
git status --short
git add -A
git commit -m "Заняття 13: README, RELEASE.md, audit.py, .env.example, /version"
git tag -a v1.0 -m "Реліз 1.0"
git push origin main
git push github main
git push origin v1.0
git push github v1.0
bash deploy.sh
python3 try_bot.py "/version"
/opt/club/venv/bin/python3 audit.py

git status --short має показати твої нові й змінені файли й не показати .env (інакше зупинись!). git tag -a створює тег із повідомленням і датою, а не лише голу наклейку. Кожен git push закінчується рядком main -> main чи * [new tag] v1.0 -> v1.0. deploy.sh (заняття 12) проганяє тести й перезапускає службу, щоб у Telegram з’явилась команда /version. Далі бот відповідає Версія бота: v1.0, а аудит — Готово: 10 з 10..

12 Репетиція переїзду: проєкт збирається з нуля

git clone ~/repo.git ~/clone-test
cd ~/clone-test
git tag
ls -a
BOT_POLLING=0 /opt/club/venv/bin/python3 -m pytest -q
cd ~
rm -rf ~/clone-test

Ти щойно зробив те, що робитиме людина на новому комп’ютері: завантажив код «з нуля». git tag покаже v1.0. У списку файлів ls -a має бути код, README.md, .env.example, але не .env і не база — їх не мало бути в репозиторії. Тести в копії мають пройти (N passed). Якщо тест упав на ModuleNotFoundError або No such file — значить, якийсь файл існує лише в тебе й не доданий у git: додай його в справжньому ~/app командою git add, збережи комітом, поправ тег (крок 11) і повтори. Без такого файлу переїзд на новий сервер був би сюрпризом.

13 Написати виступ і прорепетирувати день показу

nano ~/app/VYSTUP.md

Запиши чотири частини плану з теорії (Проблема, Демо, Як влаштовано, Чого навчився) — по 2–3 речення своїми словами. Поряд пропиши сценарій демо з п’яти кроків:

1. /start
2. /ask що таке API?  (або своя команда)
3. ранковий звіт або скрипт за розкладом
4. чужий номер: python3 try_bot.py --id 999 "/run privit"   → «Ця команда лише для власника бота.»
5. /version   → v1.0 (або v1.0-N-g…, якщо після релізу були коміти)

Прорепетируй п’ять кроків через try_bot.py — він працює й без Telegram:

  1. python3 try_bot.py "/start";
  2. python3 try_bot.py "/ask що таке API?". Якщо ШІ-шлюз не підключено, бот відповість ввічливою відмовою — так і має бути, покажи її як є;
  3. команда власника: OWNER_CHAT_ID=777 python3 try_bot.py --id 777 "/scripts" (777 — умовний номер власника);
  4. чужа людина: python3 try_bot.py --id 999 "/run privit" має отримати відмову;
  5. python3 try_bot.py "/version": v1.0 або v1.0-N-g… (v1.0 і ще N комітів зверху).

Відповіді мають збігатися з тим, що ти пишеш у сценарії. Тепер уголос, із секундоміром: у ліміт 2–3 хвилини? Забагато — прибери деталі, лишивши ті, що ти справді хочеш, щоб гості запам’ятали.

14 Прибрати секрети з екрана й записати план «після показу»

Пройдися чеклістом із теорії (розділ 4) перед виходом на сцену: clear у терміналі; .env не відкрито; Telegram-чат без особистих повідомлень; запасні знімки екрана зроблено. А тепер допиши в кінець VYSTUP.md три рядки, які виконаєш одразу після показу:

Після показу:
1. @BotFather → /revoke → мій бот → новий токен
2. nano ~/app/.env  (замінити BOT_TOKEN)  →  systemctl --user restart club-bot
3. написати боту /start і побачити відповідь

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

Зберегти роботу на GitHub

15 Відправити виступ і перевірити реліз на GitHub

cd ~/app
git add VYSTUP.md
git commit -m "Заняття 13: план виступу і дня показу"
git push origin main
git push github main
git push github v1.0

Відкрий у браузері свій репозиторій на GitHub. Перевір: у README.md правильно показуються всі розділи; гілка (кнопка зліва зверху) відкриває список тегів, де є v1.0; у налаштуваннях (Settings, внизу) видно, що репозиторій Private; файлу .env у списку немає. За бажанням на сторінці репозиторію натисни Releases → Create a new release, вибери тег v1.0 і встав текст з RELEASE.md: так реліз матиме власну сторінку. Якщо в тебе працює GitHub Actions (заняття 12), біля коміту з тегом має бути зелена галочка.

Що перевіряє автоматика

Автоперевірка нічого не змінює в твоєму репозиторії й нічого не шле в Telegram. Вона читає README.md і RELEASE.md і дивиться, чи там твій текст, а не шаблон: рядки, які ти не змінив, не рахуються. Перевіряє, що тег v1.0 стоїть на коміті, де проходять тести, і що тег відправлено в ~/repo.git. Запускає твій audit.py і порівнює його відповіді зі своїми: аудит, який каже ✔ там, де не гаразд (або навпаки), не зараховується. Шукає токени й секрети в файлах та в усій історії git. Дивиться бекап, відновлення, Restart=always і таймер ранкового звіту. Виступ і демо оцінює викладач.

Натисни «Перевірити практичну частину» в розділі «Перевірка виконаних завдань» нижче на сторінці. Перевірка тега й аудиту займає до півтори хвилини — зачекай.

КодЩо перевіряєтьсяЯкщо не зараховано
L13.1README: сім розділів з твоїм текстом і справжніми командами
автоперевірка
У ~/app/README.md мають бути розділи «Що це», «Для кого», «Як запустити», «Команди бота», «Приклад розмови», «Що вміє», «Чого я навчився», у кожному щонайменше 40 символів твого тексту і кілька різних слів (рядки з TODO видали, незмінені рядки шаблону не рахуються). У «Команди бота» назви щонайменше 4 справжні команди з твого бота у зворотних лапках, напр. `/help`; у «Що вміє» — 3 різні пункти «- …».
L13.2тег v1.0: на коміті проходять тести, тег відправлено
автоперевірка
Тег має стояти на коміті, де вже є тека tests і всі тести зелені, та бути відправлений у ~/repo.git. Якщо тег поставлено зарано: git tag -fa v1.0 -m "Реліз 1.0" (на правильному коміті), git push -f origin v1.0 (-f лише для тега). Початково: git tag -a v1.0 -m "Реліз 1.0" && git push origin v1.0
L13.3RELEASE.md: що в релізі, обмеження, як відкотитися
автоперевірка
У ~/app/RELEASE.md: заголовок «# Реліз v1.0», розділ «Що в релізі» (≥3 різні пункти «- …»), «Відомі обмеження» (≥2 різні пункти), «Як відкотитися» з командою git revert або git reset і твоїм реченням про перевірку відкату. Усі рядки з TODO видали.
L13.4audit.py дописаний, друкує 10 пунктів і не бреше
автоперевірка
Скопіюй /opt/club/kurs/13/audit.py у ~/app і допиши три перевірки (пункти 2, 5, 8): прибери рядки return "ще не написано…". Аудит має надрукувати рівно десять рядків «✔ N. …»/«✘ N. …»; перевірка порівнює їх із власною — якщо аудит каже ✔ там, де не гаразд (або навпаки), він не зарахується. У повідомленні вказано пункт і причину: підправ саме цю перевірку (а якщо причина в RELEASE.md чи README, спершу виправ їх: цим займаються L13.1 і L13.3).
L13.5секретів немає ні в коді, ні в історії git; є .env.example
автоперевірка
Токен і інші секрети не мають бути в жодному файлі git і жодному коміті, а .env має ігноруватися (токена Telegram у .env може й не бути). Заміни .env.example (git add .env.example): ті самі змінні, що в .env, але без значень. Якщо токен колись потрапив у коміт — @BotFather → /revoke, новий токен у .env; історію чистить викладач.
L13.6свіжий бекап (до доби) і відновлення перевірено
автоперевірка
Потрібні: таймер бекапу (systemctl --user enable --now club-backup.timer), копія в ~/backups молодша за 24 години (python3 backup.py) і python3 restore.py, що створює ~/restore-test/app.db. Бекап, з якого не відновлювались, — не бекап.
L13.7служба сама перезапускається, ранковий таймер увімкнено
автоперевірка
У ~/.config/systemd/user/club-bot.service має бути рядок Restart=always (після змін: systemctl --user daemon-reload і systemctl --user restart club-bot). Таймер ранкового звіту: systemctl --user enable --now club-morning.timer
L13.8виступ на дні показу: 2–3 хвилини за планом (проблема, демо, як влаштовано, чого навчився)
викладач
Позначку ставить викладач на занятті або після нього.
L13.9демо живого бота пройшло за сценарієм (/start, команда, розклад, відмова чужому, звіт) або показано запасний варіант
викладач
Позначку ставить викладач на занятті або після нього.

Твої відповіді на питання уроку

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

Перевірка виконаних завдань

Список критеріїв і що саме вони означають — у таблиці вище, «Що перевіряє автоматика». Тут — та сама перевірка, але прямо зараз, без очікування на найближчий прохід за розкладом.

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

  1. Репетиція вголос. Двічі розкажи свій виступ із секундоміром: уклався в 2–3 хвилини? Один раз — комусь удома чи другу. Спитай: що було незрозуміло?
  2. Перевірка README очима друга. Дай посилання на свій README другу (або запиши його на папір) і попроси «запустити» бота лише за інструкцією, нічого в тебе не питаючи. Де він застряг — там README недописаний: виправ.
  3. Розділ «Що далі». Додай у README розділ ## Що далі з трьома ідеями, куди рости (теорія, розділ 6). Одна з них має бути з нового для тебе: нова команда, інший сервіс, інша мова.
  4. Після показу. Виконай три рядки «Після показу» з VYSTUP.md: /revoke у @BotFather, новий токен у .env, перезапуск, /start. Запиши в VYSTUP.md, о котрій годині це зробив.
  5. Збережи. git add -A, git commit -m "Заняття 13: домашня робота", git push origin main і git push github main.

Якщо щось не працює

L13.1: README не проходить

L13.2: тег v1.0

L13.3: RELEASE.md

L13.4: audit.py

L13.5: секрети в репозиторії

L13.6: бекап і відновлення

L13.7: служба і таймер