# Shipping Build Artifacts > Haz del build una puerta real sobre lo que distribuyes: entradas ausentes que no abortan, límites de tamaño solo superiores, listas de archivos que se desfasan, bundles obsoletos y verificación contra el árbol fuente en vez del artefacto. Fuente: https://skillsagentes.com/skills/kajisho5/ffmpeg-skill/shipping-build-artifacts Markdown: https://skillsagentes.com/skills/kajisho5/ffmpeg-skill/shipping-build-artifacts.md Repositorio: https://github.com/kajisho5/ffmpeg-skill Autor: kajisho5 Licencia: MIT Actualizado: hace 4 días Coste de contexto: 149 tok instalada, 2.1k tok al activarse, 2.1k tok con todos los archivos del bundle Bundle: 1 archivo, 8 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent claude-code # Cursor npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent cursor # Codex npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent codex # Gemini CLI npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent gemini # Windsurf npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent windsurf # Cline npx -y skills add kajisho5/ffmpeg-skill --skill build-artifacts --agent cline ``` ## Qué hace - Al escribir o revisar un script de build, exige que una entrada declarada que falte termine con salida distinta de cero, no con una advertencia. - Añade un límite inferior a las comprobaciones de tamaño del artefacto y verifica que el número de entradas coincida con lo esperado. - Comprueba que la lista de archivos empaquetados esté derivada de los entrypoints o validada contra el manifiesto y el HTML de entrada. - En CI, reconstruye los bundles commiteados y hace fallar el pipeline si hay diferencias; fija el constructor a una versión exacta. - Antes de publicar, extrae la versión con un parser, la compara con el manifiesto, lista el contenido del artefacto y lo instala fuera del repo para ejercitar un símbolo real. ## Cuándo usarla - Al escribir o revisar un script de build o empaquetado. - Al revisar un paso de copia a `dist/`. - Al trabajar en un flujo de release que suba un zip o un instalador. - Al tratar con un activo compilado versionado en el repositorio. ## Qué la activa - "El build avisa de que falta un archivo pero sale con 0 y el release sube un zip roto; ¿cómo lo hago fallar?" - "Revisa el script que copia a dist/ y comprueba que no pueda generar un paquete incompleto." - "El bundle de web/ está commiteado pero no se regenera cuando cambia el código; ¿cómo lo protejo en CI?" - "Antes de publicar, verifica que el artefacto tenga todos los entrypoints y que el binario arranque de verdad." - "El script de release usa grep -P, que aborta en macOS; cámbialo a algo portable y con test de versión." ## Antes de instalar - Necesita en el PATH: jq, npx, python ## Archivos - SKILL.md — 8 KB ## SKILL.md Reproducido tal cual desde kajisho5/ffmpeg-skill bajo MIT. Esta sección es el documento original y está en inglés. # Shipping Build Artifacts Lint, type-check, and tests run against the source tree. What users install is a *different* set of bytes — assembled by a script that most gates never look at, then uploaded by a workflow that trusts whatever the script left behind. Every failure below ships a broken or stale artifact under fully green CI. ## A script that warns and exits 0 is not a gate The shape is universal: a declared list of inputs, a copy loop, a friendly warning when one is missing. ```js for (const f of DIST_FILES) { if (!fs.existsSync(f)) { console.warn(`Warning: ${f} not found, skipping`); // build "succeeds" continue; } fs.copyFileSync(f, path.join("dist", f)); } ``` Move one required file aside and the script prints a line nobody reads, exits 0, and produces a `dist/` without it. Nothing downstream notices: the test job ran against the source tree, and the release job zips `dist/` and attaches it to a public release. The artifact is wholly non-functional — the entrypoint imports a file that isn't there — and the failure is discovered by users. ```js const missing = DIST_FILES.filter((f) => !fs.existsSync(f)); if (missing.length) { console.error(`Missing build inputs: ${missing.join(", ")}`); process.exit(1); } ``` The rule: inside a build script, `warn` may only describe something the artifact survives without. If you cannot say what still works when that file is absent, it is an error and the process must exit non-zero. ## Bound the artifact size on *both* sides A packaging check with only a ceiling — "fail if the zip exceeds 500 KB" — is a cost guard, not a correctness one. A build that silently dropped half its files is *smaller*, so it passes the only check that exists. ```js assert(bytes < 500 * 1024, "package too large"); assert(bytes > 20 * 1024, "package suspiciously small — inputs likely missing"); assert(entries.length === DIST_FILES.length, "package entry count mismatch"); ``` Better still, assert on contents rather than a proxy: list the archive's entries and compare against the set the entrypoints require. ## Derive the file list, or check it against the entrypoints `DIST_FILES` — like a build backend's `only-include`, or a hand-written `package_data` — is a *second* copy of "what this app is made of." The first copy is the manifest, the entry HTML, and the import graph. They drift in one direction: someone adds `utils.js`, references it from the popup, and forgets the copy list. The build stays green and the feature is dead in the packaged app. Either derive the list (bundle from the real entrypoints), or add a check that every path referenced by the manifest and by `