{"id":29055852,"url":"https://github.com/xfenix/pycon2022","last_synced_at":"2025-06-27T04:35:43.093Z","repository":{"id":53830437,"uuid":"517414517","full_name":"xfenix/pycon2022","owner":"xfenix","description":"Примеры к докладу «Современный CI/CD пайплайн для python микросервисов» на конференции pycon 2022","archived":false,"fork":false,"pushed_at":"2022-09-06T13:06:22.000Z","size":9736,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-14T07:14:27.008Z","etag":null,"topics":["ci","cicd","conference","docker","gitlab","gitlab-ci","kubernetes","microservices","pycon","pycon2022"],"latest_commit_sha":null,"homepage":"https://pycon.ru/sovremennyj-ci-cd-pajplajn-dlya-python-mikroservisov","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xfenix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-24T19:12:01.000Z","updated_at":"2024-02-05T15:14:38.000Z","dependencies_parsed_at":"2022-08-21T20:40:16.520Z","dependency_job_id":null,"html_url":"https://github.com/xfenix/pycon2022","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xfenix/pycon2022","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xfenix%2Fpycon2022","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xfenix%2Fpycon2022/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xfenix%2Fpycon2022/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xfenix%2Fpycon2022/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xfenix","download_url":"https://codeload.github.com/xfenix/pycon2022/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xfenix%2Fpycon2022/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262188404,"owners_count":23272345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci","cicd","conference","docker","gitlab","gitlab-ci","kubernetes","microservices","pycon","pycon2022"],"created_at":"2025-06-27T04:35:04.879Z","updated_at":"2025-06-27T04:35:43.066Z","avatar_url":"https://github.com/xfenix.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Современный CI/CD пайплайн для python микросервисов\n\u003ca href=\"https://pycon.ru/\"\u003e![](https://badgen.net/badge/pycon/2022/?color=yellow)\u003c/a\u003e\n\nЭтот репозиторий содержит примеры кода для моего доклада. Я не сомневаюсь, что все это не подходит для продакшена, но при этом уверен, что кого-то это натолкнет на мысли, кто-то сможет отсюда взять куски, узнать какие-то типично кривые трюки с башем или просто вдохновиться или огорчиться и сделать что-то своё, лучше.\nДанный код, как и весь код в репозитории, хоть и из живого проекта, но никогда не полировался и не затачивался для публикации в виде опенсорса. Он существует как дополнительный материал к презентации.\n\n### Содержимое\n* Презентация доступна тут [./presentation.pdf](./presentation.pdf)\n* Полноценные куски CI/CD джоб (а точнее, шаблонов) вы можете посмотреть в файле [./jobs.yml](./jobs.yml). Конечно, там много специфики, но что-то из этого вам может пригодится.\n* Вот тут можно посмотреть как можно полноценно устроить CD для helm + k8s [./helm-cd.yml](./helm-cd.yml) с поддержкой staging/production сред. Вероятно, вас удивит странный подход к формированию переменных окружения для разных сред с помощью страшных баш трансформаций. Это происходит из общего желания уменьшить дублирование кода (а именно, переменных). Дело в том, что переменные в гитлабе хоть и можно привязывать к средам, но в рамках 1 репозитория, а в случае моей презентации и моего пайплайна, есть группа и подгруппа над каждым репозиторием, и в каждом из них указаны переменные, которые наследуются и попадают в пайплайн. И вот их получать контекстно, в зависимости от окружения не получается (или в моей версии гитлаба невозможно). Поэтому вы и видите некрасивые трансформации.\n* Автоверсионирование с защитой от чистки вы можете посмотреть вот здесь [./scripts/auto-semver.py](./scripts/auto-semver.py)\n* [./scripts/validate-gitlab-ci.py](./scripts/validate-gitlab-ci.py) неработоспособный скрипт (он работал только в лейауте моего централизованного пайплайна, а под ваш нужно будет немного адаптировать), цель которого продемонстрировать, что если у вас есть централизованный пайплайн (как в моем докладе) и вы хотите тестировать и его самого, то можно базово отвалидировать через сам gitlab собранные файлы этого пайплайна. Разумеется, написав для него .gitlab-ci.yml (получается по смыслу мета-пайплайн — пайплайн для пайплайна). Вы должны отдать ваши template jobs и «публичный интерфейс» (или несколько) и отправить его в gitlab линтер. Это поможет вам проверить ваш пайплайн на базовую корректность и работоспособность.\n* [./scripts/lint.py](./scripts/lint.py) тут лежит pylint \u0026 mypy линтинги с поддержкой baseline, возможности падения при оценке ниже требуемой оценки, а так же поддержкой «автопоиска» того, что нужно линтить в pylint. Сам алгоритм поиска это три очень плохих строчки и его легко улучшить, но это я уже оставлю вам.\n\n### Возможности, на которые я делаю акцент\n* `set -x` в начале пайплайна: даёт вам возможность видеть как запускаются ваши баш команды и значительно упрощают их отладку.\n* `set -u` в `.vars-check-job` — штука, которая позволяет вам с помощью простого echo защитить свой пайплайн от отсутсвующих переменных. Установите флаг, распечатайте переменные и если каких-то из них нет, пайплайн упадёт.\n* «Двойная докеризация» — собирайте в вашем пайплайне ваш образ с помощью `docker build`, [kaniko](https://github.com/GoogleContainerTools/kaniko) или [buildah](https://buildah.io/). В [./jobs.yml](./jobs.yml) пример с использованием buildah. В кавычках, потому что это не совсем двойная докеризация, но я не нашёл термин лучше, поэтому использую его. Имеется ввиду сборка контейнера внутри контейнера и запуск команд внутри контейнера, который запущен внутри контейнера.\n* Наследуйтесь от одной job'ы: потом проще ей задавать разные атрибуты, такие как interruptible или retry.\n* Для множества микросервисов вам поможет централизация — сделать единый репозиторий и использовать пресеты. Т.е., например, вы используете текущий [./jobs.yml](./jobs.yml), а дальше пишете в `.gitlab-ci.yml` следующее:\n    ```yaml\n    include:\n    - project: 'xfenix/pycon2022'\n      file: 'public-example.yml'\n    ```\n    где:\n    * xfenix/pycon2022 — путь к вашему репозиторию внутри вашего gitlab инстанса.\n    * public-example.yml — «пресет», где вы собираете пайплайн из jobs.yml. Имеет смысл собрать несколько таких пресетов. У нас в проекте есть `python`, `python-postgres`, `pypi`, `pypi-poetry`, `docker-build`, `frontend`.\n    * если вам нужен ещё более гранулярный контроль за составом пайплайна, подключайте не пресет, а jobs.yml напрямую.\n* Если возможно, имеет смысл публичные переменные тоже собирать в пресеты. Например, у вас несколько репозиториев используют одинаковые не секретные переменные (username, docker registry address и прочее). Можно занести их в gitlab group vars, но они будут всегда «скрыты» (чтобы их посмотреть вам нужно будет зайти вглубь настроек gitlab проекта), а некоторым юзерам и вовсе недоступны, поэтому я и предлагаю положить их в файл. Пример: [./group-vars.yml](./group-vars.yml)\n* Сборка образов в идеале должна предшествовать всем следующим шагам: сначала собираем образ, пушим его в удаленный registry, затем тестируем его, проводим статический анализ, а в конце скачиваем этот образ из registry, перетегиваем его и пушим с новым release тегом (характерным для вас) в удаленный registry. Смысл этого заключается в том, что в продакшн идут строго те образы, чьё окружение мы протестировали и статически проанализировали.\n* Немного bash — не страшно!\n* Шаблонные подстановки вроде `${VARIABLE:-default value}` очень помогают.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxfenix%2Fpycon2022","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxfenix%2Fpycon2022","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxfenix%2Fpycon2022/lists"}