name: TestNDeploy

on: [push, pull_request]

jobs:
  # Install and cache dependencies
  cache:
    name: Caching
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [ 2.7, 3.6, 3.7, 3.8 ]

    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Get pip cache dir
        id: pip-cache-dir
        run: |
          echo "::set-output name=dir::$(pip cache dir)"
      - name: pip cache
        id: pip-cache
        uses: actions/cache@v2
        with:
          path: ${{ steps.pip-cache-dir.outputs.dir }}
          key: pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }}
      - name: Install Linux dependencies
        if: ${{ matrix.python-version == 3.8 && steps.pip-cache.outputs.cache-hit != 'true' }}
        run: |
          sudo apt-get install libxslt-dev libxml2-dev -y
      - name: Install project dependencies
        if: ${{ steps.pip-cache.outputs.cache-hit != 'true' }}
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements-dev.txt

  lint:
    name: Linting
    runs-on: ubuntu-latest
    needs: cache
    strategy:
      matrix:
        python-version: [3.7]
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    # Retrieve the previously cached dependencies
    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "::set-output name=dir::$(pip cache dir)"
    - name: pip cache
      uses: actions/cache@v2
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }}
    # Still need to properly install the dependencies - it will only skip the download part
    - name: Install project dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements-dev.txt
    - name: Lint with flake8
      run:
        make lint

  test:
    name: Unit test
    runs-on: ubuntu-latest
    needs: lint
    strategy:
      fail-fast: false
      matrix:
        python-version: [2.7, 3.6, 3.7, 3.8]

    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "::set-output name=dir::$(pip cache dir)"
    - name: pip cache
      uses: actions/cache@v2
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }}
    - name: Install Linux dependencies
      if: ${{ matrix.python-version == 3.8 }}
      run: |
        sudo apt-get install libxslt-dev libxml2-dev -y
    - name: Install project dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements-dev.txt
        pip install pytest-cov
    - name: Test with pytest
      run: |
        make test-coverage
    - name: "Upload coverage to Codecov"
      if: ${{ github.repository == 'spulec/moto'}}
      uses: codecov/codecov-action@v1
      with:
        fail_ci_if_error: true
        flags: unittests

  testserver:
    name: Unit tests in Server Mode
    runs-on: ubuntu-latest
    needs: lint
    strategy:
      matrix:
        python-version: [2.7, 3.6, 3.7, 3.8]

    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Start MotoServer
      run: |
        python setup.py sdist
        docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/travis_moto_server.sh &
        python wait_for.py
    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "::set-output name=dir::$(pip cache dir)"
    - name: pip cache
      uses: actions/cache@v2
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }}
    - name: Install Linux dependencies
      if: ${{ matrix.python-version == 3.8 }}
      run: |
        sudo apt-get install libxslt-dev libxml2-dev -y
    - name: Install project dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements-dev.txt
    - name: Test ServerMode/Coverage
      env:
        TEST_SERVER_MODE: ${{ true }}
      run: |
        make test-coverage
    - name: "Upload coverage to Codecov"
      if: ${{ github.repository == 'spulec/moto'}}
      uses: codecov/codecov-action@v1
      with:
        fail_ci_if_error: true
        flags: servertests

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    needs: [test, testserver]
    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'spulec/moto' }}
    strategy:
      matrix:
        python-version: [3.8]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Update & Build
        run: |
          pip install wheel packaging
          python update_version_from_git.py
          python setup.py sdist bdist_wheel
      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@master
        with:
          password: ${{ secrets.PYPI_API_TOKEN }}
      - name: Get version number
        run: |
          version=$(grep -oP '(?<=__version__ = ")[0-9.a-z]+(?=")' moto/__init__.py)
          echo "moto_version=$version" >> $GITHUB_ENV
      - uses: octokit/graphql-action@v2.x
        name: Get PR info
        id: get_pr
        with:
          query: |
            query get_pr($owner:String!,$repo:String!,$commit:GitObjectID) {
              repository(owner:$owner,name:$repo) {
                object(oid:$commit) {
                  ... on Commit {
                    associatedPullRequests(last: 1){
                      edges {
                        node {
                          baseRepository {
                            nameWithOwner
                          }
                          merged
                          number
                        }
                      }
                    }
                  }
                }
              }
            }
          owner: ${{ github.event.repository.owner.name }}
          repo: ${{ github.event.repository.name }}
          commit: "${{ github.sha }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Get PR number
        run: |
          nr="${{ fromJSON(steps.get_pr.outputs.data).repository.object.associatedPullRequests.edges[0].node.number }}"
          repo="${{ fromJSON(steps.get_pr.outputs.data).repository.object.associatedPullRequests.edges[0].node.baseRepository.nameWithOwner }}"
          if [ -z "$nr" ]
          then
            echo "PR nr not found in $msg"
            echo "pr_found=false" >> $GITHUB_ENV
          else
            echo "PR NR: $nr"
            echo "pr_nr=$nr" >> $GITHUB_ENV
            echo "pr_repo=$repo" >> $GITHUB_ENV
            echo "pr_found=true" >> $GITHUB_ENV
          fi
      - name: Leave PR comment with Moto version
        uses: peter-evans/create-or-update-comment@v1
        if: env.pr_found == 'true' && env.pr_repo == 'spulec/moto'
        with:
          issue-number: ${{ env.pr_nr }}
          body: |
            This is now part of moto >= ${{ env.moto_version }}
