πŸ“œπŸ‘† Π ΡƒΠΊΠΈ ΠΏΡ€ΠΎΡ‡ΡŒ: автоматизация Ρ€ΡƒΡ‡Π½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ GitHub Actions

Из этой ΡΡ‚Π°Ρ‚ΡŒΠΈ Π²Ρ‹ ΡƒΠ·Π½Π°Π΅Ρ‚Π΅, ΠΊΠ°ΠΊ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠ΄ΠΎΠ²Ρ‹Π΅ Π±Π°Π·Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ GitHub Actions Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ рСпозитория с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ.

Данная ΡΡ‚Π°Ρ‚ΡŒΡ являСтся ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠΌ. Автор: Sabrina Li. Бсылка Π½Π° ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄.

Π’ идСальном ΠΌΠΈΡ€Π΅ всС ваши ΠΊΠΎΠ΄ΠΎΠ²Ρ‹Π΅ Π±Π°Π·Ρ‹ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡΡŒ Π±Ρ‹ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС. Но Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΌΠΈΡ€Π΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ часто приходится ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠ΄ Π² Π΄Π²ΡƒΡ… Ρ€Π°Π·Π½Ρ‹Ρ… мСстах. НапримСр, Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠ΄, ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, Ρ‚Π°ΠΊ ΠΈ Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΏΡ€ΠΈΠ΅Ρ‚Π°Ρ€Π½ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.

Π’ 2019 Π³ΠΎΠ΄Ρƒ ΠΌΡ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ Π² FullStory. Если Π±Ρ‹ ΠΌΡ‹ ΠΏΠΎΠΏΡ‹Ρ‚Π°Π»ΠΈΡΡŒ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ, Π½Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ Π½Π΅ Π·Π°Π±Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ выпускаСм Π½ΠΎΠ²ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°. Для этого ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π΄Π²Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (ΠΊΠΎΠΌΠ°Π½Π΄Π°, которая ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ исходный ΠΊΠΎΠ΄ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°, ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°, которая ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ) для ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ†ΠΈΠΈ своСй Ρ€Π°Π±ΠΎΡ‚Ρ‹. И Ссли Π²Ρ‹ Π½Π΅Π΄ΠΎΡƒΠΌΠ΅Π²Π°Π΅Ρ‚Π΅, Π·Π½Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ – Ρ‚ΠΎΠΆΠ΅. Нам Π½ΡƒΠΆΠ΅Π½ Π±Ρ‹Π» Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ способ синхронизации ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° со сниппСтами ΠΊΠΎΠ΄Π° Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, ΠΌΡ‹ использовали встроСнный Π² GitHub инструмСнт CI/CD ΠΈ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ процСсса – GitHub Actions для обновлСния нашСго ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΏΡƒΡ‚Π΅ΠΌ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ΄Π° ΠΈΠ· нашСго API ΠΈ автоматичСского создания pull request с Π»ΡŽΠ±Ρ‹ΠΌΠΈ измСнСниями. Благодаря этой Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π΅, ΠΌΡ‹ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΈ ΠΈ объСдинили нСсколько ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ с Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΊΠ°ΠΊ ΠΎΠ½Π° появилась Π² сСти Π² Π΄Π΅ΠΊΠ°Π±Ρ€Π΅ 2019 Π³ΠΎΠ΄Π°, обСспСчив ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ нашСго Browser SDK ΠΈ сократив расходы Π½Π° обслуТиваниС.

ВмСсто ΠΌΠ΅ΠΆΠ³Ρ€ΡƒΠΏΠΏΠΎΠ²ΠΎΠ³ΠΎ, Ρ€ΡƒΡ‡Π½ΠΎΠ³ΠΎ ΠΈ Ρ‡Ρ€Π΅Π²Π°Ρ‚ΠΎΠ³ΠΎ ошибками процСсса Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас Π΅ΡΡ‚ΡŒ бСзопасноС Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅. Π­Ρ‚ΠΎ позволяСт ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ нСзависимо, ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ Π½Π°ΡˆΡƒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ процСсс ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ для нашСго Browser SDK, гарантируя, Ρ‡Ρ‚ΠΎ наши ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² NPM всСгда Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ послСднюю Π²Π΅Ρ€ΡΠΈΡŽ нашСго сниппСта, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ прСимущСствами Π»ΡŽΠ±Ρ‹Ρ… Π½ΠΎΠ²Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ выпускаСм. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас Π΅ΡΡ‚ΡŒ шаблон для синхронизации нашСго Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ исходного ΠΊΠΎΠ΄Π° с рСпозиториями с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ Π²ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π° Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠ°. БСйчас расскаТСм, ΠΊΠ°ΠΊ ΠΌΡ‹ это сдСлали.

Π—Π°Ρ‡Π΅ΠΌ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ наши Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ

ΠœΡ‹ стрСмимся ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ простой способ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ быстро Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ FullStory Π½Π° своих сайтах. Наши ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ наш сСрвис, копируя ΠΈ вставляя Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° JavaScript Π½Π° свой Π²Π΅Π±-сайт. Π”Π°Π½Π½Ρ‹ΠΉ способ ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΌΠΈ HTML-сайтами, Π° Ρ‚Π°ΠΊΠΆΠ΅ с систСмами управлСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ (CMS), диспСтчСром Ρ‚Π΅Π³ΠΎΠ² ΠΈ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠΎΠΉ элСктронной ΠΊΠΎΠΌΠΌΠ΅Ρ€Ρ†ΠΈΠΈ.

Однако Ссли Π²Π΅Π±-сайт прСдставляСт собой одностраничноС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (SPA), созданноС с использованиСм Ρ‚Π°ΠΊΠΈΡ… Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ², ΠΊΠ°ΠΊ React, Angular, Vue ΠΈ Ρ‚. Π΄., Ρ‚ΠΎ этот способ Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ ΠΈΠ΄Π΅Π°Π»Π΅Π½. ΠœΡ‹ поняли, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ идиоматичСский способ добавлСния Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° записи ΠΈ Π½Π°ΡˆΠΈΡ… клиСнтских API-интСрфСйсов JavaScript Π² SPA. Π˜Ρ‚Π°ΠΊ, ΠΌΡ‹ создали ΠΏΠ°ΠΊΠ΅Ρ‚ NPM с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ: FullStory Browser SDK.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ прСдоставляСм инструкции ΠΏΠΎ установкС ΠΊΠ°ΠΊ Π² нашСм Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Ρ‚Π°ΠΊ ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎ Π² SDK, ΠΊΠΎΠ΄ основного Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ размСщаСтся Π² Π΄Π²ΡƒΡ… мСстах: Π² нашСм Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ с Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит ΠΊΠΎΠ΄, распространяСмый Ρ‡Π΅Ρ€Π΅Π· NPM. Нам Π½ΡƒΠΆΠ΅Π½ Π±Ρ‹Π» Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ способ, ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ наши Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ микросСрвисы, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ исходного ΠΊΠΎΠ΄Π° ΠΌΠΎΠ³Π»ΠΈ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π΄ΠΈΠ½Ρ‹ΠΉ источник достовСрных Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‡ΠΈ тСсно связанными. ΠŸΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΠΌΡ‹ рассматривали модСль Β«pushΒ», ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ наша систСма сборки Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ обновлСния Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ PR. НСдостатком являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ это ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΡ‚ нашСй систСмы сборки ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ΄Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ структуру нашСго рСпозитория с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΅ΠΉ Π½Π΅ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚. Π­Ρ‚ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ слоТности ΠΈ зависимости Π² систСмС сборки Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста»

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ синхронизации Action шаг Π·Π° шагом

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ ΠΏΡ€ΠΈΡˆΠ»ΠΈ ΠΊ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡŽ, основанному Π½Π° Π΄Π²ΡƒΡ… тСхнологиях:

  • Новый общСдоступный API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅ΠΌ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°.
  • GitHub Actions

ΠŸΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ GitHub Actions Π² наш Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ Π±Ρ‹Π»ΠΎ Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΡ‚Ρ€ΠΎΠ΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ cron для извлСчСния послСднСго Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ прСдоставляСм Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Π΅Ρ‡Π½ΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ общСдоступного API. ВсС, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π±Ρ‹Π»ΠΎ Π½ΡƒΠΆΠ½ΠΎ, – это ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ микросСрвис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, GitHub Actions ΠΈΠΌΠ΅Π΅Ρ‚ встроСнныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ git ΠΈ API-интСрфСйсы управлСния GitHub, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‚ автоматичСскоС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠΉ Π²Π΅Ρ‚ΠΊΠΈ, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ PR ΠΈ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½ΡƒΠΆΠ½Ρ‹Ρ… Ρ€Π΅Ρ†Π΅Π½Π·Π΅Π½Ρ‚ΠΎΠ².

Экскурс Π² `Snippet-Sync-Job`

Π¨Π°Π³ 1. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ слуТбы сниппСтов ΠΈ прСдоставлСниС общСдоступной ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ API

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ послСдний сниппСт ΠΈΠ· Π½Π°ΡˆΠΈΡ… Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠ΅Π² с Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ общСдоступный API, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ сниппСта. Он обслуТиваСт Π»ΠΈΠ±ΠΎ Β«ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽΒ», Π»ΠΈΠ±ΠΎ Β«ES-ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΡƒΡŽΒ» Π²Π΅Ρ€ΡΠΈΡŽ сниппСта Π½Π° основС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² URL. И вуаля! Π£ нас Π΅ΡΡ‚ΡŒ способ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ послСдний сниппСт. Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ эта слуТба Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ слуТбами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‡Π΅Ρ€Π΅Π· gRPC.

Π”Π°Π½Π½ΠΎΠ΅ изобраТСния ΠΈ всС ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ взяты ΠΎΡ‚ΡΡŽΠ΄Π°.

Π¨Π°Π³ 2. Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Github Actions Π² наш Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ GitHub Actions, создайтС Ρ„Π°ΠΉΠ» main.yaml Π² ΠΏΠ°ΠΏΠΊΠ΅ github/workflows. И благодаря нСскольким строкам ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π·Π°Π΄Π°Π½ΠΈΠ΅ cron ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ обновлСния ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 24 часа.

on:
    schedule:
        - cron:  '0 0 * * *' # every 24 hours
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2
    - name: npm ci
      run: npm ci
      working-directory: ./.github/actions/sync-snippet-action
    - name: Sync snippet
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        SNIPPET_ENDPOINT: https://api.fullstory.com/code/v1/snippet?type=esm
      uses: ./.github/actions/sync-snippet-action

GitHub Actions ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‚ встраиваниС Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ процСсс, прСдоставляя сСкрСт GITHUB_TOKEN ΠΈ нСсколько Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… срСды ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. ВмСстС с ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ snippet API Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас Π΅ΡΡ‚ΡŒ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠΈΡ… дСйствий.

// accessing environment variables in .github/actions/sync-snippet-action
const {
  SNIPPET_ENDPOINT,
  GITHUB_REPOSITORY,
  GITHUB_TOKEN,
  GITHUB_SHA,
} = process.env;
// parsing the owner and repo name from GITHUB_REPOSITORY
const [owner, repo] = GITHUB_REPOSITORY.split(β€˜/’);
const repoInfo = { owner, repo };

ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ всС ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ срСды ΠΈ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ repoInfo ΠΏΠΎΠ·ΠΆΠ΅.

Π¨Π°Π³ 3. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ сниппСтов ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… PR

На этапС Sync snippet ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠ»ΠΈ послСднюю Π²Π΅Ρ‚ΠΊΡƒ main. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ axios для извлСчСния тСкста послСднСго Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° Ρ‡Π΅Ρ€Π΅Π· REST API, Π° Π·Π°Ρ‚Π΅ΠΌ сравниваСм Ρ…ΡΡˆ тСкста послСднСго Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° с Ρ‚Π΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρƒ нас Π΅ΡΡ‚ΡŒ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ рСпозитория. ΠœΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ шагам Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅ΠΌ нСсоотвСтствиС Π² Ρ…ΡΡˆ-значСниях, Ρ‡Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ обновлСния Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°. Если ΠΌΡ‹ ΠΏΠΎΠ½ΠΈΠΌΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ трСбуСтся ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅, ΠΌΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ octokit ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° @actions/github. ΠšΠ»ΠΈΠ΅Π½Ρ‚ аутСнтифицируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ env GITHUB_TOKEN, объявлСнной Π² Ρ„Π°ΠΉΠ»Π΅ main.yaml.

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΡ… ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… PR ΠΈ провСряСм, Π½Π΅ Π±Ρ‹Π» Π»ΠΈ ΡƒΠΆΠ΅ создан Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ PR. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ запускаСм ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 24 часа, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ PR Π±Ρ‹Π» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚, Π½ΠΎ Π΅Ρ‰Π΅ Π½Π΅ объСдинСн, ΠΈ Π² этом случаС ΠΌΡ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ PR. ΠœΡ‹ достигаСм этого, просто ΠΈΡ‰Π° PR, созданный Π±ΠΎΡ‚ΠΎΠΌ Github Actions, ΠΈ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ (title) являСтся константой:

// β€œThe FullStory snippet has been updated”
 
const SNIPPET_PATH = 'src/snippet.js';
const PR_TITLE = 'The FullStory snippet has been updated';
const octokit = new github.GitHub(GITHUB_TOKEN);
const openPRs = await octokit.pulls.list({
  ...repoInfo,
  state: β€˜open’,
});
console.log(β€˜checking for an on open snippet sync PR’);
// Look for PR created by github-actions[bot] with the same title
const existingPR = openPRs.data.filter(pr => pr.title === PR_TITLE && pr.user.login === β€˜github-actions[bot]’);
if (existingPR.length > 0) {
  core.setFailed(`There is already an open PR for snippet synchronization. Please close or merge this PR: ${existingPR[0].html_url}`);
   return;
}

Π¨Π°Π³ 4. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Github `octokit` для получСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄Π΅Ρ€Π΅Π²Π°

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ шагом являСтся ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° snippet.js ΠΈ созданиС PR.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ PR, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ³Π»ΡƒΠ±ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ git Π½Π°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ Plumbing. Если Π²Ρ‹ Π½Π΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ git, ΠΌΡ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π» Β«Plumbing and PorcelainΒ» Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Git, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ.

Π”Ρ€Π΅Π²ΠΎΠ²ΠΈΠ΄Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ – это структура Π΄Π°Π½Π½Ρ‹Ρ…, которая содСрТит ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ вашими Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ (BLOB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ), ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС UNIX. Нам Π½ΡƒΠΆΠ½ΠΎ сначала ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ Tree Object с Π½ΠΎΠ²Ρ‹ΠΌ содСрТимым Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ΄Π°. А Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ созданноС Π΄Π΅Ρ€Π΅Π²ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π²Π΅Ρ‚ΠΊΡƒ ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ PR.

Для этого Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ сначала ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚. Π’Π΅Ρ€Π½ΡƒΠ²ΡˆΠΈΡΡŒ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ шаг, ΠΌΡ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠ»ΠΈ main ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ sha ΠΊΠΎΠΌΠΌΠΈΡ‚Π° ΠΈΠ· process.env Π½Π° шагС 1. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ sha ΠΊΠΎΠΌΠΌΠΈΡ‚Π° ΠΌΡ‹ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚ Ρ‡Π΅Ρ€Π΅Π· ` octokit.git.getCommit ` , ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит Ρ…Π΅Ρˆ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° tree object: tree sha. Π—Π°Ρ‚Π΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ tree sha ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π΅Ρ€Π΅Π²Π° Ρ‡Π΅Ρ€Π΅Π· ` octokit.git.getTree` с рСкурсивным ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ.

Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π΅Ρ€Π΅Π²Π°, ΠΌΡ‹ нашли Β«ΡƒΠ·Π΅Π» Π΄Π΅Ρ€Π΅Π²Π°Β» ( srcTree) с нашим извСстным SNIPPET_PATH. Π­Ρ‚ΠΎΡ‚ ΡƒΠ·Π΅Π» Π΄Π΅Ρ€Π΅Π²Π° прСдставляСт Ρ„Π°ΠΉΠ» snippet.js.

console.log("getting source tree from main");
 
const getCommitResponse = await octokit.git.getCommit({
  ...repoInfo,
  commit_sha: GITHUB_SHA,
});
 
const getTreeResponse = await octokit.git.getTree({
  ...repoInfo,
  tree_sha: getCommitResponse.data.tree.sha,
  recursive: 1,
});
 
const srcTree = getTreeResponse.data.tree.find(el => el.path === SNIPPET_PATH);

Π¨Π°Π³ 5. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π½ΠΎΠ²ΠΎΠ΅ Β«TreeΒ» с ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹ΠΌ содСрТимым.

ΠŸΠΎΠ΄Ρ‹Ρ‚ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚:

  • Π£ нас Π΅ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΈΠ· общСдоступного API, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π° FullStory, Π² строковом Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅.
  • Π£ нас Π΅ΡΡ‚ΡŒ исходный Β«ΡƒΠ·Π΅Π» Π΄Π΅Ρ€Π΅Π²Π°Β» с содСрТимым Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΊΠΎΠΌΠΌΠΈΡ‚Π° Π² основной Π²Π΅Ρ‚ΠΊΠ΅.

ПослС Ρ‡Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ tree object с ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ сниппСта. Для этого ΠΌΡ‹ создаСм Π½ΠΎΠ²ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `octokit.git.createTree` ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚: наш Π½ΠΎΠ²Ρ‹ΠΉ тСкст сниппСта. ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ исходный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π΅Ρ€Π΅Π²Π° рСкурсивно, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π΅Ρ€Π΅Π²Π° содСрТит ссылки Π½Π° всС Ρ„Π°ΠΉΠ»Ρ‹ с ΠΈΡ… Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ путями. НовоС Π΄Π΅Ρ€Π΅Π²ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ всю ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈΠ· исходного Π΄Π΅Ρ€Π΅Π²Π°, Π½ΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ: Ρ„Π°ΠΉΠ» snippet.js.

console.log('creating updated source tree with new snippet file');
const createTreeResponse = await octokit.git.createTree({
   ...repoInfo,
   tree: [{
     path: SNIPPET_PATH,
     content: remoteSnippetText,
     mode: β€˜100644’,
     type: β€˜blob’,
     base_tree: srcTree.sha,
   },
   ...getTreeResponse.data.tree.filter(el => el.type !== β€˜tree’ && el.path !== SNIPPET_PATH)]
});

Π¨Π°Π³ 6. ЗафиксируйтС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π² Π½ΠΎΠ²ΠΎΠΉ Π²Π΅Ρ‚ΠΊΠ΅

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ tree object с ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΌ тСкстом Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°, Π½ΡƒΠΆΠ½ΠΎ просто Π·Π°Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ PR.

Π‘ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠΌ Π² качСствС родитСля ΠΌΡ‹ создаСм Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ `octokit.git.createCommit` ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ созданноС Π΄Π΅Ρ€Π΅Π²ΠΎ tree sha, Π·Π°Ρ‚Π΅ΠΌ создаСм Π½ΠΎΠ²ΡƒΡŽ ссылку (Π²Π΅Ρ‚Π²ΡŒ) с ΠΈΠΌΠ΅Π½Π΅ΠΌ: snippetbot/updated-snippet- ${Date.now()} с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `octokit.git.createRef`, прСдоставив Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ созданный ΠΊΠΎΠΌΠΌΠΈΡ‚ sha:

 console.log('committing new snippet file');
 const commitResponse = await octokit.git.createCommit({
   ...repoInfo,
   message: `updated ${SNIPPET_PATH}`,
   tree: createTreeResponse.data.sha,
   parents: [GITHUB_SHA],
 });
 const branchName = `refs/heads/snippetbot/updated-snippet-${Date.now()}`;
 console.log(`creating new branch named ${branchName}`);
 await octokit.git.createRef({
   ...repoInfo,
   ref: branchName,
   sha: commitResponse.data.sha,
 });

Π¨Π°Π³ 7. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ PR ΠΈ Π½Π°Π·Π½Π°Ρ‡ΡŒΡ‚Π΅ Π΅Π³ΠΎ ΡΠΎΠΏΡ€ΠΎΠ²ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΌ

ПослСдним шагом являСтся созданиС PR Ρ‡Π΅Ρ€Π΅Π· `octokit.pulls.create` ΠΈ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ ΡΠΎΠΏΡ€ΠΎΠ²ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΌ рСпозитория Ρ‡Π΅Ρ€Π΅Π· `octokit.issues.addAssignees`.

Для получСния исполнитСлСй Ρƒ нас Π΅ΡΡ‚ΡŒ Ρ„Π°ΠΉΠ» MAINTAINERS.json, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит всС дСскрипторы GitHub ΡΠΎΠΏΡ€ΠΎΠ²ΠΎΠΆΠ΄Π°ΡŽΡ‰Π΅Π³ΠΎ для этого рСпозитория, поэтому ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½Ρ‹ ΠΎ нСобходимости ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΈ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ PR.

console.log(`creating PR for branch ${branchName}`);
  const base = GITHUB_REF.split('/').pop();
  const prResponse = await octokit.pulls.create({
    ...repoInfo,
    title: PR_TITLE,
    head: branchName,
    base,
  });
 
 console.log(β€˜assigning PR to reviewers’);
 const maintainers = JSON.parse(fs.readFileSync(β€˜./MAINTAINERS.json’));
 await octokit.issues.addAssignees({
   ...repoInfo,
   issue_number: prResponse.data.number,
   assignees: maintainers,
 });
 
 console.log(`created PR: ${prResponse.data.html_url}`);

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ мысли

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ с нашим Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ ΠΈ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС ΠΎ SDK FullStory Browser Π² нашСм Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ GitHub. Π’Π°ΡˆΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ½Ρ‹ΠΌ, Π½ΠΎ, надСюсь, Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ здСсь сдСлали, Π²Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ достаточно для Π½Π°Ρ‡Π°Π»Π°. ВСроятно, Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ ΠΌΡ‹ снова Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон.

***

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
18 октября 2017

Π¨ΠΏΠ°Ρ€Π³Π°Π»ΠΊΠ° ΠΏΠΎ Git, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ прСдставлСны основныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹

Git сСгодня - это ΠΎΡ‡Π΅Π½ΡŒ популярная систСма контроля вСрсий. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΡˆΠΏΠ°Ρ€Π³Π°Π»...
admin
21 июня 2017

ΠŸΡ€ΠΎ Git, Github ΠΈ Gitflow простыми словами

НС самоС ΠΈΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅Π΅, Π½ΠΎ Ρ‚ΠΎΡ‡Π½ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ Π΄ΠΎΡ…ΠΎΠ΄Ρ‡ΠΈΠ²ΠΎΠ΅ руководство ΠΏΠΎ Git, Gith...
admin
23 фСвраля 2017

Git Π·Π° полчаса: руководство для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ…

Π’ послСдниС Π³ΠΎΠ΄Ρ‹ ΠΏΠΎΠΏΡƒΠ»ΡΡ€Π½ΠΎΡΡ‚ΡŒ git дСмонстрируСт Π²Π·Ρ€Ρ‹Π²Π½ΠΎΠΉ рост. Π­Ρ‚Π° систСма ...