{"id":314294,"date":"2020-12-04T09:01:40","date_gmt":"2020-12-04T09:01:40","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=314294"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=314294","title":{"rendered":"\u041f\u0440\u043e\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c Android \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 GitHub Actions. \u0427\u0430\u0441\u0442\u044c 2"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h3>\u0417\u0430\u043f\u0443\u0441\u043a UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 GitHub Actions<\/h3>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 Android \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 GitHub Actions, \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438: <\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u0432\u0435\u0434\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 UI-\u0442\u0435\u0441\u0442\u044b \u0432 Firebase Test Lab<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e GitHub Actions \u0438 Test Lab<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c UI-\u0442\u0435\u0441\u0442\u044b \u0432 workflow \u043d\u0430 CI\/CD. <\/p>\n<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430, \u0433\u0434\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u0441 Unit-\u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432 Android \u043f\u0440\u043e\u0435\u043a\u0442\u0435, <a href=\"https:\/\/habr.com\/ru\/company\/tuturu\/blog\/530260\/\">\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u043d\u0435\u0435.<\/a><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c unit-\u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 Java-\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u043d\u0443\u0442\u0440\u0438 JVM, \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e, \u0438 \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f flacky-\u0442\u0435\u0441\u0442\u043e\u0432. \u0422\u0430\u043a\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c 70-80% \u043e\u0442 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435, <a href=\"https:\/\/developer.android.com\/training\/testing\/fundamentals#write-tests\">\u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/a> \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0438\u043c\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>\u041d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u2013 \u0442\u0435\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0432\u0435\u0440\u044f\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0421 UI-\u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432\u0441\u0451 \u043d\u0435\u043f\u0440\u043e\u0441\u0442\u043e \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c. \u0417\u0432\u0443\u0447\u0438\u0442 \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0443\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u044d\u043d\u0442\u0443\u0437\u0438\u0430\u0437\u043c. \u041f\u043e\u0442\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043c\u0430\u0441\u0441\u0430 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u043e\u0433\u0430\u0442\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0445 \u0410\/\u0411-\u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0447\u0430\u0441\u0442\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041d\u0443\u0436\u043d\u043e \u0440\u0435\u0448\u0430\u0442\u044c, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f &#8212; \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u043b\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u044b \u0438 \u043a\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u044d\u0442\u0438\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 &#8212; \u0441\u0432\u043e\u044f \u0444\u0435\u0440\u043c\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u043e\u0432 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0441\u043b\u0443\u0433\u0430\u043c\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0442\u0435\u043c\u0430 \u043d\u0435 \u0438\u0437 \u043b\u0451\u0433\u043a\u0438\u0445.<\/p>\n<p>\u041c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u043f\u043e \u0441\u0430\u043c\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443 \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 &#8212; <a href=\"https:\/\/firebase.google.com\/products\/test-lab\/\">Firebase Test Lab<\/a><\/p>\n<p>Firebase Test Lab &#8212; \u044d\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442 Google, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0438\u043b\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430\u0445. \u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0442\u0430\u0440\u0438\u0444 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 10 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u0434\u0435\u043d\u044c \u043d\u0430 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430\u0445 \u0438 5 \u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445. \u0412 \u043f\u043b\u0430\u0442\u043d\u043e\u043c \u0442\u0430\u0440\u0438\u0444\u0435 \u0446\u0435\u043d\u0430 \u0441\u0435\u0439\u0447\u0430\u0441 1$ \u0437\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u043e-\u0447\u0430\u0441 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430, \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0442\u0430\u043a\u043e\u0435 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Test Lab \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0448\u0430\u0433\u0430\u043c\u0438:<\/p>\n<ol>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c checkout&nbsp;\u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043c\u043c\u0438\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Java-\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u043e\u0434\u0438\u043c unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0442\u043e \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 UI-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 Gradle-\u0442\u0430\u0441\u043a\u0430\u043c\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0434\u043b\u044f UI-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c APK-\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u0432 Firebase Test Lab \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e command line \u0443\u0442\u0438\u043b\u0438\u0442\u0443 <a href=\"https:\/\/cloud.google.com\/sdk\/gcloud\/reference\/firebase\/test\/android\/run\">gcloud<\/a>, \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u043c&nbsp;\u0432 Test Lab \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 APK.<\/p>\n<\/li>\n<li>\n<p>\u0416\u0434\u0451\u043c, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0439\u0434\u0443\u0442, \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 workflow GitHub Actions.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043c \u043d\u0430 Firebase \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0431\u0435 \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043d\u0435\u043c\u0443 \u0438\u0437 GitHub.<\/p>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430&nbsp;<a href=\"https:\/\/console.firebase.google.com\/\">https:\/\/console.firebase.google.com<\/a>&nbsp;\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u043e\u0434 \u0441\u0432\u043e\u0438\u043c Google-\u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u043c.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u043c \u043f\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0437\u0430\u0440\u0434\u0443, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3a4\/436\/b73\/3a4436b73bd45331644fa4e721701bca\" width=\"3268\" height=\"1194\"><figcaption><\/figcaption><\/figure>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5a6\/603\/241\/5a660324198f75935da12dfd7ee7d02c\" width=\"1178\" height=\"976\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c Google-\u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0451 \u043a\u0430\u043a \u0435\u0441\u0442\u044c, \u043d\u0430 Test Lab \u044d\u0442\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430, \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0448\u0430\u0433\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1c0\/e09\/6c2\/1c0e096c2f4e7bdccc94d3685e65d0cc\" width=\"1170\" height=\"992\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 GitHub Actions \u043a Test Lab.&nbsp;<\/p>\n<p>\u0418\u0434\u0451\u043c \u0432 \u201c\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u201d (\u201cProject settings\u201d), \u0437\u0430\u0442\u0435\u043c \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u201c\u0421\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0435 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b\u201d (\u201cService accounts\u201d). \u0422\u0430\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u201c\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0445 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432\u201d (\u201cManage service account permissions\u201d).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/906\/1c3\/c71\/9061c3c71ba4324df5657d701cd4d15a\" width=\"3134\" height=\"656\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0441 \u0442\u0435\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 CI\/CD \u0432 GitHub Actions. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0442\u0438\u043f\u0430 \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/continuous#requirements\">\u0442\u0443\u0442<\/a>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/261\/283\/92a\/26128392ad56d5fd164aca1726865cdf\" width=\"2752\" height=\"480\"><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0435 \u043f\u043e\u043b\u044f<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f91\/4d2\/37b\/f914d237bcc7ab3d072828e53e659f80\" width=\"1652\" height=\"1290\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0438\u043f \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d. \u0415\u0441\u043b\u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430, \u0442\u043e \u043d\u0430 \u0448\u0430\u0433\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 Firebase \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 403.<\/p>\n<pre><code>ERROR: (gcloud.firebase.test.android.run) Unable to access the test environment catalog: ResponseError 403: Not authorized for project ***<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/51f\/cab\/9da\/51fcab9da1110dff6b18c398ec27d695\" width=\"1632\" height=\"1244\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0448\u0430\u0433\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u201c\u0413\u043e\u0442\u043e\u0432\u043e\u201d<\/p>\n<p>\u041c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0434\u043b\u044f CI\/CD \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u201c\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u201d (\u201cCreate key\u201d).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/728\/cb9\/338\/728cb9338fab563edb6863dd132eec2f\" width=\"2740\" height=\"374\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 JSON, \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043a\u0430\u0447\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438, &#8212; \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u0422\u0430\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0440\u0430\u0437\u043d\u0430\u044f \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443 \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043f\u043b\u044e\u0441 private_key.<\/p>\n<p>\u0424\u043e\u043a\u0443\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 JSON \u0443 \u043d\u0430\u0441 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 Base64.<\/p>\n<p>\u041f\u0443\u0442\u0438 \u0434\u0432\u0430:<\/p>\n<p>1) \u0412 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0432\u0432\u043e\u0434\u0438\u043c<\/p>\n<pre><code>base64 github-actions-sample-key.json &gt; base64-key.txt<\/code><\/pre>\n<p>\u0413\u0434\u0435 github-actions-sample-key.json &#8212; \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435 JSON, \u0430 base64-key \u2013 \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>2) \u0414\u0435\u043b\u0430\u0435\u043c \u0432\u0441\u0451 \u043d\u0430&nbsp;<a href=\"https:\/\/www.base64encode.org\/\">https:\/\/www.base64encode.org\/<\/a><\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 GitHub \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 Secrets \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/95c\/30b\/965\/95c30b9659f7153e4ef2c702872685b9\" width=\"1918\" height=\"1236\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u044e\u0447\u0430 \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0438\u0442\u0435 \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043a\u043b\u044e\u0447 \u0441 Firebase \u0438 base64-key.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b Project ID \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0431\u0449\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase. \u041d\u0435 \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u0439\u0442\u0435 \u0441 Project number.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/077\/31b\/b4d\/07731bb4da025697422a47bfbc79b772\" width=\"3066\" height=\"1420\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 GitHub Actions \u0438 Test Lab. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 workflow \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 giithub\/workflows.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c workflow, \u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0433\u043e\u043d\u0430\u0445 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Test Lab \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<pre><code>ERROR: (gcloud.firebase.test.android.run) User [github-actions-ci-cd@***.iam.gserviceaccount.com] does not have permission to access project [***:initializeSettings] (or it may not exist): Cloud Tool Results API has not been used in project 254361894337 before or it is disabled. Enable it by visiting https:\/\/console.developers.google.com\/apis\/api\/toolresults.googleapis.com\/overview?project=254361894337 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.<\/code><\/pre>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438\u0437 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c API&nbsp;<a href=\"http:\/\/toolresults.googleapis.com\/\">toolresults.googleapis.com<\/a>, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043b\u044e\u0431\u044b\u043c\u0438 API \u0432 \u0441\u0432\u043e\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u201cEnable APIs and services\u201d.&nbsp;<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e5c\/88a\/fde\/e5c88afde4ac7939578c6ff2fdf18d70\" width=\"2388\" height=\"918\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c API \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u0430\u0445\u043e\u0434\u0438\u043c Cloud Tool Result API \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c.<\/p>\n<p>\u041d\u0443 \u0442\u0435\u043f\u0435\u0440\u044c-\u0442\u043e \u0443\u0436 \u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0451, \u043f\u043e\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c workflow.<\/p>\n<pre><code>name: UI_tests_on_release   on:   pull_request:     branches:       - 'main'   jobs:   assemble_ui_test_artifacts:     if: startsWith(github.head_ref, 'release\/') == true     name: Build artifacts     runs-on: ubuntu-20.04     steps:       - uses: actions\/checkout@v2       - uses: actions\/setup-java@v1         with: {java-version: 1.8}         - name: Build APK for UI test after Unit tests         run: |           .\/gradlew test           .\/gradlew assembleDebug           .\/gradlew assembleDebugAndroidTest         - name: Upload app-debug APK         uses: actions\/upload-artifact@v2         with:           name: app-debug           path: app\/build\/outputs\/apk\/debug\/app-debug.apk         - name: Upload app-debug-androidTest APK         uses: actions\/upload-artifact@v2         with:           name: app-debug-androidTest           path: app\/build\/outputs\/apk\/androidTest\/debug\/app-debug-androidTest.apk     run_ui_tests_on_firebase:     runs-on: ubuntu-20.04     needs: assemble_ui_test_artifacts     steps:       - uses: actions\/checkout@v2       - name: Download app-debug APK         uses: actions\/download-artifact@v1         with:           name: app-debug         - name: Download app-debug-androidTest APK         uses: actions\/download-artifact@v1         with:           name: app-debug-androidTest         - name: Firebase auth with gcloud         uses: google-github-actions\/setup-gcloud@master         with:           version: '290.0.1'           service_account_key: ${{ secrets.FIREBASE_KEY }}           project_id: ${{ secrets.FIREBASE_PROJECT_ID }}         - name: Run Instrumentation Tests in Firebase Test Lab         run: |           gcloud firebase test android models list           gcloud firebase test android run --type instrumentation --use-orchestrator --app app-debug\/app-debug.apk --test app-debug-androidTest\/app-debug-androidTest.apk --device model=Pixel2,version=28,locale=en,orientation=portrait<\/code><\/pre>\n<\/p>\n<p><strong>\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0443\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442<\/strong><\/p>\n<p><strong>\u0428\u0430\u0433 1<\/strong><\/p>\n<pre><code>name: UI_tests_on_release   on:   pull_request:     branches:       - 'main'   jobs:   assemble_ui_test_artifacts:     if: startsWith(github.head_ref, 'release\/') == true     name: Build artifacts     runs-on: ubuntu-20.04     steps:       - uses: actions\/checkout@v2       - uses: actions\/setup-java@v1         with: {java-version: 1.8}<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 workflow, \u0447\u0442\u043e \u0438 \u0440\u0430\u043d\u044c\u0448\u0435. Pull request \u0432 \u0432\u0435\u0442\u043a\u0443 main \u0438\u0437 \u0432\u0435\u0442\u043a\u0438, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u0430 release\/.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u0435\u043b\u0430\u0435\u043c checkout \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 Java 8.<\/p>\n<p><strong>\u0428\u0430\u0433 2<\/strong><\/p>\n<pre><code>- name: Build APK for UI test after Unit tests   run: |     .\/gradlew test     .\/gradlew assembleDebug     .\/gradlew assembleDebugAndroidTest   - name: Upload app-debug APK   uses: actions\/upload-artifact@v2   with:     name: app-debug     path: app\/build\/outputs\/apk\/debug\/app-debug.apk   - name: Upload app-debug-androidTest APK   uses: actions\/upload-artifact@v2   with:     name: app-debug-androidTest     path: app\/build\/outputs\/apk\/androidTest\/debug\/app-debug-androidTest.apk<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u043c unit-\u0442\u0435\u0441\u0442\u044b \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0434\u0432\u0430 APK &#8212; app-debug.apk \u0438 app-debug-androidTest.apk. \u041f\u043e\u0447\u0435\u043c\u0443 \u0434\u0432\u0430? \u0414\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u0438\u043d APK &#8212; \u044d\u0442\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 APK \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 instrumentation-\u0442\u0435\u0441\u0442\u044b, \u043e\u043d\u0438 \u043e\u0431\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u043e\u0441\u0442\u0430\u0451\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e \u043f\u0443\u0442\u0438 \u0438 \u0438\u043c\u0435\u043d\u0438 \u0432 upload-artifact@v2.<\/p>\n<p>\u0412\u0441\u0451 \u044d\u0442\u043e \u043c\u044b \u0443\u0436\u0435 <a href=\"https:\/\/habr.com\/ru\/company\/tuturu\/blog\/530260\/\">\u0434\u0435\u043b\u0430\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435<\/a>, \u043a\u043e\u0433\u0434\u0430 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 APK \u043a \u0440\u0435\u043b\u0438\u0437\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p><strong>\u0428\u0430\u0433 3<\/strong><\/p>\n<pre><code>run_ui_tests_on_firebase:   runs-on: ubuntu-20.04   needs: assemble_ui_test_artifacts   steps:     - uses: actions\/checkout@v2     - name: Download app-debug APK       uses: actions\/download-artifact@v1       with:         name: app-debug       - name: Download app-debug-androidTest APK       uses: actions\/download-artifact@v1       with:         name: app-debug-androidTest<\/code><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f Job \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c workflow \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 (assemble_ui_test_artifacts), \u0430 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u0442\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f.<\/p>\n<p>\u042d\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0441\u0442\u0440\u043e\u0447\u043a\u0435.<\/p>\n<pre><code>needs: assemble_ui_test_artifacts<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c action download-artifact@v1 \u0438 \u0434\u043e\u0441\u0442\u0430\u043d\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0442\u0435 \u0434\u0432\u0430 APK \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 Job.<\/p>\n<p><strong>\u0428\u0430\u0433 4<\/strong><\/p>\n<p>\u0414\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0433\u043e &#8212; \u043f\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 Test Lab \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code>- name: Firebase auth with gcloud   uses: google-github-actions\/setup-gcloud@master   with:     version: '290.0.1'     service_account_key: ${{ secrets.FIREBASE_KEY }}     project_id: ${{ secrets.FIREBASE_PROJECT_ID }}   - name: Run Instrumentation Tests in Firebase Test Lab   run: |     gcloud firebase test android models list     gcloud firebase test android run --type instrumentation --use-orchestrator --app app-debug\/app-debug.apk --test app-debug-androidTest\/app-debug-androidTest.apk --device model=Pixel2,version=28,locale=en,orientation=portrait<\/code><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c action setup-gcloud, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u0445 ID \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 Base64 \u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u0430\u0445, <a href=\"https:\/\/github.com\/google-github-actions\/setup-gcloud\/blob\/master\/setup-gcloud\/README.md\">\u0432\u0441\u0451 \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f&nbsp;<strong>gcloud firebase test android models list<\/strong>&nbsp;\u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 SDK. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0432 \u043a\u043b\u044e\u0447\u0430\u0445 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u043b\u043e\u043a\u0430\u043b\u044c, \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u044d\u043a\u0440\u0430\u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/command-line\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c workflow \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/061\/c66\/7f0\/061c667f0e7fa905e34c9bd2e6b5531f\" width=\"3324\" height=\"1294\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0441\u0430\u043c\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d! \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 Test Lab \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u0435\u043a\u0440\u0435\u0442\u043e\u0432 Project ID (\u0438\u043d\u0430\u0447\u0435 \u0432 \u0441\u0441\u044b\u043b\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u043e ID) \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u0438\u0437 \u043b\u043e\u0433\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d12\/08b\/4e8\/d1208b4e846318e00fb05e879ffbc86e\" width=\"2862\" height=\"800\"><figcaption><\/figcaption><\/figure>\n<p><strong>\u0427\u0442\u043e \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438<\/strong><\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c orchestrator, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043a\u043b\u044e\u0447 <strong>&#8212;use-orchestrator.<\/strong><\/p>\n<p>\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0441\u0442 \u0432 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0432\u043b\u0438\u044f\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u0440\u0443\u0433 \u043d\u0430 \u0434\u0440\u0443\u0433\u0430.&nbsp;<\/p>\n<p><strong>&#8212;num-flaky-test-attempts<\/strong> &#8212; \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u043b\u044f Flaky \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p><strong>&#8212;network-profile<\/strong> &#8212; \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0441\u0435\u0442\u0438 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0439 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0442\u0443\u0442:<\/p>\n<p><a href=\"https:\/\/cloud.google.com\/sdk\/gcloud\/reference\/firebase\/test\/android\/run\">https:\/\/cloud.google.com\/sdk\/gcloud\/reference\/firebase\/test\/android\/run<\/a><\/p>\n<p>\u0415\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0448\u0430\u0440\u0434\u0438\u043d\u0433 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432&nbsp;<\/p>\n<p><a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/instrumentation-test#sharding\">https:\/\/firebase.google.com\/docs\/test-lab\/android\/instrumentation-test#sharding<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/Flank\/flank\">https:\/\/github.com\/Flank\/flank<\/a><\/p>\n<p>\u0418\u0434\u0435\u044f \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c:<\/p>\n<p>1) \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c UI-\u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u0432 Test Lab \u0430 \u0432 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435, \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c\u043e\u043c \u043d\u0430 MacOS. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c&nbsp;<a href=\"https:\/\/github.com\/ReactiveCircus\/android-emulator-runner\">https:\/\/github.com\/ReactiveCircus\/android-emulator-runner<\/a><\/p>\n<p>2) \u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f UI-\u0442\u0435\u0441\u0442\u043e\u0432. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 Android SDK \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445.<\/p>\n<p><\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0437 GitHub Actions \u0432\u0441\u0451 \ud83d\ude42<\/p>\n<\/div>\n<p> \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\/company\/tuturu\/blog\/531156\/\"> https:\/\/habr.com\/ru\/company\/tuturu\/blog\/531156\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h3>\u0417\u0430\u043f\u0443\u0441\u043a UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 GitHub Actions<\/h3>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 Android \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 GitHub Actions, \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438: <\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u0432\u0435\u0434\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 UI-\u0442\u0435\u0441\u0442\u044b \u0432 Firebase Test Lab<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e GitHub Actions \u0438 Test Lab<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c UI-\u0442\u0435\u0441\u0442\u044b \u0432 workflow \u043d\u0430 CI\/CD. <\/p>\n<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430, \u0433\u0434\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u0441 Unit-\u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432 Android \u043f\u0440\u043e\u0435\u043a\u0442\u0435, <a href=\"https:\/\/habr.com\/ru\/company\/tuturu\/blog\/530260\/\">\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u043d\u0435\u0435.<\/a><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c unit-\u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 Java-\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u043d\u0443\u0442\u0440\u0438 JVM, \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e, \u0438 \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f flacky-\u0442\u0435\u0441\u0442\u043e\u0432. \u0422\u0430\u043a\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c 70-80% \u043e\u0442 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435, <a href=\"https:\/\/developer.android.com\/training\/testing\/fundamentals#write-tests\">\u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/a> \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0438\u043c\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>\u041d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u2013 \u0442\u0435\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0432\u0435\u0440\u044f\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0421 UI-\u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432\u0441\u0451 \u043d\u0435\u043f\u0440\u043e\u0441\u0442\u043e \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c. \u0417\u0432\u0443\u0447\u0438\u0442 \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0443\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u044d\u043d\u0442\u0443\u0437\u0438\u0430\u0437\u043c. \u041f\u043e\u0442\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043c\u0430\u0441\u0441\u0430 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u043e\u0433\u0430\u0442\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0445 \u0410\/\u0411-\u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0447\u0430\u0441\u0442\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041d\u0443\u0436\u043d\u043e \u0440\u0435\u0448\u0430\u0442\u044c, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f &#8212; \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u043b\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u044b \u0438 \u043a\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u044d\u0442\u0438\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 &#8212; \u0441\u0432\u043e\u044f \u0444\u0435\u0440\u043c\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u043e\u0432 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0441\u043b\u0443\u0433\u0430\u043c\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0442\u0435\u043c\u0430 \u043d\u0435 \u0438\u0437 \u043b\u0451\u0433\u043a\u0438\u0445.<\/p>\n<p>\u041c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u043f\u043e \u0441\u0430\u043c\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443 \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 &#8212; <a href=\"https:\/\/firebase.google.com\/products\/test-lab\/\">Firebase Test Lab<\/a><\/p>\n<p>Firebase Test Lab &#8212; \u044d\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442 Google, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0438\u043b\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430\u0445. \u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0442\u0430\u0440\u0438\u0444 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 10 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u0434\u0435\u043d\u044c \u043d\u0430 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430\u0445 \u0438 5 \u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445. \u0412 \u043f\u043b\u0430\u0442\u043d\u043e\u043c \u0442\u0430\u0440\u0438\u0444\u0435 \u0446\u0435\u043d\u0430 \u0441\u0435\u0439\u0447\u0430\u0441 1$ \u0437\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u043e-\u0447\u0430\u0441 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430, \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0442\u0430\u043a\u043e\u0435 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Test Lab \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0448\u0430\u0433\u0430\u043c\u0438:<\/p>\n<ol>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c checkout&nbsp;\u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043c\u043c\u0438\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Java-\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u043e\u0434\u0438\u043c unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0442\u043e \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 UI-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 Gradle-\u0442\u0430\u0441\u043a\u0430\u043c\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0434\u043b\u044f UI-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c APK-\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u0432 Firebase Test Lab \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e command line \u0443\u0442\u0438\u043b\u0438\u0442\u0443 <a href=\"https:\/\/cloud.google.com\/sdk\/gcloud\/reference\/firebase\/test\/android\/run\">gcloud<\/a>, \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u043c&nbsp;\u0432 Test Lab \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 APK.<\/p>\n<\/li>\n<li>\n<p>\u0416\u0434\u0451\u043c, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0439\u0434\u0443\u0442, \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 workflow GitHub Actions.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043c \u043d\u0430 Firebase \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0431\u0435 \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043d\u0435\u043c\u0443 \u0438\u0437 GitHub.<\/p>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430&nbsp;<a href=\"https:\/\/console.firebase.google.com\/\">https:\/\/console.firebase.google.com<\/a>&nbsp;\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u043e\u0434 \u0441\u0432\u043e\u0438\u043c Google-\u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u043c.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u043c \u043f\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0437\u0430\u0440\u0434\u0443, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c Google-\u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0451 \u043a\u0430\u043a \u0435\u0441\u0442\u044c, \u043d\u0430 Test Lab \u044d\u0442\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430, \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0448\u0430\u0433\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 GitHub Actions \u043a Test Lab.&nbsp;<\/p>\n<p>\u0418\u0434\u0451\u043c \u0432 \u201c\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u201d (\u201cProject settings\u201d), \u0437\u0430\u0442\u0435\u043c \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u201c\u0421\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0435 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b\u201d (\u201cService accounts\u201d). \u0422\u0430\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u201c\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0445 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432\u201d (\u201cManage service account permissions\u201d).<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0441 \u0442\u0435\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 CI\/CD \u0432 GitHub Actions. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0442\u0438\u043f\u0430 \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 <a href=\"https:\/\/firebase.google.com\/docs\/test-lab\/android\/continuous#requirements\">\u0442\u0443\u0442<\/a>.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0435 \u043f\u043e\u043b\u044f<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0438\u043f \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d. \u0415\u0441\u043b\u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430, \u0442\u043e \u043d\u0430 \u0448\u0430\u0433\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 Firebase \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 403.<\/p>\n<pre><code>ERROR: (gcloud.firebase.test.android.run) Unable to access the test environment catalog: ResponseError 403: Not authorized for project ***<\/code><\/pre>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0448\u0430\u0433\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u201c\u0413\u043e\u0442\u043e\u0432\u043e\u201d<\/p>\n<p>\u041c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0434\u043b\u044f CI\/CD \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u201c\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u201d (\u201cCreate key\u201d).<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 JSON, \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043a\u0430\u0447\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438, &#8212; \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u0422\u0430\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0440\u0430\u0437\u043d\u0430\u044f \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443 \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043f\u043b\u044e\u0441 private_key.<\/p>\n<p>\u0424\u043e\u043a\u0443\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 JSON \u0443 \u043d\u0430\u0441 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 Base64.<\/p>\n<p>\u041f\u0443\u0442\u0438 \u0434\u0432\u0430:<\/p>\n<p>1) \u0412 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0432\u0432\u043e\u0434\u0438\u043c<\/p>\n<pre><code>base64 github-actions-sample-key.json &gt; base64-key.txt<\/code><\/pre>\n<p>\u0413\u0434\u0435 github-actions-sample-key.json &#8212; \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435 JSON, \u0430 base64-key \u2013 \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>2) \u0414\u0435\u043b\u0430\u0435\u043c \u0432\u0441\u0451 \u043d\u0430&nbsp;<a href=\"https:\/\/www.base64encode.org\/\">https:\/\/www.base64encode.org\/<\/a><\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 GitHub \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 Secrets \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u044e\u0447\u0430 \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0438\u0442\u0435 \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043a\u043b\u044e\u0447 \u0441 Firebase \u0438 base64-key.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b Project ID \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0431\u0449\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase. \u041d\u0435 \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u0439\u0442\u0435 \u0441 Project number.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 GitHub Actions \u0438 Test Lab. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 workflow \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 giithub\/workflows.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c workflow, \u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0433\u043e\u043d\u0430\u0445 UI-\u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Test Lab \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<pre><code>ERROR: (gcloud.firebase.test.android.run) User [github-actions-ci-cd@***.iam.gserviceaccount.com] does not have permission to access project [***:initializeSettings] (or it may not exist): Cloud Tool Results API has not been used in project 254361894337 before or it is disabled. Enable it by visiting https:\/\/console.developers.google.com\/apis\/api\/toolresults.googleapis.com\/overview?project=254361894337 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.<\/code><\/pre>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438\u0437 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c API&nbsp;<a href=\"http:\/\/toolresults.googleapis.com\/\">toolresults.googleapis.com<\/a>, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043b\u044e\u0431\u044b\u043c\u0438 API \u0432 \u0441\u0432\u043e\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u201cEnable APIs and services\u201d.&nbsp;<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c API \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u0430\u0445\u043e\u0434\u0438\u043c Cloud Tool Result API \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c.<\/p>\n<p>\u041d\u0443 \u0442\u0435\u043f\u0435\u0440\u044c-\u0442\u043e \u0443\u0436 \u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0451, \u043f\u043e\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c workflow.<\/p>\n<pre><code>name: UI_tests_on_release   on:   pull_request:     branches:       - 'main'   jobs:   assemble_ui_test_artifacts:     if: startsWith(github.head_ref, 'release\/') == true     name: Build artifacts     runs-on: ubuntu-20.04     steps:       - uses: actions\/checkout@v2       - uses: actions\/setup-java@v1         with: {java-version: 1.8}         - name: Build APK for UI test after Unit tests         run: |           .\/gradlew test           .\/gradlew assembleDebug           .\/gradlew assembleDebugAndroidTest         - name: Upload app-debug APK         uses: actions\/upload-artifact@v2         with:           name: app-debug           path: app\/build\/outputs\/apk\/debug\/app-debug.apk         - name: Upload app-debug-androidTest APK         uses: actions\/upload-artifact@v2         with:           name: app-debug-androidTest           path: app\/build\/outputs\/apk\/androidTest\/debug\/app-debug-androidTest.apk     run_ui_tests_on_firebase:     runs-on: ubuntu-20.04     needs: assemble_ui_test_artifacts     steps:       - uses: actions\/checkout@v2       - name: Download app-debug APK         uses: actions\/download-artifact@v1         with:           name: app-debug         - name: Download app-debug-androidTest APK         uses: actions\/download-artifact@v1         with:           name: app-debug-androidTest         - name: Firebase auth with gcloud         uses: google-github-actions\/setup-gcloud@master         with:           version: '290.0.1'           service_account_key: ${{ secrets.FIREBASE_KEY }}           project_id: ${{ secrets.FIREBASE_PROJECT_ID }}         - name: Run Instrumentation Tests in Firebase Test Lab         run: |           gcloud firebase test android models list           gcloud firebase test android run --type instrumentation --use-orchestrator --app app-debug\/app-debug.apk --test app-debug-androidTest\/app-debug-androidTest.apk --device model=Pixel2,version=28,locale=en,orientation=portrait<\/code><\/pre>\n<\/p>\n<p><strong>\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0443\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442<\/strong><\/p>\n<p><strong>\u0428\u0430\u0433 1<\/strong><\/p>\n<pre><code>name: UI_tests_on_release   on:   pull_request:     branches:       - 'main'   jobs:   assemble_ui_test_artifacts:     if: startsWith(github.head_ref, 'release\/') == true     name: Build artifacts     runs-on: ubuntu-20.04     steps:       - uses: actions\/checkout@v2       - uses: actions\/setup-java@v1         with: {java-version: 1.8}<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 workflow, \u0447\u0442\u043e \u0438 \u0440\u0430\u043d\u044c\u0448\u0435. Pull request \u0432 \u0432\u0435\u0442\u043a\u0443 main \u0438\u0437 \u0432\u0435\u0442\u043a\u0438, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u0430 release\/.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u0435\u043b\u0430\u0435\u043c checkout \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 Java 8.<\/p>\n<p><strong>\u0428\u0430\u0433 2<\/strong><\/p>\n<pre><code>- name: Build APK for UI test after Unit tests   run: |     .\/gradlew test     .\/gradlew assembleDebug     .\/gradlew assembleDebugAndroidTest   - name: Upload app-debug APK   uses: actions\/upload-artifact@v2   with:     name: app-debug     path: app\/build\/outputs\/apk\/debug\/app-debug.apk   - name: Upload app-debug-androidTest APK   uses: actions\/upload-artifact@v2   with:     name: app-debug-androidTest     path: app\/build\/outputs\/apk\/androidTest\/debug\/app-debug-androidTest.apk<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u043c unit-\u0442\u0435\u0441\u0442\u044b \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0434\u0432\u0430 APK &#8212; app-debug.apk \u0438 app-debug-androidTest.apk. \u041f\u043e\u0447\u0435\u043c\u0443 \u0434\u0432\u0430? \u0414\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u0438\u043d APK &#8212; \u044d\u0442\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 APK \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 instrumentation-\u0442\u0435\u0441\u0442\u044b, \u043e\u043d\u0438 \u043e\u0431\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u043e\u0441\u0442\u0430\u0451\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e \u043f\u0443\u0442\u0438 \u0438 \u0438\u043c\u0435\u043d\u0438 \u0432 upload-artifact@v2.<\/p>\n<p>\u0412\u0441\u0451 \u044d\u0442\u043e \u043c\u044b \u0443\u0436\u0435 <a href=\"https:\/\/habr.com\/ru\/company\/tuturu\/blog\/530260\/\">\u0434\u0435\u043b\u0430\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435<\/a>, \u043a\u043e\u0433\u0434\u0430 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 APK \u043a \u0440\u0435\u043b\u0438\u0437\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p><strong>\u0428\u0430\u0433 3<\/strong><\/p>\n<pre><code>run_ui_tests_on_firebase:   runs-on: ubuntu-20.04   needs: assemble_ui_test_artifacts   steps:     - uses: actions\/checkout@v2     - name: Download app-debug APK       uses: actions\/download-artifact@v1       with:         name: app-debug       - name: Download app-debug-androidTest APK       uses: actions\/download-artifact@v1       with:         name: app-debug-androidTest<\/code><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f Job \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c workflow \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 (assemble_ui_test_artifacts), \u0430 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u0442\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f.<\/p>\n<p>\u042d\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0441\u0442\u0440\u043e\u0447\u043a\u0435.<\/p>\n<pre><code>needs: assemble_ui_test_artifacts<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c action download-artifact@v1 \u0438 \u0434\u043e\u0441\u0442\u0430\u043d\u0435\u043c \u043f\u043e<\/p>\n<\/ol>\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-314294","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314294","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=314294"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314294\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=314294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=314294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=314294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}