Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Feb 2026 12:28:11 +0000
From:      Hiroki Tagato <tagattie@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: dc5d1ed9379b - main - Mk/Uses/electron.mk: Secure reproducibility of node modules tarball in case of pnpm
Message-ID:  <69a2df5b.3f79f.35224cf8@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by tagattie:

URL: https://cgit.FreeBSD.org/ports/commit/?id=dc5d1ed9379bf9b2bebfe8631b2caa99a7cf0819

commit dc5d1ed9379bf9b2bebfe8631b2caa99a7cf0819
Author:     Hiroki Tagato <tagattie@FreeBSD.org>
AuthorDate: 2026-02-28 12:25:03 +0000
Commit:     Hiroki Tagato <tagattie@FreeBSD.org>
CommitDate: 2026-02-28 12:28:02 +0000

    Mk/Uses/electron.mk: Secure reproducibility of node modules tarball in case of pnpm
    
    Formerly, node_modules directories produced by "pnpm install" were
    used for node modules tarball. However, .modules.yaml file contained
    in the tarball is not reliably reproducible and differs in some way
    depending on the environment and/or timing where/when the tarball was
    produced.
    
    Instead of relying on node_modules directories, we use pnpm
    store (produced by "pnpm fetch") for node modules tarball. We can use
    the tarball later to install node modules into appropriate directories
    using "pnpm install". Note that the timestamp "checkedAt" in each JSON
    file in the pnpm store is reset to 0 to ensure reproducibility.
    
    Reported by:    feld (via private email)
    Tested by:      feld
---
 Mk/Uses/electron.mk | 53 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/Mk/Uses/electron.mk b/Mk/Uses/electron.mk
index afbf0588cf09..1e3905813bc0 100644
--- a/Mk/Uses/electron.mk
+++ b/Mk/Uses/electron.mk
@@ -378,11 +378,14 @@ NPM_REBUILD_CMD?=	${NPM_CMDNAME} rebuild
 .    endif
 .  elif ${_NODEJS_NPM} == pnpm
 NPM_LOCKFILE?=		pnpm-lock.yaml
-NPM_MODULE_CACHE?=	node_modules
+NPM_MODULE_CACHE?=	pnpm-store
 NPM_CMDNAME?=		pnpm
-NPM_CACHE_SETUP_CMD?=	${NPM_CMDNAME} set extendNodePath false
-NPM_FETCH_CMD?=		${NPM_CMDNAME} install
-NPM_FETCH_FLAGS+=	--frozen-lockfile --ignore-scripts --loglevel=error
+NPM_CACHE_SETUP_CMD?=	${DO_NADA}
+NPM_FETCH_CMD?=		${NPM_CMDNAME} fetch
+NPM_FETCH_FLAGS+=	--frozen-lockfile --ignore-scripts --loglevel=error \
+			--store-dir ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}
+NPM_EXTRACT_CMD?=	${NPM_CMDNAME} install
+NPM_EXTRACT_FLAGS+=	${NPM_FETCH_FLAGS} --offline
 NPM_EXEC_CMD?=		${NPM_CMDNAME} exec
 NPM_REBUILD_CMD?=	${NPM_CMDNAME} rebuild
 .  endif
@@ -460,7 +463,7 @@ DISTFILES+=		${_DISTFILE_prefetch}:prefetch
 .    if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == yarn1
 FETCH_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR}
 .    elif ${_NODEJS_NPM} == pnpm
-FETCH_DEPENDS+=	${YQ_CMD}:textproc/yq
+FETCH_DEPENDS+=	${JQ_CMD}:textproc/jq
 .    endif
 
 electron-fetch-node-modules:
@@ -475,16 +478,11 @@ electron-fetch-node-modules:
 			cd $${dir} && \
 			${SETENV} ${MAKE_ENV} ${NPM_FETCH_CMD} ${NPM_FETCH_FLAGS}; \
 			${RM} $${dir}/${NPM_MODULE_CACHE}/.gitignore; \
-			if [ -f $${dir}/${NPM_MODULE_CACHE}/.modules.yaml ]; then \
-				${YQ_CMD} -yi 'del(.prunedAt, .storeDir)' \
-					$${dir}/${NPM_MODULE_CACHE}/.modules.yaml; \
-			fi; \
-			${RM} $${dir}/${NPM_MODULE_CACHE}/.pnpm-workspace-state*.json; \
 		done; \
 	fi
 
 electron-archive-node-modules:
-.    if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == pnpm
+.    if ${_NODEJS_NPM} == npm
 	@if [ -d ${WRKDIR}/node-modules-cache ]; then \
 		${ECHO_MSG} "===>  Archiving prefetched node modules"; \
 		for dir in `${FIND} -s ${WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \
@@ -501,7 +499,20 @@ electron-archive-node-modules:
 			${RM} -r ${WRKDIR}; \
 		fi; \
 	fi
-.    elif ${_NODEJS_NPM:Myarn*}
+.    elif ${_NODEJS_NPM:Myarn*} || ${_NODEJS_NPM} == pnpm
+.      if ${_NODEJS_NPM} == pnpm
+	@if [ -d ${WRKDIR}/node-modules-cache ]; then \
+		${FIND} ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE} \
+			-type f -name '*.json' -exec ${SH} -c ' \
+			for f do \
+				${JQ_CMD} -c "walk(if type == \"object\" and has(\"checkedAt\") then .checkedAt = 0 else . end)" $${f} > $${f}.tmp && mv $${f}.tmp $${f}; \
+			done \
+			' ${SH} {} ';'; \
+		for dir in projects tmp; do \
+			${RM} -r ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/*/$${dir}; \
+		done; \
+	fi
+.      endif
 	@if [ -d ${WRKDIR}/node-modules-cache ]; then \
 		${ECHO_MSG} "===>  Archiving prefetched node modules"; \
 		cd ${WRKDIR}/node-modules-cache && \
@@ -554,7 +565,7 @@ electron-copy-package-file:
 .    endif
 
 electron-install-node-modules:
-.    if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == pnpm
+.    if ${_NODEJS_NPM} == npm
 	@${ECHO_MSG} "===>  Moving prefetched node modules to ${NPM_EXTRACT_WRKSRC}"
 	@if [ -d ${EXTRACT_WRKDIR}/node-modules-cache ]; then \
 		for dir in `${FIND} -s ${EXTRACT_WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \
@@ -582,6 +593,22 @@ electron-install-node-modules:
 		cd ${NPM_EXTRACT_WRKSRC} && \
 		${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \
 	fi
+.    elif ${_NODEJS_NPM} == pnpm
+	@${ECHO_MSG} "===>  Installing node modules from prefetched cache"
+	@if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \
+		${MKDIR} ${WRKDIR}/node-modules-cache; \
+		${MV} ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ${WRKDIR}/node-modules-cache; \
+	fi
+	@if [ -d ${PKGJSONSDIR} ]; then \
+		cd ${PKGJSONSDIR} && \
+		for dir in `${FIND} . -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \
+			cd ${NPM_EXTRACT_WRKSRC}/$${dir} && \
+			${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \
+		done; \
+	else \
+		cd ${NPM_EXTRACT_WRKSRC} && \
+		${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \
+	fi
 .    endif
 .  endif # _ELECTRON_FEATURE_EXTRACT
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69a2df5b.3f79f.35224cf8>