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
50 changes: 50 additions & 0 deletions .github/workflows/stale-lock-files.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Stale Lock Files

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths:
- '.github/workflows/*.md'
- 'scripts/check-stale-lock-files.sh'
- '.github/workflows/stale-lock-files.yml'

permissions:
contents: read

jobs:
check-stale-lock-files:
name: Check for stale .lock.yml files
runs-on: ubuntu-latest
timeout-minutes: 5
concurrency:
group: ci-${{ github.ref }}-stale-lock-files
cancel-in-progress: true
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Fetch base branch
if: github.event_name == 'pull_request'
run: git fetch origin ${{ github.base_ref }} --no-tags

- name: Check stale lock files

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] workflow_dispatch does not populate github.base_ref, so the script receives --base-ref "origin/" (empty ref). The fallback on a clean checkout finds no working-tree changes and silently exits 0 — the guard is a no-op for manual runs.

💡 Suggested fix

Guard the base-ref flag on whether the event is a pull request:

- name: Check stale lock files
  run: |
    if [ -n "${{ github.base_ref }}" ]; then
      bash scripts/check-stale-lock-files.sh --base-ref "origin/${{ github.base_ref }}"
    else
      bash scripts/check-stale-lock-files.sh
    fi

Or simply remove workflow_dispatch from the triggers if a meaningful manual run is not needed.

@copilot please address this.

run: |
bash scripts/check-stale-lock-files.sh --base-ref "origin/${{ github.base_ref }}"

- name: Add step summary on failure
if: failure()
run: |
echo "## ❌ Stale Lock Files Detected" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "One or more \`.github/workflows/*.md\` files were modified but their" >> $GITHUB_STEP_SUMMARY
echo "compiled \`.lock.yml\` outputs were not regenerated." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**To fix**, recompile the workflows and commit the updated lock files:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "make recompile" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Then commit the regenerated \`.lock.yml\` files together with the \`.md\` changes." >> $GITHUB_STEP_SUMMARY
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -473,9 +473,17 @@ bundle-js:
@echo "✓ bundle-js tool built"
@echo "To bundle a JavaScript file: ./bundle-js <input-file> [output-file]"

# Test all code (Go, JavaScript, and wasm golden)
# Run Bash script tests (check-stale-lock-files, check-workflow-drift)
.PHONY: test-scripts
test-scripts: build
@echo "Running Bash script tests..."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test-scripts target passes ./$(BINARY_NAME) to check-workflow-drift_test.sh but declares no build prerequisite. If the binary doesn't exist, the test fails with a misleading "No such file or directory" error.

Fix by adding the build prerequisite:

test-scripts: build

@copilot please address this.

bash scripts/check-stale-lock-files_test.sh
bash scripts/check-workflow-drift_test.sh ./$(BINARY_NAME)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] test-scripts runs check-workflow-drift_test.sh which requires the binary ./$(BINARY_NAME) to already exist, but test-scripts declares no dependency on build. Running make test-scripts on a clean checkout will fail with a missing binary error.

💡 Suggested fix

Add build as a prerequisite:

.PHONY: test-scripts
test-scripts: build
\techo "Running Bash script tests..."
\tbash scripts/check-stale-lock-files_test.sh
\tbash scripts/check-workflow-drift_test.sh ./$(BINARY_NAME)
\t@echo "✓ All Bash script tests passed"

check-stale-lock-files_test.sh does not need the binary, so the cost is only incurred when the drift test actually runs.

@copilot please address this.

@echo "✓ All Bash script tests passed"

# Test all code (Go, JavaScript, wasm golden, and shell scripts)
.PHONY: test-all
test-all: test test-js test-wasm-golden
test-all: test test-js test-wasm-golden test-scripts

# Run tests with coverage
.PHONY: test-coverage
Expand Down Expand Up @@ -1238,7 +1246,8 @@ help:
@echo " test-impacted-js - Run impacted JavaScript unit tests for current branch changes"
@echo " test-impacted-go - Run impacted Go unit tests for current branch changes"
@echo " test-impacted - Run impacted JavaScript and Go unit tests for current branch changes"
@echo " test-all - Run all tests (Go, JavaScript, and wasm golden)"
@echo " test-scripts - Run Bash script tests (check-stale-lock-files, check-workflow-drift)"
@echo " test-all - Run all tests (Go, JavaScript, wasm golden, and shell scripts)"
@echo " test-wasm-golden - Run wasm golden tests (Go string API path)"
@echo " test-wasm - Build wasm and run Node.js golden comparison test"
@echo " update-wasm-golden - Regenerate wasm golden files from current compiler output"
Expand Down
61 changes: 61 additions & 0 deletions scripts/check-stale-lock-files_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,67 @@ else
fail "--base-ref should pass when markdown + lock changed" "$(cat "$T10_OUT")"
fi

# ---------------------------------------------------------------------------
# Test 11: .md files in excluded shared/ subdirectory are not flagged.
# ---------------------------------------------------------------------------
echo "Test 11: .md files in shared/ subdirectory are excluded..."
T11="$TMP_ROOT/t11"
mkdir -p "$T11"
git -C "$T11" init -q
git -C "$T11" config user.email "test@test.com"
git -C "$T11" config user.name "Test"
mkdir -p "$T11/.github/workflows/shared"
printf '%s\n' "# shared-tool" > "$T11/.github/workflows/shared/tools.md"
git -C "$T11" add .
git -C "$T11" commit -q -m "initial"
printf '%s\n' "# shared-tool (edited)" > "$T11/.github/workflows/shared/tools.md"
T11_OUT="$TMP_ROOT/t11-output.txt"
if (cd "$T11" && bash "$STALE_SCRIPT" >"$T11_OUT" 2>&1); then
pass "shared/ .md files are excluded (exits 0)"
else
fail "shared/ .md files should be excluded (should exit 0)" "$(cat "$T11_OUT")"
fi

# ---------------------------------------------------------------------------
# Test 12: .md files in excluded skills/ subdirectory are not flagged.
# ---------------------------------------------------------------------------
echo "Test 12: .md files in skills/ subdirectory are excluded..."
T12="$TMP_ROOT/t12"
mkdir -p "$T12"
git -C "$T12" init -q
git -C "$T12" config user.email "test@test.com"
git -C "$T12" config user.name "Test"
mkdir -p "$T12/.github/workflows/skills"
printf '%s\n' "# skill-doc" > "$T12/.github/workflows/skills/example.md"
git -C "$T12" add .
git -C "$T12" commit -q -m "initial"
printf '%s\n' "# skill-doc (edited)" > "$T12/.github/workflows/skills/example.md"
T12_OUT="$TMP_ROOT/t12-output.txt"
if (cd "$T12" && bash "$STALE_SCRIPT" >"$T12_OUT" 2>&1); then
pass "skills/ .md files are excluded (exits 0)"
else
fail "skills/ .md files should be excluded (should exit 0)" "$(cat "$T12_OUT")"
fi

# ---------------------------------------------------------------------------
# Test 13: unknown --base-ref falls back to working-tree diff and still
# catches a stale .md in the working tree.
# ---------------------------------------------------------------------------
echo "Test 13: unknown --base-ref falls back gracefully and still catches stale .md..."
T13="$TMP_ROOT/t13"
mkdir -p "$T13"
create_fixture_repo "$T13" "fallback-workflow"
# Modify the .md in the working tree (not committed)
printf '%s\n' "# fallback-workflow (edited)" > "$T13/.github/workflows/fallback-workflow.md"
T13_OUT="$TMP_ROOT/t13-output.txt"
if (cd "$T13" && bash "$STALE_SCRIPT" --base-ref "nonexistent-sha-12345" >"$T13_OUT" 2>&1); then
fail "unknown base-ref with stale .md should exit 1" "$(cat "$T13_OUT")"
elif grep -q "fallback-workflow.md" "$T13_OUT"; then
pass "unknown --base-ref falls back gracefully and catches stale .md"
else
fail "unknown --base-ref fallback output did not name the stale file" "$(cat "$T13_OUT")"
fi

echo
echo "Tests passed: $TESTS_PASSED"
echo "Tests failed: $TESTS_FAILED"
Expand Down
Loading