Skip to content

chore(deps): bump DavidAnson/markdownlint-cli2-action from 23.2.0 to 24.1.0 #266

chore(deps): bump DavidAnson/markdownlint-cli2-action from 23.2.0 to 24.1.0

chore(deps): bump DavidAnson/markdownlint-cli2-action from 23.2.0 to 24.1.0 #266

Workflow file for this run

name: Required Checks
on:
push:
branches: [main]
pull_request:
branches: [main]
merge_group:
types: [checks_requested]
permissions:
contents: read
concurrency:
group: required-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: lint
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install shellcheck
run: sudo apt-get install -y shellcheck
- name: Shellcheck on all shell scripts
run: find . -name "*.sh" | xargs shellcheck
- name: Install yamllint
run: pip install yamllint
- name: yamllint on all YAML files
run: yamllint -c .yamllint.yaml .
- name: Check for Python files
id: py-check
run: |
count=$(find . -name "*.py" -not -path "./.git/*" | wc -l)
echo "count=${count}" >> "$GITHUB_OUTPUT"
- name: Install mypy and run type check
if: steps.py-check.outputs.count != '0'
run: pip install mypy && mypy --ignore-missing-imports .
- name: No Python files — emit notice and validate syntax
if: steps.py-check.outputs.count == '0'
run: |
echo "::notice::No Python files found; skipping mypy"
find . -name "*.py" -not -path "./.git/*" | xargs -r python -m py_compile
echo "Python compile check complete (0 files)"
- name: Set up Node.js (for tsc)
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: dagger/package-lock.json
- name: Install dagger TypeScript deps
run: cd dagger && npm ci
- name: TypeScript type check (tsc --noEmit)
run: cd dagger && npx tsc --noEmit
- name: Verify issue #92 invariants
# Static-source regression guard moved from ci.yml/lint-scripts
# (closes #94 F1). See scripts/verify-issue-92-invariants.sh
# for the three invariants enforced.
run: bash scripts/verify-issue-92-invariants.sh
forbid-suppressions:
name: forbid-suppressions
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: "Reject silent-failure workaround in shell/YAML/Dockerfile/justfile/HCL"
run: |
# Matches the forbidden idiom at end of line or before a trailing
# comment. See docs/runbooks/no-silent-failures.md (ported from
# HomericIntelligence/Odysseus#280).
set -euo pipefail
mapfile -t files < <(git ls-files \
-- \
'*.sh' '*.bash' '*.yml' '*.yaml' '*.hcl' \
'Dockerfile*' '**/Dockerfile*' \
'justfile' '**/justfile' 'Justfile' '**/Justfile')
# Skip the runbook (documents the rule and quotes the forbidden idiom)
# and this workflow file itself (heredoc would otherwise self-match).
declare -a scan_files=()
for f in "${files[@]}"; do
case "$f" in
docs/runbooks/no-silent-failures.md) continue ;;
.github/workflows/_required.yml) continue ;;
esac
scan_files+=("$f")
done
if [ "${#scan_files[@]}" -eq 0 ]; then
echo "No files to scan"
exit 0
fi
if grep -nE '\|\|[[:space:]]*true([[:space:]]*$|[[:space:]]+#)' "${scan_files[@]}"; then
echo ""
echo '::error::Found silent-failure workarounds above. Refactor per docs/runbooks/no-silent-failures.md.'
exit 1
fi
echo 'OK: no silent-failure workarounds found'
- name: "Reject continue-on-error workflow opt-out"
run: |
set -euo pipefail
mapfile -t files < <(git ls-files -- '.github/workflows/*.yml' '.github/workflows/*.yaml')
if [ "${#files[@]}" -eq 0 ]; then
echo "No workflow files"
exit 0
fi
if grep -nE '^[[:space:]]*continue-on-error:[[:space:]]*true[[:space:]]*$' "${files[@]}"; then
echo ""
echo '::error::Found "continue-on-error: true" above. Fix the root cause per docs/runbooks/no-silent-failures.md.'
exit 1
fi
echo 'OK: no "continue-on-error: true" found'
unit-tests:
name: unit-tests
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup pixi
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
pixi-version: v0.69.0
cache: true
- name: Bootstrap proteus
run: pixi run bootstrap-proteus
- name: Run pytest
run: pixi run pytest tests/unit -v
- name: Run pipeline-config unit tests
run: pixi run pytest tests/test_loader.py tests/test_topology.py tests/test_handlers.py -q
- name: Install jq
run: sudo apt-get install -y jq
- name: Test dispatch-apply.sh payload construction
run: ./scripts/test/test-dispatch-apply.sh
- name: Test check-symlinks.sh broken-symlink detection
run: bash tests/unit/check-symlinks.test.sh
- name: Test promote-image.sh argument validation
run: bash tests/unit/promote-image.test.sh
- name: Run required-checks ruleset regression test
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash tests/test-required-checks-ruleset.sh
integration-tests:
name: integration-tests
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup pixi
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
pixi-version: v0.69.0
cache: true
- name: Bootstrap proteus
run: pixi run bootstrap-proteus
- name: Schema-in-sync check
run: pixi run pytest tests/unit/test_schema_in_sync.py -v
- name: Pipeline-config dry-run (drift guard)
run: |
for f in configs/pipelines/*.yaml; do
svc=$(basename "$f" .yaml)
pixi run python -m proteus run "$f" --service "$svc" --dry-run
done
- name: Run pipeline-config integration tests
run: pixi run pytest tests/test_main_integration.py -q
- name: Validate pipeline configs against pipeline schema
run: pixi run python -m proteus.pipeline validate 'configs/pipelines/*.yaml'
- name: Assert jq present (required by dispatch-apply DLQ)
run: command -v jq && jq --version
- name: Run merge-queue activation fail-safe tests
run: bash tests/merge-queue-activation.test.sh
- name: Test dispatch-apply host validation (fail-closed contract)
run: bash tests/dispatch-apply.test.sh
- name: Run dispatch-apply retry/DLQ tests
run: bash tests/dispatch-apply-retry.test.sh
- name: Run remediation-plan sync test
run: bash tests/remediation-plan-sync.test.sh
- name: Run remediation-plan checkbox regression test
run: bash tests/remediation-plan-checkboxes.test.sh
security-dependency-scan:
name: security/dependency-scan
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
exit-code: '1'
severity: CRITICAL,HIGH
security-secrets-scan:
name: security/secrets-scan
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Install Gitleaks
run: |
GITLEAKS_VERSION=8.30.1
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/')
curl -sSfL \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${OS}_${ARCH}.tar.gz" \
| tar -xz -C /usr/local/bin gitleaks
gitleaks version
- name: Run Gitleaks
run: |
# Gitleaks exits 1 on any finding (default). The SARIF upload step
# below uses `if: always()` so the report is preserved even when
# this step fails. See docs/runbooks/no-silent-failures.md.
set -euo pipefail
if [ -f .gitleaks.toml ]; then
gitleaks detect --source . --config .gitleaks.toml \
--report-format sarif --report-path gitleaks.sarif
else
gitleaks detect --source . \
--report-format sarif --report-path gitleaks.sarif
fi
- name: Upload Gitleaks SARIF
if: always() && hashFiles('gitleaks.sarif') != ''
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gitleaks-report
path: gitleaks.sarif
retention-days: 90
- name: Enforce Gitleaks on PRs (fail on findings)
if: github.event_name == 'pull_request'
run: |
# PR-only enforcement; main pushes stay advisory per
# docs/runbooks/no-silent-failures.md Bucket E and issue #86.
if [ -f .gitleaks.toml ]; then
gitleaks detect --source . --config .gitleaks.toml --exit-code 1
else
gitleaks detect --source . --exit-code 1
fi
security-npm-audit:
name: security/npm-audit
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: dagger/package-lock.json
- name: Install dependencies (locked)
run: cd dagger && npm ci
- name: npm audit (production, high+)
run: cd dagger && npm audit --omit=dev --audit-level=high
build:
name: build
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Validate shell script shebangs
run: |
count=$(find . -name "*.sh" | xargs head -1 | grep -c "#!/" || true)
echo "Found ${count} shebang line(s) across shell scripts"
- name: Bash syntax check on all shell scripts
run: find . -name "*.sh" | xargs -I{} bash -n {}
schema-validation:
name: schema-validation
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install check-jsonschema
run: pip install check-jsonschema
- name: Validate GitHub workflow files against schema
run: |
# Validation is advisory: schemastore is sometimes stale relative to
# new Actions syntax. Emit a workflow warning on mismatch but do not
# fail the job. Explicit `if`-guard replaces the prior
# `continue-on-error: true` (Bucket E, docs/runbooks/no-silent-failures.md).
set -euo pipefail
if find .github/workflows -name "*.yml" | \
xargs check-jsonschema \
--schemafile https://json.schemastore.org/github-workflow
then
echo "OK: workflow files match schemastore schema"
else
echo "::warning::Workflow schema validation reported issues (advisory)."
fi
deps-version-sync:
name: deps/version-sync
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Report pinned versions in shell scripts (informational)
run: |
echo "=== Pinned version strings in shell scripts ==="
grep -rh "version=" . --include="*.sh" | sort -u || echo "(none found)"
exit 0
- name: Validate pyproject.toml version if present
run: |
if [ -f pyproject.toml ]; then
python -c "
import tomllib, pathlib
data = tomllib.loads(pathlib.Path('pyproject.toml').read_text())
ver = data.get('project', {}).get('version') or data.get('tool', {}).get('poetry', {}).get('version')
print(f'pyproject.toml version: {ver}')
"
else
echo "No pyproject.toml found — skipping version check"
fi
markdownlint:
name: markdownlint
runs-on: ubuntu-24.04
timeout-minutes: 5
needs: lint
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Run markdownlint-cli2
uses: DavidAnson/markdownlint-cli2-action@6bf21b07787794f89a243495939cd651942aeabe # v20.0.0
with:
globs: "**/*.md
!.claude/**"
config: ".markdownlint.yaml"
pixi-check:
name: pixi-check
runs-on: ubuntu-24.04
timeout-minutes: 10
needs: lint
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Skip if no pixi.toml
id: detect
run: |
if [ ! -f pixi.toml ]; then
echo "::notice::No pixi.toml in repo, skipping pixi-check"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup pixi
if: steps.detect.outputs.skip == 'false'
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
pixi-version: v0.69.0
cache: true
- name: pixi install (locked)
if: steps.detect.outputs.skip == 'false'
run: |
if [ -f pixi.lock ]; then
pixi install --locked
else
echo "::warning::pixi.toml present but pixi.lock missing — running unlocked"
pixi install
fi
justfile-check:
name: justfile-check
runs-on: ubuntu-24.04
timeout-minutes: 5
needs: lint
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Skip if no justfile
id: detect
run: |
if [ ! -f justfile ] && [ ! -f Justfile ]; then
echo "::notice::No justfile in repo, skipping justfile-check"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Install just
if: steps.detect.outputs.skip == 'false'
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
with:
just-version: "1.36.0"
- name: Validate justfile
if: steps.detect.outputs.skip == 'false'
run: |
just --evaluate >/dev/null
just --list >/dev/null
symlink-check:
name: symlink-check
runs-on: ubuntu-24.04
timeout-minutes: 3
needs: lint
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Run symlink check
run: bash scripts/check-symlinks.sh
branch-protection-test:
name: branch-protection-test
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup pixi
uses: prefix-dev/setup-pixi@a09b6247153796b190642a2b53fac4241043cf6f # v0.10.0
with:
pixi-version: v0.69.0
- name: Validate ruleset JSON
run: pixi run jq . .github/branch-protection.main.json >/dev/null
- name: Verify every context maps to a real workflow job name
run: bash scripts/verify-context-names.sh
- name: Run offline branch-protection verifier test
run: pixi run test-branch-protection
version-consistency:
name: version-consistency
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Run version-consistency tests (issue #101)
run: bash tests/version-consistency.test.sh
# Canonical aggregate gate for the test category (Odysseus CI naming
# convention, docs/ci-naming-convention.md). Emits the canonical check-run
# `test` that the Ecosystem CI Status board's test column targets. The split
# suites (unit-tests / integration-tests / branch-protection-test) are kept
# as their own check-runs; this job just succeeds once they all pass.
test:
name: test
runs-on: ubuntu-24.04
timeout-minutes: 5
needs: [unit-tests, integration-tests, branch-protection-test]
steps:
- name: All test suites passed
run: |
echo "OK: unit-tests, integration-tests, branch-protection-test all green"
# Canonical `package` gate (Odysseus CI naming convention). Builds the
# distributable for the installable `proteus` Python CLI (pyproject.toml
# declares a setuptools build-backend and a `proteus` console script).
package:
name: package
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
- name: Install build frontend
run: pip install build
- name: Build sdist and wheel
run: python -m build --sdist --wheel --outdir dist/
- name: Verify distributable artifacts exist
run: |
set -euo pipefail
ls -l dist/
test -n "$(ls dist/proteus-*.tar.gz 2>/dev/null)" || {
echo "::error::No sdist produced under dist/"; exit 1; }
test -n "$(ls dist/proteus-*-py3-none-any.whl 2>/dev/null)" || {
echo "::error::No wheel produced under dist/"; exit 1; }
echo "OK: sdist and wheel built"
- name: Upload distributable artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: proteus-dist
path: dist/
retention-days: 7
# Canonical `install` gate (Odysseus CI naming convention). Install smoke
# test: pip-installs the built wheel into a clean virtualenv and exercises
# the `proteus` console-script entry point declared in pyproject.toml.
install:
name: install
runs-on: ubuntu-24.04
timeout-minutes: 10
needs: package
steps:
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
- name: Download distributable artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: proteus-dist
path: dist/
- name: Install wheel into a clean virtualenv
run: |
set -euo pipefail
python -m venv /tmp/proteus-venv
# shellcheck disable=SC1091
. /tmp/proteus-venv/bin/activate
wheel="$(ls dist/proteus-*-py3-none-any.whl)"
pip install "$wheel"
echo "Installed: $wheel"
- name: Run installed CLI entry point (smoke test)
run: |
set -euo pipefail
# shellcheck disable=SC1091
. /tmp/proteus-venv/bin/activate
# The `proteus` console script is the installed package's public
# surface. `--help` exits 0 only if the entry point resolves and
# argparse builds cleanly.
proteus --help
# `validate --help` exercises the validate subcommand wiring.
proteus validate --help