Skip to main content

Python 빌드 및 테스트

CI(연속 통합) 워크플로를 만들어 Python 프로젝트를 빌드하고 테스트할 수 있습니다.

참고: GitHub 호스트 실행기는 현재 GitHub Enterprise Server에서 지원되지 않습니다. GitHub public roadmap에 예정된 향후 지원에 대해 자세히 알아볼 수 있습니다.

소개

이 가이드에서는 Python 패키지를 빌드하고 테스트하고 게시하는 방법을 보여 줍니다.

GitHub 호스트 실행기에는 Python 및 PyPy를 포함하는 소프트웨어가 사전 설치된 도구 캐시가 있습니다. 사용자는 아무것도 설치할 필요가 없습니다. 최신 소프트웨어 및 사전 설치된 Python 및 PyPy 버전의 전체 목록은 "GitHub 호스팅 실행기 사용" 항목을 참조하세요.

필수 조건

YAML 및 GitHub Actions의 구문에 대해 잘 알고 있어야 합니다. 자세한 내용은 "워크플로 작성"을(를) 참조하세요.

Python과 pip에 대한 기본 학습을 선행하는 것이 좋습니다. 자세한 내용은 다음을 참조하세요.

GitHub Enterprise Server에서 자체 호스팅 실행기 사용

실행기를 자체 호스팅하는 GitHub Enterprise Server에서 actions/setup-LANGUAGE 같은 설정 작업을 사용할 경우 인터넷에 액세스할 수 없는 실행기에서 도구 캐시를 설정해야 할 수 있습니다. 자세한 정보는 "인터넷에 액세스할 수 없는 자체 호스팅 실행기에서 도구 캐시 설정"을(를) 참조하세요.

Python 워크플로 템플릿 사용

빠르게 시작하려면 워크플로 템플릿을 리포지토리의 .github/workflows 디렉터리에 추가합니다.

GitHub은(는) 리포지토리에 이미 하나 이상의 .py 파일이 있는 경우에 작동해야 하는 Python용 워크플로 템플릿을 제공합니다. 이 가이드의 후속 섹션에서는 이 워크플로 템플릿을 사용자 지정하는 방법에 대한 예시를 제공합니다.

  1. GitHub에서 리포지토리의 기본 페이지로 이동합니다.

  2. 리포지토리 이름 아래에서 작업을 클릭합니다.

    "github/docs" 리포지토리의 탭 스크린샷. "작업" 탭은 주황색 윤곽선으로 강조 표시됩니다.

  3. 리포지토리에 워크플로가 이미 있는 경우 새 워크플로를 클릭합니다.

  4. "워크플로 선택" 페이지에는 권장되는 워크플로 템플릿의 선택 항목이 표시됩니다. "Python 애플리케이션"을 검색합니다.

  5. "Python 애플리케이션" 워크플로에서 구성을 클릭합니다.

    "Python 애플리케이션" 워크플로 템플릿을 찾을 수 없는 경우, 다음 워크플로 코드를 리포지토리의 .github/workflows 디렉터리에 있는 python-app.yml(이)라는 새 파일에 복사합니다.

    YAML
    name: Python application
    
    on:
      push:
        branches: [ "main" ]
      pull_request:
        branches: [ "main" ]
    
    permissions:
      contents: read
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
        - uses: actions/checkout@v4
        - name: Set up Python 3.13
          uses: actions/setup-python@v5
          with:
            python-version: "3.13"
        - name: Install dependencies
          run: |
            python -m pip install --upgrade pip
            pip install ruff pytest
            if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
        - name: Lint and format Python code with ruff
          run: |
           # Lint with the default set of ruff rules with GitHub Annotations
           ruff check --format=github --target-version=py39
           # Verify the code is properly formatted
           ruff format --diff --target-version=py39
        - name: Test with pytest
          run: |
            pytest
    
  6. 필요에 따라 워크플로를 편집합니다. 예를 들어 Python 버전을 변경합니다.

  7. 변경 내용 커밋을 클릭합니다.

Python 버전 지정

GitHub 호스트 실행기에서 사전 설치된 버전의 Python 또는 PyPy를 사용하려면 setup-python 작업을 사용하세요. 이 작업은 각 실행기의 도구 캐시에서 Node.js의 특정 버전을 찾아 필수 이진 파일을 PATH에 추가합니다. 이는 나머지 작업 동안 유지됩니다. 특정 버전의 Python이 도구 캐시에 사전 설치되어 있지 않으면 setup-python 작업이 python-versions 리포지토리에서 적절한 버전을 다운로드하고 설정합니다.

setup-python 작업을 사용하는 것은 다양한 실행기 및 Python 버전 간에 일관된 동작을 보장하므로 GitHub Actions로 Python을 사용하는 데 권장되는 방법입니다. 자체 호스트 실행기를 사용하는 경우 Python을 설치하고 이를 PATH에 추가해야 합니다. 자세한 내용은 setup-python 작업을 참조하세요.

아래 테이블에서는 각 GitHub호스트 실행기에서 도구 캐시의 위치를 설명합니다.

UbuntuMacWindows
도구 캐시 디렉터리/opt/hostedtoolcache/*/Users/runner/hostedtoolcache/*C:\hostedtoolcache\windows\*
Python 도구 캐시/opt/hostedtoolcache/Python/*/Users/runner/hostedtoolcache/Python/*C:\hostedtoolcache\windows\Python\*
PyPy 도구 캐시/opt/hostedtoolcache/PyPy/*/Users/runner/hostedtoolcache/PyPy/*C:\hostedtoolcache\windows\PyPy\*

자체 호스팅 실행기를 사용하는 경우 setup-python 작업을 사용하여 종속성을 관리하도록 실행기를 구성할 수 있습니다. 자세한 내용은 setup-python 추가 정보에서 자체 호스트 실행기로 setup-python 사용을 참조하세요.

GitHub는 의미 체계 버전 관리 구문을 지원합니다. 자세한 내용은 “의미 체계 버전 관리 사용” 및 “의미 체계 버전 관리 사양”을 참조하세요.

여러 Python 버전 사용

다음 예시에서는 작업에 대한 행렬을 사용하여 여러 Python 버전을 설정합니다. 자세한 내용은 "워크플로에서 작업 변형 실행"을(를) 참조하세요.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["pypy3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      # You can test your matrix by printing the current Python version
      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

특정 Python 버전 사용

특정한 Python 버전을 구성할 수 있습니다. 예: 3.12. 또는 의미 체계 버전 구문을 사용하여 최신 부 릴리스를 가져올 수 있습니다. 이 예시에서는 Python 3의 최신 부 릴리스를 사용합니다.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        # This is the version of the action for setting up Python, not the Python version.
        uses: actions/setup-python@v5
        with:
          # Semantic version range syntax or exact version of a Python version
          python-version: '3.x'
          # Optional - x64 or x86 architecture, defaults to x64
          architecture: 'x64'
      # You can test your matrix by printing the current Python version
      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

버전 제외

사용할 수 없는 Python 버전을 지정하면 setup-python##[error]Version 3.7 with arch x64 not found 오류와 함께 실패합니다. 오류 메시지에는 사용 가능한 버전이 포함됩니다.

실행하지 않으려는 Python 구성이 있는 경우 워크플로에서 exclude 키워드를 사용할 수도 있습니다. 자세한 내용은 "GitHub Actions에 대한 워크플로 구문"을(를) 참조하세요.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ["3.9", "3.11", "3.13", "pypy3.10"]
        exclude:
          - os: macos-latest
            python-version: "3.11"
          - os: windows-latest
            python-version: "3.11"

기본 Python 버전 사용

종속성을 명시적으로 설정하는 데 도움이 되므로 setup-python을 사용하여 워크플로에서 사용되는 Python 버전을 구성하는 것이 좋습니다. setup-python을 사용하지 않으면 python을 호출할 때 PATH에서 설정된 Python의 기본 버전이 모든 셸에서 사용됩니다. Python의 기본 버전은 GitHub 호스트 실행기마다 다르며 이로 인해 예기치 않은 변경이 발생하거나 예상보다 이전 버전을 사용할 수 있습니다.

GitHub 호스트 실행기설명
UbuntuUbuntu 실행기에는 /usr/bin/python/usr/bin/python3에 설치된 여러 버전의 시스템 Python이 있습니다. Ubuntu와 함께 패키지된 Python 버전은 GitHub가 도구 캐시에 설치하는 버전에 추가됩니다.
Windows도구 캐시에 있는 Python 버전을 제외하고 Windows에는 동일한 버전의 시스템 Python이 제공되지 않습니다. 다른 실행기와 일관된 동작을 유지하고 setup-python 작업 없이 즉시 사용 가능한 Python을 허용하기 위해 GitHub는 도구 캐시의 몇 가지 버전을 PATH에 추가합니다.
macOSmacOS 실행기에는 도구 캐시의 일부인 버전 외에 둘 이상의 시스템 Python 버전이 설치되어 있습니다. 시스템 Python 버전은 /usr/local/Cellar/python/* 디렉터리에 있습니다.

종속성 설치

GitHub 호스트 실행기에는 pip 패키지 관리자가 설치되어 있습니다. 코드를 빌드하고 테스트하기 전에 pip을 사용하여 PyPI 패키지 레지스트리에서 종속성을 설치할 수 있습니다. 예를 들어 아래 YAML은 pip 패키지 설치 프로그램과 setuptoolswheel 패키지를 설치하거나 업그레이드합니다.

종속성을 캐시하여 워크플로 속도를 높일 수도 있습니다. 자세한 내용은 "워크플로 속도를 높이기 위한 종속성 캐싱"을(를) 참조하세요.

YAML
steps:
- uses: actions/checkout@v4
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.x'
- name: Install dependencies
  run: python -m pip install --upgrade pip setuptools wheel

요구 사항 파일

pip을 업데이트한 후 일반적인 다음 단계는 _requirements.txt_에서 종속성을 설치하는 것입니다. 자세한 내용은 pip를 참조하세요.

YAML
steps:
- uses: actions/checkout@v4
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.x'
- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt

종속성 캐싱

setup-python작업을 사용하여 종속성을 캐시하고 복원할 수 있습니다.

다음 예시에서는 pip에 대한 종속성을 캐시합니다.

YAML
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'
- run: pip install -r requirements.txt
- run: pip test

기본적으로 setup-python 작업은 전체 리포지토리에서 종속성 파일(pip의 경우 requirements.txt, pipenv의 경우 Pipfile.lock 또는 poetry의 경우 poetry.lock)을 검색합니다. 자세한 내용은 setup-python 추가 정보에서 "패키지 종속성 캐싱"을 참조하세요.

사용자 지정 요구사항이 있거나 캐싱에 대한 세부적인 제어가 필요한 경우 cache 작업을 사용할 수 있습니다. pip는 실행기의 운영 체제에 따라 다른 위치에 종속성을 캐시합니다. 캐시해야 하는 경로는 사용하는 운영 체제에 따라 위의 Ubuntu 예시와 다를 수 있습니다. 자세한 내용은 cache 작업 리포지토리에서 Python 캐싱 예시를 참조하세요.

코드 테스트

코드를 빌드하고 테스트하기 위해 로컬에서 사용하는 것과 동일한 명령을 사용할 수 있습니다.

pytest 및 pytest-cov를 사용하여 테스트

제에서pytest``pytest-cov 그런 다음 테스트가 실행되어 JUnit 형식으로 출력되고 코드 검사 결과는 Cobertura로 출력됩니다. 자세한 내용은 JUnitCobertura를 참조하세요.

YAML
steps:
- uses: actions/checkout@v4
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.x'
- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
- name: Test with pytest
  run: |
    pip install pytest pytest-cov
    pytest tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html

Ruff를 사용하여 코드 린팅 및/또는 서식 지정

다음 예시에서는 ruff을(를) 설치하거나 업그레이드하고 이를 사용하여 모든 파일을 린트합니다. 자세한 내용은 Ruff를 참조하세요.

YAML
steps:
- uses: actions/checkout@v4
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.x'
- name: Install the code linting and formatting tool Ruff
  run: pipx install ruff
- name: Lint code with Ruff
  run: ruff check --output-format=github --target-version=py39
- name: Check code formatting with Ruff
  run: ruff format --diff --target-version=py39
  continue-on-error: true

서식 지정 단계가 continue-on-error: true 설정되었습니다. 이렇게 하면 서식 지정 단계가 성공하지 못한 경우 워크플로가 실패하지 않습니다. 모든 서식 지정 오류를 해결했으면 워크플로가 새 문제를 catch할 수 있도록 해당 옵션을 제거할 수 있습니다.

tox를 사용하여 테스트 실행

GitHub Actions를 사용하면 tox로 테스트를 실행하고 여러 작업에 작업을 분산할 수 있습니다. 특정 버전을 지정하는 대신 PATH에서 Python 버전을 선택하려면 -e py 옵션을 사용하여 tox를 호출해야 합니다. 자세한 내용은 tox를 참조하세요.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python: ["3.9", "3.11", "3.13"]

    steps:
      - uses: actions/checkout@v4
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
      - name: Install tox and any other packages
        run: pip install tox
      - name: Run tox
        # Run tox using the version of Python in `PATH`
        run: tox -e py

워크플로 데이터를 아티팩트로 패키지

워크플로가 완료된 후 볼 아티팩트를 업로드할 수 있습니다. 예를 들어 로그 파일, 코어 덤프, 테스트 결과 또는 스크린샷을 저장해야 할 수 있습니다. 자세한 내용은 "워크플로에서 데이터 저장 및 공유"을(를) 참조하세요.

다음 예시는 upload-artifact 작업을 사용하여 pytest 실행의 테스트 결과를 보관하는 방법을 보여 줍니다. 자세한 내용은 upload-artifact 작업을 참조하세요.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

    steps:
      - uses: actions/checkout@v4
      - name: Setup Python # Set Python version
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      # Install pip and pytest
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pytest
      - name: Test with pytest
        run: pytest tests.py --doctest-modules --junitxml=junit/test-results-${{ matrix.python-version }}.xml
      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-results-${{ matrix.python-version }}
          path: junit/test-results-${{ matrix.python-version }}.xml
        # Use always() to always run this step to publish test results when there are test failures
        if: ${{ always() }}

PyPI에 게시

CI 테스트를 통과하면 Python 패키지를 PyPI에 게시하도록 워크플로를 구성할 수 있습니다. 이 섹션에서는 릴리스를 게시할 때마다 GitHub Actions를 사용하여 PyPI에 패키지를 업로드하는 방법을 보여 줍니다. 자세한 내용은 "리포지토리에서 릴리스 관리"을(를) 참조하세요.

아래 예시 워크플로에서는 신뢰할 수 있는 게시를 사용하여 PyPI를 인증하므로 수동으로 구성된 API 토큰이 필요하지 않습니다.

YAML
# 이 워크플로는 GitHub에서 인증되지 않은 작업을 사용합니다.
# 작업은 타사에서 제공하며
# 별도의 서비스 약관, 개인정보처리방침, 지원 설명서에서 규정됩니다.
# 참조하세요.

# 커밋 SHA에 작업을 고정하는 것이 좋습니다.
# 최신 버전을 얻으려면 SHA를 업데이트해야 합니다.
# 태그 또는 분기를 참조할 수도 있지만 경고 없이 작업이 변경될 수 있습니다.

name: Upload Python Package

on:
  release:
    types: [published]

permissions:
  contents: read

jobs:
  release-build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: Build release distributions
        run: |
          # NOTE: put your own distribution build steps here.
          python -m pip install build
          python -m build

      - name: Upload distributions
        uses: actions/upload-artifact@v3
        with:
          name: release-dists
          path: dist/

  pypi-publish:
    runs-on: ubuntu-latest

    needs:
      - release-build

    permissions:
      # IMPORTANT: this permission is mandatory for trusted publishing
      id-token: write

    # Dedicated environments with protections for publishing are strongly recommended.
    environment:
      name: pypi
      # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
      # url: https://pypi.org/p/YOURPROJECT

    steps:
      - name: Retrieve release distributions
        uses: actions/download-artifact@v3
        with:
          name: release-dists
          path: dist/

      - name: Publish release distributions to PyPI
        uses: pypa/gh-action-pypi-publish@6f7e8d9c0b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d