name: cicd

on:
  push:
    branches: '**'
  pull_request:
    branches: '**'

env:
  PAGES_DEPLOY_ARTIFACT_DIR: '.cache/typedoc'
  PAGES_DEPLOY_ARTIFACT_BUILDING_JOB: 'typedoc'
  TURBO_TOKEN: ${{ secrets.VERCEL_TOKEN }}
  TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
  TURBO_REMOTE_ONLY: true

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
  cancel-in-progress: true

jobs:
  lint:
    name: lint:${{ matrix.lint-kind }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x]
        lint-kind: [tsc, es, format, md, style, svelte, depcheck]
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 1
      - name: setup node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: pnpm setup
        uses: pnpm/action-setup@v2
        with:
          run_install: false
      - name: get pnpm store directory
        id: pnpm-cache
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
      - name: cache
        id: cache
        uses: actions/cache@v3
        with:
          path: |
            ${{ steps.pnpm-cache.outputs.STORE_PATH }}
            .cache
          key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-
      - name: install
        run: pnpm install
      - name: lint:${{ matrix.lint-kind }}
        run: pnpm run lint:${{ matrix.lint-kind }}
  typedoc:
    name: typedoc
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x]
    steps:
      - name: checkout
        uses: actions/checkout@v3
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        with:
          fetch-depth: 1
      - name: setup node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        with:
          node-version: ${{ matrix.node-version }}
      - name: pnpm setup
        uses: pnpm/action-setup@v2
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        with:
          run_install: false
      - name: get pnpm store directory
        id: pnpm-cache
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
      - name: cache
        id: cache
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        uses: actions/cache@v3
        with:
          path: |
            ${{ steps.pnpm-cache.outputs.STORE_PATH }}
            .cache
          key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-
      - name: install
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        run: pnpm install
      - name: typedoc
        if: env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc'
        run: pnpm run typedoc
      - name: prepare pages (use index.html as 404.html)
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
        run: |
          cp ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/index.html ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/404.html
      - name: setup pages
        uses: actions/configure-pages@v2
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
      - name: upload artifact
        uses: actions/upload-pages-artifact@v1
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'typedoc' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' && 
          github.ref_name == github.event.repository.default_branch && 
          github.event_name != 'pull_request'
        with:
          path: ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}
  test:
    name: test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x]
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 1
      - name: setup node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: pnpm setup
        uses: pnpm/action-setup@v2
        with:
          run_install: false
      - name: get pnpm store directory
        id: pnpm-cache
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
      - name: cache
        id: cache
        uses: actions/cache@v3
        with:
          path: |
            ${{ steps.pnpm-cache.outputs.STORE_PATH }}
            .cache
          key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-
      - name: install
        run: pnpm install
      - name: test
        run: pnpm run test
      - name: merge lcov reports
        run: pnpm run merge-coverage
      - name: upload coverage result to codacy
        uses: codacy/codacy-coverage-reporter-action@v1
        with:
          project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
          coverage-reports: coverage/lcov.info
      - name: upload coverage result to codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          directory: coverage
      - name: prepare pages (use index.html as 404.html)
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'test' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
        run: |
          cp ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/index.html ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/404.html
      - name: setup pages
        uses: actions/configure-pages@v2
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'test' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
      - name: upload artifact
        uses: actions/upload-pages-artifact@v1
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'test' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' && 
          github.ref_name == github.event.repository.default_branch && 
          github.event_name != 'pull_request'
        with:
          path: ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}
  build:
    name: build
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x]
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 1
      - name: setup node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: pnpm setup
        uses: pnpm/action-setup@v2
        with:
          run_install: false
      - name: get pnpm store directory
        id: pnpm-cache
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
      - name: cache
        id: cache
        uses: actions/cache@v3
        with:
          path: |
            ${{ steps.pnpm-cache.outputs.STORE_PATH }}
            .cache
          key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-
      - name: install
        run: pnpm install
      - name: build
        env:
          BASE_HREF: '/${{ github.event.repository.name }}/'
        run: pnpm run build
      - name: prepare pages (use index.html as 404.html)
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'build' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
        run: |
          cp ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/index.html ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}/404.html
      - name: setup pages
        uses: actions/configure-pages@v2
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'build' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          github.ref_name == github.event.repository.default_branch &&
          github.event_name != 'pull_request'
      - name: upload artifact
        uses: actions/upload-pages-artifact@v1
        if: |
          env.PAGES_DEPLOY_ARTIFACT_BUILDING_JOB == 'build' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' && 
          github.ref_name == github.event.repository.default_branch && 
          github.event_name != 'pull_request'
        with:
          path: ${{ env.PAGES_DEPLOY_ARTIFACT_DIR }}
  deploy:
    name: deploy
    if: |
      github.ref_name == github.event.repository.default_branch && 
      github.event_name != 'pull_request'
    runs-on: ubuntu-latest
    needs: [build, test, lint, typedoc]
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: deploy to github pages
        uses: actions/deploy-pages@v1
        id: deployment
        if: |
          env.PAGES_DEPLOY_ARTIFACT_DIR != '' &&
          env.PAGES_DEPLOY_ARTIFACT_DIR != null
  release:
    name: release
    if:
      github.ref_name == github.event.repository.default_branch &&
      github.event_name != 'pull_request'
    runs-on: ubuntu-latest
    needs: [build, test, lint, typedoc]
    strategy:
      matrix:
        artifact: ['cli', 'core', 'vite-plugin-autolib']
    steps:
      - name: checkout
        uses: actions/checkout@v3
      - name: setup node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18
          registry-url: 'https://registry.npmjs.org'
      - name: pnpm setup
        uses: pnpm/action-setup@v2
        with:
          run_install: false
      - name: get pnpm store directory
        id: pnpm-cache
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
      - name: get package name
        id: packageName
        uses: notiz-dev/github-action-json-property@release
        with:
          path: 'packages/${{ matrix.artifact }}/package.json'
          prop_path: 'name'
      - name: get package version
        id: packageVersion
        uses: notiz-dev/github-action-json-property@release
        with:
          path: 'packages/${{ matrix.artifact }}/package.json'
          prop_path: 'version'
      - name: |
          Check if ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}} is already deployed
        run: |
          IS_ON_NPM=$(if [ ! -z "$(npm view ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}}  2> /dev/null)" ]; then echo 'true'; else echo 'false'; fi)
          echo "IS_ON_NPM=$IS_ON_NPM" >> $GITHUB_ENV
          echo "was ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}} already on npm: $IS_ON_NPM"
      - name: cache
        id: cache
        uses: actions/cache@v3
        if: env.IS_ON_NPM != 'true'
        with:
          path: |
            ${{ steps.pnpm-cache.outputs.STORE_PATH }}
            .cache
          key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-
      - name: install
        if: env.IS_ON_NPM != 'true'
        run: pnpm install
      - name: |
          build ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}}
        if: env.IS_ON_NPM != 'true'
        run: |
          npx turbo run build-lib_ --filter="${{ matrix.artifact }}" --concurrency 16 --cache-dir=.cache/turbo
      - name: |
          publint ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}}
        if: env.IS_ON_NPM != 'true'
        run: |
          npx turbo run publint_ --filter="${{ matrix.artifact }}" --concurrency 16 --cache-dir=.cache/turbo
      - name: |
          release ${{steps.packageName.outputs.prop}}@${{steps.packageVersion.outputs.prop}} on npm
        if: env.IS_ON_NPM != 'true'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          pnpm publish --access public --provenance packages/${{ matrix.artifact }}/dist/
