GitHub Copilot Workspaceを使ってみた!開発プロセスの新時代を体験
こちらは、Mavs Advent Calendar 2024 14日目の記事です🐺!
🌲🌲🌲
ハコザキです!
今回は GitHub Copilot Workspace についてご紹介します!
皆さんの周りで GitHub Copilot を使っている人はどれくらいいるでしょうか?
私の実感では、弊社では約3割のメンバーが利用しています。
私自身、GitHub Copilot を使い始めて1年ほどになりますが、
少し前から存在を知っていたGitHub Copilot Workspaceには興味を持ちながらも、まだ使ったことがありませんでした。
この記事では、GitHub Copilot Workspaceの基本的な使い方や感想をお伝えします。なお、GitHub Copilot そのものの説明は省略し、Workspace に焦点を絞って解説します。
GitHub Copilot Workspaceとは?
GitHub Copilot Workspaceとは、GitHub Copilotの新機能で、新しい統合開発環境です。
開発プロセス全体(構築、テスト、実行まで)を、Copilotとタッグを組んで進めることができます!
具体的には、プロセスを細分化したタスクに分け、それぞれを順番に対応していくイメージです。
今回は React + ViteでOpenWeather APIを使った、
簡易的なお天気情報取得アプリの静的画面実装とAPI連携部分をタスクとして進めてみます!
事前準備
要件定義
要件は以下の通りです。
# react-weather-app
## 要件定義
都市名を入力すると、その都市の現在の天気情報が参照できるアプリケーションです
### 機能要件
* 検索ボックスから都市名を入力し、ユーザーの入力値によって表示する天気を変化
* 現在の天気(気温、天候、湿度、風速など)を表示
* 温度の表示単位は摂氏(°C)
* ユーザーが無効な都市名を入力した場合、適切なエラーメッセージを表示
### 技術要件
* Reactを使用してフロントエンドを構築
* ビルドツールにはViteを使用
* 天気データの取得には [OpenWeather API](https://openweathermap.org/api)を使用
* スタイリングには Tailwind CSSを使用
* エラーハンドリングを実装し、APIエラーやネットワークエラー時に適切なメッセージを表示
### UI要件
* 検索ボックス: 都市名を入力するための検索フィールド。ユーザーの入力でリアルタイムに結果を取得
* 天気情報の表示エリア: 現在の天気(気温、天候、湿度、風速など)を表示するエリア
* エラーメッセージエリア: 無効な都市名が入力された場合やAPIエラー時にメッセージを表示するエリア
### その他
* ユーザーインターフェースはシンプルで直感的に操作できるデザイン
* モバイル、タブレット、デスクトップに対応するレスポンシブデザイン
* APIキーの管理: APIキーは環境変数で管理し、セキュリティに配慮
GitHub Copilot Workspaceはissue単位(セクション)で作業を行うため、
上記をさらに細かくする必要があります。
タスクの細分化
## 1. プロジェクトセットアップ
- Reactプロジェクトの初期セットアップ
- Reactプロジェクトの初期化
- ビルドツールにはViteを使用
- スタイリングはTailwind CSSを使う
## 2. 基本UIの構築
- 基本レイアウトとスタイルの作成
- シンプルなヘッダー、検索ボックス、天気情報表示エリアを含む基本レイアウトを作成。
- 検索ボックスコンポーネントの作成
- 都市名を入力するための検索ボックスを実装。
- 検索ボックスの入力値を管理するためのReactステートを作成。
- 天気情報表示コンポーネントの作成
- 天気情報(気温、天候、湿度、風速)を表示するためのコンポーネントを作成。
- テスト用のダミーデータを使用して表示レイアウトを確認。
## 3. API連携
- OpenWeather APIの設定
- OpenWeather APIキーを取得してプロジェクトに追加。
- `.env` ファイルを作成して、APIキーを環境変数で管理。
- 天気データ取得のためのAPIコール実装
- Fetch APIを使用して、OpenWeather APIからデータを取得する関数を作成。
- APIリクエスト時のエラーハンドリングを実装。
- ユーザー入力に基づく天気データの取得
- 検索ボックスの入力値を元にAPIコールを行い、天気データを取得。
- 天気情報表示コンポーネントに取得データを渡す。
リポジトリの作成
GitHub Copilot Workspaceは最低限リポジトリ・タスクが必要になります。
そのためリポジトリを作っておきます。
今回は、react-weather-appというリポジトリ名で進めます

リポジトリ作った後の画面からREADMEを作成し、要件定義を記述しておきます。

これで準備完了です。
実際にGitHub Copilot Workspaceを使ってみたいと思います!!!
基本的な流れを、静的実装のタスクベースで解説していきます。
基本的な流れ
起票(Create) = Copilotへの指示
まずは、どういったことして欲しいのかまとめる必要があります。 ここは指示する側である私たちがCopilotにどういったことをして欲しいのかIssueベースで作成します。

計画(Plan) = Copilotからの方針提案
続いてIssueを解決するまでの具体的な方針を考えてくれます。

訳すとこんな感じです。
トップページには、TailwindCSSのスタイリングでシンプルなヘッダー、検索ボックス、天気情報表示エリアがありますか?
現状
* いいえ、トップページにはTailwindCSSによるシンプルなヘッダー、検索ボックス、天気情報表示エリアはありません。
* src/App.tsx`にある現在のトップページには、ロゴ、「Hello world!」のヘッダ、ボタン、テキストはありますが、検索ボックスや天気情報表示エリアはありません。
* tailwind.config.js`と`src/index.css`にあるように、TailwindCSSはプロジェクト内で設定されていますが、必要な要素には適用されていません。
* src/App.tsx`の既存のレイアウトとスタイリングは、問題で指定された要件を満たしていません。
変更後の状況
* トップページにシンプルなヘッダー、検索ボックス、天気情報表示エリアをTailwindCSSスタイリングで追加しました。
* src/App.tsx`ファイルは、ヘッダー、検索ボックス、天気情報表示エリアを含むように更新されました。
* ヘッダーには 「Weather App 」というタイトルが含まれています。
* 検索ボックスでは都市名を入力できます。
* 天気情報表示エリアには、現在の天気の詳細が表示されます。
* ヘッダー、検索ボックス、および天気情報表示エリアには、TailwindCSS スタイリングが適用されています。
* ヘッダーには背景色とパディングがあります。
* 検索ボックスにはボーダー、パディング、マージンがあります。
* 天気情報表示エリアには、ボーダー、パディング、マージンがあります。
すごい…!! コードから現状の把握を行い、
どのようなことをすれば解決に繋がるのか分析し具体的にまとめてくれました。
現状、変更後の項目については変更可能で、それぞれ私たち側で軌道修正もできました。
実装(Develop) = Copilotによる実装
今回は提案のまま進めたいと思います。
続いて、実際にコードを出力してもらいます。左部分のGenerate planのところから、
Generate Codeを選択することで今回はApp.tsxに色々編集がありました。
コードベースで、追加や編集、削除、変数やファイル名の変更まで提案してくれます。
生成してくれたコードに対し、ブラウザ上で適宜修正等できるのでVSCodeなど開く必要はありません…!

レビュー(Review) = CopilotによるPR作成
問題なさそうであれば、右上のCreate Pull Requestボタンからいくつかアクションを選ぶことができます。ブランチ名も提案してくれます…!

PRのdescriptionも生成してくれるようでした!
英語の出力のため、必要に応じて日本語に訳す必要があります…!
動作検証
実際にお願いしたものを動かしてみた結果がこちらです!
ヘッダーや検索フィールドが表示され、検索ボタンをクリックするとダミーデータが表示されました。
API連携
静的なページを作る部分については問題なさそうだったため、続いて外部APIを使った動的化を行いました。
最初に生成されたのはaxiosベースのAPI通信だったため、fetch APIを使うように指示したところ
数秒で変更してくれました。レスポンスデータの動的化であったりエラーハンドリングについても最低限対応はされているようです。
出力してくれたコード
import { useState } from 'react'
import './App.css'
function App() {
const [city, setCity] = useState('')
const [weather, setWeather] = useState(null)
const [error, setError] = useState('')
const fetchWeatherData = async (city) => {
try {
const apiKey = process.env.REACT_APP_OPENWEATHER_API_KEY
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`
)
if (!response.ok) {
throw new Error('Failed to fetch weather data')
}
const data = await response.json()
setWeather({
temperature: `${data.main.temp}°C`,
condition: data.weather[0].description,
humidity: `${data.main.humidity}%`,
windSpeed: `${data.wind.speed} km/h`
})
setError('')
} catch (error) {
setError('Failed to fetch weather data. Please try again.')
setWeather(null)
}
}
const handleSearch = () => {
if (city.trim() !== '') {
fetchWeatherData(city)
} else {
setError('Please enter a city name.')
setWeather(null)
}
}
return (
<div className="container mx-auto p-4">
<header className="bg-blue-500 text-white p-4">
<h1 className="text-2xl">Weather App</h1>
</header>
<div className="my-4">
<input
type="text"
value={city}
onChange={(e) => setCity(e.target.value)}
placeholder="Enter city name"
className="border p-2 mr-2"
/>
<button onClick={handleSearch} className="bg-blue-500 text-white p-2">
Search
</button>
</div>
{error && <p className="text-red-500">{error}</p>}
{weather && (
<div className="border p-4">
<h2 className="text-xl">Weather Information</h2>
<p>Temperature: {weather.temperature}</p>
<p>Condition: {weather.condition}</p>
<p>Humidity: {weather.humidity}</p>
<p>Wind Speed: {weather.windSpeed}</p>
</div>
)}
</div>
)
}
export default App
.env、.gitignoreの設定も合わせて行ってくれました。

ふわふわした内容だと注意されます
Copilot Workspace couldn't understand the intent of your issue. Please check the automatically chosen referencese via 'View referenceses' below, and add relevant file or directory names to the issue description. Alternatively clarify the intent of the issue or try regenerating the exploration.
Copilot Workspaceは、あなたの問題の意図を理解できませんでした。以下の「View referenceses」で自動的に選択された参照先を確認し、関連するファイル名またはディレクトリ名をissueの説明に追加してください。または、issueの意図を明確にするか、探査を再生成してみてください。
このような文章が表示された場合は、タスクが遂行できないことを表しています。 どのようなことが問題になっていて、どのような状態になれば解決になるのかなど、Issueの内容をもう少し明確にする必要があります!
気になるところ
初期構築はある程度人の手で行った方が良い
現状の把握から始めるため、空リポジトリの状態だと期待するような結果が返りにくかったです。
今回は1回もコードを編集せず、環境構築からCopilotにお願いしてみたかったのですが、 バージョンが古かったりするのである程度ベース構築・ライブラリ導入くらいまでは手動で追加すると効率は良くなると思います! = 公式サイトなどのインストール手順を踏んだ方が早いです..!
おわり
今回、GitHub Copilot Workspace を使い、ReactでWebアプリケーションを作ってみました。
動くアプリケーションが生成された瞬間は率直にすごいと思いました。 普段行っている「issue 作成 → 要件定義 → 開発 → PR作成」といったプロセスを、Copilotと一緒に進める体験はとても新鮮でした。そして少し未来を感じさせるものでした。
一方で、環境構築などにはまだ課題がある部分もありましたが、
既存のリポジトリに導入する際も問題なく活用できると感じています。
生成AIとの開発経験は、今後のエンジニアにとって重要なスキルになっていくでしょう。
この新しい視点をぜひ皆さんにも体験してほしいと思います!