📦

ちょっと`flutter build`したくなった時向けのCodespaces

2023/04/09に公開

はじめに

ちょっとだけ直してflutter buildflutter pub getしたいなぁ。そういったことありませんか?
私はあります。

余談

特にここ最近 dependabot の PR でpubspec.lockの sha256 を消してしまうので、git diffをチェックしているジョブが失敗する問題がありました。

https://github.com/KoheiKanagu/kingu_dev/pull/180/commits/517a3106d66f7ddbf55a12867ddda940bce93445

pubspec.lockに sha256 が追加されるようになったのは最近のことなので、dependabot が使っている Dart のバージョンが上がれば解決するように思います。
[pub] : Dependabot fails after upgrading flutter · Issue #6867 · dependabot/dependabot-core

が、アップデートを待ってられないので、手動でflutter pub getしてpubspec.lockを更新する必要があります。(Github Actions を使ってflutter pub getを実行する方法もあると思いますが、それはまた別のお話。)

要は対象の PR にチェックアウトしてflutter pub getやその他flutterコマンドが実行できればできればいいのです。

そんな時に Codespaces

Codespaces は.devcontainerディレクトリに設定ファイルを置くだけで VS Code のリモート開発環境が簡単に作れるので、使い捨てる環境を作るのには最適です。

https://github.com/KoheiKanagu/kingu_dev/tree/main/.devcontainer

.devcontainer/devcontainer.json
{
  "name": "kingu_dev",
  "image": "mcr.microsoft.com/vscode/devcontainers/base:debian",
  "customizations": {
    "vscode": {
      "extensions": [
        "Dart-Code.dart-code",
        "Dart-Code.flutter",
        "esbenp.prettier-vscode",
        "foxundermoon.shell-format",
        "timonwong.shellcheck",
        "redhat.vscode-yaml"
      ],
      "settings": {
        "dart.flutterSdkPath": "/home/vscode/flutter/bin"
      }
    }
  },
  "updateContentCommand": ".devcontainer/bootstrap.sh",
  "containerEnv": {
    "FLUTTER_HOME": "/home/vscode/flutter/bin"
  },
  "remoteEnv": {
    "PATH": "${containerEnv:PATH}:${containerEnv:FLUTTER_HOME}:/home/vscode/.pub-cache/bin"
  },
  "features": {
    "ghcr.io/devcontainers/features/sshd:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "remoteUser": "vscode"
}
.devcontainer/bootstrap.sh
#!/bin/bash
set -euxo pipefail

# Flutter
CHANNEL="beta" # or "stable"

TAGS=$(gh api repos/flutter/flutter/git/refs/tags --paginate | jq -r '.[].ref' | sed 's/refs\/tags\///' | grep '^[0-9].*')

## Search latest tag
if [ "$CHANNEL" = "beta" ]; then
    TARGET_TAG=$(echo "$TAGS" | grep '\.pre$' | sort -V | tail -n 1)
elif [ "$CHANNEL" = "stable" ]; then
    TARGET_TAG=$(echo "$TAGS" | grep -v '\.pre$' | sort -V | tail -n 1)
else
    echo "CHANNEL is invalid."
    exit 1
fi

## Install Flutter
if [ -d "$FLUTTER_HOME" ]; then
    git -C "$FLUTTER_HOME" checkout "$TARGET_TAG"
else
    git clone https://github.com/flutter/flutter.git --depth 1 --branch "$TARGET_TAG" "$HOME/flutter"
fi

flutter --version

flutter pub global activate melos
flutter pub global activate grinder

ざっくり解説

devcontainer.jsonで設定できる項目の詳細は Dev Container metadata reference を参照してください。

customizations.vscode.extensions

このコンテナで必要としている VS Code の Extensions を指定しています。

Flutter において必須なのはDart-Code.dart-codeDart-Code.flutterだけなので、それ以外はお好みで追加してください。

customizations.vscode.settings

このコンテナにおける VS Code の設定を指定しています。

この例では Flutter SDK のパスを指定しています。

updateContentCommand

テンプレートの作成時とそれ以降の更新時に実行されるコマンドで、この例ではbootstrap.shを実行しています。

containerEnvremoteEnv

パスを通します。

${containerEnv:FLUTTER_HOME}${containerEnv:PATH}あたりが分かりにくいですが、最終的にコンテナ内ではそれぞれ次のようになっています。

@KoheiKanagu ➜ /workspaces/kingu_dev (main) $ echo $FLUTTER_HOME
/home/vscode/flutter/bin
@KoheiKanagu ➜ /workspaces/kidney (main) $ echo $PATH
/vscode/bin/linux-x64/b3e4e68a0bc097f0ae7907b217c1119af9e03435/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/vscode/flutter/bin:/home/vscode/.pub-cache/bin:/home/vscode/.local/bin

例では/home/vscode/.pub-cache/binもパスに追加していますが、これはflutter pub global activateでインストールしたコマンドを使えるようにするためなので、必要なければ削除してください。

features

これも必須ではないので、お好みで変更してください。

おわりに

Codespaces のスペックはそこまで強くないのではないので、ビルド等は遅いです。

つよつよ 32 コアにすれば快適かもしれませんが、ガッツリ開発するならローカルの方が快適のように思います。

なお、ローカルにコンテナの実行環境がある場合は Dev Containers: Clone Repository in Container Volume... からコンテナ作れるので、そちらを使うのも手です。

GitHubで編集を提案

Discussion