Integración con CI
Usa pcpm ci para instalaciones estrictas y reproducibles en CI.
CI es donde PCPM se amortiza. Un build clean-room de una solución .NET
grande que tardaba minutos se convierte en unos pocos segundos,
porque el store global ya está caliente en la mayoría de runners de
CI, y pcpm ci es lo bastante estricto como para detectar drift de
“funciona en mi máquina”.
La forma de una ejecución de CI con PCPM
- Restaurar:
pcpm ci— instala exactamente lo que dicepcpm.lock, sin flotantes, sin sorpresas, falla rápido si el lockfile está desactualizado. - Build:
dotnet build— sin cambios respecto a un pipeline sin PCPM. - Test:
dotnet test— sin cambios.
Puedes hacer los pasos 2 y 3 con una sola invocación de dotnet test;
PCPM solo se ocupa del paso 1.
¿Por qué pcpm ci y no pcpm install?
pcpm install es un comando para desarrolladores. Hace lo posible
por seguir adelante incluso si el lockfile está desactualizado — por
ejemplo, si haces pcpm add Foo y olvidas commitear pcpm.lock,
pcpm install re-resolverá y actualizará el lockfile.
pcpm ci es un comando de CI. Hace lo siguiente:
- Rehúsa ejecutarse si falta
pcpm.lock. - Rehúsa ejecutarse si
Directory.Packages.propsypcpm.lockno coinciden. - Nunca escribe en
pcpm.lock. O bien tiene éxito con las versiones exactas del lockfile, o bien falla con un exit no-cero.
Esto atrapa una clase de bugs que de otro modo serían silenciosos:
alguien sube una versión en CPM y olvida actualizar el lockfile. En
la máquina del desarrollador, pcpm install re-resolvería y la nueva
versión se colaría. En CI, pcpm ci fallaría y el build quedaría
rojo.
GitHub Actions
name: build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Cache PCPM store
uses: actions/cache@v4
with:
path: |
~/.local/share/pcpm/store
~/.nuget/packages
key: pcpm-${{ hashFiles('**/pcpm.lock') }}
restore-keys: |
pcpm-
- name: Install PCPM
run: dotnet tool install --global pcpm
- name: Restore
run: pcpm ci
- name: Build
run: dotnet build --no-restore -c Release
- name: Test
run: dotnet test --no-build -c Release
El paso de caché es lo que hace esto rápido. La clave de caché es
pcpm.lock, así que el store se reutiliza mientras el lockfile sea
el mismo. Una restauración típica con caché tarda 2-5 segundos en
una solución de 50 proyectos.
GitLab CI
build:
image: mcr.microsoft.com/dotnet/sdk:10.0
variables:
PCPM_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pcpm"
cache:
key:
files:
- pcpm.lock
paths:
- .cache/pcpm
before_script:
- dotnet tool install --global pcpm
script:
- pcpm ci
- dotnet build --no-restore -c Release
- dotnet test --no-build -c Release
Notas sobre la caché
- Clave de caché:
pcpm.lockes la granularidad correcta. Un cambio en el lockfile invalida la caché, por diseño. - Ruta de caché: Es el store global. En Linux es
~/.local/share/pcpm/store; en macOS,~/Library/Application Support/pcpm/store; en Windows,%LOCALAPPDATA%\pcpm\store. Usapcpm store pathpara obtener el valor exacto en tiempo de ejecución. - Cachea también
~/.nuget/packages: el layout con hardlinks hace que esto sea pequeño (unos pocos cientos de MB en soluciones grandes), pero cachearlo hace quedotnet restoremismo sea un no-op. - No caches entre ramas en builds de PR: un PR que añade una dependencia no debería contaminar la caché de la rama principal. La mayoría de proveedores de CI lo manejan automáticamente (la clave de caché incluye la rama).
Pre-flight local
Antes de hacer push, puedes ejecutar el mismo comando en local:
pcpm ci
Si pasa en local, pasará en CI. Esto es intencional — pcpm ci es
el mismo binario en ambos entornos.