name: Continuous integration

on:
  push:
    branches: [ master ]

jobs:

  # Build, test and analyze
  build-test-analyze:
    name: Build, test and analyze
    if: "!contains(github.event.head_commit.message, '[skip test]')"
    uses: lowlighter/metrics/.github/workflows/test.yml@master

  # Format code
  format:
    name: Format code
    runs-on: ubuntu-latest
    needs: [ build-test-analyze ]
    if: always() && (needs.build-test-analyze.result == 'success' || needs.build-test-analyze.result == 'skipped')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Setup Dprint
        run: |
          curl -fsSL https://dprint.dev/install.sh | sh
          cp /home/runner/.dprint/bin/dprint /usr/local/bin/dprint
          npm install -g eslint
      - name: Checkout master
        run: git checkout master
      - name: Format code
        run: |
          dprint fmt --config .github/config/dprint.json
      - name: Publish formatted code
        run: |
          set +e
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com
          git add --all
          git commit -m "chore: code formatting"
          git push
          set -e

  # Update plugins and template indexes, along with README.md
  update-indexes:
    name: Publish rebuilt metrics indexes
    runs-on: ubuntu-latest
    needs: [ format ]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Setup NodeJS
        uses: actions/setup-node@v2
        with:
          node-version: 17
      - name: Pull changes
        run: |
          git checkout master
          git pull
      - name: Setup metrics
        run: npm ci
      - name: Publish rebuild metrics indexes
        run: npm run build -- publish

  # Rebase main branch on master
  update-main:
    name: Rebase main on master
    runs-on: ubuntu-latest
    needs: [ update-indexes ]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Setup NodeJS
        uses: actions/setup-node@v2
        with:
          node-version: 17
      - name: Pull
        run: git pull
      - name: Checkout main
        run: git checkout main
      - name: Rebase main on master
        run: git merge master
      - name: Push main
        run: git push origin main

  # Build docker image from master and publish it to GitHub registry
  docker-master:
    name: Publish master to GitHub registry
    runs-on: ubuntu-latest
    needs: [ update-indexes ]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Login to GitHub registry
        run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
      - name: Build docker image
        run: docker build -t ghcr.io/lowlighter/metrics:master .
      - name: Publish to GitHub registry
        run: docker push ghcr.io/lowlighter/metrics:master
      - name: Tag docker image (beta) and publish to GitHub registry
        run: |
          set +e
          METRICS_VERSION=$(cat package.json | grep -Po '(?<="version": ")\d+[.]\d+(?=[.]0-beta")')
          METRICS_VERSION_BETA="$METRICS_VERSION-beta"
          set -e
          if [[ "$METRICS_VERSION_BETA" != "v-beta" ]]; then
            echo "Beta version: v$METRICS_VERSION_BETA"
            docker tag ghcr.io/lowlighter/metrics:master ghcr.io/lowlighter/metrics:$(echo "v$METRICS_VERSION_BETA")
            docker push ghcr.io/lowlighter/metrics:$(echo "v$METRICS_VERSION_BETA")
          fi
      - name: Tag docker image (main) and publish to GitHub registry
        run: |
          docker tag ghcr.io/lowlighter/metrics:master ghcr.io/lowlighter/metrics:main
          docker push ghcr.io/lowlighter/metrics:main

  # Test lowlighter/metrics@master
  action-master-test:
    name: Test lowlighter/metrics@master
    runs-on: ubuntu-latest
    needs: [ docker-master ]
    steps:
      - name: Run tests
        uses: lowlighter/metrics@master
        with:
          token: MOCKED_TOKEN
          plugins_errors_fatal: yes
          dryrun: yes
          use_mocked_data: yes
          verify: yes

  # Publish examples
  publish-examples:
    name: Publish examples
    needs: [ docker-master ]
    uses: lowlighter/metrics/.github/workflows/examples.yml@master
    secrets:
      METRICS_TOKEN: ${{ secrets.METRICS_TOKEN }}
      METRICS_TOKEN_WITH_SCOPES: ${{ secrets.METRICS_TOKEN_WITH_SCOPES }}
      METRICS_TOKEN_PERSONAL: ${{ secrets.METRICS_TOKEN_PERSONAL }}
      PAGESPEED_TOKEN: ${{ secrets.PAGESPEED_TOKEN }}
      SPOTIFY_TOKENS: ${{ secrets.SPOTIFY_TOKENS }}
      STOCK_TOKEN: ${{ secrets.STOCK_TOKEN }}
      TWITTER_TOKEN: ${{ secrets.TWITTER_TOKEN }}
      WAKATIME_TOKEN: ${{ secrets.WAKATIME_TOKEN }}

  # Publish examples (presets)
  publish-examples-presets:
    name: Publish examples (presets)
    needs: [ docker-master ]
    uses: lowlighter/metrics/.github/workflows/examples.presets.yml@master

  # Build docker image from master and publish it to GitHub registry with release tag
  docker-release:
    name: Publish release to GitHub registry
    runs-on: ubuntu-latest
    needs: [ action-master-test, publish-examples ]
    if: contains(github.event.head_commit.message, '[release]')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Login to GitHub registry
        run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
      - name: Pull docker image (master)
        run: docker pull ghcr.io/lowlighter/metrics:master
      - name: Tag docker image (release)
        run: docker tag ghcr.io/lowlighter/metrics:master ghcr.io/lowlighter/metrics:$(echo '${{ github.event.head_commit.message }}' | grep -Po 'v\d+[.]\d+')
      - name: Publish release to GitHub registry
        run: docker push ghcr.io/lowlighter/metrics:$(echo '${{ github.event.head_commit.message }}' | grep -Po 'v\d+[.]\d+')
      - name: Tag docker image (latest)
        run: docker tag ghcr.io/lowlighter/metrics:master ghcr.io/lowlighter/metrics:latest
      - name: Publish latest to GitHub registry
        run: docker push ghcr.io/lowlighter/metrics:latest

  # Rebase latest branch on master
  update-latest:
    name: Rebase latest on master
    runs-on: ubuntu-latest
    needs: [ docker-release, publish-examples ]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Setup NodeJS
        uses: actions/setup-node@v2
        with:
          node-version: 17
      - name: Setup metrics
        run: npm ci
      - name: Pull
        run: git pull
      - name: Checkout latest
        run: git checkout latest
      - name: Rebase latest on master
        run: git merge master
      - name: Push latest
        run: git push origin latest

  # Test lowlighter/metrics@latest
  action-latest-test:
    name: Test lowlighter/metrics@latest
    runs-on: ubuntu-latest
    needs: [ update-latest ]
    steps:
      - name: Run tests
        uses: lowlighter/metrics@latest
        with:
          token: MOCKED_TOKEN
          plugins_errors_fatal: yes
          dryrun: yes
          use_mocked_data: yes
          verify: yes

  # Publish GitHub release
  publish-release:
    name: Publish release
    runs-on: ubuntu-latest
    needs: [ action-latest-test ]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Setup NodeJS
        uses: actions/setup-node@v2
        with:
          node-version: 17
      - name: Setup metrics
        run: npm ci
      - name: Publish release
        run: node .github/scripts/release.mjs
        env:
          GITHUB_TOKEN: ${{ github.token }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}

  # Deploy to metrics.lecoq.io
  deploy-latest:
    name: Deploy lowlighter/metrics@latest
    runs-on: ubuntu-latest
    needs: [ action-latest-test ]
    if: contains(github.event.head_commit.message, '[deploy]')
    steps:
      - name: Deploy web instance
        run: "curl -H 'Content-Type: application/json' --data '${{ secrets.WEB_DEPLOY_TOKEN }}' -X POST https://deploy.metrics.lecoq.io"
