Кросс-платформенный package registry на доске выглядит безобидно: NuGet-пакеты лежат в одном месте, пайплайны тянут их из другого, все довольны. А потом токен протухает в самый неподходящий момент, три пайплайна ложатся на целый день — и команда на собственной шкуре узнаёт, какой невидимый налог она платила с каждого деплоя. Это история про тот день и про уборку, которая за ним последовала.
Пакеты в Azure, пайплайны в GitLab
Такую схему никто не проектирует специально — она нарастает сама. NuGet-пакеты жили в Azure DevOps. CI/CD крутился в GitLab. Между ними сидел personal access token, PAT, который тихо отсчитывал дни до своего протухания, и дату эту никто не выписал в календарь.
Каждый билд тянулся через эту щель. dotnet restore аутентифицировался в Azure по PAT, забирал пакеты и надеялся, что креды ещё живы. Почти всегда живы. Пока однажды не оказались мёртвыми. Токен протух посреди спринта, и три пайплайна разом покраснели, потому что все они опирались на один и тот же секрет. Целый день ушёл на то, что не дало ни одной фичи и ни одного фикса.
Zero trust, только не тот, который хороший
Хуже всего была культура, выросшая вокруг этой хрупкости. Никто ничему не доверял.
- PAT-токены протухали посреди спринта — без предупреждения и без хозяина.
- CI/CD-переменные были раскиданы по проектам без единой строчки документации.
- Разработчики реально боялись трогать NuGet-конфиг: в прошлый раз кто-то его поправил — и три пайплайна легли на целый день.
Вот этот страх и есть настоящая цена. Когда люди перестают трогать систему из страха, что она рванёт, система перестаёт улучшаться. Она костенеет. Остаётся племенное знание о том, какой токен куда идёт, — и единственный человек, который в этом разбирался, уходит в отпуск ровно на той неделе, когда всё ломается.
Миграция: одна платформа для кода, пакетов и пайплайнов
Фикс был не гениальным. Он был структурным. Я перенёс всё в GitLab Package Registry — на ту же платформу, где уже жил код и крутились пайплайны. Те же стены, та же дверь.
Ключевой была аутентификация. Каждый personal access token заменили на CI_JOB_TOKEN. Он встроен в GitLab CI, ограничен рамками конкретного job'а и не требует никакой ротации. Отслеживать нечего: токен живёт ровно столько, сколько идёт job. Календарь ротации кредов и сюрпризы посреди спринта просто перестали быть классом проблем.
Кладбище переменных
Перенести пакеты — только половина работы. CI/CD-переменные были отдельным цирком, и вот их разбор как раз требовал головы.
Открыть список переменных было как открыть ящик со всяким хламом:
- Старые Azure DevOps PAT, которые никто не помнил, когда создавал.
- Дубли NuGet source URL с чуть-чуть разными именами — так что никогда не поймёшь, какой из них реально использует job.
- Переменные, пережившие тех, кто их завёл.
Я проревизил каждую. По каждой вопрос был прямой: это вообще кто-нибудь ещё читает? Если нет — в топку. Если две делают одно и то же — в одну. Работа скучная, неблагодарная — и ровно такая, которую никто не делает, пока скука не превращается в аварию.
Как пайплайн выглядит теперь
Когда пакеты переехали в GitLab, а переменные вычистили, пайплайн схлопнулся в то, что объясняется на одном выдохе:
dotnet restoreтянет из GitLab Package Registry.- Build и pack.
- Push пакета обратно в тот же registry.
Каждый шаг аутентифицируется автоматически job-токеном. Никакого PAT в какой-то переменной. Никакого кросс-платформенного рукопожатия. Никакого напоминания в календаре «проротировать секрет, пока он не уронил три пайплайна в пятницу под вечер».
Вывод: не давайте пакетам и пайплайнам жить в разных мирах
Если ваши пакеты живут в одном мире, а пайплайны — в другом, вы платите налог с каждого деплоя. Он проявляется как оверхед на аутентификацию, как configuration drift, как племенное знание о том, какой кред куда идёт, — а время от времени как целый потерянный день, когда забытый токен наконец протухает.
Консолидируйте. Уберите код, пакеты и пайплайны за одну стену, чтобы платформа сама раздавала короткоживущие ограниченные креды, а не вы вручную нянчили долгоживущие. Один registry. Один поток аутентификации. Одной причиной меньше для пайплайна упасть в 17:00 в пятницу.
И честный вопрос напоследок: сколько токенов в ваших пайплайнах может протухнуть завтра — и знаете ли вы это на самом деле?