diff --git a/.github/actions/next-stats-action/Dockerfile b/.github/actions/next-stats-action/Dockerfile index 9eb8e8b16d11..bddae70bfd56 100644 --- a/.github/actions/next-stats-action/Dockerfile +++ b/.github/actions/next-stats-action/Dockerfile @@ -1,18 +1,19 @@ # syntax=docker.io/docker/dockerfile:1 -FROM ubuntu:22.04 +FROM ubuntu:24.04 LABEL com.github.actions.name="Next.js PR Stats" LABEL com.github.actions.description="Compares stats of a PR with the main branch" LABEL repository="https://github.com/vercel/next-stats-action" -RUN apt update && apt upgrade -y -RUN apt install unzip wget curl nano htop screen build-essential pkg-config libssl-dev git build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libreadline-dev libffi-dev python3 moreutils jq iproute2 openssh-server sudo whois dnsutils apache2-utils -y +# use apt-get instead of apt, because apt does not have a stable CLI interface +RUN apt-get update && apt-get upgrade -y +RUN apt-get install unzip wget curl nano htop screen build-essential pkg-config libssl-dev git build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libreadline-dev libffi-dev python3 moreutils jq iproute2 openssh-server sudo whois dnsutils apache2-utils -y RUN ln $(which python3) /usr/bin/python RUN curl -sfLS https://install-node.vercel.app/v20.9.0 | bash -s -- -f -RUN npm i -g corepack@0.31 +RUN npm i -g corepack@0.34.6 RUN corepack enable WORKDIR /next-stats @@ -21,8 +22,8 @@ WORKDIR /next-stats COPY package.json ./ RUN pnpm install --production -# caching optimization -COPY . . +# Do this copy after the pnpm install to optimize docker caching +COPY --exclude=node_modules . . RUN git config --global user.email 'stats@localhost' && \ git config --global user.name 'next stats' diff --git a/.github/actions/next-stats-action/src/index.js b/.github/actions/next-stats-action/src/index.js index 666bf561fa49..0f66b85c6cff 100644 --- a/.github/actions/next-stats-action/src/index.js +++ b/.github/actions/next-stats-action/src/index.js @@ -110,25 +110,36 @@ if (!allowedActions.has(actionInfo.actionName) && !actionInfo.isRelease) { logger(`Running initial build for ${dir}`) if (!actionInfo.skipClone) { const usePnpm = existsSync(path.join(dir, 'pnpm-lock.yaml')) + if (usePnpm) { + // TODO: we can remove this explicit `corepack use` once Next.js + // 16.3 is released, but we must override it for now because 16.2 uses + // pnpm 9.6.0, which supports different arguments. `diffRepoDir` + // points to the most recent stable tag. + await exec.spawnPromise('corepack use pnpm@10.33.0', { + cwd: dir, + }) + } if (!statsConfig.skipInitialInstall) { - await exec.spawnPromise( - `cd ${dir}${ - usePnpm - ? // --no-frozen-lockfile is used here to tolerate lockfile - // changes from merging latest changes - // --package-import-method=copy avoids hardlink issues on - // self-hosted runners, and the store is colocated with the - // workdir to avoid EXDEV copy failures on overlayfs runners. - ` && pnpm install --no-frozen-lockfile --package-import-method=copy --store-dir=${pnpmStoreDir}` - : ' && yarn install --network-timeout 1000000' - }`, - { env: { PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' } } - ) + const command = usePnpm + ? 'pnpm install ' + + // tolerate lockfile changes from merging latest changes + '--no-frozen-lockfile ' + + // avoid hardlink issues on self-hosted runners, + '--package-import-method=clone-or-copy ' + + // the store is colocated with the workdir to avoid EXDEV copy + // failures on overlayfs runners. + `--store-dir=${pnpmStoreDir}` + : 'yarn install --network-timeout=1000000' + await exec.spawnPromise(command, { + env: { PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' }, + cwd: dir, + }) await exec.spawnPromise( statsConfig.initialBuildCommand || - `cd ${dir} && ${usePnpm ? 'pnpm build' : 'echo built'}` + (usePnpm ? 'pnpm build' : 'echo built'), + { cwd: dir } ) } }