diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 2814ee8..5627d14 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -19,9 +19,9 @@ jobs: uses: helpers4/action/conventional-commits@main with: checkout: "true" - scopes: "angular-dev|auto-header|dotfiles-sync|essential-dev|git-absorb|package\ - -auto-install|peon-ping|shell-history-per-project|typescript-dev|vi\ - te-plus|deps|CI-CD" + scopes: "angular-dev|auto-header|dotfiles-sync|essential-dev|git-absorb|github-\ + dev|package-auto-install|peon-ping|shell-history-per-project|typesc\ + ript-dev|vite-plus|deps|CI-CD" pr-comment: "error" - name: Set status @@ -77,6 +77,10 @@ jobs: baseImage: debian:latest - features: dotfiles-sync baseImage: mcr.microsoft.com/devcontainers/base:ubuntu + - features: github-dev + baseImage: mcr.microsoft.com/devcontainers/base:debian + - features: github-dev + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu outputs: status: ${{ steps.status.outputs.status }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f7dd07a..e43e05a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -62,6 +62,12 @@ jobs: - features: peon-ping baseImage: mcr.microsoft.com/devcontainers/base:ubuntu + # github-dev - requires common-utils (curl, ca-certificates) + - features: github-dev + baseImage: mcr.microsoft.com/devcontainers/base:debian + - features: github-dev + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu + # dotfiles-sync - works on any base image - features: dotfiles-sync baseImage: debian:latest diff --git a/AGENTS.md b/AGENTS.md index 5376c77..c80bb4a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ Follow [Conventional Commits](https://www.conventionalcommits.org/) with a gitmo **Format:** `(): ` -**Scopes:** angular-dev, auto-header, dotfiles-sync, essential-dev, git-absorb, package-auto-install, peon-ping, shell-history-per-project, typescript-dev, vite-plus, CI-CD +**Scopes:** angular-dev, auto-header, dotfiles-sync, essential-dev, git-absorb, github-dev, package-auto-install, peon-ping, shell-history-per-project, typescript-dev, vite-plus, CI-CD | Emoji | Type | Description | |-------|------|-------------| @@ -109,7 +109,8 @@ devcontainer features test . # Test all | Feature | Version | Description | Dependencies | |---------|---------|-------------|--------------| -| essential-dev | 1.0.0 | Git, Copilot, Markdown, editor enhancements | — | +| essential-dev | 1.0.2 | Git visualization, editor enhancements, Markdown | — | +| github-dev | 1.0.0 | GitHub CLI (gh), Copilot, PR & Issues, Actions, RemoteHub | — | | typescript-dev | 1.0.5 | TypeScript/JS dev with import management | essential-dev | | angular-dev | 1.0.2 | Angular dev, port 4200 forwarding | — | | vite-plus | — | Vite development setup | — | diff --git a/README.md b/README.md index 067fd55..78ee34a 100644 --- a/README.md +++ b/README.md @@ -106,11 +106,10 @@ Syncs local Git, SSH, GPG, and npm configuration files into the devcontainer. Wo ### essential-dev -Core development environment with Git integration, GitHub Copilot, Markdown support, and essential editor enhancements. Perfect base for all development projects. +Core development environment with Git visualization, Markdown support, and essential editor enhancements. For GitHub tooling (gh CLI, Copilot, PR & Issues), use `github-dev`. **Key benefits:** -- Git integration with history, graph visualization, and PR support -- GitHub Copilot for AI-powered code assistance +- Git history, graph visualization, and conventional commits support - Complete Markdown support with preview and linting - Multi-cursor, code comparison, and local file history - File format support (YAML, JSON, CSV, XML, Makefile) @@ -118,9 +117,23 @@ Core development environment with Git integration, GitHub Copilot, Markdown supp [📖 Documentation](./src/essential-dev/README.md) +### github-dev + +GitHub CLI (`gh`) and GitHub VS Code extensions (Copilot, Copilot Chat, Pull Requests & Issues, GitHub Actions, RemoteHub). + +**Key benefits:** +- `gh` CLI for PRs, issues, releases, and Actions runs from the terminal +- Streamlined GitHub workflows in both the terminal and VS Code +- GitHub Copilot and Copilot Chat for AI assistance +- Pull Requests & Issues panel inside VS Code +- GitHub Actions workflow editor with validation +- RemoteHub to browse remote repos without cloning + +[📖 Documentation](./src/github-dev/README.md) + ### typescript-dev -TypeScript/JavaScript development setup with indexing, import management, HTML/CSS intelligence, and web tools. Built on top of `essential-dev` for Git, Copilot, and editor enhancements. +TypeScript/JavaScript development setup with indexing, import management, HTML/CSS intelligence, and web tools. Built on top of `essential-dev` for core Git/editor enhancements, with Copilot and PR tooling provided by `github-dev`. **Key benefits:** - Latest TypeScript with indexing and import management @@ -166,6 +179,7 @@ Features from this repository are available via GitHub Container Registry. Refer { "features": { "ghcr.io/helpers4/devcontainer/essential-dev:1": {}, + "ghcr.io/helpers4/devcontainer/github-dev:1": {}, "ghcr.io/helpers4/devcontainer/vite-plus:1": {}, "ghcr.io/helpers4/devcontainer/package-auto-install:1": {}, "ghcr.io/helpers4/devcontainer/typescript-dev:1": {}, @@ -185,7 +199,8 @@ Features from this repository are available via GitHub Container Registry. Refer | Feature | Description | Documentation | |---------|-------------|---------------| -| [essential-dev](./src/essential-dev) | Core dev environment with Git, Copilot, Markdown, and editor tools | [README](./src/essential-dev/README.md) | +| [essential-dev](./src/essential-dev) | Core dev environment with Git visualization, editor tools, and Markdown | [README](./src/essential-dev/README.md) | +| [github-dev](./src/github-dev) | gh CLI, Copilot, PR & Issues, Actions, RemoteHub | [README](./src/github-dev/README.md) | | [auto-header](./src/auto-header) | Automatic file headers with customizable templates (simple or custom) | [README](./src/auto-header/README.md) | | [vite-plus](./src/vite-plus) | Complete Vite+ toolchain with Oxc, Vitest, and VS Code integration | [README](./src/vite-plus/README.md) | | [package-auto-install](./src/package-auto-install) | Automatic package installation with corepack support for Node 24+ | [README](./src/package-auto-install/README.md) | diff --git a/src/essential-dev/devcontainer-feature.json b/src/essential-dev/devcontainer-feature.json index 81dbe46..a0ad63f 100644 --- a/src/essential-dev/devcontainer-feature.json +++ b/src/essential-dev/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "essential-dev", - "version": "1.0.1", + "version": "1.0.2", "name": "Essential Development Environment", - "description": "Core development environment with Git integration, GitHub Copilot, Markdown support, and essential editor enhancements. Perfect base for all development projects.", - "documentationURL": "https://github.com/helpers4/devcontainer/tree/main/features/essential-dev", + "description": "Core development environment with Git visualization, Markdown support, and essential editor enhancements.", + "documentationURL": "https://github.com/helpers4/devcontainer/tree/main/src/essential-dev", "customizations": { "vscode": { "extensions": [ @@ -11,12 +11,7 @@ "eamodio.gitlens", "donjayamanne.githistory", "gxl.git-graph-3", - "github.vscode-pull-request-github", - "github.vscode-github-actions", "vivaxy.vscode-conventional-commits", - // AI Assistant - "github.copilot", - "github.copilot-chat", // Editor Enhancements "cardinal90.multi-cursor-case-preserve", "moshfeu.compare-folders", diff --git a/src/essential-dev/install.sh b/src/essential-dev/install.sh index 451243a..b041801 100644 --- a/src/essential-dev/install.sh +++ b/src/essential-dev/install.sh @@ -36,9 +36,8 @@ echo "" echo "✅ essential-dev feature configured" echo "" echo "📦 VS Code extensions installed:" -echo " - Git integration (history, graph, PR support)" -echo " - GitHub Copilot AI assistance" -echo " - Markdown support with preview" +echo " - Git integration (history, graph, conventional commits)" +echo " - Markdown support with preview and linting" echo " - Editor enhancements (multi-cursor, compare, local history)" echo " - File format support (YAML, JSON, CSV, XML, Makefile)" echo "" diff --git a/src/github-dev/README.md b/src/github-dev/README.md new file mode 100644 index 0000000..4771a65 --- /dev/null +++ b/src/github-dev/README.md @@ -0,0 +1,96 @@ +# GitHub Development Environment (github-dev) + +Installs the **GitHub CLI (`gh`)** and adds the essential GitHub VS Code extensions (Copilot, Copilot Chat, Pull Requests & Issues, GitHub Actions, RemoteHub). Automatically authenticates `gh` if a token is available in the environment. + +## Usage + +```json +{ + "features": { + "ghcr.io/helpers4/devcontainer/github-dev:1": {} + } +} +``` + +Combine with `essential-dev` for a complete development environment: + +```json +{ + "features": { + "ghcr.io/helpers4/devcontainer/essential-dev:1": {}, + "ghcr.io/helpers4/devcontainer/github-dev:1": {} + } +} +``` + +## Options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `ghVersion` | string | `latest` | GitHub CLI version to install (e.g. `2.50.0` or `latest`) | + +## What Gets Installed + +### GitHub CLI (`gh`) + +Installed from [GitHub Releases](https://github.com/cli/cli/releases). Supports `x86_64`, `aarch64`, and `armv7l`. + +Common uses inside the devcontainer: + +```bash +gh auth status # Check authentication +gh pr list # List open PRs +gh pr create # Create a PR from current branch +gh pr checkout 123 # Check out a PR locally +gh issue list # List issues +gh run list # List workflow runs +gh run watch # Watch a running workflow +gh release create v1.0.0 # Create a release +gh repo clone org/repo # Clone a repository +``` + +### VS Code Extensions + +| Extension | Purpose | +|-----------|---------| +| `github.copilot` | AI code completions | +| `github.copilot-chat` | AI chat assistant | +| `github.vscode-pull-request-github` | PR and issue management inside VS Code | +| `github.vscode-github-actions` | GitHub Actions workflow editor with validation | +| `github.remotehub` | Browse remote GitHub repositories without cloning | + +## Authentication + +### Auto-auth via token (recommended) + +Set `GH_TOKEN` (or `GITHUB_TOKEN`) in your environment and `gh` will authenticate automatically on shell startup — no manual `gh auth login` needed. + +**Local / DevPod:** add to your `devcontainer.json`: + +```json +{ + "remoteEnv": { + "GH_TOKEN": "${localEnv:GH_TOKEN}" + } +} +``` + +Then set `GH_TOKEN` on your host machine (`export GH_TOKEN=ghp_...` in your shell profile). + +**GitHub Codespaces:** `GITHUB_TOKEN` is injected automatically — `gh` is authenticated with no extra configuration. + +**CI/CD:** set `GH_TOKEN` as a repository or organization secret. + +### SSH + +Use `dotfiles-sync` to bring your SSH keys into the container. + +### Manual + +```bash +gh auth login +``` + +## Version History + +- **v1.0.0**: Initial release. gh CLI, Copilot, Copilot Chat, Pull Requests & Issues, GitHub Actions, RemoteHub extensions. Auto-auth via `GH_TOKEN`/`GITHUB_TOKEN`. Extracted from `essential-dev`. diff --git a/src/github-dev/devcontainer-feature.json b/src/github-dev/devcontainer-feature.json new file mode 100644 index 0000000..83528d6 --- /dev/null +++ b/src/github-dev/devcontainer-feature.json @@ -0,0 +1,36 @@ +{ + "id": "github-dev", + "version": "1.0.0", + "name": "GitHub Development Environment", + "description": "GitHub CLI (gh) and GitHub VS Code extensions (Copilot, Copilot Chat, Pull Requests & Issues, GitHub Actions, RemoteHub). Centralizes all GitHub tooling in one feature.", + "documentationURL": "https://github.com/helpers4/devcontainer/tree/main/src/github-dev", + "options": { + "ghVersion": { + "type": "string", + "default": "latest", + "description": "GitHub CLI version to install (e.g. '2.50.0' or 'latest')" + } + }, + "customizations": { + "vscode": { + "extensions": [ + // GitHub Platform + "github.vscode-pull-request-github", + "github.vscode-github-actions", + "github.remotehub", + // AI Assistant + "github.copilot", + "github.copilot-chat" + ], + "settings": { + // GitHub Copilot + "github.copilot.enable": { + "*": true + } + } + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} diff --git a/src/github-dev/gh-auth.sh b/src/github-dev/gh-auth.sh new file mode 100644 index 0000000..035dd26 --- /dev/null +++ b/src/github-dev/gh-auth.sh @@ -0,0 +1,26 @@ +# This file is part of helpers4. +# Copyright (C) 2025 baxyz +# SPDX-License-Identifier: LGPL-3.0-or-later +# +# Auto-authenticate gh CLI if GH_TOKEN or GITHUB_TOKEN is set in the environment. +# Sourced from /etc/profile.d/ on shell startup. + +_gh_auto_auth() { + # Resolve token: prefer GH_TOKEN, fall back to GITHUB_TOKEN + local token="${GH_TOKEN:-${GITHUB_TOKEN:-}}" + + [ -z "${token}" ] && return 0 + ! command -v gh >/dev/null 2>&1 && return 0 + + # Already authenticated — skip + if gh auth status >/dev/null 2>&1; then + return 0 + fi + + echo "${token}" | gh auth login --with-token 2>/dev/null && \ + echo "github-dev: gh authenticated via token" || \ + echo "github-dev: gh auth failed (invalid token?)" +} + +_gh_auto_auth +unset -f _gh_auto_auth diff --git a/src/github-dev/install.sh b/src/github-dev/install.sh new file mode 100755 index 0000000..b77fc63 --- /dev/null +++ b/src/github-dev/install.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash + +# This file is part of helpers4. +# Copyright (C) 2025 baxyz +# SPDX-License-Identifier: LGPL-3.0-or-later +# +# Installs github-dev devcontainer feature. +# - GitHub CLI (gh) from GitHub Releases + +set -e + +GH_VERSION="${_BUILD_ARG_GHVERSION:-"${GHVERSION:-"latest"}"}" + +echo "Setting up github-dev devcontainer feature..." +echo " gh version requested: ${GH_VERSION}" +echo "" + +# ============================================================================ +# 2. Check if gh is already installed at the expected location +# ============================================================================ + +GH_INSTALLED=false + +if command -v gh >/dev/null 2>&1; then + EXISTING_VER="$(gh --version | head -1)" + if [ "${GH_VERSION}" = "latest" ]; then + echo "gh already installed (${EXISTING_VER}), skipping download" + GH_INSTALLED=true + else + EXISTING_VER_NUM="$(gh --version | head -1 | awk '{print $3}')" + if [ "${EXISTING_VER_NUM}" = "${GH_VERSION}" ]; then + echo "gh ${GH_VERSION} already installed, skipping download" + GH_INSTALLED=true + else + echo "gh ${EXISTING_VER_NUM} installed but ${GH_VERSION} requested, upgrading..." + fi + fi +fi + +# ============================================================================ +# 3. Install GitHub CLI (gh) if needed +# ============================================================================ + +if [ "${GH_INSTALLED}" = "false" ]; then + ARCH="$(uname -m)" + case "${ARCH}" in + x86_64) GH_ARCH="amd64" ;; + aarch64) GH_ARCH="arm64" ;; + armv7l) GH_ARCH="armv6" ;; + *) + echo "Unsupported architecture: ${ARCH}" + exit 1 + ;; + esac + + echo "Architecture: ${ARCH} -> ${GH_ARCH}" + + # Resolve 'latest' to an actual version number + if [ "${GH_VERSION}" = "latest" ]; then + echo "Resolving latest gh version..." + GH_VERSION="$(curl -fsSL https://api.github.com/repos/cli/cli/releases/latest \ + | grep '"tag_name"' | sed 's/.*"v\([^"]*\)".*/\1/')" + if [ -z "${GH_VERSION}" ]; then + echo "Failed to resolve latest gh version, aborting" + exit 1 + fi + echo "Latest gh version: ${GH_VERSION}" + fi + + GH_TARBALL="gh_${GH_VERSION}_linux_${GH_ARCH}.tar.gz" + GH_URL="https://github.com/cli/cli/releases/download/v${GH_VERSION}/${GH_TARBALL}" + GH_TMP="$(mktemp -d)" + + cleanup() { rm -rf "${GH_TMP}"; } + trap cleanup EXIT + + echo "Downloading gh ${GH_VERSION} (${GH_ARCH})..." + curl -fsSL "${GH_URL}" -o "${GH_TMP}/${GH_TARBALL}" + + echo "Installing gh..." + tar -xzf "${GH_TMP}/${GH_TARBALL}" -C "${GH_TMP}" + install -m 0755 "${GH_TMP}/gh_${GH_VERSION}_linux_${GH_ARCH}/bin/gh" /usr/local/bin/gh +fi + +# Ensure gh is available at /usr/local/bin even if pre-installed elsewhere +if [ ! -x /usr/local/bin/gh ] && command -v gh >/dev/null 2>&1; then + ln -sf "$(command -v gh)" /usr/local/bin/gh + echo "Symlinked $(command -v gh) -> /usr/local/bin/gh" +fi + +# Verify +if /usr/local/bin/gh --version >/dev/null 2>&1; then + echo "gh ready: $(/usr/local/bin/gh --version | head -1)" +else + echo "gh verification failed" + exit 1 +fi + +# ============================================================================ +# 3. Install gh auto-auth profile.d script +# ============================================================================ + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +install -m 0644 "${SCRIPT_DIR}/gh-auth.sh" /etc/profile.d/gh-auth.sh +echo "gh-auth.sh installed to /etc/profile.d/gh-auth.sh" + +# ============================================================================ +# Summary +# ============================================================================ + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "github-dev feature installed!" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "Installed:" +echo " $(gh --version | head -1)" +echo "" +echo "Auto-auth: set GH_TOKEN or GITHUB_TOKEN env var to authenticate gh on shell startup" +echo "" +echo "VS Code extensions (installed by devcontainer spec):" +echo " github.copilot" +echo " github.copilot-chat" +echo " github.vscode-pull-request-github" +echo " github.vscode-github-actions" +echo " github.remotehub" diff --git a/src/typescript-dev/devcontainer-feature.json b/src/typescript-dev/devcontainer-feature.json index 45ea5d0..03bb8ce 100644 --- a/src/typescript-dev/devcontainer-feature.json +++ b/src/typescript-dev/devcontainer-feature.json @@ -2,7 +2,7 @@ "id": "typescript-dev", "version": "1.0.5", "name": "TypeScript Development Environment", - "description": "TypeScript/JavaScript development setup with indexing, import management, HTML/CSS intelligence, and web tools. Requires essential-dev for Git, Copilot, and editor enhancements.", + "description": "TypeScript/JavaScript development setup with indexing, import management, HTML/CSS intelligence, and web tools. Built on top of essential-dev for core Git/editor enhancements, with Copilot and PR tooling provided by github-dev.", "documentationURL": "https://github.com/helpers4/devcontainer/tree/main/src/typescript-dev", "installsAfter": [ "ghcr.io/helpers4/devcontainer/essential-dev" diff --git a/test/github-dev/test.sh b/test/github-dev/test.sh new file mode 100755 index 0000000..18e80a2 --- /dev/null +++ b/test/github-dev/test.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Test script for github-dev feature +# Copyright (c) 2025 helpers4 +# Licensed under LGPL-3.0 - see LICENSE file for details + +set -e + +echo "Testing github-dev feature..." + +# Test 1: gh CLI is installed and executable +if command -v gh >/dev/null 2>&1; then + GH_VER="$(gh --version | head -1)" + echo "PASS: gh CLI installed: ${GH_VER}" +else + echo "FAIL: gh CLI not found" + exit 1 +fi + +# Test 2: gh is in /usr/local/bin +if [ -x /usr/local/bin/gh ]; then + echo "PASS: gh installed at /usr/local/bin/gh" +else + echo "FAIL: gh not found at /usr/local/bin/gh" + exit 1 +fi + +# Test 3: gh version is parseable (basic sanity) +GH_VERSION_NUM="$(gh --version | head -1 | awk '{print $3}')" +if [ -n "${GH_VERSION_NUM}" ]; then + echo "PASS: gh version parseable: ${GH_VERSION_NUM}" +else + echo "WARN: could not parse gh version number" +fi + +# Test 4: gh-auth.sh profile.d script is installed +if [ -f /etc/profile.d/gh-auth.sh ]; then + echo "PASS: /etc/profile.d/gh-auth.sh present" +else + echo "FAIL: /etc/profile.d/gh-auth.sh not found" + exit 1 +fi + +# Test 5: gh-auth.sh is readable (not executable — it is sourced) +if [ -r /etc/profile.d/gh-auth.sh ]; then + echo "PASS: /etc/profile.d/gh-auth.sh is readable" +else + echo "FAIL: /etc/profile.d/gh-auth.sh is not readable" + exit 1 +fi + +echo "" +echo "github-dev feature test complete!"