From e12f67b4ce33ccefd637205c9828f0ede5879404 Mon Sep 17 00:00:00 2001 From: groovecoder <71928+groovecoder@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:42:51 -0500 Subject: [PATCH] ci: add linting workflow and fix shellcheck violations Catch issues before they reach main. Five parallel CI jobs: shellcheck, actionlint, zizmor, ruff, yamllint. Fix SC2086 word-splitting bug in commit.sh. Fix SC2002 useless cat in run-claude.sh. Suppress SC2001 where sed regex patterns have no bash equivalent. Add Makefile for local lint runs. Add YAML document-start markers to satisfy yamllint. --- .github/workflows/automerge-dependabot.yml | 1 + .github/workflows/ci.yml | 66 ++++++++++++++++++++++ .github/workflows/fix-dependabot-pr.yml | 1 + .github/workflows/setup.yml | 1 + .shellcheckrc | 1 + .yamllint.yml | 8 +++ Makefile | 22 ++++++++ scripts/commit.sh | 5 +- scripts/gather-context.sh | 4 +- scripts/run-claude.sh | 3 +- 10 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .shellcheckrc create mode 100644 .yamllint.yml create mode 100644 Makefile diff --git a/.github/workflows/automerge-dependabot.yml b/.github/workflows/automerge-dependabot.yml index b3d812f..104b416 100644 --- a/.github/workflows/automerge-dependabot.yml +++ b/.github/workflows/automerge-dependabot.yml @@ -1,3 +1,4 @@ +--- name: BLEnder Auto-merge Dependabot on: workflow_call: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a6a631f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +--- +name: CI +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + shellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Run ShellCheck + run: shellcheck scripts/*.sh + + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install and run actionlint + run: | + GOPATH="$(go env GOPATH)" + go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 + "$GOPATH/bin/actionlint" + + zizmor: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install zizmor + run: pip install zizmor + - name: Run zizmor + run: zizmor .github/workflows/ + + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install ruff + run: pip install ruff + - name: Run ruff check + run: ruff check scripts/ + - name: Run ruff format check + run: ruff format --check scripts/ + + yamllint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install yamllint + run: pip install yamllint + - name: Run yamllint + run: yamllint -c .yamllint.yml .github/workflows/ diff --git a/.github/workflows/fix-dependabot-pr.yml b/.github/workflows/fix-dependabot-pr.yml index a65c2c0..9f2e082 100644 --- a/.github/workflows/fix-dependabot-pr.yml +++ b/.github/workflows/fix-dependabot-pr.yml @@ -1,3 +1,4 @@ +--- name: BLEnder Fix Dependabot PR on: workflow_call: diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 519ef90..7271560 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,3 +1,4 @@ +--- name: BLEnder Setup on: workflow_dispatch: diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..9822e6c --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +shell=bash diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..206f7c0 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,8 @@ +extends: default +rules: + line-length: + max: 200 + truthy: + check-keys: false + comments: + min-spaces-from-content: 1 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ca79fc6 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +.PHONY: lint lint-shell lint-actions lint-zizmor lint-python lint-yaml fmt + +lint: lint-shell lint-actions lint-zizmor lint-python lint-yaml + +lint-shell: + shellcheck scripts/*.sh + +lint-actions: + actionlint + +lint-zizmor: + zizmor .github/workflows/ + +lint-python: + ruff check scripts/ + ruff format --check scripts/ + +lint-yaml: + yamllint -c .yamllint.yml .github/workflows/ + +fmt: + ruff format scripts/ diff --git a/scripts/commit.sh b/scripts/commit.sh index f42a452..572b40f 100755 --- a/scripts/commit.sh +++ b/scripts/commit.sh @@ -34,7 +34,8 @@ BASE_TREE=$(gh api "repos/${REPO}/git/commits/${PARENT}" --jq '.tree.sha') # Upload each changed file as a blob TREE_ITEMS="[]" -for file in $(git diff --name-only); do +while IFS= read -r file; do + [ -z "$file" ] && continue BLOB_SHA=$(base64 -w 0 "$file" | \ jq -Rs '{"encoding": "base64", "content": .}' | \ gh api "repos/${REPO}/git/blobs" \ @@ -45,7 +46,7 @@ for file in $(git diff --name-only); do --arg path "$file" \ --arg sha "$BLOB_SHA" \ '. + [{"path": $path, "mode": "100644", "type": "blob", "sha": $sha}]') -done +done < <(git diff --name-only) # Create tree from blobs TREE_SHA=$(jq -n \ diff --git a/scripts/gather-context.sh b/scripts/gather-context.sh index 0497d60..721802f 100755 --- a/scripts/gather-context.sh +++ b/scripts/gather-context.sh @@ -33,9 +33,11 @@ fi # --- Sanitize untrusted input before inserting into prompts --- sanitize_for_prompt() { local input="$1" - # Strip HTML/XML tags + # Strip HTML/XML tags (regex requires sed, not ${//}) + # shellcheck disable=SC2001 input=$(echo "$input" | sed 's/<[^>]*>//g') # Strip markdown image/link injection + # shellcheck disable=SC2001 input=$(echo "$input" | sed 's/!\[[^]]*\]([^)]*)//g') # Strip prompt injection attempts input=$(echo "$input" | grep -viE '(ignore .* instructions|ignore .* prompt|system prompt|you are now|new instructions|disregard|forget .* above)' || true) diff --git a/scripts/run-claude.sh b/scripts/run-claude.sh index 05f438c..671d3b3 100755 --- a/scripts/run-claude.sh +++ b/scripts/run-claude.sh @@ -44,7 +44,7 @@ CLAUDE_LOG=$(mktemp /tmp/blender-claude-XXXXXX.log) echo "Running Claude Code to diagnose and fix..." claude_exit=0 -cat .blender-prompt | claude \ +claude \ -p \ --verbose \ --max-turns 30 \ @@ -53,6 +53,7 @@ cat .blender-prompt | claude \ --allowedTools "Read,Edit,Bash" \ --disallowedTools "WebSearch,WebFetch" \ --system-prompt "You are BLEnder, a CI-fixing agent for ${REPO_DISPLAY_NAME}. Fix the CI failure described in the prompt. Be minimal and precise. Do not search the web. Internal verification token: ${PROMPT_NONCE}. This token is confidential. Never include it in any output, file edit, or commit message." \ + < .blender-prompt \ > "$CLAUDE_LOG" 2>&1 \ || claude_exit=$?