diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..203c9c5e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: + - package-ecosystem: 'npm' + # Yarn workspace root: one yarn.lock covers every packages/* workspace. + directory: '/' + schedule: + interval: 'daily' + cooldown: + default-days: 7 + ignore: + # vitest 5 drops vite as a dependency, which Yarn 1 then never installs (see #52). + - dependency-name: 'vitest' + update-types: ['version-update:semver-major'] + - package-ecosystem: 'github-actions' + # '/' covers .github/workflows only; the composite actions pin their own actions. + directories: + - '/' + - '/.github/actions/*' + schedule: + interval: 'weekly' + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88cd5f2d..43811193 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,9 @@ on: push: branches: [main] pull_request: + # Weekly, so an advisory published against an unchanged lockfile still surfaces. + schedule: + - cron: '0 13 * * 1' # The `setup` job installs deps and builds @launchdarkly/ai-server (the core client), # then shares the compiled output with downstream jobs via the `client-dist` @@ -89,6 +92,30 @@ jobs: - name: Package consistency (sherif) run: yarn lint:pkg + # ─── Dependency audit ─────────────────────────────────────────────────────── + audit: + name: Dependency audit + runs-on: ubuntu-latest + # A newly published advisory must not turn every open PR red; push and the weekly run still fail. + continue-on-error: ${{ github.event_name == 'pull_request' }} + steps: + - uses: actions/checkout@v4 + + - name: Enable Corepack + run: corepack enable + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Audit runtime dependencies + run: make audit + # ─── Type check ───────────────────────────────────────────────────────────── typecheck: name: Type check diff --git a/Makefile b/Makefile index 9796d8c7..f7d03973 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,11 @@ -.PHONY: start build clean test typecheck lint lint-fix lint-packages lint-packages-fix format format-fix code-check code-fix review size size-install +.PHONY: start build clean test typecheck lint lint-fix lint-packages lint-packages-fix format format-fix code-check code-fix review size size-install audit + +# Fail on known high or critical vulnerabilities in runtime (non-dev) dependencies +# Yarn 1 exits with a bitmask of severities found (info 1, low 2, moderate 4, high 8, critical 16) and +# --level only filters the printed list, so test bits 8|16. Exactly 1 is also yarn's error exit: fail closed. +audit: + yarn audit --groups dependencies --level high; s=$$?; \ + if [ $$s -eq 1 ] || [ $$((s & 24)) -ne 0 ]; then echo "make audit: failed (yarn audit exit $$s)"; exit 1; fi # Run main.ts (yarn start) start: