無料でCI/CDのパイプラインを構築したい



CI/CDを知った先に以下の問題にブチあたります。

> iosは、ビルド時間が長いため、お金がかかりやすく、CI/CDが自学自習でやりづらい。。。
> CI/CDのワークフローを勉強したい。。。
> 無料でCI/CDを実現し、個人開発に導入したい。。。

**以上な要望をGithub Actions のセルフホストランナーを使うと、無料でCI/CDを実現できます。**

実際に、モダンな自社開発企業（iosの業界を牽引しているエウレカなど）では、CI/CD分の費用削減として、用いられている。

## セルフホストランナーとは
セルフホストランナーを使用して、githubActionsが用意した仮想環境でなく、自前で用意した環境（EC2などのWebサーバーなど）で実行できる機能。
自分のMacBookでも実行できるのでjob実行の際に、料金がかからないのが利点。
何十回と実行しても、使用時間は0分で収まっており、料金は発生していない。
なので、自社開発や個人開発、github actionsの学習には重宝されると思う。

![スクリーンショット 2021-12-13 15.09.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1322570/a8321e78-30ed-6691-c5f0-d45ce5b0bba7.png)


## github上でのセルフホストランナーに必要な設定

![スクリーンショット 2021-12-06 21.32.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1322570/96041a58-abf6-0b4a-3100-466c36b0794b.png)

settings → Actions → Runners →　右上の緑のボタン「New self-hosted runner」を押下

![スクリーンショット 2021-12-06 21.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1322570/182148fe-f642-b074-c932-48a34c582c35.png)



・Runner image
macOSを選択する。

・Download
記載されているコマンドを任意のディレクトリで全て実行。

・Configure
コマンド２つとも実行する。

これでgithubの設定は完了。
以降、```./run.sh ``` でgithub actionsでのjobを監視状態にできる。


## work-flow
iosもandroidも要領は同じです。
```runs-on: self-hosted```１行加えるだけです。これで、セルフホストランナーに向き先が変わる。すごく簡単！

```
jobs: 
  build: 
    runs-on: self-hosted // 追記
```

work flowはいつもどおりに構築。
今回は、iOSで実装し、キャッシュなどを考慮せず、必要最低限の構築。

```yml
on:
  push:
    branches:
      - "main"

jobs:
  build:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v2

      # gem install
      - name: Install Bundled Gems
        run: |
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      # Select Xcode
      - name: Select Xcode
        run: sudo xcode-select -s '/Applications/Xcode_12.5.1.app/Contents/Developer'

      # pod install
      - name: Install Pods
        run: bundle exec pod install

      - name: Show Xcode version
        run: xcodebuild -version

      # build
      - name: Build
        run: xcodebuild
          -scheme ${{ secrets.DEV_SCHEME_NAME }}
          -sdk iphonesimulator
          -configuration Debug
          -workspace ${{ secrets.DEV_WORK_SPACE }}
          build

      # unit test
      - name: Run tests
        run: xcodebuild
          -scheme ${{ secrets.DEV_SCHEME_NAME }}
          -sdk iphonesimulator
          -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max'
          -workspace ${{ secrets.DEV_WORK_SPACE }}
          clean test

      # deploy
      - name: Deploy to deploygate
        env:
          USERNAME: ${{ secrets.USERNAME }}
          DEPLOYGATE_API_TOKEN: ${{ secrets.DEPLOYGATE_API_TOKEN }}
          DEPLOYGATE_USER: ${{ secrets.DEPLOYGATE_USER }}
          DEV_WORK_SPACE: ${{ secrets.DEV_WORK_SPACE }}
          DEV_SCHEME_NAME: ${{ secrets.DEV_SCHEME_NAME }}
          DEV_CONFIGURATION: ${{ secrets.DEV_CONFIGURATION }}
          DEV_EXPORT_METHOD: ${{ secrets.DEV_EXPORT_METHOD }}
        run: bundle exec fastlane deproy_deploygate
```

```
# fastlane

platform :ios do
  desc "Submit a new AdHoc Build to Deploygate"
  lane :deproy_deploygate do
    cocoapods
    gym(
      workspace: ENV["DEV_WORK_SPACE"],
      scheme: ENV["DEV_SCHEME_NAME"],
      configuration: ENV["DEV_CONFIGURATION"],
      export_method: ENV["DEV_EXPORT_METHOD"],
      clean: true,
    )
    deploygate(
      api_token: ENV["DEPLOYGATE_API_TOKEN"],
      user: ENV["DEPLOYGATE_USER"],
      message: last_git_commit[:message]
    )
  end
end

```

## 補足

### 使用制限
使用制限は余程のjobを実行しない限り、引っ掛かる項目はなさそう

> ・セルフホストランナーを使用する場合、GitHubアクションの使用にはいくつかの制限があります。これらの制限は変更される可能性があります。
>
・ワークフローの実行時間 - 各ワークフローの実行は72時間までに制限されます。 ワークフローの実行がこの制限に達すると、そのワークフローの実行はキャンセルされます。
>
・ジョブキュー時間-セルフホストランナーの各ジョブは、最大24時間キューに入れることができます。セルフホストランナーがこの制限内でジョブの実行を開始しない場合、ジョブは終了し、完了できません。
>
・APIリクエスト - リポジトリ内のすべてのアクションにわたって、1時間のうちに最大1000回のAPIリクエストを実行できます。 この制限を超えた場合、超過のAPIコールは失敗し、それによってジョブも失敗するかもしれません。
>
・Job matrix - ジョブマトリックスは、ワークフローの実行ごとに最大で256のジョブを生成できます。 この制限は、セルフホストランナーにも適用されます。
>
・Workflow run queue - リポジトリごとに10秒間隔で、500以上のワークフロー実行をキューに入れることはできません。 ワークフローの実行がこの制限に達すると、そのワークフローの実行は終了させられ、完了に失敗します。

### ・ セルフホストランナーは、プライベートリポジトリでのみ利用する
リポジトリのフォークが危険なコードをセルフホストランナーマシン上で実行できる可能性があるため。

> セルフホストランナーで実行されている信頼できないワークフローは、特にマシンがジョブ間で環境を維持している場合、マシンとネットワーク環境に重大なセキュリティリスクをもたらします。リスクには次のものがあります。
・ マシン上で実行されている悪意のあるプログラム。
・ マシンのランナーサンドボックスからの脱出。
・ マシンのネットワーク環境へのアクセスを公開します。
・ マシン上に不要または危険なデータを永続化する。

[About self-hosted runners](https://docs.github.com/ja/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security)

### ・ sudoコマンドでパスワードが聞かれる。
今回の場合、２個目のステップで以下のsudoコマンドを実行する際は、管理者権限で実行しなければいけないので、PCのパスワードを聞かれる。
手動で打ってもいいが、自動化したいので環境変数使うなどパスワードが聞かれない対策が必要

（１）sudoコマンド使用しない方法
```
  env:
    DEVELOPER_DIR: /Applications/Xcode_11.2.1.app/Contents/Developer
```

（２）sudoersファイルでsudoコマンドで変更できるユーザと実行できるコマンドを適宜編集する方法。

```run: sudo xcode-select -s '/Applications/Xcode.app/Contents/Developer'```

```sudo visudo```でsudoersファイルを編集して、以下１行を任意の箇所へ追記する。
これで、sudo code-selectにより、マシンの管理者であるときにシステムがパスワードを要求するのを防ぐことができる。

```
%admin  ALL=NOPASSWD: /usr/bin/xcode-select
```

https://wa3.i-3-i.info/word13805.html

## 参考
[Github ActionsでiOSアプリのデプロイを自動化する](https://qiita.com/hirothings/items/0cd2561dbf6c53cf470c)