Posted on

Tło tej historii jest takie: w jednym z projektów na iOS, nad którym pracuję, wdrożyliśmy system ciągłej integracji od Apple'a - Xcode Cloud. Do przekazywania sekretów używamy w projekcie zmiennych środowiskowych, a Xcode Cloud udostępnia relatywnie przyjemny interfejs do ich ustawiania. Niestety da się to robić jedynie pojedynczo, a ponieważ aplikacja jest w fazie ciągłego rozwoju, klikanie po interfejsie stało się po jakimś czasie irytujące. Wpadłem więc na pomysł, że zmienne środowiskowe będziemy przechowywać w samym repozytorium, w pliku .env, który następnie zaszyfrujemy przy użyciu OpenSSL, a deszyfracją i integracją tych informacji zajmie się skrypt uruchamiany automatycznie w czasie komplacji, w ostatnim możliwym momencie. W takim przypadku jedyną zmienną środowiskową, którą trzeba dodać do Xcode Cloud, i która na dodatek będzie się zmieniać raczej rzadko, jest klucz deszyfrujący. Jego złożoność zależy tylko i wyłącznie od nas, algorytmy szyfrujące można sobie dobierać ze wszystkich dostępnych, bezpieczeństwo zachowane, wygoda zwiększona.

Oczywiście rozwiązanie to działało przede wszystkim na Xcode Cloud, ale nic nie stało na przeszkodzie, żeby również lokalnie skorzystać z tego dobrodziejstwa. Plik .env można dorzucić do .gitignore, i następnie bez ryzyka trzymać lokalnie na swoim komputerze. Dodatkowo nasz skrypt zajmuje się również aktualizacją wersji zaszyfrowanej, jeśli coś zmienimy, sprawdza także spójność danych. Wszystko, co zostało do zrobienia, to wrzucenie do swojego lokalnego pliku ~/.zshrc zmiennej środowiskowej DECRYPTION_KEY=supertajnehaslo123, odpalenie Xcode'a i problem załatwiony, prawda?
Prawda?

nieprawda.png

Otusz nieprawda.

Okazuje się, że Xcode nie ma dostępu do lokalnych zmiennych środowiskowych. Teraz tak: ja nie wiem, czy to dobrze, czy jednak nie dobrze. Gdybym miał powiedzieć, co cenię w życiu najbardziej, to powiedziałbym, że nie Xcode'a. No ale siła przyzwyczajenia, natywna aplikacja, znajomy interfejs. Trzeba rozwiązać kolejny problem - na szczęście ten jest banalnie prosty.

Kto ma dostęp do zmiennych środowiskowych? Każdy, kto jest odpalony z Terminala. Wystarczyło więc napisać skrypt open -a /Applications/Xcode.app mujprojekt.xcodeproj, i ta, oraz każda inna zmienna we wszechświecie jest dostępna! Oczywiście można to zoptymalizować - wystarczy stworzyć osobny plik i tam wrzucić tę zmienną, a następnie zrobić coś w stylu source tajnyplik && open ..., albo nawet wrzucać zmienną bezpośrednio w komendzie DECRYPTION_KEY=abc open..., you know the drill.

Została ostatnia sprawa. Odpalanie terminala i uruchamianie skryptu to stanowczo zbyt dużo pracy. Na szczęście od jakiegoś czasu macOS ma aplikację "Skróty"! W tej aplikacji można sobie zrobić "skrót" do praktycznie dowolnej czynności, w tym oczywiście skrót do uruchomienia komendy w Terminalu. W ten oto sposób, co prawda dorobiłem się kolejnej ikonki w moim systemowym Docku, ale za to nie muszę już klikać jak małpa po zmiennych środowiskowych w Xcode Cloud. Ciekawe, czy one kiedykolwiek się zmienią. Byłoby naprawdę szkoda, gdyby moje wspaniałe rozwiązanie nie zaoszczędziło czasu ani pracy nikomu nigdy.