ππ Π ΡΠΊΠΈ ΠΏΡΠΎΡΡ: Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΡ ΡΡΡΠ½ΡΡ Π·Π°Π΄Π°Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ GitHub Actions
ΠΠ· ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ Π²Ρ ΡΠ·Π½Π°Π΅ΡΠ΅, ΠΊΠ°ΠΊ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΠΊΠΎΠ΄ΠΎΠ²ΡΠ΅ Π±Π°Π·Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ GitHub Actions Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Ρ ΠΎΡΠΊΡΡΡΡΠΌ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ.
Π ΠΈΠ΄Π΅Π°Π»ΡΠ½ΠΎΠΌ ΠΌΠΈΡΠ΅ Π²ΡΠ΅ Π²Π°ΡΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΡΠ΅ Π±Π°Π·Ρ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΡ Π±Ρ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅. ΠΠΎ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ ΠΌΠΈΡΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ ΡΠ°ΡΡΠΎ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΊΠΎΠ΄ Π² Π΄Π²ΡΡ ΡΠ°Π·Π½ΡΡ ΠΌΠ΅ΡΡΠ°Ρ . ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΊΠΎΠ΄, ΠΊΠ°ΠΊ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Ρ ΠΎΡΠΊΡΡΡΡΠΌ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ, ΡΠ°ΠΊ ΠΈ Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ ΠΈΠ»ΠΈ ΠΏΡΠΎΠΏΡΠΈΠ΅ΡΠ°ΡΠ½ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.
Π 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. ΠΠ°ΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΠ½ΡΠΌ, Π½ΠΎ, Π½Π°Π΄Π΅ΡΡΡ, ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΌΡ Π·Π΄Π΅ΡΡ ΡΠ΄Π΅Π»Π°Π»ΠΈ, Π²Π°ΠΌ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π΄Π»Ρ Π½Π°ΡΠ°Π»Π°. ΠΠ΅ΡΠΎΡΡΠ½ΠΎ, Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ ΠΌΡ ΡΠ½ΠΎΠ²Π° Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΠ°Π±Π»ΠΎΠ½.