{"id":464682,"date":"2025-06-26T15:01:19","date_gmt":"2025-06-26T15:01:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=464682"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=464682","title":{"rendered":"<span>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c CI\/CD Android-\u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0430\u0441\u0442\u044c 2. \u0417\u0430\u043f\u0443\u0441\u043a Android-\u0442\u0435\u0441\u0442\u043e\u0432<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ef5\/e51\/bc9\/ef5e51bc93287d71f47a776bb9ad8049.png\" width=\"780\" height=\"425\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ef5\/e51\/bc9\/ef5e51bc93287d71f47a776bb9ad8049.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ef5\/e51\/bc9\/ef5e51bc93287d71f47a776bb9ad8049.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u041e \u0447\u0451\u043c \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f?<\/h2>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b \u0438 \u044f Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 Scanny. \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0442\u043e, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448 CI\/CD, \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c Unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 Build Flavors \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 \u043d\u0430\u0448\u0443 Telegram-\u0433\u0440\u0443\u043f\u043f\u0443.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Android-\u0442\u0435\u0441\u0442\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 CI\/CD \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <a href=\"https:\/\/github.com\/MarathonLabs\/marathon\" rel=\"noopener noreferrer nofollow\">Marathon Labs<\/a> \u0438 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\" rel=\"noopener noreferrer nofollow\">Firebase Test Lab<\/a>.<\/p>\n<p>\u0426\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e CI\/CD \u0434\u043b\u044f Android \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/scanny\/articles\/918364\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c CI\/CD Android-\u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0430\u0441\u0442\u044c 1. \u041d\u0430\u0447\u0430\u043b\u043e.<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u0437\u0434\u0435\u0441\u044c.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c CI\/CD Android-\u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0430\u0441\u0442\u044c 3. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0435\u0440\u0441\u0438\u0439 \u0432 Play Market.<\/p>\n<\/li>\n<\/ol>\n<h2>Marathon Labs<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u0448\u0435 Android-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 Marathon Labs. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 <a href=\"https:\/\/cloud.marathonlabs.io\/\" rel=\"noopener noreferrer nofollow\">Marathon Labs Cloud<\/a> \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 <a href=\"https:\/\/cloud.marathonlabs.io\/tokens\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438<\/a>.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/183\/3c2\/b8a\/1833c2b8a31b194a07d4a4ebb00f473a.png\" width=\"248\" height=\"218\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/183\/3c2\/b8a\/1833c2b8a31b194a07d4a4ebb00f473a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/183\/3c2\/b8a\/1833c2b8a31b194a07d4a4ebb00f473a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043e\u043d \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u043d\u0430\u0448 CI\/CD \u0441 Marathon Labs. \u0421\u0430\u043c \u0442\u043e\u043a\u0435\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3c5\/7ee\/c1c\/3c57eec1c9188c228fa308acc9991674.png\" width=\"694\" height=\"321\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3c5\/7ee\/c1c\/3c57eec1c9188c228fa308acc9991674.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3c5\/7ee\/c1c\/3c57eec1c9188c228fa308acc9991674.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0434\u0430\u0435\u043c \u0435\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 slug, \u043e\u043d \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b \u043a \u0440\u0430\u0431\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u042d\u0442\u043e\u0442 \u044d\u0442\u0430\u043f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cc6\/60a\/821\/cc660a821092c143e772257557ea0094.png\" width=\"217\" height=\"327\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/cc6\/60a\/821\/cc660a821092c143e772257557ea0094.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cc6\/60a\/821\/cc660a821092c143e772257557ea0094.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0448\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Marathon Cloud.<\/p>\n<pre><code class=\"yaml\">runAndroidTestsUsingMarathon:     stage: tests     script:          - .\/gradlew app:assembleSomeBuildFlavorDebug       - .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest          - VERSION=\"1.0.46\"       - curl --location https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\/download\/${VERSION}\/marathon-cloud-v${VERSION}-{the archive we need} --output \/tmp\/marathon-cloud          - mkdir -p \/marathon       - tar -xzf \/tmp\/marathon-cloud --directory \/marathon       - mv \/marathon\/marathon-cloud-v${VERSION}-{the archive we need}\/marathon-cloud \/usr\/local\/bin\/       - chmod +x \/usr\/local\/bin\/marathon-cloud          - marathon-cloud devices android       - marathon-cloud run android --application \"app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk\" --test-application \"app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk\" --name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} --project ${MARATHON_CLOUD_PROJECT_ID}     rules:       - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" &amp;&amp; $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"master\"'<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c APK \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 APK.<\/p>\n<pre><code class=\"yaml\"> .\/gradlew app:assembleSomeBuildFlavorDebug    .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest  <\/code><\/pre>\n<p>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c <a href=\"https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\" rel=\"noopener noreferrer nofollow\">Marathon Cloud CLI<\/a>  \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- VERSION=\"1.0.46\"   - curl --location https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\/download\/${VERSION}\/marathon-cloud-v${VERSION}-{the archive we need} --output \/tmp\/marathon-cloud<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0430\u0440\u0445\u0438\u0432.<\/p>\n<pre><code class=\"yaml\">- mkdir -p \/marathon  <\/code><\/pre>\n<p>\u0418 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 \u044d\u0442\u0443 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- tar -xzf \/tmp\/marathon-cloud --directory \/marathon  <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0439 \u0444\u0430\u0439\u043b marathon-cloud \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>\/usr\/local\/bin\/<\/code>.<\/p>\n<pre><code class=\"yaml\">- mv \/marathon\/marathon-cloud-v${VERSION}-{the archive we need}\/marathon-cloud \/usr\/local\/bin\/<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <code>marathon-cloud<\/code>.<\/p>\n<pre><code class=\"yaml\">- chmod +x \/usr\/local\/bin\/marathon-cloud <\/code><\/pre>\n<p>\u041f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b. \u0414\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<pre><code class=\"yaml\">- marathon-cloud devices android<\/code><\/pre>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b.<\/p>\n<pre><code class=\"yaml\">- marathon-cloud run android --application \"app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk\" --test-application \"app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk\" --name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} --project ${MARATHON_CLOUD_PROJECT_ID}  <\/code><\/pre>\n<p>\u0413\u0434\u0435 \u043c\u044b \u0434\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u043c\u044f \u0432\u0435\u0442\u043a\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e MR.<\/p>\n<pre><code class=\"yaml\">--name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}<\/code><\/pre>\n<p>\u0418 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <code>slug<\/code> \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443.<\/p>\n<pre><code class=\"yaml\">--project ${MARATHON_CLOUD_PROJECT_ID}<\/code><\/pre>\n<blockquote>\n<p>\u0412\u0410\u0416\u041d\u041e<br \/>\u0417\u0434\u0435\u0441\u044c, \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>marathon-cloud<\/code> \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>--api-key<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u0448 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>MARATHON_CLOUD_API_KEY<\/code>, \u0442\u043e Marathon \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>marathon-cloud<\/code>.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e, \u0447\u0442\u043e \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u043a\u0440\u0435\u0442\u044b (\u0442\u043e\u043a\u0435\u043d\u044b, \u043a\u043b\u044e\u0447\u0438 \u0438 \u0442.\u0434.) \u043b\u0443\u0447\u0448\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 Gitlab variables. \u041a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/yandex.cloud\/en\/docs\/managed-gitlab\/tutorials\/gitlab-lockbox-integration\" rel=\"noopener noreferrer nofollow\">Yandex Lockbox<\/a>, <a href=\"https:\/\/cloud.google.com\/security\/products\/secret-manager\" rel=\"noopener noreferrer nofollow\">Google Cloud Secret Manager<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/hashicorp\/vault\" rel=\"noopener noreferrer nofollow\">HashiCorp Vault<\/a>.<\/p>\n<\/blockquote>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">MARATHON_CLOUD_API_KEY<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u0448 \u0442\u043e\u043a\u0435\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">MARATHON_CLOUD_PROJECT_ID<\/p>\n<\/td>\n<td>\n<p align=\"left\">Slug \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">CI_MERGE_REQUEST_SOURCE_BRANCH_NAME<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u0442\u043a\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e MR, <a href=\"https:\/\/docs.gitlab.com\/ci\/variables\/predefined_variables\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0443\u0442<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435, \u0438\u0442\u043e\u0433\u043e\u043c \u0438\u043c\u0435\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u043a\u0440\u0430\u0441\u043e\u0442\u0443.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/526\/294\/3e1\/5262943e11237d7f46ce174135be4178.png\" width=\"1714\" height=\"194\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/526\/294\/3e1\/5262943e11237d7f46ce174135be4178.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/526\/294\/3e1\/5262943e11237d7f46ce174135be4178.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>Firebase Test Lab<\/h2>\n<p><strong>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435,<\/strong> \u0434\u0430\u043d\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e <code>Firebase<\/code> \u0443\u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u0421 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 Firebase \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e 1 \u0440\u0430\u0437.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432 <a href=\"https:\/\/console.cloud.google.com\/\" rel=\"noopener noreferrer nofollow\">Google Cloud<\/a>, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 3 API \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430:<\/p>\n<ol>\n<li>\n<p>Cloud Functions API;<\/p>\n<\/li>\n<li>\n<p>Cloud Testing API;<\/p>\n<\/li>\n<li>\n<p>Cloud Tool Results API.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>APIs &amp; Services<\/code>, \u0433\u0434\u0435 \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u043c \u043c\u0435\u043d\u044e \u0438\u0449\u0435\u043c \u043f\u0443\u043d\u043a\u0442 <code>Enabled APIs and Services<\/code> \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0442\u0443\u0434\u0430.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d7c\/bf5\/5be\/d7cbf55bece84726834b806d5a54d4dd.png\" width=\"269\" height=\"411\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d7c\/bf5\/5be\/d7cbf55bece84726834b806d5a54d4dd.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d7c\/bf5\/5be\/d7cbf55bece84726834b806d5a54d4dd.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Enable APIs and Services<\/code> \u0438 \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435 \u0432\u0432\u043e\u0434\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f API, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432\u044b\u0448\u0435, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0445. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0443\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a85\/36b\/fb8\/a8536bfb8c3980080d4a446e2cb1f671.png\" width=\"1469\" height=\"519\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a85\/36b\/fb8\/a8536bfb8c3980080d4a446e2cb1f671.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a85\/36b\/fb8\/a8536bfb8c3980080d4a446e2cb1f671.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>IAM &amp; Admin<\/code> \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Service Accounts<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Create service acount<\/code>.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ab6\/917\/282\/ab6917282e3fdcf20843ed89745a396c.png\" width=\"225\" height=\"563\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ab6\/917\/282\/ab6917282e3fdcf20843ed89745a396c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ab6\/917\/282\/ab6917282e3fdcf20843ed89745a396c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f &#8212; \u0442\u0443\u0442 \u043d\u0430 \u0432\u0430\u0448 \u0432\u043a\u0443\u0441 \u0438 \u0446\u0432\u0435\u0442. \u0414\u0430\u043b\u0435\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <code>Grant this service account access to project<\/code> \u0437\u0430\u0434\u0430\u0435\u043c \u0440\u043e\u043b\u044c <code>Editor<\/code>. 3 \u0448\u0430\u0433 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e26\/717\/c18\/e26717c187d6a121d0f58a501e9f2a55.png\" width=\"1004\" height=\"700\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e26\/717\/c18\/e26717c187d6a121d0f58a501e9f2a55.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e26\/717\/c18\/e26717c187d6a121d0f58a501e9f2a55.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c JSON-\u043a\u043b\u044e\u0447, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c Google Cloud \u0441 \u043d\u0430\u0448\u0438\u043c CI\/CD, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/566\/84e\/194\/56684e1948dc5eccc9d4fd5cd1c67000.png\" width=\"542\" height=\"411\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/566\/84e\/194\/56684e1948dc5eccc9d4fd5cd1c67000.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/566\/84e\/194\/56684e1948dc5eccc9d4fd5cd1c67000.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Keys<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 <code>Add key<\/code>.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d3c\/e27\/17c\/d3ce2717c6469e80baa89aea25bd1248.png\" width=\"612\" height=\"406\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d3c\/e27\/17c\/d3ce2717c6469e80baa89aea25bd1248.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d3c\/e27\/17c\/d3ce2717c6469e80baa89aea25bd1248.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u044e\u0447, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u043a\u043b\u044e\u0447\u0430 &#8212; JSON. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u043d\u0430 \u043d\u0430\u0448 \u041f\u041a.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/26f\/11c\/31f\/26f11c31f15a6f0816d33b3db80e9c20.png\" width=\"627\" height=\"405\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/26f\/11c\/31f\/26f11c31f15a6f0816d33b3db80e9c20.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/26f\/11c\/31f\/26f11c31f15a6f0816d33b3db80e9c20.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0421 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0432\u0441\u0435, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">GOOGLE_CLOUD_PROJECT_ID<\/p>\n<\/td>\n<td>\n<p align=\"left\">Id \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 google cloud<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">SERVICE_ACCOUNT<\/p>\n<\/td>\n<td>\n<p align=\"left\">JSON-\u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438 \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u044d\u0442\u0430\u043f\u0435, \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0438 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0441\u044e\u0434\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e <code>GOOGLE_CLOUD_PROJECT_ID<\/code>, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/87c\/f14\/0c3\/87cf140c3edd7df35da354f982974be3.png\" width=\"1151\" height=\"446\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/87c\/f14\/0c3\/87cf140c3edd7df35da354f982974be3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/87c\/f14\/0c3\/87cf140c3edd7df35da354f982974be3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412\u0441\u0451, \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u044d\u0442\u0430\u043f\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u044b \u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a pipeline&#8217;\u043d\u0443.<\/p>\n<pre><code class=\"yaml\">runAndroidTestsUsingFirebase:     stage: tests     script:           - .\/gradlew app:assembleSomeBuildFlavorDebug       - .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest          - apt-get update       - apt install python3-pip --yes          - curl https:\/\/dl.google.com\/dl\/cloudsdk\/channels\/rapid\/google-cloud-sdk.tar.gz --output \/tmp\/google-cloud-sdk.tar.gz       - mkdir -p \/google       - tar zxf \/tmp\/google-cloud-sdk.tar.gz --directory \/google       - \/google\/google-cloud-sdk\/install.sh --quiet       - source \/google\/google-cloud-sdk\/path.bash.inc          - gcloud components update       - gcloud config set project ${GOOGLE_CLOUD_PROJECT_ID}          - echo $SERVICE_ACCOUNT &gt; \/tmp\/service-account.json       - gcloud auth activate-service-account --key-file \/tmp\/service-account.json          - gcloud firebase test android models list       - gcloud firebase test android versions list          - gcloud firebase test android run \\   --type instrumentation \\   --use-orchestrator \\   --app app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk \\   --test app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk \\   --device model=Pixel2,version=30,locale=ru,orientation=portrait    rules:       - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" &amp;&amp; $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"master\"'<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c APK \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 APK.<\/p>\n<pre><code class=\"yaml\">.\/gradlew app:assembleSomeBuildFlavorDebug   .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438.<\/p>\n<pre><code class=\"yaml\">- apt-get update  <\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c python \u0438 pip (\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438). <code>--yes<\/code> &#8212; \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<pre><code class=\"yaml\">- apt install python3-pip --yes<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c Google Cloud SDK.<\/p>\n<pre><code class=\"yaml\">- curl https:\/\/dl.google.com\/dl\/cloudsdk\/channels\/rapid\/google-cloud-sdk.tar.gz --output \/tmp\/google-cloud-sdk.tar.gz<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0430\u0440\u0445\u0438\u0432.<\/p>\n<pre><code class=\"yaml\">- mkdir -p \/google  <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0430\u0440\u0445\u0438\u0432 \u0432 \u043d\u0430\u0448\u0443 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- tar zxf \/tmp\/google-cloud-sdk.tar.gz --directory \/google<\/code><\/pre>\n<p>\u0418 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 SDK.<\/p>\n<pre><code class=\"yaml\">- \/google\/google-cloud-sdk\/install.sh --quiet<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 <code>Google Cloud SDK<\/code> \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043c \u0432\u0441\u0435 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u0442.\u0434. \u0432 \u043d\u0430\u0448 <code>PATH<\/code> (\u0412 Linux, \u0437\u0434\u0435\u0441\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0438\u0449\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043d\u0438\u043c\u0438 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438).<\/p>\n<pre><code class=\"yaml\">- source \/google\/google-cloud-sdk\/path.bash.inc<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u0448 <code>Google Cloud<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b SDK.<\/p>\n<pre><code class=\"yaml\">- gcloud components update<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0434\u043e \u044d\u0442\u043e\u0433\u043e.<\/p>\n<pre><code class=\"yaml\">- gcloud config set project ${GOOGLE_CLOUD_PROJECT_ID}<\/code><\/pre>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f.<\/p>\n<pre><code class=\"yaml\">- echo $SERVICE_ACCOUNT &gt; \/tmp\/service-account.json   - gcloud auth activate-service-account --key-file \/tmp\/service-account.json<\/code><\/pre>\n<p>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u041e\u0421 Android, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code class=\"yaml\">- gcloud firebase test android models list   - gcloud firebase test android versions list  <\/code><\/pre>\n<p>\u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u044d\u0442\u0430\u043f\u043e\u043c \u043c\u044b \u0443\u0436\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430\u0448\u0438\u0445 Android-\u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Firebase. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/command-line\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<pre><code class=\"yaml\">- gcloud firebase test android run \\   --type instrumentation \\   --use-orchestrator \\   --app app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk \\   --test app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk \\   --device model=Pixel2.arm,version=30,locale=ru,orientation=portrait <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043e\u0442\u0447\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 Firebase.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f32\/e3d\/782\/f32e3d782507267a2d2d1f6e23fceafa.png\" width=\"1149\" height=\"227\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/f32\/e3d\/782\/f32e3d782507267a2d2d1f6e23fceafa.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f32\/e3d\/782\/f32e3d782507267a2d2d1f6e23fceafa.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9a5\/110\/bd6\/9a5110bd60baba14acb9707e6bc0317a.png\" width=\"512\" height=\"101\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9a5\/110\/bd6\/9a5110bd60baba14acb9707e6bc0317a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9a5\/110\/bd6\/9a5110bd60baba14acb9707e6bc0317a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0443 \u0432\u043e\u0442 \u0438 \u0432\u0441\u0435, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0438\u0445 Android-\u0442\u0435\u0441\u0442\u043e\u0432 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c 2-\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432: Marathon Labs \u0438 Firebase Test Lab. \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 release-\u0441\u0431\u043e\u0440\u043e\u043a \u0432 Play Market, \u0433\u0434\u0435 \u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c pipeline. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u044d\u0433\u043e\u0432 \u0432 Gitlab \u0431\u0443\u0434\u0435\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u0435. \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0431\u0443\u0434\u0435\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 2-\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439:  <a href=\"https:\/\/github.com\/Triple-T\/gradle-play-publisher\" rel=\"noopener noreferrer nofollow\">Gradle Play Publisher<\/a> \u0438 <a href=\"https:\/\/github.com\/fastlane\/fastlane\" rel=\"noopener noreferrer nofollow\">Fastlane<\/a>.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u044b \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u0441\u0432\u043e\u0439 Docker Image \u0441\u043e \u0432\u0441\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c, \u0438 \u0434\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u043c CI\/CD. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b (Python, awscli \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.).<\/p>\n<p>\u0415\u0449\u0435 \u0443\u0432\u0438\u0434\u0438\u043c\u0441\u044f!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/922066\/\"> https:\/\/habr.com\/ru\/articles\/922066\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<h2>\u041e \u0447\u0451\u043c \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f?<\/h2>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b \u0438 \u044f Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 Scanny. \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0442\u043e, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448 CI\/CD, \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c Unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 Build Flavors \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 \u043d\u0430\u0448\u0443 Telegram-\u0433\u0440\u0443\u043f\u043f\u0443.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Android-\u0442\u0435\u0441\u0442\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 CI\/CD \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <a href=\"https:\/\/github.com\/MarathonLabs\/marathon\" rel=\"noopener noreferrer nofollow\">Marathon Labs<\/a> \u0438 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\" rel=\"noopener noreferrer nofollow\">Firebase Test Lab<\/a>.<\/p>\n<p>\u0426\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e CI\/CD \u0434\u043b\u044f Android \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/scanny\/articles\/918364\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c CI\/CD Android-\u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0430\u0441\u0442\u044c 1. \u041d\u0430\u0447\u0430\u043b\u043e.<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u0437\u0434\u0435\u0441\u044c.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c CI\/CD Android-\u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0430\u0441\u0442\u044c 3. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0435\u0440\u0441\u0438\u0439 \u0432 Play Market.<\/p>\n<\/li>\n<\/ol>\n<h2>Marathon Labs<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u0448\u0435 Android-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 Marathon Labs. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 <a href=\"https:\/\/cloud.marathonlabs.io\/\" rel=\"noopener noreferrer nofollow\">Marathon Labs Cloud<\/a> \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 <a href=\"https:\/\/cloud.marathonlabs.io\/tokens\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438<\/a>.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043e\u043d \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u043d\u0430\u0448 CI\/CD \u0441 Marathon Labs. \u0421\u0430\u043c \u0442\u043e\u043a\u0435\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0434\u0430\u0435\u043c \u0435\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 slug, \u043e\u043d \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b \u043a \u0440\u0430\u0431\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u042d\u0442\u043e\u0442 \u044d\u0442\u0430\u043f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0448\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Marathon Cloud.<\/p>\n<pre><code class=\"yaml\">runAndroidTestsUsingMarathon:     stage: tests     script:          - .\/gradlew app:assembleSomeBuildFlavorDebug       - .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest          - VERSION=\"1.0.46\"       - curl --location https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\/download\/${VERSION}\/marathon-cloud-v${VERSION}-{the archive we need} --output \/tmp\/marathon-cloud          - mkdir -p \/marathon       - tar -xzf \/tmp\/marathon-cloud --directory \/marathon       - mv \/marathon\/marathon-cloud-v${VERSION}-{the archive we need}\/marathon-cloud \/usr\/local\/bin\/       - chmod +x \/usr\/local\/bin\/marathon-cloud          - marathon-cloud devices android       - marathon-cloud run android --application \"app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk\" --test-application \"app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk\" --name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} --project ${MARATHON_CLOUD_PROJECT_ID}     rules:       - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" &amp;&amp; $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"master\"'<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c APK \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 APK.<\/p>\n<pre><code class=\"yaml\"> .\/gradlew app:assembleSomeBuildFlavorDebug    .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest  <\/code><\/pre>\n<p>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c <a href=\"https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\" rel=\"noopener noreferrer nofollow\">Marathon Cloud CLI<\/a>  \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- VERSION=\"1.0.46\"   - curl --location https:\/\/github.com\/MarathonLabs\/marathon-cloud-cli\/releases\/download\/${VERSION}\/marathon-cloud-v${VERSION}-{the archive we need} --output \/tmp\/marathon-cloud<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0430\u0440\u0445\u0438\u0432.<\/p>\n<pre><code class=\"yaml\">- mkdir -p \/marathon  <\/code><\/pre>\n<p>\u0418 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 \u044d\u0442\u0443 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- tar -xzf \/tmp\/marathon-cloud --directory \/marathon  <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0439 \u0444\u0430\u0439\u043b marathon-cloud \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>\/usr\/local\/bin\/<\/code>.<\/p>\n<pre><code class=\"yaml\">- mv \/marathon\/marathon-cloud-v${VERSION}-{the archive we need}\/marathon-cloud \/usr\/local\/bin\/<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <code>marathon-cloud<\/code>.<\/p>\n<pre><code class=\"yaml\">- chmod +x \/usr\/local\/bin\/marathon-cloud <\/code><\/pre>\n<p>\u041f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b. \u0414\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<pre><code class=\"yaml\">- marathon-cloud devices android<\/code><\/pre>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b.<\/p>\n<pre><code class=\"yaml\">- marathon-cloud run android --application \"app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk\" --test-application \"app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk\" --name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} --project ${MARATHON_CLOUD_PROJECT_ID}  <\/code><\/pre>\n<p>\u0413\u0434\u0435 \u043c\u044b \u0434\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u043c\u044f \u0432\u0435\u0442\u043a\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e MR.<\/p>\n<pre><code class=\"yaml\">--name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}<\/code><\/pre>\n<p>\u0418 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <code>slug<\/code> \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443.<\/p>\n<pre><code class=\"yaml\">--project ${MARATHON_CLOUD_PROJECT_ID}<\/code><\/pre>\n<blockquote>\n<p>\u0412\u0410\u0416\u041d\u041e<br \/>\u0417\u0434\u0435\u0441\u044c, \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>marathon-cloud<\/code> \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>--api-key<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u0448 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>MARATHON_CLOUD_API_KEY<\/code>, \u0442\u043e Marathon \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>marathon-cloud<\/code>.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e, \u0447\u0442\u043e \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u043a\u0440\u0435\u0442\u044b (\u0442\u043e\u043a\u0435\u043d\u044b, \u043a\u043b\u044e\u0447\u0438 \u0438 \u0442.\u0434.) \u043b\u0443\u0447\u0448\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 Gitlab variables. \u041a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/yandex.cloud\/en\/docs\/managed-gitlab\/tutorials\/gitlab-lockbox-integration\" rel=\"noopener noreferrer nofollow\">Yandex Lockbox<\/a>, <a href=\"https:\/\/cloud.google.com\/security\/products\/secret-manager\" rel=\"noopener noreferrer nofollow\">Google Cloud Secret Manager<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/hashicorp\/vault\" rel=\"noopener noreferrer nofollow\">HashiCorp Vault<\/a>.<\/p>\n<\/blockquote>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">MARATHON_CLOUD_API_KEY<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u0448 \u0442\u043e\u043a\u0435\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">MARATHON_CLOUD_PROJECT_ID<\/p>\n<\/td>\n<td>\n<p align=\"left\">Slug \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">CI_MERGE_REQUEST_SOURCE_BRANCH_NAME<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u0442\u043a\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e MR, <a href=\"https:\/\/docs.gitlab.com\/ci\/variables\/predefined_variables\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0443\u0442<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435, \u0438\u0442\u043e\u0433\u043e\u043c \u0438\u043c\u0435\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u043a\u0440\u0430\u0441\u043e\u0442\u0443.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>Firebase Test Lab<\/h2>\n<p><strong>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435,<\/strong> \u0434\u0430\u043d\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e <code>Firebase<\/code> \u0443\u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u0421 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 Firebase \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e 1 \u0440\u0430\u0437.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432 <a href=\"https:\/\/console.cloud.google.com\/\" rel=\"noopener noreferrer nofollow\">Google Cloud<\/a>, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 3 API \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430:<\/p>\n<ol>\n<li>\n<p>Cloud Functions API;<\/p>\n<\/li>\n<li>\n<p>Cloud Testing API;<\/p>\n<\/li>\n<li>\n<p>Cloud Tool Results API.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>APIs &amp; Services<\/code>, \u0433\u0434\u0435 \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u043c \u043c\u0435\u043d\u044e \u0438\u0449\u0435\u043c \u043f\u0443\u043d\u043a\u0442 <code>Enabled APIs and Services<\/code> \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0442\u0443\u0434\u0430.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Enable APIs and Services<\/code> \u0438 \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435 \u0432\u0432\u043e\u0434\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f API, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432\u044b\u0448\u0435, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0445. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0443\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>IAM &amp; Admin<\/code> \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Service Accounts<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Create service acount<\/code>.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0412 \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f &#8212; \u0442\u0443\u0442 \u043d\u0430 \u0432\u0430\u0448 \u0432\u043a\u0443\u0441 \u0438 \u0446\u0432\u0435\u0442. \u0414\u0430\u043b\u0435\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <code>Grant this service account access to project<\/code> \u0437\u0430\u0434\u0430\u0435\u043c \u0440\u043e\u043b\u044c <code>Editor<\/code>. 3 \u0448\u0430\u0433 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c JSON-\u043a\u043b\u044e\u0447, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c Google Cloud \u0441 \u043d\u0430\u0448\u0438\u043c CI\/CD, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Keys<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 <code>Add key<\/code>.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u044e\u0447, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u043a\u043b\u044e\u0447\u0430 &#8212; JSON. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u043d\u0430 \u043d\u0430\u0448 \u041f\u041a.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0432\u0441\u0435, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">GOOGLE_CLOUD_PROJECT_ID<\/p>\n<\/td>\n<td>\n<p align=\"left\">Id \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 google cloud<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">SERVICE_ACCOUNT<\/p>\n<\/td>\n<td>\n<p align=\"left\">JSON-\u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438 \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u044d\u0442\u0430\u043f\u0435, \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0438 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0441\u044e\u0434\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e <code>GOOGLE_CLOUD_PROJECT_ID<\/code>, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412\u0441\u0451, \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u044d\u0442\u0430\u043f\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u044b \u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a pipeline&#8217;\u043d\u0443.<\/p>\n<pre><code class=\"yaml\">runAndroidTestsUsingFirebase:     stage: tests     script:           - .\/gradlew app:assembleSomeBuildFlavorDebug       - .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest          - apt-get update       - apt install python3-pip --yes          - curl https:\/\/dl.google.com\/dl\/cloudsdk\/channels\/rapid\/google-cloud-sdk.tar.gz --output \/tmp\/google-cloud-sdk.tar.gz       - mkdir -p \/google       - tar zxf \/tmp\/google-cloud-sdk.tar.gz --directory \/google       - \/google\/google-cloud-sdk\/install.sh --quiet       - source \/google\/google-cloud-sdk\/path.bash.inc          - gcloud components update       - gcloud config set project ${GOOGLE_CLOUD_PROJECT_ID}          - echo $SERVICE_ACCOUNT &gt; \/tmp\/service-account.json       - gcloud auth activate-service-account --key-file \/tmp\/service-account.json          - gcloud firebase test android models list       - gcloud firebase test android versions list          - gcloud firebase test android run \\   --type instrumentation \\   --use-orchestrator \\   --app app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk \\   --test app\/build\/outputs\/apk\/androidTest\/{build flavor name}\/debug\/{your apk's name}-androidTest.apk \\   --device model=Pixel2,version=30,locale=ru,orientation=portrait    rules:       - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" &amp;&amp; $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"master\"'<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c APK \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 APK.<\/p>\n<pre><code class=\"yaml\">.\/gradlew app:assembleSomeBuildFlavorDebug   .\/gradlew app:assembleSomeBuildFlavorDebugAndroidTest<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438.<\/p>\n<pre><code class=\"yaml\">- apt-get update  <\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c python \u0438 pip (\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438). <code>--yes<\/code> &#8212; \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<pre><code class=\"yaml\">- apt install python3-pip --yes<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c Google Cloud SDK.<\/p>\n<pre><code class=\"yaml\">- curl https:\/\/dl.google.com\/dl\/cloudsdk\/channels\/rapid\/google-cloud-sdk.tar.gz --output \/tmp\/google-cloud-sdk.tar.gz<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0430\u0440\u0445\u0438\u0432.<\/p>\n<pre><code class=\"yaml\">- mkdir -p \/google  <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0430\u0440\u0445\u0438\u0432 \u0432 \u043d\u0430\u0448\u0443 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">- tar zxf \/tmp\/google-cloud-sdk.tar.gz --directory \/google<\/code><\/pre>\n<p>\u0418 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 SDK.<\/p>\n<pre><code class=\"yaml\">- \/google\/google-cloud-sdk\/install.sh --quiet<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 <code>Google Cloud SDK<\/code> \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043c \u0432\u0441\u0435 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u0442.\u0434. \u0432 \u043d\u0430\u0448 <code>PATH<\/code> (\u0412 Linux, \u0437\u0434\u0435\u0441\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0438\u0449\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043d\u0438\u043c\u0438 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438).<\/p>\n<pre><code class=\"yaml\">- source \/google\/google-cloud-sdk\/path.bash.inc<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u0448 <code>Google Cloud<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b SDK.<\/p>\n<pre><code class=\"yaml\">- gcloud components update<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0434\u043e \u044d\u0442\u043e\u0433\u043e.<\/p>\n<pre><code class=\"yaml\">- gcloud config set project ${GOOGLE_CLOUD_PROJECT_ID}<\/code><\/pre>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f.<\/p>\n<pre><code class=\"yaml\">- echo $SERVICE_ACCOUNT &gt; \/tmp\/service-account.json   - gcloud auth activate-service-account --key-file \/tmp\/service-account.json<\/code><\/pre>\n<p>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u041e\u0421 Android, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code class=\"yaml\">- gcloud firebase test android models list   - gcloud firebase test android versions list  <\/code><\/pre>\n<p>\u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u044d\u0442\u0430\u043f\u043e\u043c \u043c\u044b \u0443\u0436\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430\u0448\u0438\u0445 Android-\u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Firebase. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/command-line\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<pre><code class=\"yaml\">- gcloud firebase test android run \\   --type instrumentation \\   --use-orchestrator \\   --app app\/build\/outputs\/apk\/{build flavor name}\/debug\/{your apk's name}.apk \\<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-464682","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/464682","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=464682"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/464682\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=464682"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=464682"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=464682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}