Skip to content

ci(antipattern): broaden TS allowlist (cli, mod.ts, lsp-server, *vsco… #74

ci(antipattern): broaden TS allowlist (cli, mod.ts, lsp-server, *vsco…

ci(antipattern): broaden TS allowlist (cli, mod.ts, lsp-server, *vsco… #74

# SPDX-License-Identifier: PMPL-1.0-or-later
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <jonathan.jewell@open.ac.uk>
# Validates GitHub workflows against RSR security standards
name: Workflow Security Linter
on:
push:
paths:
- '.github/workflows/**'
pull_request:
paths:
- '.github/workflows/**'
workflow_dispatch:
permissions:
contents: read
jobs:
lint-workflows:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check SPDX Headers
run: |
echo "=== Checking SPDX License Headers ==="
failed=0
for file in .github/workflows/*.yml .github/workflows/*.yaml; do
[ -f "$file" ] || continue
if ! head -1 "$file" | grep -q "^# SPDX-License-Identifier:"; then
echo "ERROR: $file missing SPDX header"
failed=1
fi
done
if [ $failed -eq 1 ]; then
echo "Add '# SPDX-License-Identifier: PMPL-1.0-or-later' as first line"
exit 1
fi
echo "All workflows have SPDX headers"
- name: Check Permissions Declaration
run: |
echo "=== Checking Permissions ==="
failed=0
for file in .github/workflows/*.yml .github/workflows/*.yaml; do
[ -f "$file" ] || continue
if ! grep -q "^permissions:" "$file"; then
echo "ERROR: $file missing top-level 'permissions:' declaration"
failed=1
fi
done
if [ $failed -eq 1 ]; then
echo "Add 'permissions:
contents: read' at workflow level"
exit 1
fi
echo "All workflows have permissions declared"
- name: Check SHA-Pinned Actions

Check failure on line 63 in .github/workflows/workflow-linter.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/workflow-linter.yml

Invalid workflow file

You have an error in your yaml syntax on line 63
run: |
echo "=== Checking Action Pinning ==="
unpinned=$(grep -rnE "^[[:space:]]+uses:" .github/workflows/ | \
grep -v "@[a-f0-9]\{40\}" | \
grep -v "uses: \./\|uses: docker://\|uses: actions/github-script" || true)
if [ -n "$unpinned" ]; then
echo "ERROR: Found unpinned actions:"
echo "$unpinned"
exit 1
fi
echo "All actions are SHA-pinned"
- name: Check for Duplicate Workflows
run: |
echo "=== Checking for Duplicates ==="
if [ -f .github/workflows/codeql.yml ] && [ -f .github/workflows/codeql-analysis.yml ]; then
echo "ERROR: Duplicate CodeQL workflows found"
exit 1
fi
echo "No critical duplicates found"
- name: Check Secrets Guards
run: |
echo "=== Checking Secrets Usage ==="
if [ -f .github/workflows/mirror.yml ]; then
if grep -q "secrets\." .github/workflows/mirror.yml; then
if ! grep -q "if:.*vars\." .github/workflows/mirror.yml; then
echo "::warning::mirror.yml uses secrets without vars guard"
fi
fi
fi
echo "Secrets check complete"
- name: Summary
run: |
echo "=== Workflow Linter Summary ==="
echo "All critical checks passed."