name: CI

on:
  workflow_dispatch: {}
  push:
    branches:
      - master
      - beta
      - sdk-release/**
      - feature/**
    tags:
      - v[0-9]+.[0-9]+.[0-9]+*
  pull_request:
    branches:
      - master
      - beta
      - sdk-release/**
      - feature/**

jobs:
  lint:
    name: Lint & Mypy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python 3
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - name: mypy
        run: make mypy
      - name: lint
        run: make lint
      - name: fmtcheck
        run: make fmtcheck

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Python 3
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"

      - name: Install tools
        run: make venv

      - name: Build and check package
        run: |
          set -x
          source venv/bin/activate
          python setup.py clean --all sdist bdist_wheel --universal
          python -m twine check dist/*

      - name: "Upload Artifact"
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist/

  test:
    # Specific ubuntu version to support python 3.6 testing
    # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 for details
    # move to ubuntu-latest when we drop 3.6
    runs-on: ubuntu-20.04
    strategy:
      fail-fast: false
      matrix:
        python:
          - { version: "3.6" , env: "py36" }
          - { version: "3.7" , env: "py37" }
          - { version: "3.8" , env: "py38" }
          - { version: "3.9" , env: "py39" }
          - { version: "3.10" , env: "py310" }
          - { version: "3.11" , env: "py311" }
          - { version: "3.12" , env: "py312" }
          - { version: "pypy-3.7" , env: "py3.7" }
          - { version: "pypy-3.8" , env: "py3.8" }
          - { version: "pypy-3.9" , env: "py3.9" }
          - { version: "pypy-3.10" , env: "py3.10" }
    name: Test (${{ matrix.python.version }})
    steps:
      - uses: actions/checkout@v3

      - name: Set up Python ${{ matrix.python.version }} and 3.10
        uses: actions/setup-python@v4
        with:
          python-version: |
            ${{ matrix.python.version }}
            3.10

      - uses: stripe/openapi/actions/stripe-mock@master

      - name: Typecheck with pyright
        run: PYRIGHT_ARGS="-- --pythonversion ${{ matrix.python.version }}" make pyright
        # Skip typecheking in pypy legs
        if: ${{ !contains(matrix.python.version, 'pypy') }}

      - name: Test with pytest
        run: TOX_ARGS="-e ${{ matrix.python.env }}" make ci-test

      - name: Calculate and publish coverage
        run: make coveralls
        if: env.COVERALLS_REPO_TOKEN && matrix.python.version == '3.10'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

  publish:
    name: Publish
    if: >-
      ((github.event_name == 'workflow_dispatch') || (github.event_name == 'push')) &&
      startsWith(github.ref, 'refs/tags/v') &&
      endsWith(github.actor, '-stripe')
    needs: [build, test, lint]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Download all workflow run artifacts
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: dist
      - name: Set up Python 3
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"

      - name: Configure GPG Key
        run: |
          set -ex
          echo $GPG_SIGNING_PRIVKEY | base64 --decode | gpg --import --batch --yes --pinentry-mode loopback --passphrase "$GPG_SIGNING_PASSPHRASE"
        env:
          GPG_SIGNING_PRIVKEY: ${{ secrets.GPG_SIGNING_PRIVKEY }}
          GPG_SIGNING_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }}
      - name: Install tools
        run: make venv
      - name: Publish packages to PyPy
        run: |
          set -ex
          source venv/bin/activate
          export VERSION=$(cat VERSION)
          gpg --detach-sign --local-user $GPG_SIGNING_KEYID  --pinentry-mode loopback --passphrase $GPG_SIGNING_PASSPHRASE -a dist/stripe-$VERSION.tar.gz
          gpg --detach-sign --local-user $GPG_SIGNING_KEYID  --pinentry-mode loopback --passphrase $GPG_SIGNING_PASSPHRASE -a dist/stripe-$VERSION-py2.py3-none-any.whl

          python -m twine upload --verbose dist/stripe-$VERSION.tar.gz  dist/stripe-$VERSION-py2.py3-none-any.whl dist/stripe-$VERSION.tar.gz.asc dist/stripe-$VERSION-py2.py3-none-any.whl.asc
        env:
          GPG_SIGNING_KEYID: ${{ secrets.GPG_SIGNING_KEYID }}
          TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
          TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
          GPG_SIGNING_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }}
      - uses: stripe/openapi/actions/notify-release@master
        if: always()
        with:
          bot_token: ${{ secrets.SLACK_BOT_TOKEN }}
