name: Publish ui-core-micha to npm

on:
  push:
    branches:
      - main
    paths:
      - "package.json"
      - "pnpm-lock.yaml"
      - "src/**"
      - "tsconfig.build.json"
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - name: Check out code
        uses: actions/checkout@v6
        with:
          fetch-depth: 2

      - name: Set up Node
        uses: actions/setup-node@v6
        with:
          node-version: '24.15.0'
          registry-url: 'https://registry.npmjs.org'

      - name: Decide whether to publish
        id: version_check
        run: |
          node <<'NODE'
          const fs = require('fs');
          const cp = require('child_process');

          const outputPath = process.env.GITHUB_OUTPUT;
          const githubEvent = process.env.GITHUB_EVENT_NAME || '';

          function writeOutput(value) {
            fs.appendFileSync(outputPath, `should_publish=${value}\n`, 'utf8');
          }

          if (githubEvent === 'workflow_dispatch') {
            console.log('Manual dispatch: publish enabled.');
            writeOutput('true');
            process.exit(0);
          }

          const current = JSON.parse(fs.readFileSync('package.json', 'utf8')).version;
          let published;
          try {
            published = cp.execFileSync(
              'npm',
              ['view', '@micha.bigler/ui-core-micha', 'version'],
              { encoding: 'utf8' }
            ).trim();
          } catch (error) {
            console.log(
              'Could not fetch the published npm version (the package may not exist yet or the registry is unavailable). Publishing.'
            );
            writeOutput('true');
            process.exit(0);
          }

          console.log(`Published version: ${published}`);
          console.log(`Current version:  ${current}`);

          function parse(version) {
            return version.split('.').map((part) => Number.parseInt(part, 10) || 0);
          }

          function greaterThan(a, b) {
            const left = parse(a);
            const right = parse(b);
            const maxLength = Math.max(left.length, right.length);
            for (let index = 0; index < maxLength; index += 1) {
              const lv = left[index] || 0;
              const rv = right[index] || 0;
              if (lv > rv) return true;
              if (lv < rv) return false;
            }
            return false;
          }

          if (greaterThan(current, published)) {
            console.log('Version increased. Publishing.');
            writeOutput('true');
          } else {
            console.log('Version did not increase. Skipping publish.');
            writeOutput('false');
          }
          NODE

      - name: Set up pnpm
        if: steps.version_check.outputs.should_publish == 'true'
        uses: pnpm/action-setup@v6
        with:
          version: 11.1.2

      - name: Show version from package.json
        if: steps.version_check.outputs.should_publish == 'true'
        run: node -e "console.log('Version from package.json:', require('./package.json').version);"

      - name: Install dependencies (pnpm)
        if: steps.version_check.outputs.should_publish == 'true'
        run: pnpm install --frozen-lockfile

      - name: Build
        if: steps.version_check.outputs.should_publish == 'true'
        run: pnpm run build

      - name: Run tests
        if: steps.version_check.outputs.should_publish == 'true'
        run: pnpm run test

      - name: Ensure recent npm for trusted publishing
        if: steps.version_check.outputs.should_publish == 'true'
        run: npm install -g npm@latest

      - name: Publish to npm (Trusted Publishing)
        if: steps.version_check.outputs.should_publish == 'true'
        run: npm publish --access public
