diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c7ce48c..29d5bf3 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,25 +3,15 @@ # [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster ARG VARIANT="3.12-bullseye" FROM mcr.microsoft.com/vscode/devcontainers/python:1-${VARIANT} -# Set environment variables + ENV DEBIAN_FRONTEND=noninteractive -# Install system dependencies -# The base image includes a Yarn APT source with an untrusted/expired GPG key; removing it prevents `apt-get update` from failing. -RUN rm -f /etc/apt/sources.list.d/yarn.list \ - && apt-get update && apt-get install -y --no-install-recommends \ - curl \ - build-essential \ - wget \ - && apt-get clean && rm -rf /var/lib/apt/lists/* +# The base image includes a Yarn APT source with an untrusted/expired GPG key; +# removing it prevents `apt-get update` from failing. .NET is now installed via +# devcontainer features (see devcontainer.json) which are cached by Codespaces +# across rebuilds — so no wget / dotnet-install.sh needed at image-build time. +RUN rm -f /etc/apt/sources.list.d/yarn.list -# Install .NET 10 SDK -RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh \ - && chmod +x dotnet-install.sh \ - && ./dotnet-install.sh --channel 10.0 --install-dir /usr/share/dotnet \ - && rm dotnet-install.sh \ - && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet - # Define the path to the virtualenv to work with ARG VENV_PATH="/home/vscode/venv" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6220f70..089db94 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,49 +2,47 @@ // README at: https://github.com/devcontainers/templates/tree/main/src/python { "name": "Python 3", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { "dockerfile": "Dockerfile", "context": "..", "args": { - "VARIANT": "3.12-bullseye" + "VARIANT": "3.12-bullseye" } - }, - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "", - - // Configure tool-specific properties. + }, + // .NET is installed via devcontainer feature rather than wget + shell install + // in the Dockerfile. Features are cached by the Codespaces infra across + // rebuilds and are baked into prebuilt images — massive cold-start win + // for conference wifi. + "features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "10.0" + } + }, + // Pre-restore NuGet packages (Swashbuckle etc.) during container creation + // so attendees' first `dotnet run` doesn't wait on a cold restore. + "onCreateCommand": "cd /workspaces/${localWorkspaceFolderBasename}/src/csharp-app-complete && dotnet restore", "customizations": { "codespaces": { "openFiles": [ - "src/python-app/webapp/main.py", - "README.md" + "src/python-app/webapp/main.py", + "README.md" ] }, "vscode": { "settings": { - "python.defaultInterpreterPath": "/home/vscode/venv/bin/python", - "python.terminal.activateEnvInCurrentTerminal": true, - "workbench.editorAssociations": { - "*.md": "vscode.markdown.preview.editor" - } + "python.defaultInterpreterPath": "/home/vscode/venv/bin/python", + "python.terminal.activateEnvInCurrentTerminal": true, + "workbench.editorAssociations": { + "*.md": "vscode.markdown.preview.editor" + } }, "extensions": [ - "ms-python.python", - "ms-python.vscode-pylance", - "ms-dotnettools.csharp", - "ms-dotnettools.csdevkit", - "GitHub.copilot" + "ms-python.python", + "ms-python.vscode-pylance", + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit", + "GitHub.copilot" ] } } - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" } diff --git a/.github/workflows/codespaces-prebuilds.yml b/.github/workflows/codespaces-prebuilds.yml new file mode 100644 index 0000000..ea1d8c7 --- /dev/null +++ b/.github/workflows/codespaces-prebuilds.yml @@ -0,0 +1,30 @@ +name: "Codespaces Prebuilds" + +# Triggers GitHub Codespaces to build a prebuild image on push to main and +# whenever the devcontainer config changes. Prebuilt images bake the devcontainer +# features (.NET, Python deps) into a cached image, so attendees launching a +# Codespace get a warm container in ~30 seconds instead of a 5-10 minute cold +# build — critical for workshops on conference wifi. +# +# NOTE: This workflow only defines the schedule. Prebuilds must also be enabled +# in the repository Settings → Codespaces → Set up prebuild. Once enabled, this +# file ensures they refresh on the right triggers. + +on: + push: + branches: + - main + paths: + - ".devcontainer/**" + - ".github/workflows/codespaces-prebuilds.yml" + - "src/python-app/requirements.txt" + workflow_dispatch: + +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Prebuild marker + run: | + echo "Devcontainer changed — Codespaces will refresh the prebuild." + echo "Actual prebuild runs on GitHub's Codespaces infrastructure, not in this job." diff --git a/docs/en/create-csharp-scaffolding.md b/docs/en/create-csharp-scaffolding.md index bd412e1..3c55535 100644 --- a/docs/en/create-csharp-scaffolding.md +++ b/docs/en/create-csharp-scaffolding.md @@ -2,9 +2,12 @@ > *You should use GitHub Copilot in Agent Mode for this step and onwards.* -Now that you have a good understanding of the project and its tests, you can start creating the C# scaffolding. You will start by creating a special file with instructions. This file is called *Copilot Instructions* and it should live in the [.github\instructions] folder. We've pre-created an empty file for you so all that is needed is to fill it out with new instructions. +Now that you have a good understanding of the project and its tests, you can start creating the C# scaffolding. You will start by customising the repository-wide *Copilot Instructions* file, which lives at `.github/copilot-instructions.md` in the root of the repository. This file has been pre-populated with Python-focused guidance, and you will replace its contents with C#-focused instructions for the migration ahead. -For this step, open the `.github\instructions\instructions.md` file and add the following: +!!! note "`.github/copilot-instructions.md` vs `.github/instructions/`" + `.github/copilot-instructions.md` is the single repository-wide instructions file that Copilot loads for every chat in this repo. The `.github/instructions/` folder is a different mechanism — it holds multiple glob-scoped files (with `applyTo` frontmatter) that only activate when you edit matching paths. Those files are already populated and should not be edited for this step. + +For this step, open `.github/copilot-instructions.md` and **replace its entire contents** with the following: ```markdown # C# .NET 10 WebApi Migration Instructions diff --git a/docs/en/workshop-introduction.md b/docs/en/workshop-introduction.md index de982d5..45d1fe7 100644 --- a/docs/en/workshop-introduction.md +++ b/docs/en/workshop-introduction.md @@ -15,7 +15,7 @@ This workshop will guide you through a realistic migration scenario using GitHub **Why did Zava choose C# for this migration?** - Easier integration with Zava's existing C# backend and internal tooling after the acquisition, reducing integration friction and time-to-market - - First-class Azure ecosystem support (Application Insights, Azure AD integration, IaC tooling) for enterprise deployments + - First-class Azure ecosystem support (Application Insights, Microsoft Entra ID integration, IaC tooling) for enterprise deployments - Strong enterprise tooling (Visual Studio, JetBrains Rider, .NET analyzers) that improves developer productivity, debugging and refactoring at scale **Why incremental validation matters in production:** @@ -43,7 +43,7 @@ You will be working with a Python project (representing an acquired service) tha Zava enforces a set of enterprise standards for services running in production. Below are the key standards and how migrating to C#/.NET helps meet them more effectively than the current Python-based implementation: -- Security and identity: .NET has mature libraries for secure authentication/authorization (Azure AD integration, token validation, strong cryptography libraries) and a robust ecosystem of security scanning and policy enforcement tools. +- Security and identity: .NET has mature libraries for secure authentication/authorization (Microsoft Entra ID integration, token validation, strong cryptography libraries) and a robust ecosystem of security scanning and policy enforcement tools. - Observability and diagnostics: Deep integration with Application Insights, structured logging (ILogger), distributed tracing, and first-class telemetry SDKs make it easier to meet Zava's observability SLAs. - Reliability and performance: Strong concurrency primitives, the .NET runtime optimizations, and optional ahead-of-time compilation reduce latency and improve throughput for enterprise load patterns. - Maintainability and governance: Static typing, Roslyn analyzers, standardized NuGet package management, and enforced code quality checks help Zava keep a consistent, auditable codebase across teams. diff --git a/docs/ja/create-csharp-scaffolding.md b/docs/ja/create-csharp-scaffolding.md index fafe982..78df904 100644 --- a/docs/ja/create-csharp-scaffolding.md +++ b/docs/ja/create-csharp-scaffolding.md @@ -2,9 +2,12 @@ > *このステップ以降は GitHub Copilot の Agent モードを使います。* -プロジェクトとテストの全体像を把握できたら、C# プロジェクト雛形の作成に進みましょう。まず最初に、インストラクション用の特別なファイルを作成します。このファイルは *Copilot Instructions* と呼ばれ、`.github\instructions` フォルダに置きます。空のファイルがあらかじめ用意されているので、以下の指示内容を書き込むだけでOKです。 +プロジェクトとテストの全体像を把握できたら、C# プロジェクト雛形の作成に進みましょう。まず最初に、リポジトリ全体に適用される *Copilot Instructions* ファイルをカスタマイズします。このファイルはリポジトリのルートにある `.github/copilot-instructions.md` です。現在は Python に関する内容で事前設定されているので、これから行う C# 移行に向けた内容に**全体を置き換えます**。 -`.github\instructions\instructions.md` ファイルを開き、以下の内容を追記してください: +!!! note "`.github/copilot-instructions.md` と `.github/instructions/` の違い" + `.github/copilot-instructions.md` はリポジトリ全体で使われる単一の Copilot インストラクションファイルで、このリポジトリ内のすべてのチャットで自動的に読み込まれます。一方 `.github/instructions/` フォルダは別の仕組みで、`applyTo` フロントマターで指定されたパスを編集するときだけ有効になる、glob スコープ付きの複数のファイルを置くためのものです。これらのファイルは既に内容が入っており、このステップでは編集する必要はありません。 + +`.github/copilot-instructions.md` を開き、**ファイルの内容をすべて以下で置き換えてください**: ```markdown # C# .NET 10 WebApi Migration Instructions diff --git a/docs/ja/workshop-introduction.md b/docs/ja/workshop-introduction.md index acd459f..16a6b40 100644 --- a/docs/ja/workshop-introduction.md +++ b/docs/ja/workshop-introduction.md @@ -15,7 +15,7 @@ Zava は最近、Python でアプリ開発をしている企業を買収しま **Zava が C# を選んだ理由** - 買収後の既存 C# バックエンドや社内ツールとの統合が容易になり、統合コストと市場投入までの時間を短縮できる - - Azure エコシステムとの深い統合 (Application Insights・Azure AD・IaC ツール群) によりエンタープライズデプロイが確実になる + - Azure エコシステムとの深い統合 (Application Insights・Microsoft Entra ID・IaC ツール群) によりエンタープライズデプロイが確実になる - Visual Studio・JetBrains Rider・.NET アナライザーなどの豊富なツール群により、開発生産性とリファクタリング・デバッグ効率が大規模でも維持される **本番環境で段階的な検証が重要な理由** @@ -42,7 +42,7 @@ Python プロジェクト(買収したサービスを想定)を使って作 Zava は本番環境で稼働するサービスに対して、一連のエンタープライズ標準を定めています。以下の主要な標準と、C#/.NET への移行がそれぞれの標準をより効果的に満たす理由を示します。 -- セキュリティとアイデンティティ: .NET には安全な認証・認可のための成熟したライブラリ (Azure AD 統合・トークン検証・強力な暗号化ライブラリ) と堅牢なセキュリティスキャン・ポリシー適用ツールのエコシステムがある +- セキュリティとアイデンティティ: .NET には安全な認証・認可のための成熟したライブラリ (Microsoft Entra ID 統合・トークン検証・強力な暗号化ライブラリ) と堅牢なセキュリティスキャン・ポリシー適用ツールのエコシステムがある - オブザーバビリティと診断: Application Insights との深い統合・構造化ログ (ILogger)・分散トレーシング・ファーストクラスのテレメトリ SDK により、Zava のオブザーバビリティ SLA を満たしやすい - 信頼性とパフォーマンス: 強力な並行処理プリミティブ・.NET ランタイムの最適化・オプションの AOT コンパイルにより、エンタープライズ負荷パターンでのレイテンシ削減とスループット向上を実現する - 保守性とガバナンス: 静的型付け・Roslyn アナライザー・標準化された NuGet パッケージ管理・コード品質チェックの自動適用により、チーム全体で一貫した監査可能なコードベースを維持できる