# This file tests more or less everything related to a pull request. All
# in one big job. At the end, if all the testing passes, it proceeds
# to upload all the files that were built to our Dev environment.
# This way, if the tests passed, you'll be able to review the built
# pages on a public URL.

name: PR Test

on:
  pull_request:
    branches:
      - main
    paths:
      - ".github/workflows/pr-test.yml"
      - "files/en-us/**"

jobs:
  tests:
    runs-on: ubuntu-latest
    env:
      BASE_SHA: ${{ github.event.pull_request.base.sha }}
      HEAD_SHA: ${{ github.event.pull_request.head.sha }}

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js environment
        uses: actions/setup-node@v3
        with:
          node-version: "16"
          cache: yarn

      - name: Install all yarn packages
        run: |
          yarn --frozen-lockfile

      - name: Get changed files
        run: |
          # Use the GitHub API to get the list of changed files
          # documenation: https://docs.github.com/rest/commits/commits#compare-two-commits
          DIFF_DOCUMENTS=$(gh api repos/{owner}/{repo}/compare/${{ env.BASE_SHA }}...${{ env.HEAD_SHA }} \
            --paginate \
            --jq '.files | .[] | select(.status|IN("added", "modified", "renamed", "copied", "changed")) | .filename')

          # filter out files that are not markdown files
          GIT_DIFF_CONTENT=$(echo "${DIFF_DOCUMENTS}" | egrep -i "^files/.*\.(md)$" | xargs)
          echo "GIT_DIFF_CONTENT=${GIT_DIFF_CONTENT}" >> $GITHUB_ENV

          # filter out files that are not attachments
          GIT_DIFF_FILES=$(echo "${DIFF_DOCUMENTS}" | egrep -i "^files/.*\.(png|jpeg|jpg|gif|svg|webp)$" | xargs)
          echo "GIT_DIFF_FILES=${GIT_DIFF_FILES}" >> $GITHUB_ENV

          # filter out files that are not _redirects.txt
          GIT_DIFF_REDIRECTS=$(echo "${DIFF_DOCUMENTS}" | egrep -i "^files/.*/_redirects\.txt$" | xargs)
          echo "GIT_DIFF_REDIRECTS=${GIT_DIFF_REDIRECTS}" >> $GITHUB_ENV
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build changed content
        if: ${{ env.GIT_DIFF_CONTENT }}
        env:
          CONTENT_ROOT: ${{ github.workspace }}/files

          # This is so that if there's a single 'unsafe_html' flaw, it
          # completely fails the build.
          # But all other flaws should be 'warn', so that we can include
          # information about the flaws when we analyze the built PR.
          BUILD_FLAW_LEVELS: "unsafe_html: error, *:warn"

          # Because we build these pages in a way that you get a toolbar,
          # so the flaws can be displayed, but we don't want any of the
          # other toolbar features like "Fix fixable flaws" or "Quick-edit"
          # we set this to disable that stuff.
          REACT_APP_CRUD_MODE_READONLY: true

          # Setting this to an empty string effectively means that the
          # <iframe> src will end up being the relative URL of the current
          # document as a base.
          # I.e. like this, if the current document is '/en-US/docs/Foo':
          #  <iframe src="/en-US/docs/Foo/_samples_/index.html">
          # ...for example.
          # Yes, it's potentially "insecure" because the iframe will execute
          # whatever code is inserted into the code example. But since the
          # whole (possible) domain for PR builds will never be somewhere
          # where there are interesting cookies, it's a safe choice.
          BUILD_LIVE_SAMPLES_BASE_URL: ""

          # In these builds, we never care for or need the ability to sign in.
          # This environment variable will disable that functionality entirely.
          REACT_APP_DISABLE_AUTH: true

          # TODO: This should be implicit when `CI=true`
          BUILD_NO_PROGRESSBAR: true

        run: |
          # The reason this script isn't in `package.json` is because
          # you don't need that script as a writer. It's only used in CI
          # and it can't use the default CONTENT_ROOT that gets set in
          # package.json.
          yarn build ${{ env.GIT_DIFF_CONTENT }}

          echo "Disk usage size of build/"
          du -sh $BUILD_OUT_ROOT

          # Save the PR number into the build
          echo ${{ github.event.number }} > build/NR

          # Download the raw diff blob and store that inside the ./build/
          # directory.
          # The purpose of this is for the PR Review Companion to later
          # be able to use this raw diff file for the benefit of analyzing.
          wget https://github.com/${{ github.repository }}/compare/${{ env.BASE_SHA }}...${{ env.HEAD_SHA }}.diff -O build/DIFF

      - name: Merge static assets with built documents
        if: ${{ env.GIT_DIFF_CONTENT }}
        run: |
          rsync -a node_modules/@mdn/yari/client/build/ build/

          # Now that build/ directory contains everything you need to deploy
          # that as a site. HTML, static assets, images, etc.
          # However, that Yari static files is very heavy and it's in large
          # part due to the .map files.
          # In fact, as of March 2021, the client/build/static directory
          # is 2.3MB but only 864KB without all the .map files.
          # Let's delete those this time because this isn't the right time
          # to debug JS or CSS.
          echo "Before..."
          du -sh build
          find build/static -type f -name "*.map" | xargs ls -lh
          find build/static -type f -name "*.map" | xargs rm
          echo "After..."
          du -sh build

      - uses: actions/upload-artifact@v3
        if: ${{ env.GIT_DIFF_CONTENT }}
        with:
          name: build
          path: build/

      - name: Check changed files
        if: ${{ env.GIT_DIFF_FILES }}
        run: |
          echo ${{ env.GIT_DIFF_FILES }}

          export CONTENT_ROOT=$(pwd)/files
          yarn filecheck ${{ env.GIT_DIFF_FILES }}

      - name: Validate redirects
        if: ${{ env.GIT_DIFF_REDIRECTS }}
        run: |
          echo ${{ env.GIT_DIFF_REDIRECTS }}
          yarn content validate-redirects