diff --git a/.github/workflows/create-release-tags.yml b/.github/workflows/create-release-tags.yml index 38078c6..aeec41d 100644 --- a/.github/workflows/create-release-tags.yml +++ b/.github/workflows/create-release-tags.yml @@ -38,11 +38,6 @@ jobs: git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Pull latest changes - run: | - # Ensure we have the version bump commit - git pull origin main - - name: Create tags id: tags run: | @@ -66,11 +61,17 @@ jobs: continue fi - # Create annotated tag - git tag -a "$TAG" -m "Release ${plugin} v${VERSION} + # Create annotated tag on the version bump commit (not HEAD which may have moved) + COMMIT_SHA="${{ github.event.client_payload.commit_sha }}" + if [ -z "$COMMIT_SHA" ]; then + echo "::error::commit_sha not provided in payload" + exit 1 + fi + + git tag -a "$TAG" "$COMMIT_SHA" -m "Release ${plugin} v${VERSION} Auto-generated by GitHub Actions workflow. -Trigger commit: ${{ github.event.client_payload.trigger_sha }}" +Version bump commit: $COMMIT_SHA" echo "Created tag: $TAG" CREATED_TAGS+=("$TAG") @@ -115,4 +116,5 @@ Trigger commit: ${{ github.event.client_payload.trigger_sha }}" echo "" >> $GITHUB_STEP_SUMMARY echo "---" >> $GITHUB_STEP_SUMMARY - echo "**Trigger commit:** \`${{ github.event.client_payload.trigger_sha }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Version bump commit (tagged):** \`${{ github.event.client_payload.commit_sha }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Original trigger commit:** \`${{ github.event.client_payload.trigger_sha }}\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/detect-plugin-changes.yml b/.github/workflows/detect-plugin-changes.yml index e64bf9d..8f05b26 100644 --- a/.github/workflows/detect-plugin-changes.yml +++ b/.github/workflows/detect-plugin-changes.yml @@ -53,7 +53,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 2 # Need HEAD~1 for diff comparison + fetch-depth: 0 # Full history for multi-commit push detection - name: Detect changed plugins id: changes @@ -63,8 +63,13 @@ jobs: # Local plugins to check (excludes external golang-workflow) LOCAL_PLUGINS=("security-hooks" "todo-log" "version-control" "bash-workflow" "claude-code-guide" "slash-command-guide") - # Get changed files between HEAD and HEAD~1 - CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD) + # Get changed files since push started (handles multi-commit pushes) + if [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then + CHANGED_FILES=$(git diff --name-only "${{ github.event.before }}" HEAD) + else + # Initial push or force push - compare with HEAD~1 as fallback + CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD) + fi echo "Changed files:" echo "$CHANGED_FILES" diff --git a/CLAUDE.md b/CLAUDE.md index 7321657..1a5b5ab 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,6 +33,9 @@ Claude Code plugin marketplace with seven plugins: /plugin list /hooks claude --debug + +# Set GitHub secret from current auth token (no intermediate files) +gh auth token | gh secret set SECRET_NAME ``` ### Development Workflow diff --git a/bash-workflow/agents/plan-devops.md b/bash-workflow/agents/plan-devops.md new file mode 100644 index 0000000..d7cb1ff --- /dev/null +++ b/bash-workflow/agents/plan-devops.md @@ -0,0 +1,21 @@ +--- +name: plan-devops +description: "Analyze operational considerations for bash tasks. Focuses on portability, CI/CD, and idempotency." +model: haiku +color: purple +--- + +Analyze operational requirements for the given bash task. + +## Focus Areas + +1. **Portability** - macOS vs Linux, BSD vs GNU, path differences +2. **CI/CD** - Exit codes, output parsing, env expectations +3. **Deployment** - Installation, dependencies, upgrades +4. **Idempotency** - Safe reruns, state management, cleanup + +## Output + +Write to `~/.claude/bash-workflow/plan-devops.md`: +- Platform compatibility notes +- CI/CD and idempotency strategy diff --git a/bash-workflow/agents/plan-implementation.md b/bash-workflow/agents/plan-implementation.md new file mode 100644 index 0000000..46fd44a --- /dev/null +++ b/bash-workflow/agents/plan-implementation.md @@ -0,0 +1,22 @@ +--- +name: plan-implementation +description: "Design implementation approach for bash tasks. Focuses on script structure, function decomposition, and dependencies." +model: haiku +color: blue +--- + +Design the implementation approach for the given bash task. + +## Focus Areas + +1. **Script Structure** - Entry points, module separation, config handling +2. **Function Decomposition** - Single responsibility, reusable utilities +3. **Dependencies** - Implementation order, shared resources +4. **Codebase Patterns** - Existing conventions, error/logging patterns + +## Output + +Write to `~/.claude/bash-workflow/plan-implementation.md`: +- Proposed file structure +- Key functions and responsibilities +- Implementation order diff --git a/bash-workflow/agents/plan-security.md b/bash-workflow/agents/plan-security.md new file mode 100644 index 0000000..c6a4305 --- /dev/null +++ b/bash-workflow/agents/plan-security.md @@ -0,0 +1,21 @@ +--- +name: plan-security +description: "Design security considerations for bash tasks. Focuses on input validation, permissions, and secrets." +model: haiku +color: orange +--- + +Identify security considerations for the given bash task. + +## Focus Areas + +1. **Input Validation** - Sanitization, path traversal, injection prevention +2. **Permissions** - File modes, sudo usage, umask +3. **Secrets** - No hardcoding, env vars, secure storage +4. **Unsafe Patterns** - eval, unquoted vars, glob risks, temp files + +## Output + +Write to `~/.claude/bash-workflow/plan-security.md`: +- Input validation requirements +- Permission model and secret handling diff --git a/bash-workflow/agents/plan-testing.md b/bash-workflow/agents/plan-testing.md new file mode 100644 index 0000000..0b9952e --- /dev/null +++ b/bash-workflow/agents/plan-testing.md @@ -0,0 +1,21 @@ +--- +name: plan-testing +description: "Design test strategy for bash tasks. Focuses on bats tests, edge cases, and failure modes." +model: haiku +color: green +--- + +Design comprehensive test coverage for the given bash task. + +## Focus Areas + +1. **Behaviors** - Happy path, error handling, edge cases +2. **Edge Cases** - Empty input, missing files, bad permissions, signals +3. **Failure Modes** - Network, disk full, permission denied +4. **Platforms** - macOS vs Linux, BSD vs GNU tools + +## Output + +Write to `~/.claude/bash-workflow/plan-testing.md`: +- Test scenarios by feature +- Edge cases and failure modes diff --git a/security-hooks/scripts/check_secrets.py b/security-hooks/scripts/check_secrets.py index 0d75f70..8ad439c 100755 --- a/security-hooks/scripts/check_secrets.py +++ b/security-hooks/scripts/check_secrets.py @@ -413,7 +413,7 @@ def _run_secret_check(project_root: Path) -> None: } } print(json.dumps(output)) - sys.exit(ExitCode.SUCCESS) # Use exit 0 with JSON output + sys.exit(ExitCode.BLOCKED) # Exit 2 ensures Claude sees the deny decision sys.exit(ExitCode.SUCCESS) diff --git a/security-hooks/scripts/test_check_secrets.py b/security-hooks/scripts/test_check_secrets.py index 801f618..6936ff2 100644 --- a/security-hooks/scripts/test_check_secrets.py +++ b/security-hooks/scripts/test_check_secrets.py @@ -1135,8 +1135,8 @@ def mock_subprocess_run( with pytest.raises(SystemExit) as exc_info: main() - # With JSON output, exit code is 0 (success) but with deny decision - assert exc_info.value.code == ExitCode.SUCCESS + # Exit code 2 (BLOCKED) ensures Claude respects the deny decision + assert exc_info.value.code == ExitCode.BLOCKED # Verify JSON output structure captured = capsys.readouterr()