-
Notifications
You must be signed in to change notification settings - Fork 1
Updates to Dependabot #716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sophie-poole-nhs
wants to merge
2
commits into
main
Choose a base branch
from
chore/update-dependabot-config
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+266
−35
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,49 +1,48 @@ | ||
| version: 2 | ||
|
|
||
| updates: | ||
| # The target-branch is main (default branch) by default. | ||
| # Dependabot raises grouped PRs every Wednesday. | ||
| # Non-security patch/minor updates are merged on sprint Wednesdays (biweekly) | ||
| # and squash-merged into a single commit before promoting to the release branch. | ||
| # Security updates (critical/high) are handled immediately outside this cadence. | ||
|
|
||
| - package-ecosystem: "github-actions" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "daily" | ||
| interval: "weekly" | ||
| day: "wednesday" | ||
| groups: | ||
| artifact: | ||
| patterns: [ "actions/*artifact" ] | ||
| all-actions: | ||
| patterns: ["*"] | ||
| cooldown: | ||
| default-days: 7 | ||
|
|
||
| - package-ecosystem: "npm" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "daily" | ||
| interval: "weekly" | ||
| day: "wednesday" | ||
| groups: | ||
| next: | ||
| patterns: [ "next", "next*", "*next", "*next*" ] | ||
| react: | ||
| patterns: [ "react", "react*", "*react", "*react*" ] | ||
| aws-sdk: | ||
| patterns: [ "@aws-sdk/*" ] | ||
| jest: | ||
| patterns: [ "jest", "jest*", "*jest", "*jest*" ] | ||
| testing-library: | ||
| patterns: [ "@testing-library/*" ] | ||
| eslint: | ||
| patterns: [ "eslint", "eslint*", "*eslint", "*eslint*" ] | ||
| prettier: | ||
| patterns: [ "prettier", "prettier*", "*prettier", "*prettier*" ] | ||
| all-non-major: | ||
| patterns: ["*"] | ||
| update-types: ["minor", "patch"] | ||
| ignore: | ||
| - dependency-name: "next" | ||
| versions: [">=16.0.0"] | ||
| - dependency-name: "eslint-config-next" | ||
| versions: [">=16.0.0"] | ||
| - dependency-name: "eslint" | ||
| versions: [ ">=10.0.0" ] | ||
| versions: [">=10.0.0"] | ||
| cooldown: | ||
| default-days: 7 | ||
|
|
||
| - package-ecosystem: "terraform" | ||
| directories: [ "/infrastructure/modules/**" ] | ||
| directories: ["/infrastructure/modules/**"] | ||
| groups: | ||
| infrastructure-updates: | ||
| patterns: [ "*" ] | ||
| patterns: ["*"] | ||
| ignore: | ||
| - dependency-name: "*" | ||
| update-types: [ "version-update:semver-major", "version-update:semver-minor" ] | ||
| update-types: ["version-update:semver-major", "version-update:semver-minor"] | ||
| schedule: | ||
| interval: "weekly" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| name: "CI/CD dependency cooldown check" | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'package.json' | ||
| - 'package-lock.json' | ||
|
|
||
| jobs: | ||
| cooldown-check: | ||
| name: "Dependency cooldown verification" | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - name: "Checkout code" | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: "Set up Node.js" | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: '.tool-versions' | ||
|
|
||
| - name: "Install dependencies" | ||
| run: npm ci | ||
|
|
||
| - name: "Check dependency cooldown (changed packages only)" | ||
| run: ./scripts/reports/check-dependency-cooldown.sh 7 "origin/${{ github.base_ref }}" |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| # Checks that changed npm dependencies (direct and transitive) meet the | ||
| # required cooldown period. By default, diffs package-lock.json against a base | ||
| # ref to only check packages whose versions changed — i.e. the ones Dependabot | ||
| # is proposing to update. Falls back to checking all dependencies when no base | ||
| # ref is available. | ||
| # | ||
| # Usage: | ||
| # $ [options] ./check-dependency-cooldown.sh [cooldown_days] [base_ref] | ||
| # | ||
| # Options: | ||
| # cooldown_days Number of days since publication required (default: 4) | ||
| # base_ref Git ref to diff against (default: origin/main) | ||
| # Set to "--all" to check every dependency | ||
| # VERBOSE=true Show all the executed commands, default is 'false' | ||
|
|
||
| # ============================================================================== | ||
|
|
||
| function main() { | ||
|
|
||
| cd "$(git rev-parse --show-toplevel)" | ||
|
|
||
| local cooldown_days="${1:-4}" | ||
| local base_ref="${2:-origin/main}" | ||
|
|
||
| local now_epoch | ||
| now_epoch=$(date +%s) | ||
| local cooldown_seconds=$((cooldown_days * 86400)) | ||
| local threshold_epoch=$((now_epoch - cooldown_seconds)) | ||
|
|
||
| local packages | ||
| packages=$(determine-packages "$cooldown_days" "$base_ref") | ||
|
|
||
| if [[ -z "$packages" ]]; then | ||
| echo "No dependencies found. Run 'npm install' first." | ||
| exit 1 | ||
| fi | ||
|
|
||
| check-cooldown "$packages" "$cooldown_days" "$now_epoch" "$threshold_epoch" | ||
| } | ||
|
|
||
| # ============================================================================== | ||
|
|
||
| function determine-packages() { | ||
|
|
||
| local cooldown_days="$1" | ||
| local base_ref="$2" | ||
|
|
||
| if [[ "$base_ref" == "--all" ]]; then | ||
| echo "Dependency Cooldown Check — ALL dependencies (minimum ${cooldown_days} days)" >&2 | ||
| echo "=========================================================================" >&2 | ||
| echo "" >&2 | ||
| get-all-packages | ||
| else | ||
| echo "Dependency Cooldown Check — CHANGED dependencies vs ${base_ref} (minimum ${cooldown_days} days)" >&2 | ||
| echo "=========================================================================" >&2 | ||
| echo "" >&2 | ||
|
|
||
| if ! git rev-parse --verify "${base_ref}" >/dev/null 2>&1; then | ||
| echo "WARNING: Base ref '${base_ref}' not found. Falling back to checking all dependencies." >&2 | ||
| echo "" >&2 | ||
| get-all-packages | ||
| else | ||
| local changed | ||
| changed=$(get-changed-packages "$base_ref") | ||
|
|
||
| if [[ -z "$changed" ]]; then | ||
| echo "No dependency version changes detected against ${base_ref}. Nothing to check." >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "$changed" | ||
| fi | ||
| fi | ||
| } | ||
|
|
||
| function get-all-packages() { | ||
|
|
||
| local deps_json | ||
| deps_json=$(npm ls --all --json 2>/dev/null || echo '{}') | ||
| echo "$deps_json" | jq -r ' | ||
| [recurse(.dependencies // {} | to_entries[] | .value) | .dependencies // {} | to_entries[] | "\(.key)|\(.value.version // "unknown")"] | ||
| | unique[] | ||
| ' 2>/dev/null || echo "" | ||
| } | ||
|
|
||
| function get-changed-packages() { | ||
|
|
||
| local base_ref="$1" | ||
|
|
||
| # Extract changed packages from the lockfile diff. | ||
| # Lockfile v3 keys look like "node_modules/pkg" or "node_modules/scope/pkg". | ||
| # We look for lines adding a new "version" under a node_modules entry. | ||
| git diff "${base_ref}" -- package-lock.json \ | ||
| | node -e ' | ||
| const fs = require("fs"); | ||
| const diff = fs.readFileSync(0, "utf8"); | ||
| const lockfile = JSON.parse(fs.readFileSync("package-lock.json", "utf8")); | ||
| const pkgs = lockfile.packages || {}; | ||
| // Collect every node_modules path mentioned in added lines of the diff | ||
| const changedPaths = new Set(); | ||
| for (const line of diff.split("\n")) { | ||
| // Hunk headers in the diff reference keys like "node_modules/foo" | ||
| const keyMatch = line.match(/^[+]\s*"(node_modules\/.+?)":\s*\{/); | ||
| if (keyMatch) changedPaths.add(keyMatch[1]); | ||
| } | ||
| // Also detect version-line changes and map them back | ||
| let currentPath = null; | ||
| for (const line of diff.split("\n")) { | ||
| const pathMatch = line.match(/^[\s+"]*"?(node_modules\/.+?)"?\s*:\s*\{/); | ||
| if (pathMatch) currentPath = pathMatch[1]; | ||
| if (currentPath && /^\+.*"version"/.test(line)) changedPaths.add(currentPath); | ||
| } | ||
| const seen = new Set(); | ||
| for (const p of changedPaths) { | ||
| const entry = pkgs[p]; | ||
| if (!entry || !entry.version) continue; | ||
| // Derive package name from the path (handles scoped packages) | ||
| const name = p.replace(/^.*node_modules\//, ""); | ||
| const key = name + "|" + entry.version; | ||
| if (!seen.has(key)) { seen.add(key); console.log(key); } | ||
| } | ||
| ' 2>/dev/null || echo "" | ||
| } | ||
|
|
||
| function check-cooldown() { | ||
|
|
||
| local packages="$1" | ||
| local cooldown_days="$2" | ||
| local now_epoch="$3" | ||
| local threshold_epoch="$4" | ||
| local exit_code=0 | ||
| local pass_count=0 | ||
| local fail_count=0 | ||
| local skip_count=0 | ||
|
|
||
| local count | ||
| count=$(echo "$packages" | wc -l | tr -d ' ') | ||
| echo "Checking ${count} package(s)..." | ||
| echo "" | ||
|
|
||
| printf "%-45s %-15s %-12s %s\n" "Package" "Version" "Days ago" "Status" | ||
| printf "%-45s %-15s %-12s %s\n" "-------" "-------" "--------" "------" | ||
|
|
||
| while IFS='|' read -r name version; do | ||
| [[ -z "$name" ]] && continue | ||
|
|
||
| if [[ "$version" == "unknown" || -z "$version" ]]; then | ||
| printf "%-45s %-15s %-12s %s\n" "$name" "$version" "-" "SKIP" | ||
| ((skip_count += 1)) | ||
| continue | ||
| fi | ||
|
|
||
| # Query npm registry for the publish date of this specific version | ||
| local time_json | ||
| time_json=$(npm view "${name}" time --json 2>/dev/null || echo "{}") | ||
| local publish_date | ||
| publish_date=$(echo "$time_json" | jq -r '."'"${version}"'" // empty' 2>/dev/null || echo "") | ||
|
|
||
| if [[ -z "$publish_date" ]]; then | ||
| printf "%-45s %-15s %-12s %s\n" "$name" "$version" "-" "SKIP" | ||
| ((skip_count += 1)) | ||
| continue | ||
| fi | ||
|
|
||
| # Use node for portable date parsing (works on both macOS and Linux) | ||
| local publish_epoch | ||
| publish_epoch=$(node -e "console.log(Math.floor(new Date(process.argv[1]).getTime()/1000))" "$publish_date") | ||
|
|
||
| local days_ago=$(( (now_epoch - publish_epoch) / 86400 )) | ||
|
|
||
| if [[ "$publish_epoch" -gt "$threshold_epoch" ]]; then | ||
| printf "%-45s %-15s %-12s %s\n" "$name" "$version" "${days_ago}d" "FAIL" | ||
| ((fail_count += 1)) | ||
| exit_code=1 | ||
| else | ||
| printf "%-45s %-15s %-12s %s\n" "$name" "$version" "${days_ago}d" "PASS" | ||
| ((pass_count += 1)) | ||
| fi | ||
| done <<< "$packages" | ||
|
|
||
| echo "" | ||
| echo "Results: ${pass_count} passed, ${fail_count} failed, ${skip_count} skipped" | ||
| echo "Cooldown period: ${cooldown_days} days" | ||
|
|
||
| if [[ "$exit_code" -ne 0 ]]; then | ||
| echo "" | ||
| echo "ERROR: Some dependencies do not meet the ${cooldown_days}-day cooldown period." | ||
| echo "These versions were published too recently and may not be stable." | ||
| fi | ||
|
|
||
| exit "$exit_code" | ||
| } | ||
|
|
||
| # ============================================================================== | ||
|
|
||
| function is-arg-true() { | ||
|
|
||
| if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then | ||
| return 0 | ||
| else | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| # ============================================================================== | ||
|
|
||
| is-arg-true "${VERBOSE:-false}" && set -x | ||
|
|
||
| main "$@" | ||
|
|
||
| exit 0 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.