poetry와 github actions를 활용한 파이썬 라이브러리 배포 자동화
파이썬 개발을 하다 보면 필요한 라이브러리를 pip install
커맨드를 통해 쉽게 다운받아서 활용합니다. pandas
, pydantic
, fastapi
등 유명한 라이브러리가 많습니다. 이렇게 라이브러리를 설치해 사용하기도 하지만, 때로는 직접 라이브러리를 만들어서 배포하고 싶을 때가 있습니다. 파이썬에서는 어떻게 다른 사람들이 사용할 수 있는 라이브러리를 만들어 배포할까요?
오늘은 실습을 통해 직접 파이썬 라이브러리를 만들고, Github Actions를 이용해 라이브러리의 버전이 변경될 때마다 자동으로 배포하는 시스템을 만들어보겠습니다.
poetry 소개
poetry
는 의존성 관리 및 패키지 배포를 손쉽게 잘할 수 있도록 도와주는 도구입니다. poetry
를 사용하지 않더라도 requirements.txt에 직접 사용한 라이브러리를 명시해서 의존성 관리를 할 수 있지만 수동으로 관리할 경우 실수하기 쉽고 라이브러리 변경이 생길 때마다 번거로운 과정을 거쳐야 합니다. 또한 배포를 위해서 setup.py
를 직접 작성해 주어야 합니다.
poetry
는 이러한 번거로운 과정을 최소화하여 패키지를 관리해 주고 setupy.py
같은 추가적인 파일 작성이나 라이브러리 없이 단순한 커맨드 만으로 빌드 및 배포를 쉽게 가능하게 합니다. 사용자는 poetry add
를 통해 라이브러리 설치, poetry build
를 통해 빌드, poetry publish
를 통해 배포를 할 수 있습니다.
간단한 랜덤 닉네임 생성 라이브러리 제작하기
1. poetry 설치
poetry를 설치하기 위해서는 아래 명령어를 입력합니다.
맥,리눅스/WSL
curl -sSL https://install.python-poetry.org | python3 -
윈도우 (파워쉘)
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
설치가 완료되었다면 아래 명령어를 입력해 정상적으로 poetry가 설치되었는지 확인합니다.
poetry --version
아래와 같은 이미지가 나타나면 정상적으로 설치가 완료된 것입니다.
2. poetry 프로젝트 세팅
라이브러리를 만드실 디렉토리를 하나 생성하고 아래의 명령어를 입력해줍니다.
poetry init
질문에 나오는 정보에 필요한대로 답하시면 됩니다. 저는 아래와 같이 세팅하였습니다.
저희는 라이브러리를 만들어서 배포할 것이기 때문에 이름이 중요합니다. Pypi 에서 본인이 만들고자 하는 라이브러리가 존재하지 않는 것을 확인하고 만드는 것을 추천드립니다.
입력을 끝마치면 pyproject.toml
이라는 파일이 생성되는데 여기서 의존성 관리가 이루어지게 됩니다. (개발 도구들의 설정 관리가 이루어지기도 하는데 여기서 해당 부분은 넘어가겠습니다.)
3. 라이브러리 개발
아래와 같이 간단하게 한국어로 된 자동 닉네임을 생성하기 위한 라이브러리를 만들어 보았습니다. 👉 Github 커밋 보기
# koname/__init__.py
import random
ADJECTIVES = [
"영롱한",
"빛나는",
"반짝이는",
"빛나는",
"귀여운",
"멋진",
"아름다운",
"화려한",
"행복한",
"행운의",
"고운",
"예쁜",
"화난",
"정열적인",
"무서운",
"무시무시한",
"감동적인",
"감격적인",
]
NOUNS = [
"호랑이",
"사자",
"코끼리",
"기린",
"코알라",
"팬더",
"늑대",
"여우",
"오소리",
"청솔모",
"다람쥐",
"토끼",
"사슴",
"햄스터",
"고양이",
"강아지",
"송아지",
"족제비",
]
def generate_nickname(digits: int = 4):
adjective = random.choice(ADJECTIVES)
noun = random.choice(NOUNS)
number = random.randint(0, 10**digits - 1)
return f"{adjective}{noun}{number:0{digits}d}"
만드신 프로젝트는 본인의 Github에 등록해줍니다.
4. Pypi 가입하기
파이썬 라이브러리는 Pypi라는 파이썬 공식 레포지토리를 통해 배포됩니다. 해당 레포지토리로 배포가 되면 pip inistall
을 통해서 모두가 설치할 수 있게 됩니다. 배포를 위해서는 우선 Pypi 계정이 필요합니다. 사이트에 접속하시고 우측 상단의 Register 버튼을 클릭해 회원가입을 진행합니다.
5. OpenID Connect를 위해 프로젝트 등록
저희는 Github Actions를 통해서 배포를 자동화할 계획입니다. 이를 위해서는 OpenID Connect를 위한 Publisher를 등록해 주어야 합니다. OpenID Connect를 사용하지 않고 영구 토큰을 발급할 수도 있지만, OpenID Connect를 통해서 영구 토큰을 발급받지 않고도 안전하게 자동 배포를 할 수 있기 때문에 보안적으로 권장되는 방법입니다.
우측 상단의 프로필 버튼을 누르고 Account Settings ➡️ Publishing 을 눌러주세요.
이후, 아래로 스크롤 하셔서 필요한 정보를 입력해 줍니다. 여기서 workflow name은 이후 6번에서 github actions에서 등록할 파일 이름입니다.
6. Github Actions Workflow 작성
Github Actions는 Github에서 제공해 주는 CI/CD 도구입니다. 이를 활용해서 자동화된 배포 등을 쉽게 수행할 수 있습니다. 쉘을 통해서 수동으로 진행하는 각 단계를 클라우드(Github) 상에서 자동으로 수행한다고 보시면 됩니다. 우선 3번에서 생성한 본인의 프로젝트 파일에 .github/workflows
폴더를 생성하고 내부에 release.yaml
파일을 생성한 다음 아래 코드를 붙여넣기 해주세요. 👉 Github 커밋 보기
# .github/workflows/release.yaml
name: Release
on:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install Poetry and Packages
run: |
curl -sSL https://install.python-poetry.org | python3 -
poetry install
- name: Determine Version Change
id: version_check
run: |
VERSION="v$(poetry version -s)"
echo "Current version: $VERSION"
LATEST_RELEASE=$(curl -s -H "Authorization: token ${{ github.token }}" \
https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r '.tag_name')
echo "Latest release version: $LATEST_RELEASE"
if [ "$VERSION" != "$LATEST_RELEASE" ]; then
echo "Version has changed."
echo "version_changed=true" >> $GITHUB_OUTPUT
echo "new_version=$VERSION" >> $GITHUB_OUTPUT
else
echo "No version change detected."
echo "version_changed=false" >> $GITHUB_OUTPUT
fi
- name: Create Release
if: steps.version_check.outputs.version_changed == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version_check.outputs.new_version }}
generate_release_notes: True
- name: mint API token
if: steps.version_check.outputs.version_changed == 'true'
id: mint-token
run: |
# retrieve the ambient OIDC token
resp=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi")
oidc_token=$(jq -r '.value' <<< "${resp}")
# exchange the OIDC token for an API token
resp=$(curl -X POST https://pypi.org/_/oidc/mint-token -d "{\"token\": \"${oidc_token}\"}")
api_token=$(jq -r '.token' <<< "${resp}")
# mask the newly minted API token, so that we don't accidentally leak it
echo "::add-mask::${api_token}"
# see the next step in the workflow for an example of using this step output
echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}"
- name: Build and publish to PyPI
if: steps.version_check.outputs.version_changed == 'true'
run: |
poetry build
poetry publish -u __token__ -p ${{ steps.mint-token.outputs.api-token }}
여기서는 Github Actions에 대한 자세한 설명보다는 주목할 만한 몇가지 스텝에 대해서 설명하도록 하겠습니다.
- Determin Version Change 단계
pyproject.toml
파일의 버전이 변경되었는지를 확인하는 단계입니다. pyproject.toml
의 version
필드가 변경된다면 (e.g. 0.1.0
-> 0.2.0
) steps.version_check.outputs.version_changed
필드가 "true"
로 반환됩니다. (Thanks to '민기')
- Create Release 단계
1번에서 steps.version_check.outputs.version_changed
가 "true"
로 반환된다면 Github Release를 생성합니다.
- mint API token 단계
Pypi에서 사용할 임시 토큰을 발급하는 단계입니다. 이 단계를 통해서 Pypi에서 영구 토큰을 발급하지 않고도 단기간 유효한 임시 토큰을 통해 배포를 진행할 수 있습니다. 해당 단계를 거치면 steps.mint-token.outputs.api-token
에 임시 토큰이 담기게 됩니다.
- Build and publish to PyPi
마지막으로 Poetry를 통해서 빌드와 배포를 수행하는 단계입니다. mint API token
단계에서 생성한 토큰을 활용하여 배포를 진행하게 됩니다.
7. Github Actions 확인하기
6번 과정을 마쳤다면 해당 변경사항을 Github에 반영해 주도록 합니다. main
브랜치에 해당 코드가 반영되었다면 Github Actions가 트리거 될 것입니다. Workflow의 진행 상황은 Github 레포지토리에서 Actions 탭을 통해 확인할 수 있습니다.
8. 배포된 라이브러리 설치 및 확인
이제 모든 과정이 완료되었습니다. 본인이 배포된 라이브러리가 설치 가능한지 확인해 봅시다.
pip install konickname
트러블 슈팅
혹시 문제가 발생한다면 댓글로 남겨주시면 감사하겠습니다. 해당 부분을 확인하고 아래 항목을 업데이트하겠습니다 :)
1. Pypi에 등록한 정보와 Github 정보가 일치하지 않으면 Actions가 실패할 수 있습니다. 레포지토리 네임 등의 정보를 잘 입력하셨는지 확인해주세요.
오늘은 파이썬 라이브러리를 만들고, 이를 poetry와 Github Actions의 도움으로 자동으로 배포하는 과정에 대해서 알아보았습니다. 여러분들께서도 직접 본인의 라이브러리를 만들어서 배포해 보시면 어떨까요? 이 포스트가 그 과정에 조금이라도 도움이 되면 좋겠습니다. 읽어주셔서 감사합니다. 🥰