Add skills for setting up local otel stack - #23
Open
djpnicholls wants to merge 4 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new Setup playbook category focused on standing up and using a local OpenTelemetry (OTel) stack for development/testing, and ensures the deploy scripts generate corresponding Claude/Copilot skill wrappers.
Changes:
- Add four new setup playbooks covering: creating a local OTel stack, discovering an existing stack, using the stack (endpoints/queries), and .NET OTel instrumentation guidance.
- Add companion scripts/configs for the local stack (Podman/Docker Compose configs, start/stop scripts, smoke test, and config validation).
- Update
deploy.sh/deploy.ps1,.contextrouting, README structure docs, and add deploy regression/idempotency tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test-deploy.sh |
New Bash deploy regression suite covering setup playbooks, wrappers, idempotency, and config validation. |
tests/test-deploy.ps1 |
New PowerShell deploy regression suite for the same setup playbook/wrapper expectations. |
tests/fixtures/assess-observability-skill.md |
Fixture to pin existing wrapper generation output for regression checking. |
README.md |
Documents the new playbooks/setup/ category and companion-script deployment behaviour. |
playbooks/setup/create-local-otel-stack.md |
Main playbook for creating/running the local OTel stack with multiple runtime scenarios. |
playbooks/setup/discover-local-otel-stack.md |
Playbook for detecting and validating whether the local stack is already running. |
playbooks/setup/use-local-otel-stack.md |
Playbook for configuring OTLP exporters and querying metrics/logs/traces from the stack. |
playbooks/setup/instrument-dotnet-otel.md |
Playbook for .NET OpenTelemetry instrumentation patterns and known pitfalls. |
playbooks/setup/create-local-otel-stack/versions.env |
Single source of truth for container image tags used by scripts/config. |
playbooks/setup/create-local-otel-stack/validate-config.sh |
CI-friendly validation of stack configs and expected invariants. |
playbooks/setup/create-local-otel-stack/test-local-otel-stack.sh |
End-to-end smoke test that starts the stack, emits telemetry, and asserts data presence. |
playbooks/setup/create-local-otel-stack/start-local-otel-stack.sh |
Podman-based start/stop/cleanup helper for the local stack. |
playbooks/setup/create-local-otel-stack/Start-LocalOtelStack.ps1 |
PowerShell analogue of the start/stop/cleanup helper (Windows-friendly). |
playbooks/setup/create-local-otel-stack/otel-collector-config.yaml |
Host-side collector config routing telemetry into Victoria* backends. |
playbooks/setup/create-local-otel-stack/otel-collector-sidecar-config.yaml |
Sidecar collector config for agent containers forwarding to host collector. |
playbooks/setup/create-local-otel-stack/otel-collector-config-compose.yaml |
Compose-network collector config using service names for backend routing. |
playbooks/setup/create-local-otel-stack/docker-compose.yaml |
Compose definition for the stack using ${IMAGE_*} substitution from versions.env. |
deploy.sh |
Generates skill wrappers for playbooks/setup/*.md with broader tool access for Claude. |
deploy.ps1 |
Adds setup to wrapper-generation categories with the same allowed-tools intent. |
core/.context/index.md |
Adds keyword routing entries for the new setup playbooks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+95
to
+109
| assert_contains() { | ||
| local test_name="$1" | ||
| local file_path="$2" | ||
| local expected="$3" | ||
|
|
||
| if grep -q "$expected" "$file_path"; then | ||
| echo " PASS: $test_name - contains '$expected'" | ||
| PASSED=$((PASSED + 1)) | ||
| return 0 | ||
| else | ||
| echo " FAIL: $test_name - missing '$expected'" | ||
| FAILED=$((FAILED + 1)) | ||
| return 1 | ||
| fi | ||
| } |
Comment on lines
+242
to
+264
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f | sort | xargs sha256sum > /tmp/tc5_run1.txt | ||
| find "$TC5_DIR" -type f -perm /111 | sort > /tmp/tc5_perms1.txt | ||
|
|
||
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f | sort | xargs sha256sum > /tmp/tc5_run2.txt | ||
| find "$TC5_DIR" -type f -perm /111 | sort > /tmp/tc5_perms2.txt | ||
|
|
||
| if diff -q /tmp/tc5_run1.txt /tmp/tc5_run2.txt >/dev/null 2>&1; then | ||
| pass "File checksums identical across both runs" | ||
| else | ||
| fail "File checksums differ between runs" | ||
| diff /tmp/tc5_run1.txt /tmp/tc5_run2.txt || true | ||
| fi | ||
|
|
||
| if diff -q /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt >/dev/null 2>&1; then | ||
| pass "Executable permissions identical across both runs" | ||
| else | ||
| fail "Executable permissions differ between runs" | ||
| diff /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt || true | ||
| fi | ||
|
|
||
| rm -rf "$TC5_DIR" /tmp/tc5_run1.txt /tmp/tc5_run2.txt /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt |
Comment on lines
+609
to
+613
| for playbook in "$SCRIPT_DIR"/playbooks/setup/*.md; do | ||
| filename=$(basename "$playbook") | ||
| generate_skills_for_selected_agents "$playbook" "setup/$filename" \ | ||
| "Read, Grep, Glob, Bash, Write, Edit, Agent" | ||
| done |
Capture regression fixture from unmodified codebase and write test suites (bash + PowerShell) covering setup/ playbook deployment, agent-scoped wrappers, idempotency, and validate-config execution. All new test cases fail (Red) as expected — setup/ content does not exist yet. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Port four OpenTelemetry operational skills from devopsin@9fa20ff0 (feature/split-telemetry-skills) into playbooks/setup/: - create-local-otel-stack.md + companion scripts/configs - discover-local-otel-stack.md - use-local-otel-stack.md - instrument-dotnet-otel.md Key changes: - New playbooks/setup/ category with keywords frontmatter - deploy.sh: setup/ loop with unrestricted Bash allowed-tools - deploy.ps1: setup entry in $playbookCategories - core/.context/index.md: setup playbook routing entries - README.md: setup/ in repository structure - docker-compose.yaml: all ports bound to 127.0.0.1 - validate-config.sh: per-port localhost binding assertions - Related Skills links updated to sibling-file format - Provenance comments and local-dev-only warnings added Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Security: - Bind Docker inline examples to 127.0.0.1 (not 0.0.0.0) in playbook docs - Bind Podman/PowerShell start scripts to 127.0.0.1 on all ports including 13133 - Add health_check extension to host and compose collector configs Documentation: - Add docker-compose -f flag pointing to docker-compose.yaml in all examples - Move provenance comments inside YAML frontmatter block (fix HTML-before-frontmatter) - Convert multi-line description: > to single-line description: "..." in all playbooks Tests: - Assert Claude wrappers contain unrestricted Bash and correct description/path - Assert Copilot wrappers omit allowed-tools: field PowerShell: - Fix Wait-ForHealth to use -ErrorAction Stop instead of *>$null Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
djpnicholls
force-pushed
the
feature/otel-skills
branch
from
July 8, 2026 10:16
d65d900 to
bb37926
Compare
Comment on lines
+14
to
+16
| # Image versions — single source of truth | ||
| # shellcheck source=versions.env | ||
| source "$SCRIPT_DIR/versions.env" |
| http: | ||
| endpoint: "0.0.0.0:4318" | ||
| cors: | ||
| allowed_origins: ["http://*", "https://*"] |
| http: | ||
| endpoint: "0.0.0.0:4318" | ||
| cors: | ||
| allowed_origins: ["http://*", "https://*"] |
Comment on lines
+242
to
+264
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f | sort | xargs sha256sum > /tmp/tc5_run1.txt | ||
| find "$TC5_DIR" -type f -perm /111 | sort > /tmp/tc5_perms1.txt | ||
|
|
||
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f | sort | xargs sha256sum > /tmp/tc5_run2.txt | ||
| find "$TC5_DIR" -type f -perm /111 | sort > /tmp/tc5_perms2.txt | ||
|
|
||
| if diff -q /tmp/tc5_run1.txt /tmp/tc5_run2.txt >/dev/null 2>&1; then | ||
| pass "File checksums identical across both runs" | ||
| else | ||
| fail "File checksums differ between runs" | ||
| diff /tmp/tc5_run1.txt /tmp/tc5_run2.txt || true | ||
| fi | ||
|
|
||
| if diff -q /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt >/dev/null 2>&1; then | ||
| pass "Executable permissions identical across both runs" | ||
| else | ||
| fail "Executable permissions differ between runs" | ||
| diff /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt || true | ||
| fi | ||
|
|
||
| rm -rf "$TC5_DIR" /tmp/tc5_run1.txt /tmp/tc5_run2.txt /tmp/tc5_perms1.txt /tmp/tc5_perms2.txt |
- validate-config.sh: remove source of versions.env (arbitrary code
execution risk in CI); the variables were unused — validation only
reads the file as text
- validate-config.sh: use grep -F -- for fixed-string matching in
assert_contains to avoid false positives from regex metacharacters
(e.g. 127.0.0.1 dot-matching any char)
- deploy.sh: wrap docs/ and setup/ skill-generation loops in
directory-existence guards, matching the PowerShell Test-Path
behaviour and preventing set -e failures on empty/missing dirs
- tests/test-deploy.sh TC5: replace fixed /tmp/tc5_*.txt paths with
mktemp files to avoid concurrent-run collisions; use find -exec
sha256sum {} + to handle filenames with whitespace
- otel-collector-config.yaml, otel-collector-config-compose.yaml:
restrict CORS allowed_origins to localhost only
(http://localhost:* and http://127.0.0.1:*) to prevent arbitrary
websites from posting telemetry to the local collector
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Comment on lines
+246
to
+252
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f -exec sha256sum {} + | sort > "$TC5_CHECKSUMS1" | ||
| find "$TC5_DIR" -type f -perm /111 | sort > "$TC5_PERMS1" | ||
|
|
||
| "$REPO_DIR/deploy.sh" --agents all --overwrite "$TC5_DIR" >/dev/null 2>&1 | ||
| find "$TC5_DIR" -type f -exec sha256sum {} + | sort > "$TC5_CHECKSUMS2" | ||
| find "$TC5_DIR" -type f -perm /111 | sort > "$TC5_PERMS2" |
Comment on lines
+60
to
+66
| if ($IsLinux -or $IsMacOS) { | ||
| if (Test-Path $Path) { | ||
| $mode = (Get-Item $Path).UnixMode | ||
| if ($mode -match 'x') { | ||
| Pass "$Label is executable" | ||
| } else { | ||
| Fail "$Label is not executable: $Path" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is useful for testing opentelemetry instrumentation.