欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Android的自動化構建及發(fā)布

 更新時間:2017年06月05日 14:10:29   作者:貌似掉線  
本篇文章主要介紹了Android的自動化構建及發(fā)布,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

在一個App從開發(fā)到測試的過程中,我有很長一段時間都是這樣做的:打包,上傳到tower,在tower上編寫本次更新說明,通知測試。一般情況下,打包及上傳的過程大概也就2分鐘。除此之外,由于項目代碼有作混淆,并且使用了bugly,因此在發(fā)出每個版本之后還需要將混淆的mapping.txt傳到bugly上。當日復一日,并且有時還遇到網(wǎng)絡較差的情況時,這種人工手動的工作方式就很影響工作效率及心情了。因此,自動化構建及發(fā)布就成了必須掌握的技能了。

本篇分享的是我在Android自動化構建的一些經(jīng)驗,涉及到的工具及網(wǎng)站如下:

- Gradle
- fir.im
- Gitlab
- gitlab-ci-multi-runner

所述內容包含:
- 使用Gradle自動構建并發(fā)布到fir
- 使用Gitlab-CI,在提交時自動化構建并發(fā)布到fir
- 在服務器配置Docker版的gitlab-ci-multi-runner
- 多flavor時,在fir上同時發(fā)布的解決方案

Gradle及fir帶來的解放生產力

構建并上傳apk到fir

我接觸fir.im的時間比較早,那時官方就已經(jīng)提供了一個命令行打包并上傳的工具fir-cli。但是有兩個問題是我難以忍受的:

1. 它需要安裝,并且由于使用ruby編寫,所以還需要ruby環(huán)境

2. 它會構建所有flavor的版本,雖然最后只上傳一個(該問題后來已經(jīng)解決)

于是,在發(fā)現(xiàn)它有提供API之后,我查閱了下Gradle的文檔,自己寫了一個簡單的fir發(fā)布插件——fir-publish。
這個插件很小很輕,沒有使用額外依賴庫,網(wǎng)絡請求使用的也是Gradle本身就有的http-client的API。使用方式如下:
首先在根項目的build.gradle中加入以下依賴:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.githang:fir:0.1.6'
  }
}

然后在app里的build.gradle文件末尾加入以下配置:

apply plugin: 'fir'
fir {
  apiToken //fir.im上的API token
  bundleId android.defaultConfig.applicationId
  flavor "Test" (如果沒有productFlavor,可不配置此項),僅在上傳apk時需要
  appName 你的應用名稱,僅在上傳apk時需要
  icon 應用圖標路徑,僅在上傳圖標時需要
  changeLog "更新日志" // 或者使用 file("日志文件路徑")
}

其中的API token在你登錄fir之后,點擊自己的賬號就可以獲取。

該插件向你的project添加以下4個任務:

- firCert 獲取上傳憑證
- firIcon 上傳圖標,依賴于firCert
- firApk 上傳APK,依賴于firCert及assembleRelease(或assembleFlavorRelease)
- firAll 上傳圖標及APK,依賴于firIcon及firApk

在上面的配置中,更新日志可以直接寫在上面,也可以單獨創(chuàng)建一個更新日志的文件(推薦),每次要發(fā)布時只需要修改這個文件上的更新日志,然后執(zhí)行以下命令即可自動構建并發(fā)布到fir:

./gradlew firAll

注:windows用戶在前面不需要加./

這樣,我們只需要讓測試人員關注fir上的更新動態(tài)即可,而不必自己去等待構建完成再上傳然后等待上傳完成再去寫更新日志。

構建時上傳mapping.txt到bugly

關于自動上傳mapping.txt到bugly的問題,其實bugly本身已有提供相關的Gradle插件bugly。但是它會在每次構建Release版本中都執(zhí)行上傳mapping.txt,而通常我們只是在最終打包版本給測試的時候才需要,所以我修改了一下配置:

def isPublish = hasProperty("publish")
bugly {
  appId = '你的appId'
  appKey = '你的appKey' 
  execute = isPublish 
  upload = isPublish
}

在這里新增加了一個變量 ,僅在有publish屬性時才執(zhí)行上傳的命令,這個屬性在執(zhí)行的時候帶入,因此我們打包并發(fā)布的命令將進一步演變?yōu)槿缦拢?/p>

./gradlew firApk -Ppublish

Gitlab-CI帶來的進一步解放

在上面的過程中,其實我們解決的最大問題是把構建——發(fā)布——編寫版本更新日志這三個步驟合成一步,少去了中間過程的等待,但是結果還是我們要在每次需要時去手動執(zhí)行這一步。
CI類的服務能夠讓我們把代碼推送到服務器上時即可開始構建,使得我們的整個構建過程達到真正的自動化,而不用人工參與。

由于公司使用的是Gitlab,所以這里只談Gitlab-CI相關的內容。

新版的Gitlab CI中使用的是gitlab-ci-multi-runner,關于它的安裝可以到參考其官方文檔,這里不再贅述。

需要注意一點的是,在安裝之后進行注冊時,如果你是想注冊為共享runner(所有項目都可使用),那么第一個問題的地址應該是你們公司gitlab的地址,第二個問題的token在管理員界面的runner配置中可以看到。如果是想注冊為私有的runner,則其url與token在項目的設置中可以看到。

接下來,只需要在我們的項目的根目錄中添加一個.gitlab-ci.yml文件,并在其中進行CI配置,然后提交并推送到我們的gitlab上即可。

還是以我這里的公司項目為例。項目采用Git-flow流程進行開發(fā),在要發(fā)布時會創(chuàng)建release分支,因此需要發(fā)布到fir上給測試人員的是release分支及tag上的代碼,其他分支的代碼我們只需要進行構建測試就可以了。在我們公司的項目中,有開發(fā)環(huán)境 、測試環(huán)境及生產環(huán)境,分別對應三個productFlavor:Develop, Test,Official,它們之間只有API的地址不同。因此,構建測試使用其中一個環(huán)境的就可以了。

所以腳本如下:

before_script:
 - chmod +x ./gradlew

compileTest:
 script: "./gradlew clean aDevelopDebug"
 except:
  - /^release.*$/
  - tags

publishToFir:
 script: "./gradlew clean firApk -Ppublish"
 type: deploy
 only:
  - /^release.*$/
  - tags

在這里,我定義了兩個ci任務,分別是compileTest以及publishToFir。script表示該任務所執(zhí)行的命令。except表示不對哪些分支進行構建。使用git-flow流程時,將發(fā)布的分支都是以release/xxx來命名,所以這里用正則來表示。only表示僅對哪些分支執(zhí)行這個構建任務。type表示任務的類型。

將配置提交,然后推送到Gitlab上,就能夠觸發(fā)CI去執(zhí)行我們所定義的構建任務了。如果你成功了配置了Gitlab上的郵箱發(fā)送服務,那么我們就可以不用主動去關心這個結果,因為如果構建失敗了,Gitlab將會向我們發(fā)送郵件通知。

如果你不想使用docker來運行runner,可跳過下面這一節(jié)。

如果你也不需要同時在fir上發(fā)布不同flavor的APK,那么后面的也不用看了。

更高級的Docker版的CI Runner

上面雖然使用了gitlab-ci-multi-runner來完成自動化,但是它是在我本機上跑的。每次編譯時占用的內存及CPU會對開發(fā)略有影響,并且還需要我在每次開機后開個終端運行一下這個runner。公司內部是有一臺Ubuntu服務器專門用于代碼及項目相目的服務的,如果把我們的runner部署到這臺服務器上那就更好了。

公司的這臺服務器安裝了Docker,其他的服務都是以docker形式運行的。既然這樣,我也遵守規(guī)則用docker部署上runner吧。
向公司的技術大伽問來內部服務器的管理員賬號,又翻了一遍《Docker — 從入門到實踐》的PDF,然后就開始寫Dockerfile并在自己電腦上試驗了。

在踩了ubuntu版本安裝不了JDK8、掛載Android SDK目錄、沒有32位動態(tài)庫導致Android SDK執(zhí)行不了,以及中文亂碼等坑之后,目前我的Dockerfile如下:

FROM ubuntu:15.04

MAINTAINER HuangHaohang <msdx.android@qq.com>

ENV ANDROID_HOME /android-sdk

RUN apt update && apt install -y openjdk-8-jdk curl

#如果遇到android-sdk里的命令無法執(zhí)行,則需要安裝32位的動態(tài)鏈接庫。
RUN apt install -y libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5 lib32z1

RUN curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | bash
RUN apt-get install -y gitlab-ci-multi-runner

# Ensure UTF-8 locale
#COPY locale /etc/default/locale
RUN locale-gen zh_CN.UTF-8 && \
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales
RUN locale-gen zh_CN.UTF-8
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN:zh
ENV LC_ALL zh_CN.UTF-8

注:后續(xù)如果有變化,將在我的github項目上更新,地址為:https://github.com/msdx/dockerfile/blob/master/gitlab-ci-multi-runner/Dockerfile

然后執(zhí)行docker build創(chuàng)建docker鏡像之后,運行docker時掛載上android sdk以及可讀寫的gradle緩存目錄就可以了,其他問題包括runner的注冊等可參見我這里的項目說明:https://github.com/msdx/dockerfile/tree/master/gitlab-ci-multi-runner 。由于篇幅原因,這里不作贅述。

我這里把android-sdk打包并通過ssh上傳到了服務器,然后解壓在了公司的用戶目錄的android-sdk下,并在該目錄創(chuàng)建了一個文件夾GradleUserHome,用于放Gradle的緩存,最終啟動這個docker的腳本如下:

#!/bin/bash
sudo docker run -d \
 --name gitlab-ci-multi-runner \
 --restart always \
 -v /home/irain/android-sdk:/android-sdk:ro \
 -v /home/irain/GradleUserHome:/root/.gradle:rw \
 irain/gitlab-runner:registered \
 gitlab-ci-multi-runner --debug run

fir上的小技巧——多flavor的發(fā)布方式

前面提到我們公司的項目API地址是有分多個環(huán)境的(開發(fā)環(huán)境、測試環(huán)境以及生產環(huán)境)。本來我只需要打包測試環(huán)境的給測試人員用,生產環(huán)境在最終要發(fā)布的時候再自己打包。但是在這次新版本的開發(fā)中,服務端的人員也希望我能夠打包開發(fā)環(huán)境的Apk給他,這樣有時候他也可以自測一下。由于項目正在開發(fā)中,版本變化較快,所以我也想到通過自動構建發(fā)布到fir上,再由他自己去下載,這樣就可保證他可以獲得最新開發(fā)的版本。

然而,相當沮喪的一點是,fir上并不支持同一個應用多環(huán)境的發(fā)布,雖然這個需求在一年以前就有其他人提出。我問了客服,客服的建議是換一個bundleId(applicationId),當然這是不可能的,因為我們的應用使用到了高德地圖、微信分享及各種支付等許多和applicationId關聯(lián)的SDK,不可能重新部署一套。最后查看其他人分享的一個實現(xiàn)技巧。

首先,你需要在fir上注冊一個號(當然你也可以請你同事幫忙),然后把你的應用上傳上去,再進入應用的權限控制,把你的大號邀請進來,這樣你的大號上就有兩個這樣的應用了,并且可以對它上傳新版本來更新。當然,如果你使用API來上傳,則不需要邀請,只需要填不同的API Token即可。所以最終,我的app的build.gradle中關于fir發(fā)布的配置如下:

def envFlavor = hasProperty("flavor") ? getProperty("flavor") : "Test"
if (envFlavor == "Develop") {
  fir {
    apiToken "小號的api token"
    bundleId android.defaultConfig.applicationId
    flavor envFlavor
    appName "XXX-開發(fā)版"
    changeLog "git show -s --format=%B HEAD".execute().text
  }
} else {
  fir {
    apiToken "大號的api token"
    bundleId android.defaultConfig.applicationId
    flavor envFlavor
    appName "XXX-測試版"
    changeLog file("./changeLog.txt")
  }
}

其中,flavor是通過定義的envFlavor來設置,而envFlavor根據(jù)執(zhí)行的時候傳入的flavor屬性的值來設置。對應的.gitlab-ci.yml也修改如下:

before_script:
 - chmod +x ./gradlew

compileTest:
 script: "./gradlew clean firApk -Ppublish -Pflavor=Develop"
 except:
  - /^release.*$/
  - tags

publishToFir:
 script: "./gradlew clean firApk -Ppublish"
 type: deploy
 only:
  - /^release.*$/
  - tags

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論