From a44aefc5a026ed20523a585e60564d5a903baa03 Mon Sep 17 00:00:00 2001 From: Josh Luedeman Date: Wed, 22 Jul 2026 14:19:16 -0400 Subject: [PATCH] chore: add Copilot cloud-sandbox setup and dev container Add a GitHub Copilot cloud-sandbox setup tailored to this repo's .NET 8 + React (Vite) stack, plus a matching dev container, both pre-installing the hve-core-all Copilot CLI plugin from github.com/microsoft/hve-core. - .devcontainer/setup-hve-core.sh: shared best-effort, non-fatal, idempotent installer for the Copilot CLI + hve-core-all plugin - .github/workflows/copilot-setup-steps.yml: copilot-setup-steps job provisioning .NET 8 + Node 20, restoring deps, running the installer - .devcontainer/devcontainer.json: .NET 8 image + Node 20 / docker-in-docker / azure-cli features; postCreateCommand installs deps then the plugin Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 983c6dce-ae9e-479d-ac97-eff813fea0ad --- .devcontainer/devcontainer.json | 26 +++++++++ .devcontainer/setup-hve-core.sh | 26 +++++++++ .github/workflows/copilot-setup-steps.yml | 68 +++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100755 .devcontainer/setup-hve-core.sh create mode 100644 .github/workflows/copilot-setup-steps.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..f7a26fa --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,26 @@ +{ + "name": "Scaffold (.NET 8 + React)", + "image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "20" + }, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/azure-cli:1": {} + }, + "forwardPorts": [5062, 5173, 8080, 3000, 1433, 5432], + "postCreateCommand": "dotnet restore || true; dotnet tool restore || true; ( cd src/Scaffold.Web && npm ci ) || true; bash .devcontainer/setup-hve-core.sh || true", + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csdevkit", + "ms-dotnettools.csharp", + "dbaeumer.vscode-eslint", + "ms-azuretools.vscode-docker", + "GitHub.copilot", + "GitHub.copilot-chat" + ] + } + }, + "remoteUser": "vscode" +} diff --git a/.devcontainer/setup-hve-core.sh b/.devcontainer/setup-hve-core.sh new file mode 100755 index 0000000..f20655f --- /dev/null +++ b/.devcontainer/setup-hve-core.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# setup-hve-core.sh — install the GitHub Copilot CLI + hve-core-all plugin. +# +# Shared by the dev container (postCreateCommand) and the "Copilot Setup +# Steps" workflow. Best-effort, non-fatal, and idempotent by design: the +# cloud sandbox / dev container must still start even if any step here fails, +# so every fallible command degrades to a warning instead of aborting. +set -euo pipefail + +echo "==> Setting up GitHub Copilot CLI + hve-core-all plugin..." + +# 1. Install the Copilot CLI only if it is not already available (idempotent). +if command -v copilot >/dev/null 2>&1; then + echo " ✓ copilot CLI already installed ($(command -v copilot))" +else + npm install -g @github/copilot || echo "::warning::copilot CLI install failed" +fi + +# 2. Register the hve-core marketplace and install the plugin (non-fatal). +copilot plugin marketplace add microsoft/hve-core || echo "::warning::marketplace add failed" +copilot plugin install hve-core-all@hve-core || echo "::warning::hve-core-all install failed" + +# 3. List installed plugins for verification (never fail the script on this). +copilot plugin list || true + +echo "==> hve-core-all setup step complete." diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 0000000..72d3b57 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,68 @@ +name: Copilot Setup Steps + +# Prepares the GitHub Copilot cloud sandbox for this repository: provisions the +# .NET 8 + Node 20 toolchain, restores this repo's dependencies, and installs +# the hve-core-all Copilot CLI plugin (best-effort / non-blocking). + +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +permissions: + contents: read + +jobs: + # The job name MUST be exactly `copilot-setup-steps` for the Copilot coding + # agent to discover and run it before starting a task. + copilot-setup-steps: + name: Copilot Setup Steps + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + + - name: Set up .NET + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + with: + dotnet-version: '8.0.x' + + - name: Set up Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: src/Scaffold.Web/package-lock.json + + - name: Restore .NET dependencies + continue-on-error: true + run: | + dotnet restore + dotnet tool restore + + - name: Install frontend dependencies + continue-on-error: true + working-directory: src/Scaffold.Web + run: npm ci + + - name: Install hve-core-all plugin + continue-on-error: true + env: + GITHUB_TOKEN: ${{ github.token }} + run: bash .devcontainer/setup-hve-core.sh + + - name: Verify tools + run: | + echo "dotnet: $(dotnet --version 2>/dev/null || echo 'not available')" + echo "node: $(node --version 2>/dev/null || echo 'not available')" + echo "npm: $(npm --version 2>/dev/null || echo 'not available')" + echo "copilot: $(copilot --version 2>/dev/null || echo 'not available')" + copilot plugin list || true