クソアプリを高速で作るためにテンプレートリポジトリを作った

4 min読了の目安(約4300字TECH技術記事

はじめに

最近「アイデアを思いついたらサクッとアプリを作ってみる」ということが多かったのでGitHubのテンプレートリポジトリ機能を使い、テンプレートとなるリポジトリを作成したのでその話をします。

iOSアプリ開発においてテンプレートリポジトリの話です。

今回のテンプレートリポジトリは以下です。

https://github.com/tomoki69386/Template-iOS

テンプレートリポジトリとは

テンプレートリポジトリとは、あるリポジトリにあるコードをそのまま新規のリポジトリとしてコピーし使用することが出来る機能です。

フォークと違う点として、ベースとなるリポジトリから複数のリポジトリを作成出来る点やコミット履歴が別になる点などがあります。

テンプレートリポジトリにおいているもの

  • application
  • fastlane
  • github/actions

application

アプリケーションターゲットとShared frameworkの2つのターゲットをおいています。

最近のアプリ開発ではWidgetやAppClipsなど本体アプリとその他のextensionでコードを共有することが必要となるケースが増えてきたのでそれ用のshared frameworkをおいています。

詳しい相関はXcodeGenのproject.ymlを見てみてください。

fastlane

証明書の管理をfastlane matchを使用しているのでその辺のコードがあります。

あとはアプリのバージョンのインクリメントなどを行うlaneをfastfileに定義しています。

# アプリのバージョンを日付ベースにするためのlane
# 例) 2020.12.31
lane :upgrade_version do 
  today = Date.today
  shortVersionString = "#{today.year}.#{today.month}.#{today.day}"

  set_info_plist_value(
    path: './App/Resources/Info.plist',
    key: 'CFBundleShortVersionString',
    value: shortVersionString
  )

  set_info_plist_value(
    path: './Shared/Info.plist',
    key: 'CFBundleShortVersionString',
    value: shortVersionString
  )
end

# build numberをインクリメントするためのlane
lane :increment do 
  build_number = get_info_plist_value(
    path: './App/Resources/Info.plist',
    key: 'CFBundleVersion'
  ).to_i

  build_number += 1

  set_info_plist_value(
    path: './App/Resources/Info.plist',
    key: 'CFBundleVersion',
    value: "#{build_number}"
  )

  set_info_plist_value(
    path: './Shared/Info.plist',
    key: 'CFBundleVersion',
    value: "#{build_number}"
  )
end

github/actions

GitHubActionsではlintとapplication、shared frameworkのtestを実行しています。

name: CI

on:
  pull_request:
    paths:
      - '.github/workflows/lint.yml'
      - '.swiftlint.yml'
      - '**/*.swift'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: GitHub Action for SwiftLint
        uses: norio-nomura/action-swiftlint@3.1.0
      - name: GitHub Action for SwiftLint with --strict
        uses: norio-nomura/action-swiftlint@3.1.0
        with:
          args: --force-exclude
      - name: GitHub Action for SwiftLint (Only files changed in the PR)
        uses: norio-nomura/action-swiftlint@3.1.0
        env:
          DIFF_BASE: ${{ github.base_ref }}
name: CI

on:
  push:
    paths-ignore:
      - Docs/**
      - README.md

env:
  DEVELOPER_DIR: /Applications/Xcode_11.6.app/Contents/Developer

jobs:
  test-application:
    runs-on: macOS-latest
    env:
      MINT_PATH: mint/lib
      MINT_LINK_PATH: mint/bin

    steps:
    - uses: actions/checkout@v2

    - name: Install Mint
      run: brew install mint

    - name: Cache Mint packages
      uses: actions/cache@v2
      with:
        path: mint
        key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
        restore-keys: |
          ${{ runner.os }}-mint-
    - name: Generate Xcode project with XcodeGen
      run: mint run xcodegen xcodegen generate

    - name: application test
      run: |
        set -o pipefail
        xcodebuild build-for-testing test-without-building -project App.xcodeproj -scheme AppTests -configuration Debug -sdk iphonesimulator -destination "name=iPhone 8" ENABLE_TESTABILITY=YES | xcpretty -c
    - name: codecov
      run: bash <(curl -s https://codecov.io/bash)
      if: success()
  
  test-shared:
    runs-on: macOS-latest
    env:
      MINT_PATH: mint/lib
      MINT_LINK_PATH: mint/bin

    steps:
    - uses: actions/checkout@v2

    - name: Install Mint
      run: brew install mint

    - name: Cache Mint packages
      uses: actions/cache@v2
      with:
        path: mint
        key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
        restore-keys: |
          ${{ runner.os }}-mint-
    - name: Generate Xcode project with XcodeGen
      run: mint run xcodegen xcodegen generate

    - name: Shared framework test
      run: |
        set -o pipefail
        xcodebuild build-for-testing test-without-building -project App.xcodeproj -scheme SharedTests -configuration Debug -sdk iphonesimulator -destination "name=iPhone 8" ENABLE_TESTABILITY=YES | xcpretty -c
    - name: codecov
      run: bash <(curl -s https://codecov.io/bash)
      if: success()