Сдача работы: чистый клон и семь проверок
- Зачем это нужно
- «У меня работает» — не аргумент
- Проверка первая: собрать из чистого клона
- Проверка вторая: чего в репозитории быть не должно
- Проверка третья: секрет остаётся в истории
- Проверки с четвёртой по седьмую
- Как выглядит починенный проект
- Типичные ошибки
- Шпаргалка по главе
- Словарь главы
- Что должен уметь после главы
- Проверка по главе
- Куда дальше: проверенные ресурсы
Зачем это нужно
Модуль сделан, всё работает, осталось сдать. И вот здесь теряются баллы, которые уже были заработаны.
Эксперт не смотрит на вашу папку. Он берёт то, что лежит в репозитории, разворачивает у себя и пробует запустить. Если проект не собирается — неважно, что у вас он собирался. Если в истории лежит сид-фраза — это снятые баллы за безопасность, даже если файл потом удалили.
Эта глава — про семь проверок, каждая на минуту, которые закрывают почти все потери такого рода. Всё ниже проделано вживую на учебном проекте: сначала с типичными ошибками, потом исправленном.
«У меня работает» — не аргумент
Соберём проект так, как его обычно собирает уставший человек за пять минут до конца времени:
git init
git add -A
git commit -m "первый коммит"
Смотрим, что реально попало:
git ls-files
.env
node_modules/junk/a.js
package.json
src/index.ts
Четыре строки, и в них две беды сразу: в репозиторий уехал .env с сид-фразой и папка зависимостей. А tsconfig.json, README.md и файл блокировки версий — не уехали, потому что их просто нет.
Команда git ls-files — самая недооценённая в этом списке. Она показывает ровно то, что увидит эксперт. Не ls, не «я вроде всё добавил», а именно она.
Проверка первая: собрать из чистого клона
cd ..
git clone proekt proverka
cd proverka
ls -a
. .. .git .gitignore package.json src
Ставим и собираем:
npm ci
npm run build
Version 5.9.3
tsc: The TypeScript Compiler - Version 5.9.3
COMMON COMMANDS
Компилятор напечатал справку. Это не ошибка сборки — это tsc, запущенный без настроек: файла tsconfig.json в репозитории нет, компилировать нечего, и он показал, как им пользоваться.
Клонировать можно локально, без всякого сервера: git clone ./proekt ./proverka. Это занимает секунду и ловит больше половины проблем сдачи.
Проверка вторая: чего в репозитории быть не должно
printf 'node_modules/\ndist/\n.env\n' > .gitignore
git rm -r --cached node_modules .env
git add -A && git commit -m "убрал лишнее из репозитория"
git ls-files
.gitignore
package.json
src/index.ts
Добавить .gitignore после первого коммита недостаточно. Он не действует на файлы, которые уже отслеживаются, — их надо убирать руками через git rm --cached. Это ловушка, на которую попадаются почти все.
Проверка третья: секрет остаётся в истории
Рабочая копия чистая. Проверим историю:
git show HEAD~1:.env
SEED=olegs test seed for pgk champs course 2026
NODE_URL=http://127.0.0.1:6869
Сид-фраза на месте. Она в первом коммите, и там останется навсегда: история git неизменяема по устройству. Любой, у кого есть доступ к репозиторию — включая эксперта, — достанет её за одну команду.
Грепаем весь код и историю:
git grep -nEi "(api[_-]?key|secret|passw|seed *=)" -- .
.env:1:SEED=olegs test seed for pgk champs course 2026
src/index.ts:1:const SEED = 'olegs test seed for pgk champs course 2026';
Второе попадание не менее важно: сид вписан прямо в код, и удаление .env его не трогает.
Единственное настоящее лечение — сменить ключ. Переписывать историю можно, но ключ всё равно считается скомпрометированным: репозиторий мог быть склонирован, показан, попасть в резервную копию. На чемпионате это ещё и снятые баллы независимо от того, что вы сделали потом.
Проверки с четвёртой по седьмую
Файл блокировки версий. package-lock.json (или yarn.lock, Gemfile.lock, poetry.lock) должен быть в репозитории. Без него npm ci не работает вовсе, а npm install поставит новые версии — и проект, собиравшийся вчера, сегодня сломается.
README с командами запуска. Три команды подряд, которые можно скопировать:
## Запуск
npm ci
npm run build
npm start
Пример настроек. Файл .env.example с перечнем переменных и без значений:
SEED=
NODE_URL=http://127.0.0.1:6869
Понятное падение без настроек. Вот как выглядит плохо и хорошо:
const seed = process.env.SEED;
if (!seed) {
throw new Error('Не задана переменная SEED — скопируйте .env.example в .env');
}
Error: Не задана переменная SEED — скопируйте .env.example в .env
Вместо стека на сорок строк — одна строка, объясняющая, что делать.
Как выглядит починенный проект
git ls-files
.env.example
.gitignore
README.md
package-lock.json
package.json
src/index.ts
tsconfig.json
Чистый клон:
git clone proekt proverka3 && cd proverka3
npm ci && npm run build
> tsc
код возврата: 0
Запуск без настроек:
Error: Не задана переменная SEED — скопируйте .env.example в .env
Запуск с настройками:
запуск с аккаунтом длиной 15
По дороге вылез ещё один реальный отказ: error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Типы Node не были записаны в зависимости. Заметить это можно было только на чистом клоне — на рабочей машине они лежали в папке зависимостей от соседнего проекта.
Типичные ошибки
Ошибка 1. Проверять на своей папке.
Там лежит всё нужное, даже то, чего нет в репозитории. Проверка — только на чистом клоне.
Ошибка 2. Считать .gitignore задним числом работающим.
Не работает. Нужен git rm --cached.
Ошибка 3. Коммитить .env «временно».
Временного в истории git не бывает.
Ошибка 4. README из одной строки «дипломный проект».
README нужен эксперту, а не вам: три команды запуска и список переменных.
Ошибка 5. Оставлять отладочный вывод с ключами.
console.log('сид:', seed); // уедет в журнал, а журнал покажут
Ошибка 6. Сдавать, не запустив.
Последняя правка «на всякий случай» ломает сборку чаще, чем кажется. Между последним коммитом и поднятой рукой должен быть чистый клон.
Шпаргалка по главе
| Проверка | Команда |
|---|---|
| Что в репозитории | git ls-files |
| Чистый клон | git clone ./proekt ./proverka && cd proverka |
| Установка по блокировке | npm ci |
| Сборка | npm run build |
| Убрать из индекса | git rm -r --cached node_modules .env |
| Секреты в коде | git grep -nEi "(api[_-]?key|secret|passw|seed *=)" -- . |
| Секрет в истории | git show <коммит>:<файл> |
| Что изменилось за коммит | git show --stat <коммит> |
Словарь главы
| Термин | Что это |
|---|---|
| Чистый клон | Копия репозитория в новой папке; единственная честная проверка |
| Файл блокировки | package-lock.json и аналоги: точные версии зависимостей |
npm ci | Установка строго по блокировке; падает без неё |
git rm --cached | Убрать файл из отслеживания, оставив на диске |
.env.example | Перечень переменных без значений |
| Скомпрометированный ключ | Попавший в историю; лечится только заменой |
| Понятное падение | Одна строка с тем, что делать, вместо стека |
Цель: скорость ≥ 95 зн/мин, точность ≥ 90%
git ls-files
Что должен уметь после главы
- посмотреть, что реально лежит в репозитории, а не на диске;
- собрать проект из чистого клона и понять, чего не хватает;
- убрать лишнее из отслеживания и объяснить, почему
.gitignoreзадним числом не работает; - достать секрет из истории и объяснить, почему лечение — смена ключа;
- написать README и
.env.example, которыми можно пользоваться; - сделать так, чтобы программа без настроек падала понятно;
- пройти семь проверок за семь минут.
Проверка по главе
Сводная проверка по всей главе: 10 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.
Куда дальше: проверенные ресурсы
- Документация git: gitignore — правила и порядок применения.
- npm ci — чем отличается от install и когда падает.
- gitleaks — автоматический поиск секретов в истории.
- Make a README — что должно быть в README и в каком порядке.
Комментарии
Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.