Стендап Сьогодні
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

11.08.2025

Нотаризація програм під macOS (наче все працює)

Після минулих невдач з підписами під macOS нарешті, як мені здається, остаточно все виправив. Принаймні вона запускається не тільки на тому компʼютері, де я її будував.

(Зізнання: минулого разу за браком часу я намагався навайбкодити рішення — тобто питав у агента розвʼязок, та не роздивлявся в те, що відбувається. Не вийшло, та й часу пішло чимало. Урок.)

Для випуску програми я беру GoReleaser. Ця утиліта поєднує всі кроки — від збірки до створення версії на GitHub та відвантаження архівів. Але підписувати вона… вміє з недавніх пір, втім, тільки в версії за підпискою — на яку мій масштаб поки не заслуговує.

В GoReleaser є підтримка підписів, теоретично (секція signs), але ці підписи мають конкретну реалізацію (GPG тощо) та ніяк навчити того, що нам потрібно, не вийде. Тому дивимося далі.

Варто тут зʼясувати, чого ж від нас хоче Apple. Тут автентифікація складається з трьох частин. Спочатку підпис сертифікатом розробника (sign) - так само як і GPG - це криптографічний підпис, який каже, що програму скомпілював не аби хто, а я. Далі нотаризація (notarize) - а це вже особливий для Apple крок, коли ти надсилаєш програму на їхній сервіс, вони її перевіряють та реєструють в базі даних. Так, в Apple є центральна БД всіх перевірених двійкових файлів! Нарешті, коли користувач запускає застосунок перший раз, ОС перевіряє його в цій базі — що потребує підключення. Цього можна уникнути, якщо завантажити та прикріпити квиток нотаризації (staple) до пакета.

Перші два кроки на 2025 рік є практично обовʼязковими, бо без них програма в користувача не запуститься без спеціальних дій. Та так, пакети з Homebrew та інші серйозні застосунки так і роблять. (Або інший вихід — збирати двійковий файл локально.) Прикріплення теж варто робити, але то потребує пакування в епловський формат - .dmg, .pkg чи принаймні .app. Я б і не проти, але безплатний GoReleaser їх не робить.

А GoReleaser радить утиліту gon. Вона вміє і підписувати, і пакувати, і нотаризувати, і прикріпляти. Але ж мені потрібно все це робити в контексті GoReleaser, щоб поєднати зі збірками на інші платформи та відвантажити. Отже, поки задовольнився тільки підписом та нотаризацією самого двійкового файлу, після чого його забирає GoReleaser.

Весь процес збірки диригується GoReleaserом. На збірки для macOS в нього поставлений постхук. Хук викликається після компіляції, генерує конфігурацію Gon, робить всю магію, в тому числі пакує в ZIP, надсилає на нотаризацію, а потім розпаковує та вертає підписаний файл назад на місце.

З усього цього, певно, найскладнішим було те, що хуки GoReleaser запускаються без оболонки! А значить, в них не працює перенаправлення виходу, умовне виконання та інші оболонкові функції. Коли збагнув, що треба все завертати в sh -c, справи пішли.

(PS: сиджу і думаю - чи варті були всі ці зусилля, щоб заощадити 11 доларів на місяць на GoReleaser Pro?)