Repository navigation
fix(integrations): honor shared refresh for installed targets #10457
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Lint & Security | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| schedule: | |
| - cron: "17 4 * * 1" | |
| workflow_dispatch: | |
| jobs: | |
| checks: | |
| name: Lint & dependency audit | |
| if: ${{ github.event_name != 'schedule' }} | |
| runs-on: ubuntu-latest | |
| env: | |
| DOC_GLOBS: | | |
| docs/**/*.md | |
| README.md | |
| README.zh-CN.md | |
| README.ja.md | |
| README.ko.md | |
| CODE_OF_CONDUCT.md | |
| CONTRIBUTING.md | |
| DEVELOPMENT.md | |
| SECURITY.md | |
| SUPPORT.md | |
| spec-driven.md | |
| presets/*.md | |
| workflows/*.md | |
| steps: | |
| - name: Checkout | |
| id: checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install uv | |
| id: uv | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3 | |
| - name: Set up Python | |
| id: python | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.14" | |
| # Explicit prerequisites let independent checks finish after a failure | |
| # without masking that failure or continuing after cancellation. | |
| # Audit committed inputs before Markdownlint can execute repository | |
| # JavaScript configuration in this shared workspace. | |
| - name: Check committed audit requirements are current | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' && steps.uv.outcome == 'success' && steps.python.outcome == 'success' }} | |
| env: | |
| DEPENDENCY_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.before || '' }} | |
| DEPENDENCY_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.sha }} | |
| GENERATED_REQUIREMENTS: ${{ runner.temp }}/security-audit-requirements.txt | |
| run: python .github/scripts/check_security_requirements.py | |
| - name: Run pip-audit (committed requirements) | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' && steps.uv.outcome == 'success' && steps.python.outcome == 'success' }} | |
| run: uvx --from pip-audit==2.10.0 pip-audit --disable-pip --require-hashes -r .github/security-audit-requirements.txt --progress-spinner off | |
| - name: Run ruff check | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' && steps.uv.outcome == 'success' && steps.python.outcome == 'success' }} | |
| run: uvx ruff@0.15.0 check src tests | |
| - name: Run git diff --check | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| shell: bash | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| git fetch --no-tags origin "+${PR_BASE_SHA}:refs/checks/pr-base" | |
| git diff --check refs/checks/pr-base HEAD | |
| elif [ "$EVENT_NAME" = "workflow_dispatch" ]; then | |
| git diff-tree --check --no-commit-id --root --diff-merges=first-parent -r "$GITHUB_SHA" | |
| elif [ "$PUSH_BEFORE_SHA" = "0000000000000000000000000000000000000000" ]; then | |
| git diff-tree --check --no-commit-id --root -r "$GITHUB_SHA" | |
| else | |
| git fetch --no-tags origin "+${PUSH_BEFORE_SHA}:refs/checks/push-before" | |
| git diff --check refs/checks/push-before HEAD | |
| fi | |
| # Documentation only. Commands, skills, prompt templates, agent | |
| # instructions (AGENTS.md) and .github/ content are inputs to coding | |
| # agents rather than prose, and are deliberately left unlinted so a | |
| # documentation pass never reformats them. Add new documentation | |
| # paths to the DOC_GLOBS list above. | |
| - name: Verify the documentation globs match files | |
| id: documentation-globs | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| shopt -s globstar nullglob | |
| # Checked per glob, not on the total: one stale entry among several | |
| # still leaves that part of the documentation unlinted, which is the | |
| # failure #4526 was about. | |
| count=0 | |
| empty=() | |
| while IFS= read -r glob; do | |
| [ -z "$glob" ] && continue | |
| matched=0 | |
| for path in $glob; do | |
| [ -f "$path" ] && matched=$((matched + 1)) | |
| done | |
| # An array, not a string: nullglob is on, so re-expanding an | |
| # unquoted list of unmatched globs would erase it. | |
| [ "$matched" -eq 0 ] && empty+=("$glob") | |
| count=$((count + matched)) | |
| done <<< "$DOC_GLOBS" | |
| echo "documentation files matched: $count" | |
| if [ ${#empty[@]} -gt 0 ]; then | |
| for glob in "${empty[@]}"; do | |
| echo "::error::markdownlint glob matches no files: $glob (see #4526)" | |
| done | |
| exit 1 | |
| fi | |
| - name: Run markdownlint-cli2 | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' && steps.documentation-globs.outcome == 'success' }} | |
| uses: DavidAnson/markdownlint-cli2-action@696eb3f2509270d7b882d2aa68347bc676e7af34 # v25.0.0 | |
| with: | |
| globs: ${{ env.DOC_GLOBS }} | |
| # shellcheck is preinstalled on ubuntu-latest runners. | |
| # Start at --severity=error to block real bugs without flagging style | |
| # (notably SC2155). Tighten in a follow-up after cleanup. | |
| - name: Run shellcheck on shell scripts | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| run: git ls-files -z -- '*.sh' | xargs -0 shellcheck --severity=error | |
| # macOS ships bash 3.2, where bash 4+ case-modification parameter | |
| # expansions error with "bad substitution". shellcheck assumes bash 4+ | |
| # from the shebang and cannot flag these, so guard explicitly; use tr | |
| # for portable case conversion. | |
| - name: Reject bash 4+ case-modification expansions | |
| if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} | |
| run: | | |
| matches=$(git ls-files -z -- '*.sh' | xargs -0 grep -nE '\$\{[A-Za-z_][A-Za-z0-9_]*(\[[^]]*\])?(\^\^?|,,?|~~?|@[UuLl])[^}]*\}' || true) | |
| if [ -n "$matches" ]; then | |
| echo "Found bash 4+ case-modification expansion(s); use tr for portability (macOS ships bash 3.2):" | |
| echo "$matches" | |
| exit 1 | |
| fi | |
| dependency-audit-scheduled: | |
| name: Dependency audit scheduled (${{ matrix.os }}, Python ${{ matrix.python-version }}) | |
| if: ${{ github.event_name == 'schedule' }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest] | |
| python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # Keep live per-platform resolution separate from the deterministic | |
| # committed snapshot used by push, pull request, and manual runs. | |
| - name: Compile scheduled audit requirements | |
| run: | | |
| uv pip compile pyproject.toml --extra test --python-version "${{ matrix.python-version }}" --upgrade --generate-hashes --quiet --output-file "${{ runner.temp }}/spec-kit-audit-requirements.txt" | |
| - name: Run pip-audit (scheduled live resolution) | |
| run: uvx --from pip-audit==2.10.0 pip-audit --disable-pip --require-hashes -r "${{ runner.temp }}/spec-kit-audit-requirements.txt" --progress-spinner off |