# CI Arboretum : build + tests sur Node 22/24, puis smoke de packaging npx. name: CI on: push: branches: [main] pull_request: branches: [main] permissions: contents: read jobs: test: name: Build & test (Node ${{ matrix.node }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: node: [22, 24] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} cache: npm - run: npm ci - run: npm run typecheck - run: npm run build - run: npm run build:site - run: npx vitest run # packages/desktop est HORS des workspaces (CI daemon allégée) : sans cette étape, son code # n'était JAMAIS typechecké avant un tag de release. Une seule version de Node suffit, et # ELECTRON_SKIP_BINARY_DOWNLOAD évite de télécharger ~100 Mo de binaire Electron dont un # typecheck n'a aucun besoin (c'est ce qui rendait le job très long). - name: Typecheck desktop shell if: matrix.node == '22' env: ELECTRON_SKIP_BINARY_DOWNLOAD: '1' run: | npm --prefix packages/desktop ci npm run typecheck:desktop pack-smoke: name: Pack & boot smoke (Node 22) runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: npm - run: npm ci - run: npm run build # @arboretum/shared (paquet workspace NON publié) est INLINÉ dans dist/_shared au prepack # (scripts/inline-shared.mjs) : le tarball est 100 % autonome : aucun node_modules embarqué, # aucune bundleDependency, aucun symlink. On packe en mode workspace (-w), EXACTEMENT comme # le fait « npm publish » dans release.yml, puis on l'installe seul comme un vrai consommateur. - name: Pack tarball run: | rm -rf /tmp/tarballs && mkdir -p /tmp/tarballs npm pack -w @johanleroy/git-arboretum --pack-destination /tmp/tarballs ls -l /tmp/tarballs - name: Assert the package is self-contained (@arboretum/shared inlined) run: | tgz=$(ls /tmp/tarballs/*.tgz) rm -rf /tmp/inspect && mkdir -p /tmp/inspect && tar -xzf "$tgz" -C /tmp/inspect test -f /tmp/inspect/package/dist/_shared/index.js \ || { echo "ERREUR: dist/_shared/index.js absent de $tgz : inline-shared n'a pas tourné ?"; exit 1; } # On cherche les vraies formes d'IMPORT, pas la simple chaîne : un commentaire de code qui # mentionne le paquet (pour dire où vit la règle partagée) est légitime et ne casse rien. if grep -rqE "(from|require\(|import\()[[:space:]]*['\"]@arboretum/shared" /tmp/inspect/package/dist; then echo "ERREUR: import bare '@arboretum/shared' encore présent dans le JS publié" grep -rnE "(from|require\(|import\()[[:space:]]*['\"]@arboretum/shared" /tmp/inspect/package/dist; exit 1 fi echo "OK: paquet autonome : shared inliné dans dist/_shared, aucun import externe" - name: Install tarball in an empty project run: | mkdir /tmp/smoke cd /tmp/smoke npm init -y npm i /tmp/tarballs/*.tgz - name: Boot smoke (expect 401 on /api/v1/sessions) run: | cd /tmp/smoke timeout 30 node_modules/.bin/arboretum --port 7999 --db ./t.db & server_pid=$! code=000 for i in $(seq 1 20); do sleep 0.5 code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:7999/api/v1/sessions || true) if [ "$code" = "401" ]; then break; fi done echo "GET /api/v1/sessions -> HTTP $code" kill "$server_pid" 2>/dev/null || true test "$code" = "401" lint-dashes: # Interdit tout tiret cadratin (U+2014) ou demi-cadratin (U+2013) dans les fichiers suivis. # Utiliser a la place : point median, deux-points, virgule, ou tiret simple pour les plages. # `-I` ignore les fichiers BINAIRES : une icone PNG/ICO peut contenir ces octets par hasard, ce # qui faisait echouer la garde sans aucun texte fautif. Exclusion restante : les captures brutes # du terminal (fichiers texte, fidelite des fixtures de dialogue). name: No em/en dashes runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Fail on U+2014 / U+2013 (outside allow-list) run: | if git grep -nPI '[\x{2014}\x{2013}]' -- . \ ':(exclude)packages/server/test/fixtures/dialogs/*.raw'; then echo "::error::Tiret cadratin/demi-cadratin trouve. Utiliser point median, deux-points, virgule ou tiret simple (plages)." exit 1 fi