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
49 changes: 41 additions & 8 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
# Docs: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "npm"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
# Docs: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
#
# Note: Dependabot only understands `dependencies` / `devDependencies`. It cannot read or
# update the npm `overrides` block, which is where most transitive fixes in this repo live
# (e.g. `gulp-mocha > mocha`, which is what removes the vulnerable exact-pinned
# minimatch@3.0.4 and diff@5.0.0 copies). Those are handled by
# .github/workflows/dependency-security.yml instead.
#
# Reviewers are assigned via .github/CODEOWNERS - the `reviewers:` option was retired
# by GitHub in 2025 and no longer has any effect.
#
# Nothing here auto-merges. Every PR needs a human to review and merge it.

version: 2
updates:
- package-ecosystem: "npm"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "dependencies"
# Keep routine version churn to a single PR so security PRs stay easy to spot.
groups:
dev-dependencies:
dependency-type: "development"
update-types:
- "minor"
- "patch"
production-dependencies:
dependency-type: "production"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
112 changes: 112 additions & 0 deletions .github/workflows/dependency-security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# Weekly dependency security refresh.
#
# Dependabot cannot see npm `overrides`, and almost every vulnerability in this repo is
# transitive and pinned through `overrides`. That gap is why S360/Component Governance
# keeps re-raising the same alerts and why they have to be fixed by hand each time.
#
# It matters more here than in most repos: this package ships its own `node_modules`
# inside the published tarball, so a vulnerable transitive copy left here is re-detected
# downstream (e.g. in powerplatform-build-tools) no matter what that repo pins.
#
# This workflow closes the gap:
# 1. `npm update` refreshes package-lock.json inside the ranges already declared.
# Historically this alone clears most alerts - the ranges were fine, the lock was stale.
# 2. `scripts/audit-overrides.js --write` raises any range that is genuinely too low,
# resolving each advisory against the GitHub Advisory DB for its real patched version.
# 3. The build must pass before a PR is opened.
#
# Anything the script cannot fix safely (exact-pinned transitive deps, multi-major packages,
# advisories with no published fix) is reported in the PR body for a human to pick up.
name: Dependency security refresh

on:
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC
workflow_dispatch:

permissions:
contents: write
pull-requests: write

jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
lfs: true

# Node 20 rather than the repo's CI Node 16: the script needs a modern npm for
# `npm audit --json`, and Node 22+ is avoided because its native TypeScript
# stripping conflicts with ts-node/register during `npm run ci`.
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Refresh lock file within existing ranges
run: npm update

- name: Raise ranges that are still too low
id: overrides
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node scripts/audit-overrides.js --write | tee audit-report.md
npm install

- name: Check for changes
id: diff
run: |
if git diff --quiet -- package.json package-lock.json; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

# The PR is only opened if the build is green, so a broken tree is never proposed.
- name: Build and test
if: steps.diff.outputs.changed == 'true'
run: npm run ci

- name: Open pull request
if: steps.diff.outputs.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH="bot/dependency-refresh-$(date -u +%Y%m%d)"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
git add package.json package-lock.json
git commit -m "chore: weekly dependency security refresh"
git push -u origin "$BRANCH"

{
echo "## Summary"
echo
echo "Automated weekly refresh of vulnerable dependencies."
echo
cat audit-report.md
echo
echo "## Test plan"
echo
echo "- [x] \`npm ci\` clean"
echo "- [x] \`npm run ci\` passed before this PR was opened"
echo
echo "Anything listed under **Needs a human** could not be fixed safely by the script"
echo "and still requires a manual override, a lock-file patch, or an accepted-risk note."
} > pr-body.md

# No --reviewer here: .github/CODEOWNERS already requests a review for every file
# this PR touches, and passing a team reviewer explicitly can fail depending on the
# GITHUB_TOKEN's permissions.
gh pr create --base main --head "$BRANCH" \
--title "chore: weekly dependency security refresh" \
--body-file pr-body.md
Loading
Loading