name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'

      - name: Setup bun
        run: npm install -g bun

      # The build job must resolve registry @lilith/* deps (gov-detection,
      # configs) the same way publish does. Without this it installs against the
      # repo bunfig (legacy npm.black.lan, empty token) and silently under-installs —
      # the reason every prior `build` run failed even on main.
      - name: Configure registry
        run: |
          echo "@lilith:registry=https://forge.nasty.sh/api/packages/lilith/npm/" > .npmrc
          echo "//forge.nasty.sh/api/packages/lilith/npm/:_authToken=${NPM_TOKEN}" >> .npmrc

      - name: Install dependencies
        run: bun install --no-frozen-lockfile

      - name: Build
        run: bun run build

      - name: Typecheck
        run: bun run typecheck

  publish:
    needs: build
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    env:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'

      - name: Setup bun
        run: npm install -g bun

      - name: Configure registry
        run: |
          echo "@lilith:registry=https://forge.nasty.sh/api/packages/lilith/npm/" > .npmrc
          echo "//forge.nasty.sh/api/packages/lilith/npm/:_authToken=${NPM_TOKEN}" >> .npmrc
          echo "strict-ssl=false" >> .npmrc

      - name: Transform workspace deps
        run: |
          node -e "
            const fs = require('fs');
            const path = require('path');
            const transform = (deps) => {
              if (!deps) return deps;
              for (const [k, v] of Object.entries(deps)) {
                if (v.startsWith('workspace:') || v.startsWith('file:')) deps[k] = '*';
              }
              return deps;
            };
            const packagesDir = 'packages';
            if (fs.existsSync(packagesDir)) {
              for (const dir of fs.readdirSync(packagesDir)) {
                const f = path.join(packagesDir, dir, 'package.json');
                if (!fs.existsSync(f)) continue;
                const pkg = JSON.parse(fs.readFileSync(f, 'utf8'));
                pkg.dependencies = transform(pkg.dependencies);
                pkg.devDependencies = transform(pkg.devDependencies);
                pkg.peerDependencies = transform(pkg.peerDependencies);
                fs.writeFileSync(f, JSON.stringify(pkg, null, 2) + '\n');
                console.log('Transformed: ' + f);
              }
            }
          "

      - name: Install dependencies
        run: NODE_TLS_REJECT_UNAUTHORIZED=0 bun install --no-frozen-lockfile

      - name: Build
        run: bun run build

      - name: Publish all packages
        run: |
          for dir in packages/*/; do
            if [ ! -f "$dir/package.json" ]; then continue; fi
            cd "$dir"

            PKG_NAME=$(node -p "require('./package.json').name")
            PKG_VERSION=$(node -p "require('./package.json').version")
            SHOULD_PUBLISH=$(node -p "require('./package.json')?._?.publish === true")
            REGISTRY=$(node -p "require('./package.json')?._?.registry || 'none'")
            IS_PRIVATE=$(node -p "require('./package.json').private === true")

            echo "=== $PKG_NAME@$PKG_VERSION ==="

            if [ "$IS_PRIVATE" = "true" ]; then
              echo "  Skipping: private package"
              cd ../..
              continue
            fi

            if [ "$REGISTRY" != "forgejo" ] || [ "$SHOULD_PUBLISH" != "true" ]; then
              echo "  Skipping: not configured for forgejo publish"
              cd ../..
              continue
            fi

            if npm view "$PKG_NAME@$PKG_VERSION" version 2>/dev/null; then
              echo "  Already published"
            else
              echo "  Publishing..."
              npm publish --access public --no-git-checks || echo "  Publish failed: $PKG_NAME"
            fi

            cd ../..
          done
