アプリ開発難しい
アプリ開発
よく外の食事をしたときに画像を挙げているのはフォロワーさんなら知ってると思いますが、各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を導入してみました。
オープンソースのツールで、各種AIベンダのAPIを利用してレビューをしてくれます。
同種のツールにGitHub Copliotのreviewがありますが、あれは一部の言語しか対応しておらず、非対応のファイルは見てくれません。(もちろんDartは現時点未対応)
もしくはコードラビットというAIレビューサービスもあります。


今回は最終的に仕事でも使えそうな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は除外するようにしています。
モデルは以下から選べます。
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で鍵ファイルを生成し、同じ鍵で使いまわしてビルドすることよい(というか最終的にデフォになる)らしいです。(結構そこに気付くのに時間をかけてしまった)
参考













コメント