Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
".devcontainer/**",
".gitignore",
".gitattributes",
".vale/styles/Vocab/**/reject.txt",
"*.meta",
"Samples~/**",
"package-lock.json",
Expand All @@ -37,6 +38,16 @@
"words": [
"DxMessaging",
"dxmessaging",
"mtimes",
"nofilter",
"relitigate",
"DDOL",
"Reemit",
"reemit",
"unsub",
"unwaived",
"vstest",
"parameterizes",
"wallstop",
"DXMSG",
"Untargeted",
Expand Down
14 changes: 14 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"version": "2.5.7",
"resolved": "ghcr.io/devcontainers/features/common-utils@sha256:dbf431d6b42d55cde50fa1df75c7f7c3999a90cde6d73f7a7071174b3c3d0cc4",
"integrity": "sha256:dbf431d6b42d55cde50fa1df75c7f7c3999a90cde6d73f7a7071174b3c3d0cc4"
},
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "1.1.0",
"resolved": "ghcr.io/devcontainers/features/github-cli@sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671",
"integrity": "sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671"
}
}
}
6 changes: 4 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
},
"containerEnv": {
"DOTNET_CLI_TELEMETRY_OPTOUT": "1",
"DOTNET_NOLOGO": "1"
"DOTNET_NOLOGO": "1",
"NPM_CONFIG_PREFIX": "/home/vscode/.local"
},
"postCreateCommand": "(dotnet tool restore || true) && (npm install || true) && git config --global --add safe.directory ${containerWorkspaceFolder} && (tldr --update || true) && (pre-commit install --install-hooks || true)",
"postCreateCommand": "bash .devcontainer/post-create.sh",
"customizations": {
"vscode": {
"extensions": [
Expand All @@ -27,6 +28,7 @@
"GitHub.copilot",
"GitHub.copilot-chat",
"anthropic.claude-code",
"openai.chatgpt",
"streetsidesoftware.code-spell-checker",
"DavidAnson.vscode-markdownlint",
"yzhang.markdown-all-in-one"
Expand Down
99 changes: 99 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
# Post-create bootstrap for the DxMessaging devcontainer.

set -euo pipefail

BLUE='\033[0;34m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
echo -e "${GREEN}[OK]${NC} $1"
}

log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}

fail() {
echo -e "${RED}[ERROR]${NC} $1" >&2
exit 1
}

run_optional() {
local label="$1"
shift

log_info "$label"
if "$@"; then
log_success "$label completed"
else
log_warn "$label failed (continuing)"
fi
}

ensure_path_line() {
local rc_file="$1"
local path_line='export PATH="$HOME/.local/bin:$PATH"'

if [[ ! -f "$rc_file" ]]; then
return
fi

if ! grep -Fqx "$path_line" "$rc_file"; then
{
echo ""
echo "# Ensure npm user-global binaries are available"
echo "$path_line"
} >> "$rc_file"
fi
}

trap 'fail "post-create setup failed at line $LINENO"' ERR

log_info "Starting post-create setup"

mkdir -p "$HOME/.local/bin"

log_info "Configuring npm global prefix for non-root installs"
npm config set prefix "$HOME/.local"

current_prefix="$(npm config get prefix)"
if [[ "$current_prefix" != "$HOME/.local" ]]; then
fail "npm prefix is '$current_prefix', expected '$HOME/.local'"
fi
log_success "npm prefix configured: $current_prefix"

# Make codex immediately available in this session, and persist for future shells.
export PATH="$HOME/.local/bin:$PATH"
ensure_path_line "$HOME/.bashrc"
ensure_path_line "$HOME/.zshrc"

workspace_dir="${containerWorkspaceFolder:-$PWD}"

run_optional "Restoring .NET local tools" dotnet tool restore
run_optional "Installing workspace npm dependencies" npm install
run_optional "Configuring git safe.directory" git config --global --add safe.directory "$workspace_dir"
run_optional "Updating tldr cache" tldr --update
run_optional "Installing pre-commit hooks" pre-commit install --install-hooks

log_info "Installing Codex CLI"
npm install -g --prefix "$HOME/.local" @openai/codex@latest

if ! command -v codex >/dev/null 2>&1; then
fail "Codex CLI was installed but is not on PATH"
fi

codex_version="$(codex --version 2>/dev/null || true)"
if [[ -z "$codex_version" ]]; then
fail "Codex CLI did not return a version"
fi

log_success "Codex ready: $codex_version"
log_success "Post-create setup finished"
16 changes: 16 additions & 0 deletions .devcontainer/verify-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ echo ""
echo -e "${BLUE}=== .NET Tools ===${NC}"
check_tool "csharpier" "csharpier" "--version"

echo ""
echo -e "${BLUE}=== Node.js Global Tools ===${NC}"
check_tool "codex" "codex" "--version"

echo ""
echo -e "${BLUE}=== npm Configuration ===${NC}"
printf "%-20s" "npm prefix"
npm_prefix=$(npm config get prefix 2>/dev/null || echo "error")
if [ "$npm_prefix" = "$HOME/.local" ]; then
echo -e "${GREEN}✓${NC} $npm_prefix"
((PASS++))
else
echo -e "${RED}✗${NC} $npm_prefix (expected $HOME/.local)"
((FAIL++))
fi

echo ""
echo -e "${BLUE}=== Moreutils ===${NC}"
check_tool_exists "sponge" "sponge"
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/docs-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- "**/*.cs"
- "scripts/validate-docs-ascii.js"
- "scripts/validate-doc-code-patterns.js"
- "scripts/validate-docs-prose.js"
push:
branches:
- main
Expand All @@ -16,6 +17,7 @@ on:
- "**/*.cs"
- "scripts/validate-docs-ascii.js"
- "scripts/validate-doc-code-patterns.js"
- "scripts/validate-docs-prose.js"
workflow_dispatch:

concurrency:
Expand Down Expand Up @@ -65,3 +67,23 @@ jobs:

- name: Run validate-doc-code-patterns
run: node scripts/validate-doc-code-patterns.js

validate-docs-prose:
name: Validate human-prose policy
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v6
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
cache: "npm"
cache-dependency-path: package.json

- name: Run validate-docs-prose
run: node scripts/validate-docs-prose.js
89 changes: 89 additions & 0 deletions .github/workflows/hook-perf-measurement.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Hook Performance Measurement

on:
pull_request:
paths:
- ".pre-commit-config.yaml"
- "scripts/**.js"
- "scripts/measure-hook-wallclock.js"
- ".github/workflows/hook-perf-measurement.yml"
schedule:
- cron: "13 6 * * 1" # Monday 06:13 UTC; nightly was overkill for a perf gate.
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
measure:
name: Measure git hook wall-clock
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
with:
persist-credentials: false
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
cache: "npm"
cache-dependency-path: package.json

- name: Setup Python (for pre-commit)
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"

- name: Install npm dependencies
run: |
if [ -f package-lock.json ]; then
npm ci
else
npm i --no-audit --no-fund
fi

- name: Install pre-commit
run: pip install pre-commit==4.6.0

- name: Configure git user (pre-commit needs an author)
run: |
git config user.name "perf-measurement-bot"
git config user.email "perf-measurement-bot@users.noreply.github.com"

- name: Restore .NET tools
run: dotnet tool restore

- name: Diagnose .NET tool availability
run: |
dotnet --info
dotnet tool list

- name: Install pre-commit hooks
run: pre-commit install --install-hooks

- name: Warm up the hook caches (first run is always cold)
run: |
pre-commit run --hook-stage pre-commit \
--files Runtime/Core/MessageBus/MessageBus.cs >/dev/null 2>&1 || true
pre-commit run --hook-stage pre-commit \
--files .llm/skills/performance/git-hook-performance.md >/dev/null 2>&1 || true

- name: Measure wall-clock
run: node scripts/measure-hook-wallclock.js

- name: Emit JSON for downstream tooling
if: always()
run: node scripts/measure-hook-wallclock.js --json
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit-tooling-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
run: pre-commit run validate-changelog-policy --all-files

- name: Run parser script tests hook
run: pre-commit run script-parser-tests --all-files
run: pre-commit run --hook-stage pre-push script-parser-tests --all-files

- name: Diagnose managed Jest fallback environment
shell: bash
Expand Down
Loading
Loading