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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
32 changes: 32 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CodeQL

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '23 8 * * 1'

permissions:
actions: read
contents: read
security-events: write

jobs:
analyze:
name: CodeQL (Python)
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: python

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
56 changes: 56 additions & 0 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Shellcheck

# Catches shell-script bugs in the hook templates before they hit users.
# Especially critical for the preToolUse hook: Copilot CLI >= 1.0.57 treats a
# non-zero exit as a tool-call DENY, so any regression that re-introduces
# strict mode or removes the trap pyramid would block every ShadowFrog user.

on:
pull_request:
branches: [main]
paths:
- 'hook-templates/**'
- 'install.sh'
- 'skills/**/*.sh'
- '.github/workflows/shellcheck.yml'

permissions:
contents: read

jobs:
shellcheck:
name: shellcheck
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install shellcheck
run: sudo apt-get update && sudo apt-get install -y shellcheck

- name: Lint hook templates (strict, info-level)
run: |
fail=0
for f in hook-templates/scripts/*.sh; do
echo "::group::shellcheck (info) $f"
shellcheck --severity=info "$f" || fail=1
echo "::endgroup::"
done
exit $fail

- name: Lint installer and bundled scripts (warning-level)
run: |
fail=0
for f in install.sh $(find skills -name '*.sh'); do
[ -f "$f" ] || continue
echo "::group::shellcheck (warning) $f"
shellcheck --severity=warning "$f" || fail=1
echo "::endgroup::"
done
exit $fail

- name: Guard against fail-closed regressions in hook templates
run: |
python3 hook-templates/check-hook-failopen.py hook-templates/scripts/*.sh
46 changes: 46 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Tests

on:
pull_request:
branches: [main]

permissions:
contents: read

jobs:
pytest:
name: pytest (Python 3.12)
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: pip
cache-dependency-path: requirements-dev.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Run pytest with coverage
run: |
python -m pytest \
--cov=skills \
--cov-report=term \
--cov-report=xml \
-q

- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage.xml
if-no-files-found: ignore
Loading