From 183436e9f9874b2716b08fd29e389e150c3b15c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:09:49 +0000 Subject: [PATCH 01/15] Initial plan From ea3c406aaff718e5a201aafa5e484cd2e7b2b602 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:11:09 +0000 Subject: [PATCH 02/15] Add GitHub workflow to run shellcheck on changed scripts Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/shellcheck.yml diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 0000000..a47dfb5 --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,41 @@ +name: Shellcheck + +on: + pull_request: + paths: + - '**.sh' + +jobs: + shellcheck: + name: Run Shellcheck + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed shell scripts + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files: | + **.sh + + - name: Run shellcheck on changed files + if: steps.changed-files.outputs.any_changed == 'true' + run: | + echo "Changed shell scripts:" + echo "${{ steps.changed-files.outputs.all_changed_files }}" + echo "" + + # Run shellcheck on each changed file + for file in ${{ steps.changed-files.outputs.all_changed_files }}; do + echo "Checking $file..." + shellcheck "$file" + done + + - name: No shell scripts changed + if: steps.changed-files.outputs.any_changed == 'false' + run: echo "No shell scripts were changed in this PR" From 1324866717b8fa2207fb9b3880f615d04abfb487 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:11:37 +0000 Subject: [PATCH 03/15] Fix shellcheck workflow to properly handle filenames with spaces Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index a47dfb5..bf899b4 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -31,10 +31,10 @@ jobs: echo "" # Run shellcheck on each changed file - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do + while IFS= read -r file; do echo "Checking $file..." shellcheck "$file" - done + done <<< "${{ steps.changed-files.outputs.all_changed_files }}" - name: No shell scripts changed if: steps.changed-files.outputs.any_changed == 'false' From bb7761bbe905f91911b4c64998d1f350323d47d4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:12:38 +0000 Subject: [PATCH 04/15] Simplify shellcheck workflow and use proper iteration method Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index bf899b4..cd25a04 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -25,17 +25,15 @@ jobs: - name: Run shellcheck on changed files if: steps.changed-files.outputs.any_changed == 'true' + env: + ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | echo "Changed shell scripts:" - echo "${{ steps.changed-files.outputs.all_changed_files }}" + echo "$ALL_CHANGED_FILES" echo "" # Run shellcheck on each changed file - while IFS= read -r file; do + for file in $ALL_CHANGED_FILES; do echo "Checking $file..." shellcheck "$file" - done <<< "${{ steps.changed-files.outputs.all_changed_files }}" - - - name: No shell scripts changed - if: steps.changed-files.outputs.any_changed == 'false' - run: echo "No shell scripts were changed in this PR" + done From b5b7ad7a70c2679629e6c17fbfb5f211de2e7e71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:13:18 +0000 Subject: [PATCH 05/15] Use newline separator to properly handle filenames with spaces Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index cd25a04..8db2304 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -22,6 +22,7 @@ jobs: with: files: | **.sh + separator: '\n' - name: Run shellcheck on changed files if: steps.changed-files.outputs.any_changed == 'true' @@ -32,8 +33,10 @@ jobs: echo "$ALL_CHANGED_FILES" echo "" - # Run shellcheck on each changed file - for file in $ALL_CHANGED_FILES; do - echo "Checking $file..." - shellcheck "$file" - done + # Run shellcheck on each changed file (newline-separated) + while IFS= read -r file; do + if [ -n "$file" ]; then + echo "Checking $file..." + shellcheck "$file" + fi + done <<< "$ALL_CHANGED_FILES" From c497173ed31f1a61da9537d871f71d31e3517918 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:14:07 +0000 Subject: [PATCH 06/15] Add explicit permissions to workflow for security Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 8db2304..384726c 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -9,6 +9,8 @@ jobs: shellcheck: name: Run Shellcheck runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout code From cfef4cd2d3d3be0efc6e1c48453ab0ef95af8d8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:25:10 +0000 Subject: [PATCH 07/15] Replace third-party action with custom git commands Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 41 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 384726c..9425d5a 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -18,27 +18,36 @@ jobs: with: fetch-depth: 0 - - name: Get changed shell scripts - id: changed-files - uses: tj-actions/changed-files@v45 - with: - files: | - **.sh - separator: '\n' - - name: Run shellcheck on changed files - if: steps.changed-files.outputs.any_changed == 'true' - env: - ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | + # Get the base branch + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.sha }}" + + echo "Comparing $BASE_SHA...$HEAD_SHA" + echo "" + + # Get changed shell scripts + CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE_SHA...$HEAD_SHA" | grep '\.sh$' || true) + + if [ -z "$CHANGED_FILES" ]; then + echo "No shell scripts changed in this PR" + exit 0 + fi + echo "Changed shell scripts:" - echo "$ALL_CHANGED_FILES" + echo "$CHANGED_FILES" echo "" - # Run shellcheck on each changed file (newline-separated) + # Run shellcheck on each changed file + exit_code=0 while IFS= read -r file; do - if [ -n "$file" ]; then + if [ -n "$file" ] && [ -f "$file" ]; then echo "Checking $file..." - shellcheck "$file" + if ! shellcheck "$file"; then + exit_code=1 + fi fi - done <<< "$ALL_CHANGED_FILES" + done <<< "$CHANGED_FILES" + + exit $exit_code From d3cadf969dfa6241c65a26637ea763d0cf888046 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:25:48 +0000 Subject: [PATCH 08/15] Fix git diff syntax and remove redundant file check Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 9425d5a..1922d0a 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -28,7 +28,7 @@ jobs: echo "" # Get changed shell scripts - CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE_SHA...$HEAD_SHA" | grep '\.sh$' || true) + CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE_SHA..$HEAD_SHA" | grep '\.sh$' || true) if [ -z "$CHANGED_FILES" ]; then echo "No shell scripts changed in this PR" @@ -42,7 +42,7 @@ jobs: # Run shellcheck on each changed file exit_code=0 while IFS= read -r file; do - if [ -n "$file" ] && [ -f "$file" ]; then + if [ -n "$file" ]; then echo "Checking $file..." if ! shellcheck "$file"; then exit_code=1 From 825522da645021955a4e8d767e786edebfc24f8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:26:50 +0000 Subject: [PATCH 09/15] Use three-dot range for proper PR diff comparison Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 1922d0a..dcadbd6 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -28,7 +28,7 @@ jobs: echo "" # Get changed shell scripts - CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE_SHA..$HEAD_SHA" | grep '\.sh$' || true) + CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE_SHA...$HEAD_SHA" | grep '\.sh$' || true) if [ -z "$CHANGED_FILES" ]; then echo "No shell scripts changed in this PR" From ce95a12ae41fd645bc901f7f7876c5ba251f837d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:28:08 +0000 Subject: [PATCH 10/15] Quote exit_code variable for safer shell scripting Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index dcadbd6..7d5566f 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -50,4 +50,4 @@ jobs: fi done <<< "$CHANGED_FILES" - exit $exit_code + exit "$exit_code" From 6c3079b2cb1883bd1028c21fa95df44edba5e5b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:32:37 +0000 Subject: [PATCH 11/15] Update to latest versions: checkout@v6 and ubuntu-slim runner Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/workflows/shellcheck.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 7d5566f..b7aba73 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -8,13 +8,13 @@ on: jobs: shellcheck: name: Run Shellcheck - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: contents: read steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 From e6e83796d2eb0686869519b3c9990ebff5fa3615 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Thu, 5 Feb 2026 13:34:17 -0800 Subject: [PATCH 12/15] Apply suggestion from @mikeharder --- .github/workflows/shellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index b7aba73..c01a8e7 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -7,7 +7,7 @@ on: jobs: shellcheck: - name: Run Shellcheck + name: Shellcheck runs-on: ubuntu-slim permissions: contents: read From 4cf74e4996f0b8b88542b5e268acbd99682a5536 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:36:04 +0000 Subject: [PATCH 13/15] Move permissions to workflow level and update instructions Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- .github/copilot-instructions.md | 10 ++++++++++ .github/workflows/shellcheck.yml | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 08eef3b..230ec2b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -103,6 +103,16 @@ Currently, there is no automated test suite. Manual testing is performed by: - Exit with appropriate status codes (0 for success, non-zero for errors) - Use descriptive echo messages with emojis for user feedback (✅ ❌ ⚠️) +### GitHub Actions Workflows + +- Set permissions at the workflow level as the default +- Only override permissions at the job level when specific jobs need different access +- Use latest versions of actions (e.g., `actions/checkout@v6`) +- Use `ubuntu-slim` runner for lightweight, fast-running tasks (linting, formatting, etc.) +- Use `ubuntu-latest` for resource-intensive or long-running tasks +- Always set explicit permissions following the principle of least privilege +- Use custom code over third-party actions when simple and maintainable + ## Known Limitations - No automated testing infrastructure diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index c01a8e7..66c7332 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -5,12 +5,13 @@ on: paths: - '**.sh' +permissions: + contents: read + jobs: shellcheck: name: Shellcheck runs-on: ubuntu-slim - permissions: - contents: read steps: - name: Checkout code From 2f0c03b02444b16e70d328a495bfb9a790b6c0ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:41:23 +0000 Subject: [PATCH 14/15] Add temporary shellcheck error for workflow testing (SC2086) Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- disable-all-workflows.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/disable-all-workflows.sh b/disable-all-workflows.sh index 670b42b..ead9468 100755 --- a/disable-all-workflows.sh +++ b/disable-all-workflows.sh @@ -33,6 +33,9 @@ fi for id in $active_ids; do echo -n "Disabling workflow ID $id… " + # TODO: Remove this test line - intentional shellcheck error for testing + test_var=$id + echo $test_var > /dev/null gh api \ --method PUT \ /repos/"$OWNER"/"$REPO"/actions/workflows/"$id"/disable \ From 6c381c37b69a26a140601119df1a056c9d740786 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:43:48 +0000 Subject: [PATCH 15/15] Revert temporary shellcheck error (revert 2f0c03b) Co-authored-by: mikeharder <9459391+mikeharder@users.noreply.github.com> --- disable-all-workflows.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/disable-all-workflows.sh b/disable-all-workflows.sh index ead9468..670b42b 100755 --- a/disable-all-workflows.sh +++ b/disable-all-workflows.sh @@ -33,9 +33,6 @@ fi for id in $active_ids; do echo -n "Disabling workflow ID $id… " - # TODO: Remove this test line - intentional shellcheck error for testing - test_var=$id - echo $test_var > /dev/null gh api \ --method PUT \ /repos/"$OWNER"/"$REPO"/actions/workflows/"$id"/disable \