GitHub Actions + Fastlane + Cache = 👍

這篇文章的內容主要是分享過去這兩天,我在專案上啟用 GitHub Actions 的筆記

GitHub Actions

如上面圖示所言,GitHub 現在也提供了 workflows 讓我們可以在上頭做 CI/CD,而最大的優點就是它本身即掌管程式碼的所在地,所以在 trigger 方面自然會比其他單純做 CI/CD 的服務有一些優勢。

建立方式

首先,你得在你的專案裏頭建立一個 workflows 的資料夾,其路徑得為

/.github/workflows

並在裡頭新增一個 .yml 檔案,來讓 GitHub 讀取。

yml 編輯

name: Workflow name

on:
	workflow_dispatch
	push:
		branches: [ master ]
	pull_request:
		branches: [ master ]
jobs:
	build:

	runs-on: macos-latest

	steps:
		- uses: actions/checkout@v2

		- name: Setup SSH key
		   run: |
		       mkdir -p ~/.ssh
		       echo "${{ secrets.CERTIFICATE_SSH_KEY }}" >> ~/.ssh/id_rsa
		       echo "${{ secrets.OTHER_SSH_KEY }}" >> ~/.ssh/other
			   chmod 600 ~/.ssh/id_rsa
			   chmod 600 ~/.ssh/other
			   ssh-add ~/.ssh/id_rsa
			   ssh-add ~/.ssh/other

從上述的小範例來解釋,首先第一個 name 是指 workflow 的名稱,會顯示在這

on: 的話,則是 trigger 的定義方式,像我們這邊這樣寫的話,就是當 master 有 pull request 或是 push 的話,就會執行下方的 jobs

另一個 workflow_dispatch 則是可以透過手動的方式去驅動它,並且可以在這邊加入一些 inputs,這部分的文件可以查看這邊

接著下方可以建立不同的 jobs,主要要注意的是這些 jobs 會是同時進行的,所以若是有需要同時做其他事情的話,可以建立多個 jobs 在同一個 workflows 裡頭。

這邊要考量一點是,我們是使用貴貴的 macos ⋯

所以我們的一些限制會與其他主機不同。

以這個範例來說,在執行完這個步驟之後,CI 的系統會有兩把 SSH key 可以做使用。 而我們可以將敏感的資料放在 Secrets

並在 yml 裡頭使用 ${{ secrets.VARIABLE_NAME }} 來取出並加以利用。

Cache

為了加速這個過程,我們可以將 install dependecies 的結果做成 cache,這樣我們就可以不用每次都從新安裝所有的 pods

- uses: actions/cache@v1
	id: pods-cache
	with:
	path: Pods
	key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
	restore-keys: |
	${{ runner.os }}-pods-

- name: Install Dependecies
	if: steps.pods-cache.outputs.cache-hit != 'true'
		run: |
			pod install --repo-update

所有的 cache 都可以利用上述的作法來實作,像是 bundle install 的結果也是如此。

雷坑

~/.ssh/config 無效

由於此專案有兩個不同的 private repository 需要去拉東西,而我不打算建立一組 ssh key 在帳號底下並傳到 CI 上頭共用,所以便利用了 Deploy key 的特色,建立了兩組 deploy key 並個別加入到 Secrets 之中。

原先我以為可以利用 ssh config 的設定方式,透過不同的 host 來自動選取不同的 ssh key 去做事,結果幾次下來都失敗⋯

解決方法

直接在 clone 的時候宣告使用的 ssh key 是哪一把,並將預設的 id_rsa 留給後面的 Fastlane match 使用

ssh-agent bash -c 'ssh-add ~/.ssh/other; git clone git@github.com:owner/project.git'

FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD 的設立

我寫了一個步驟來上傳打包結果到 TestFlight 上

- name: fastlane upload
        env:
          FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
        run: |
          bundle exec fastlane upload_beta --verbose

原先在本地端測試時,都可以在 ~/.zshrc 裡頭直接宣告這個變數

export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD='Your password'

並在使用 upload_to_testflight 時,都會自己拿去使用來上傳到 TestFlight 上,但在 GitHub Actions 裡頭卻始終報錯

解決方法

首先,我們先在 Fastfile 的上傳的 lane 加上目標 app 的 Apple Id

upload_to_testflight(
	apple_id: "Your app's apple ID",
	skip_waiting_for_build_processing: true,
	skip_submission: true
)

並且將原本的名稱從 FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD 改成 FASTLANE_PASSWORD,簡單來說就是使用應用程式密碼來當作你帳號的密碼登入。

便可以順利上傳了!

題外話

1 macOS minute counts as 10 regular minutes…

comments powered by Disqus