2018. március 2., péntek

Fájl feltöltése Github tárolóba

Egy átlagos napon, egy átlagos feladaton dolgoztam, amikor egy teljesen átlagos, mondhatni triviális dolgot kellett megoldanom. Konkrétan: le kellett tárolni egy állományt egy megadott git tárolóba. Mi sem egyszerűbb, gondoltam naivan, de nem eszik olyan forrón a kását! Nem mennék bele túl mélyen a részletekbe, talán annyi is elég, hogy rendszeresen szoktunk sütni kép-fájlokat különböző felhőkbe. Természetesen az egész sütési folyamat automatizálva van, az eredmény pedig egy katalógusba kerül, ahol a kedves felhasználó ízlése szerint válogathat közülük. Kezdjük hát az egy pont nullával:
git add metadata ; git commit -m"New image available" ; git push

Két probléma is adódott:
  • Egyfelől nagyon ronda, persze működik, és a Jenkins-nek is megvan a joga írni a tárolót, de én valami kifinomultabb megoldásra vágytam.
  • Másfelől pedig maga a sütés egy másik git tárolóból indul ki, szóval vagy valami ideiglenes könyvtárba dolgozok (/tmp, ram disk), aminek az életciklusát kezelni kell, vagy a git tárolóban a git tároló problémájával küzdök, és kényesen ügyelek rá, hogy mindkét tárolóba csak az oda illő dolgok kerüljenek be.
Elvetettem a git parancsok használatát, úgyis Github-on tartjuk a forrást, van annak saját API-ja, megoldom elegánsan a kérdést. A dokumentációt olvasva elég hamar megtaláltam, hogy a v1-es API-ban elérhető direkt fájl feltöltést kompletten kihajították, így a legfrissebb API verzióban nincs ilyenre lehetőség. Persze tudunk fájt feltölteni, viszont ki kell hozzá nyitni a motorháztetőt, azaz a .git könyvtárban kell műveleteket végezni az API segítségével. Lássunk is neki:

A script első felében a szükséges változókat definiáltam. A GITHUB_API_KEY-nek egy Personal Access Token-t generáltam a Github felületén. Következő lépésben kiderítettem az utolsó commit azonosítóját, és helyét. A JSON válaszok értelmezésére a Jq nevű parancs-soros eszközt választottam.

A git fa szerkezetben tárolja kódunk különböző állapotait, ezért egyel tovább kell mennünk, és meg kell tudnunk, hogy a commit melyik fához tartozik.

Most, hogy tudjuk az azonosítóját a fának, feltölthetjük az új fájlt, vagyis a blob-ot.

Kezd izgalmassá válni a dolog. Ahogy említettem a .git könyvtárban kézi-munkázunk, ami azt jelenti, hogy az imént feltöltött állomány pillanatnyilag sehová sem tartozik, ahhoz ugyanis egy fához kell csatolni azt.

Majd készítünk egy új commit-ot, amit összekapcsolunk az utolsó commit-tal, és az imént kreált fára irányítjuk.

Egy utolsó lépés maradt hátra, a master ágon a HEAD címkét át kell helyezni az újdonsült elkészült commit-ra.

Nem állítom, hogy pilóta vizsga kell egy egyszerű fájl feltöltéséhez, de azért nem árt ismerni, hogy miként is működik a git, hogyan tárolja és azonosítja az objektumokat, és nem utolsó sorban miként kezeli a címkéket. A teljes script elérhető itt.