Add template for building PyPI packages
Propozycja
Zgodnie z dokumentacją tutaj https://docs.gitlab.com/ee/user/packages/pypi_repository/#create-a-package automatyzacja budowania paczek nie jest trudna i można by zacząć używać takiego mechanizmu.
Uzasadnienie
Jako że coraz więcej pojawia się MR w różnych poddziałach z kodem wężowym i wielu miejscach proponuje się zrobienie z kodu paczki pythonowej, wychodzę z propozycją uspójnienia tego i wykorzystania możliwości jaką daje nam nasz GitLab czyli własne repozytorium paczek PyPI, i tak na naszym GitLabie można z niego korzystać, ale nie widziałem żeby ktoś to robił, poczyniłem pierwsze kroki i naprawdę nie jest to trudne.
Rzeczy do omówienia
Nadziałem się jednak na pewien problem koncepcyjno/implementacyjny i chciałbym go przedstawić:
-
Repozytorium PyPI z założenia nie obsługuje nadpisywania danej wersji paczek, oznacza to że nie da się analogicznie jak to robimy z repozytorium kontenerów dockerowych dać w CI joba który to będzie uaktualniał paczkę w repozytorium paczek PyPI taki job zadziała raz i później będzie się wywalał do czasu jak nie usuniemy ręcznie danej paczki.
Rozwiązanie:
- wpadłem na jedno, można wykorzystać GraphQL API, dokładnie w taki sposób jak to się dzieje w przeglądarce i autoryzować się do niego za pomocą
GITLAB_CI_TOKEN
- przykład listowania repozytorium za pomocą curl'a:
GRAPHQL_TOKEN=<jakiś token> curl "https://dev.projects.task.gda.pl/api/graphql" --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --header "Content-Type: application/json" --request POST \ --data '[{"operationName":"getPackages","variables":{"isGroupPage":false,"fullPath":"kszym/na_wycieczki_moga_jezdzic","sort":"NAME_DESC","packageName":"","first":20},"query":"query getPackages($fullPath: ID!, $isGroupPage: Boolean!, $sort: PackageSort, $groupSort: PackageGroupSort, $packageName: String, $packageType: PackageTypeEnum, $first: Int, $last: Int, $after: String, $before: String) {\n project(fullPath: $fullPath) @skip(if: $isGroupPage) {\n id\n packages(\n sort: $sort\n packageName: $packageName\n packageType: $packageType\n after: $after\n before: $before\n first: $first\n last: $last\n ) {\n count\n nodes {\n ...PackageData\n __typename\n }\n pageInfo {\n ...PageInfo\n __typename\n }\n __typename\n }\n __typename\n }\n group(fullPath: $fullPath) @include(if: $isGroupPage) {\n id\n packages(\n sort: $groupSort\n packageName: $packageName\n packageType: $packageType\n after: $after\n before: $before\n first: $first\n last: $last\n ) {\n count\n nodes {\n ...PackageData\n __typename\n }\n pageInfo {\n ...PageInfo\n __typename\n }\n __typename\n }\n __typename\n }\n}\n\nfragment PackageData on Package {\n id\n name\n version\n packageType\n createdAt\n status\n tags {\n nodes {\n id\n name\n __typename\n }\n __typename\n }\n pipelines(last: 1) {\n nodes {\n id\n sha\n ref\n commitPath\n user {\n id\n name\n __typename\n }\n __typename\n }\n __typename\n }\n project {\n id\n fullPath\n webUrl\n __typename\n }\n __typename\n}\n\nfragment PageInfo on PageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n __typename\n}\n"}]' \ | jq
- wpadłem na jedno, można wykorzystać GraphQL API, dokładnie w taki sposób jak to się dzieje w przeglądarce i autoryzować się do niego za pomocą
Tak więc zapraszam do wyrażenia swojej opinii, innych poomysłów:
- Czy w ogóle potrzebujemy templejt który to ogarnie, dostarczy joba z kontenerem który to będzie miał spełnione podstawowe zależności (paczka
twine
) i mechanizm usuwania paczki jeśli istnieje wbefore_script
? - Czy powinniśmy do tego tworzyć dodatkowy kontener?
- Czy mechanizm usuwania powinien być w formie skryptu bashowego w
before_script
czy może jakiś prosty skrypt w pythonie który to ogarnie, za tą drugą opcją przemawia fakt że jak paczek będzie dużo to będzie trzeba je listować "per page" i nie chciałbym się bawić w to w bashu. - Czy powyższe zależności i mechanizm usuwania danej paczki powinien trafić do osobnego kontenera czy może do naszego lintera pythonowego? Wydaje mi się że do osobnego kontenera.