From cdb32098e879bad80d385d60ac8df776cc0f275f Mon Sep 17 00:00:00 2001 From: Blake Gentry Date: Wed, 13 May 2026 16:20:15 -0500 Subject: [PATCH] harden dependency update handling Add npm configuration that enforces a minimum release age, blocks git package refs, and requires the expected Node/npm engine versions. CI, release packaging, and Docker builds now use Node 24.14.1 with `npm ci` so installs follow the committed lockfile and project npm policy. Extend Dependabot coverage and cooldowns for Docker, Docker Compose, and GitHub Actions so regular dependency update PRs are delayed and reviewed through the usual workflow. Pin Docker and compose image refs to explicit patch tags and digests, including Postgres 18 for local development, so image changes happen through visible dependency updates instead of silent tag drift. --- .github/dependabot.yml | 29 ++++++++++++++++++++++ .github/workflows/ci.yaml | 12 ++++----- .github/workflows/package-and-release.yaml | 4 +-- .npmrc | 3 +++ .prettierignore | 3 ++- Dockerfile | 10 ++++---- Dockerfile.pro | 10 ++++---- docker-compose.dev.yaml | 4 +-- package-lock.json | 4 +++ package.json | 4 +++ 10 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 .npmrc diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e31e016f..b4828b97 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,6 +20,8 @@ updates: directory: "/" schedule: interval: "monthly" + cooldown: + default-days: 7 open-pull-requests-limit: 10 labels: - "dependencies" @@ -36,6 +38,21 @@ updates: update-types: ["version-update:semver-major", "version-update:semver-minor"] + - package-ecosystem: "docker-compose" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 7 + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "docker" + commit-message: + prefix: "docker" + allow: + - dependency-type: "direct" + - package-ecosystem: "gomod" directories: - "**/*" @@ -84,3 +101,15 @@ updates: tanstack: patterns: - "@tanstack/*" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 7 + labels: + - "dependencies" + - "github-actions" + commit-message: + prefix: "github-actions" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 640d5ee5..bd741233 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -133,7 +133,7 @@ jobs: strategy: matrix: node-version: - - "22.18.0" + - "24.14.1" fail-fast: false timeout-minutes: 5 @@ -155,7 +155,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install dependencies - run: npm install + run: npm ci shell: sh - name: Test ๐Ÿงช @@ -170,7 +170,7 @@ jobs: strategy: matrix: node-version: - - "22.18.0" + - "24.14.1" fail-fast: false timeout-minutes: 5 @@ -189,7 +189,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install dependencies - run: npm install + run: npm ci shell: sh - name: Cache ESLint @@ -231,10 +231,10 @@ jobs: with: cache: "npm" cache-dependency-path: package-lock.json - node-version: "22.18.0" + node-version: "24.14.1" - name: Install dependencies - run: npm install + run: npm ci shell: sh - name: Build UI bundle diff --git a/.github/workflows/package-and-release.yaml b/.github/workflows/package-and-release.yaml index e310ccff..40a2e9b7 100644 --- a/.github/workflows/package-and-release.yaml +++ b/.github/workflows/package-and-release.yaml @@ -59,10 +59,10 @@ jobs: with: cache: "npm" cache-dependency-path: package-lock.json - node-version: "22.18.0" + node-version: "24.14.1" - name: Install dependencies - run: npm install + run: npm ci shell: sh - name: Build JS ๐Ÿ—๏ธ diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..3d509f07 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +allow-git=none +engine-strict=true +min-release-age=3 diff --git a/.prettierignore b/.prettierignore index 62af73cd..6de95e1e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,4 +10,5 @@ public/** src/routeTree.gen.ts # Other files to ignore -package-lock.json +package-lock.json +.npmrc diff --git a/Dockerfile b/Dockerfile index 34930632..02ba22e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ # syntax=docker/dockerfile:1 -FROM node:22-alpine AS build-ui +FROM node:24.14.1-alpine@sha256:8510330d3eb72c804231a834b1a8ebb55cb3796c3e4431297a24d246b8add4d5 AS build-ui WORKDIR /app -COPY package.json package-lock.json ./ -RUN npm install +COPY .npmrc package.json package-lock.json ./ +RUN npm ci ENV NODE_ENV=production COPY vite.config.ts tsconfig.json tsconfig.node.json tsr.config.json ./ COPY public ./public @@ -12,7 +12,7 @@ COPY src ./src RUN npx vite build # Build the Go binary, including embedded UI files: -FROM golang:1.25.9-alpine AS build-go +FROM golang:1.25.10-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build-go WORKDIR /go/src/riverui COPY go.mod go.sum ./ @@ -29,7 +29,7 @@ COPY --from=build-ui /app/dist ./dist RUN go build -trimpath -ldflags="-w -s -buildid=" -o /bin/riverui ./cmd/riverui -FROM alpine:3.23.4 +FROM alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 ENV PATH_PREFIX="/" COPY --from=build-go /bin/riverui /bin/riverui CMD ["/bin/sh", "-c", "/bin/riverui -prefix=$PATH_PREFIX"] diff --git a/Dockerfile.pro b/Dockerfile.pro index c7aa83f1..632fbfd7 100644 --- a/Dockerfile.pro +++ b/Dockerfile.pro @@ -1,9 +1,9 @@ # syntax=docker/dockerfile:1 -FROM node:22-alpine AS build-ui +FROM node:24.14.1-alpine@sha256:8510330d3eb72c804231a834b1a8ebb55cb3796c3e4431297a24d246b8add4d5 AS build-ui WORKDIR /app -COPY package.json package-lock.json ./ -RUN npm install +COPY .npmrc package.json package-lock.json ./ +RUN npm ci ENV NODE_ENV=production COPY vite.config.ts tsconfig.json tsconfig.node.json tsr.config.json ./ COPY public ./public @@ -12,7 +12,7 @@ COPY src ./src RUN npx vite build # Build the Go binary, including embedded UI files: -FROM golang:1.25.9-alpine AS build-go +FROM golang:1.25.10-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build-go WORKDIR /go/src/riverui # Download main module dependencies first @@ -42,7 +42,7 @@ COPY --from=build-ui /app/dist ./dist WORKDIR /go/src/riverui/riverproui RUN go build -trimpath -ldflags="-w -s -buildid=" -o /bin/riverproui ./cmd/riverproui -FROM alpine:3.23.4 +FROM alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 ENV PATH_PREFIX="/" COPY --from=build-go /bin/riverproui /bin/riverproui CMD ["/bin/sh", "-c", "/bin/riverproui -prefix=$PATH_PREFIX"] diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index 4af8ef9e..aec72fab 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -2,7 +2,7 @@ name: riverui-dev services: postgres: - image: "postgres:16-alpine" + image: "postgres:18.3-alpine@sha256:54451ecb8ab38c24c3ec123f2fd501303a3a1856a5c66e98cecf2460d5e1e9d7" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres @@ -16,7 +16,7 @@ services: ports: - "5432:5432" migrate: - image: "golang:1.25-alpine" + image: "golang:1.25.10-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45" depends_on: postgres: condition: "service_healthy" diff --git a/package-lock.json b/package-lock.json index 224a73bf..0260193d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,10 @@ "": { "name": "river-ui-vite", "version": "0.0.0", + "engines": { + "node": ">=24.14.1", + "npm": ">=11.10.0" + }, "dependencies": { "@dagrejs/dagre": "^3.0.0", "@headlessui/react": "^2.2.10", diff --git a/package.json b/package.json index 15350bf9..73f1543b 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "private": true, "version": "0.0.0", "type": "module", + "engines": { + "node": ">=24.14.1", + "npm": ">=11.10.0" + }, "dependencies": { "@dagrejs/dagre": "^3.0.0", "@headlessui/react": "^2.2.10",