アプリ開発難しいなぁ…

開発
この記事は約14分で読めます。

アプリ開発難しい

アプリ開発

よく外の食事をしたときに画像を挙げているのはフォロワーさんなら知ってると思いますが、各SNSに投稿していることがあります。

TwitterからXになって人によってはほかの分散SNSに分散してしまいました。

そこで各種SNSあてに投稿しているわけですが、結構手間です。

X(Twitter)、Misskey.io、Bluesky、Nostrと上げていくのですが、画像とか上げていくと時間がかかります。

で、めんどいのでアプリを作ってみました。

各種SNSに投稿する、要はマルチポストするだけのアプリです。

なぜ投稿だけなのかは、ほかの投稿とか表示するとX規約類に引っ掛かりそうなので…

アプリ開発はほぼCorsorのAgentモードでAIに指示して作ってもらっている状態ですね。

Flutterというマルチプラットフォーム向けのフレームワークを使っていますが(AI君に任せる上で)困ったことはありません

AIはコーディングはclaude-3.7-sonnet-thinkingを、要件確認定義類はGPT-4.1を使っています。

アプリ公開の難易度

Webアプリとか、PCアプリならサイト公開やGitHub公開で十分ですが、スマホアプリとなると各種ストアに公開したくなります(任意)

そこで問題になるのがストアアカウントの選択です。

Google Play Store(Android)、Apple Store(iOS)ともに個人アカウントと組織アカウントを選択できます。

どちらもアプリを公開の為にアプリ申請をすることは変わりませんが、ストアに表示される開発者の表記が異なります。

個人アカウントの場合は氏名が公開されてしまうのが問題なんですよねー
(広告を含めた有料アプリなら住所も公開される)

私はリアル名を表示していないので困っちゃうんですよね。

で、企業アカウントになると企業として存在する事を証明するDNUS(ダンズ)番号なる世界でユニークになる番号を発行してもらわなければなりません。(Apple 経由であれば無料、代理企業経由なら有料)

おまけにApple的には法人格が無いと企業アカウントの申請もできないとか。

と言うわけで、ストアに公開するか悩み中…

その他のAI

コードレビューにPR-Agentを導入してみました。

Overview - Qodo Merge (and open-source PR-Agent)
None

オープンソースのツールで、各種AIベンダのAPIを利用してレビューをしてくれます。

同種のツールにGitHub Copliotのreviewがありますが、あれは一部の言語しか対応しておらず、非対応のファイルは見てくれません。(もちろんDartは現時点未対応)

もしくはコードラビットというAIレビューサービスもあります。

AI Code Reviews | CodeRabbit | Try for Free
AI-first pull request reviewer with context-aware feedback, line-by-line code suggestions, and real-time chat. AI Code R...

今回は最終的に仕事でも使えそうなPR-Agent+AWS Bedrock(Anthropic)にしました。

適応方法

以下のようなworkflowファイルを追加します。

on:
  pull_request:
    types: [opened, reopened, ready_for_review, synchronize]
  issue_comment:
jobs:
  pr_agent_job:
    if: ${{ github.event.sender.type != 'Bot' }}
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
      contents: write
    name: Run pr agent on every pull request, respond to user comments
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_ACCESS_KEY_SECRET }}
          aws-region: ${{ vars.AWS_REGION}}
      - name: PR Agent action step
        id: pragent
        uses: qodo-ai/pr-agent@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          github_action_config.auto_review: "true" # enable\disable auto review
          github_action_config.auto_describe: "true" # enable\disable auto describe
          github_action_config.auto_improve: "false" # enable\disable auto improve

次にモデルの設定などをする.pr_agent.tomlをプロジェクトのルートに追加します。

[config]
model = "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0"
ignore_pr_labels = ["renovate"]  # disable renovate bot
response_language = "ja-JP"

[pr_description]
generate_ai_title = true
final_update_message = true
extra_instructions="""\
Emphasize the following:
- Please use Japanese for everything.
- Titles should have a prefix following the commitlint pattern, such as feat:, chore:, test:, fix:, docs:, style:, refactor:, perf:, etc.
"""

[pr_reviewer]
require_tests_review = false
require_can_be_split_review = true
num_code_suggestions = 3
inline_code_comments = true
enable_auto_approval = true
maximal_review_effort = 5
extra_instructions="""\
Emphasize the following:
- Please use Japanese for everything.
"""

[pr_code_suggestions]
num_code_suggestions = 3
rank_suggestions = true
commitable_code_suggestions = true
demand_code_suggestions_self_review = true
extra_instructions="""\
Emphasize the following:
- Please use Japanese for everything.
"""

基本的にはモデルと参考にした設定ぐらいですね(日本語で答えてもらう)。一部のPRは除外するようにしています。

モデルは以下から選べます。

Rate limit · GitHub

AWS アクセスキー

事前にユーザーグループを作成します。

許可ポリシーに以下の様になるように設定してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "bedrock:InvokeModel",
            "Resource": "*"
        }
    ]
}

設定内容はbedrockでモデルの実行を許可するだけでOKです。

あとはユーザーを追加して、グループに追加し、アクセスキーとシークレットを取得するだけです。

aws-actions/configure-aws-credentialsで設定してあげればbedrock経由で接続できるようになります。

その他のベンダの場合はenvでベンダのAPIキーを設定してあげてください。

注意事項とか

aws-actions/configure-aws-credentialsでは複数の認証方法があります。今回はアクセストークンですが、IAM ロール経由で一時的に取得できます。

あとちゃんと.pr_agent.tomlがマスター(メイン)ブランチに取り込まれてないとデフォルトのOpenAIのモデルが選択されます。

Claude 3.7 Sonnetについて注意があります。(あくまで聞いた話ですが)

モデル名の欄にCross-region interfaceとあります。これがやっかいらしく、指定したリージョンで動作できない場合他のリージョンに転送されるらしく、権限周りがややこしくなってしまうそうです。(未確認)

なので設定の手間も少なく、性能としてまだ十分動作するClaude 3.5 Sonnet v2を選びました。

料金とか

請求がまだ使い始めたときのしかないですが

APIコールだけでそこまではしませんね。

最もPRのリクエスト自体大きくなかったのもありますが…

一応CloudWatchにトークンの使用量も転送していますがそちらも大してかかっていません。

自動デプロイとか

最初は手動でデプロイしていましたが、面倒になったので自動化しました。

次のworkflowファイルを置き、タグをpushするとビルドされます。

name: Flutter Release Build

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

jobs:
  test_and_build:
    name: Test and Build Release APK
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17.0.14'
      
      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.29.2'
          channel: 'stable'
          cache: true
      
      - name: run flutter version
        run: flutter --version
        
      - name: Create .env file
        run: |
          echo "${{ secrets.ENV_FILE }}" > .env

      - name: シークレット値のマスク
        run: |
          echo "::add-mask::${{ secrets.ANDROID_KEYSTORE_FILE }}"
          echo "::add-mask::${{ secrets.KEYSTORE_STORE_PASSWORD }}"
          echo "::add-mask::${{ secrets.KEYSTORE_KEY_PASSWORD }}"
          echo "::add-mask::${{ secrets.KEYSTORE_KEY_ALIAS }}"

      - name: キーストアファイルの復元
        run: |
          cat <<EOF | base64 --decode > android/app/release.jks
          ${{ secrets.ANDROID_KEYSTORE_FILE }}
          EOF

      - name: key.propertiesの作成
        run: |
          cat <<EOF > android/keystore.properties
          storePassword=${{ secrets.KEYSTORE_STORE_PASSWORD }}
          keyPassword=${{ secrets.KEYSTORE_KEY_PASSWORD }}
          keyAlias=${{ secrets.KEYSTORE_KEY_ALIAS }}
          storeFile=release.jks
          EOF

      - name: Get dependencies
        run: flutter pub get

      - name: Run tests
        run: flutter test
      
      - name: Get version from tag
        id: get_version
        run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
      
      - name: Build APK
        run: flutter build apk --release
      
      - name: Upload APK
        uses: actions/upload-artifact@v4
        with:
          name: app-release-${{ env.VERSION }}
          path: build/app/outputs/flutter-apk/app-release.apk
      
      - name: rename file
        run: |
          mv build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/app-release-${{ env.VERSION }}.apk

      - name: Create Release
        run: |
          gh release create ${{ github.ref_name }} --generate-notes build/app/outputs/flutter-apk/app-release-${{ env.VERSION }}.apk
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

大体はほかの人と同様です。

注意事項としてはビルド用鍵ファイル(release.jks)を設定せずともビルドできて、インストールもできます。しかしその場合、更新時に鍵の整合性が取れず競合すると出て一度アンインストールしないとインストールできません。回避するには一度keytoolで鍵ファイルを生成し、同じ鍵で使いまわしてビルドすることよい(というか最終的にデフォになる)らしいです。(結構そこに気付くのに時間をかけてしまった)

参考

PR-AgentとBedrockでGitHubのPRをAIにレビューしてもらう | DevelopersIO
PR-Agent というAIツールを導入してみた
AWSとPR-Agentを組み合わせてPRのコードレビュー自動化を試してみた。
モデルとしてAmazon Bedrock のClaude 3 Haikuモデルを利用してみた
Github - Qodo Merge (and open-source PR-Agent)
None
Build and release an Android app
How to prepare for and release an Android app to the Play store.
FlutterでAndroidのリリース用APKをビルドする前の準備いろいろ - Qiita
そろそろリリースビルドが近づいてきたので、いろいろ準備をしました。その覚え書きです。iOS版は開発者アカウントの承認が進んでいないのでいったん保留です(汗)環境などFlutter SDKは、…

Flutter開発環境をDockerで構築し、Androidアプリを実行する方法(Mac/Windows) - Qiita
モチベーションFlutter開発において、開発環境構築は意外と手間がかかります。特に、macOSとWindowsで開発環境を統一したい場合、それぞれのOSに合わせた設定が必要となり、煩雑になりがち…

 

コメント