diff --git a/tasks/pybuild/task.yaml b/tasks/pybuild/task.yaml index 9ba4ef4..daaf0c6 100644 --- a/tasks/pybuild/task.yaml +++ b/tasks/pybuild/task.yaml @@ -8,41 +8,87 @@ spec: type: string description: Subdirectory within the repo where the source code is located default: "" + - name: python-version type: string description: Python version to use (e.g., 3.9, 3.11) default: "3.9" + + - name: pypi-username + type: string + description: PyPI username (fallback) + default: "" + + - name: pypi-password + type: string + description: PyPI password or token (fallback) + default: "" + + - name: pypi-group-url + type: string + description: PyPI repository URL (install endpoint) + default: https://upload.pypi.org/legacy/ + workspaces: - name: source description: Workspace containing the cloned Git repository from git-clone-checkout + - name: pypi-auth + optional: true + description: | + A workspace containing authentication credentials for a private PyPI repository. + Should include: + - username + - password + results: - name: build-artifact-path description: Path to the built artifact directory (e.g., dist/) + steps: - name: install-dependencies image: python:$(params.python-version)-slim workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi pip install --upgrade pip - # Poetry가 있는 경우 설치 및 의존성 처리 + + PYPI_USER="$(params.pypi-username)" + PYPI_PASS="$(params.pypi-password)" + PYPI_URL="$(params.pypi-group-url)" + + if [ -f /workspace/pypi-auth/username ]; then + PYPI_USER=$(cat /workspace/pypi-auth/username) + fi + if [ -f /workspace/pypi-auth/password ]; then + PYPI_PASS=$(cat /workspace/pypi-auth/password) + fi + if [ -f pyproject.toml ]; then - echo "Detected Poetry project (pyproject.toml found)" + echo "[INFO] Poetry project detected" pip install poetry poetry config virtualenvs.in-project true + + if [ -n "$PYPI_URL" ]; then + REPO_NAME=$(echo "$PYPI_URL" | sed -E 's#https?://([^/]+)/repository/([^/]+)/?.*#\1_\2#' | tr -cd '[:alnum:]_') + echo "[INFO] Configuring poetry source '$REPO_NAME' → $PYPI_URL" + poetry config repositories."$REPO_NAME" "$PYPI_URL" + poetry config http-basic."$REPO_NAME" "$PYPI_USER" "$PYPI_PASS" + fi + poetry install --no-root - # Pip fallback (requirements.txt 및 setup.py) + elif [ -f requirements.txt ] && [ -f setup.py ]; then - echo "Detected Pip project (requirements.txt and setup.py found)" + echo "[INFO] Pip + setup.py project detected" pip install -r requirements.txt pip install build else - echo "Error: No valid build configuration found (pyproject.toml or setup.py required)" + echo "[ERROR] No valid build configuration found (pyproject.toml or setup.py required)" exit 1 fi @@ -51,39 +97,39 @@ spec: workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi - # Poetry가 사용된 경우 if [ -f pyproject.toml ]; then poetry build - echo "Built artifacts located in dist/" - ls -l dist/ - # Pip 및 setup.py 사용 elif [ -f setup.py ]; then python -m build - echo "Built artifacts located in dist/" - ls -l dist/ else - echo "Error: No build tool available" + echo "[ERROR] No build tool available" exit 1 fi - # 빌드 결과 경로를 결과로 저장 + echo "Built artifacts located in dist/" + ls -l dist/ + + # Save result path echo -n "/workspace/source/$(params.subdirectory)/dist" > /tekton/results/build-artifact-path + - name: verify-build image: ubuntu workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e DIST_PATH=$(cat /tekton/results/build-artifact-path) if [ -d "$DIST_PATH" ] && [ -n "$(ls -A $DIST_PATH)" ]; then - echo "Build artifacts successfully created in $DIST_PATH:" + echo "✅ Build artifacts successfully created in $DIST_PATH:" ls -l $DIST_PATH else - echo "Error: No build artifacts found in $DIST_PATH" + echo "❌ No build artifacts found in $DIST_PATH" exit 1 fi diff --git a/tasks/pylint/task.yaml b/tasks/pylint/task.yaml index d35e48f..2280f37 100644 --- a/tasks/pylint/task.yaml +++ b/tasks/pylint/task.yaml @@ -8,44 +8,90 @@ spec: type: string description: Subdirectory within the repo where the source code is located default: "" + - name: python-version type: string description: Python version to use (e.g., 3.9, 3.11) default: "3.9" + - name: pylint-args type: string description: Additional arguments for pylint (e.g., --fail-under=8) default: "" + + - name: pypi-username + type: string + description: PyPI username (fallback) + default: "" + + - name: pypi-password + type: string + description: PyPI password or token (fallback) + default: "" + + - name: pypi-group-url + type: string + description: PyPI repository URL (install endpoint) + default: https://upload.pypi.org/legacy/ + workspaces: - name: source description: Workspace containing the cloned Git repository from git-clone-checkout + + - name: pypi-auth + optional: true + description: | + A workspace containing authentication credentials for a private PyPI repository. + Should include: + - username + - password + steps: - name: install-dependencies image: python:$(params.python-version)-slim workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi pip install --upgrade pip - # Poetry가 있는 경우 설치 및 의존성 처리 + PYPI_USER="$(params.pypi-username)" + PYPI_PASS="$(params.pypi-password)" + PYPI_URL="$(params.pypi-group-url)" + + if [ -f /workspace/pypi-auth/username ]; then + PYPI_USER=$(cat /workspace/pypi-auth/username) + fi + if [ -f /workspace/pypi-auth/password ]; then + PYPI_PASS=$(cat /workspace/pypi-auth/password) + fi + if [ -f pyproject.toml ]; then - echo "Detected Poetry project (pyproject.toml found)" + echo "[INFO] Poetry project detected" + pip install poetry poetry config virtualenvs.in-project true + + if [ -n "$PYPI_URL" ]; then + REPO_NAME=$(echo "$PYPI_URL" | sed -E 's#https?://([^/]+)/repository/([^/]+)/?.*#\1_\2#' | tr -cd '[:alnum:]_') + echo "[INFO] Configuring poetry source '$REPO_NAME' with URL: $PYPI_URL" + poetry config repositories."$REPO_NAME" "$PYPI_URL" + poetry config http-basic."$REPO_NAME" "$PYPI_USER" "$PYPI_PASS" + fi + poetry install --no-root - poetry add pylint --group dev # Pylint를 개발 의존성으로 추가 - # Pip fallback (requirements.txt) + poetry add pylint --group dev elif [ -f requirements.txt ]; then - echo "Detected Pip project (requirements.txt found)" + echo "[INFO] Pip project detected" pip install -r requirements.txt pip install pylint else - echo "No dependency file found, installing pylint only" + echo "[INFO] No dependency file found, installing pylint only" pip install pylint fi @@ -54,24 +100,22 @@ spec: workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi - # Poetry가 사용된 경우 가상환경에서 실행 if [ -f pyproject.toml ]; then poetry run pylint $(params.pylint-args) . else pylint $(params.pylint-args) . fi - onError: continue # 린트 실패 시에도 파이프라인을 중단하지 않음 (선택적) + onError: continue # 린트 실패해도 실패로 간주하지 않음 - name: check-results image: ubuntu workingDir: /workspace/source script: | #!/usr/bin/env bash - echo "Pylint execution completed." - # Pylint 결과를 별도 파일로 저장하려면 run-lint에서 --output 옵션 추가 필요 diff --git a/tasks/pypi/task.yaml b/tasks/pypi/task.yaml index 540c437..4f11cda 100644 --- a/tasks/pypi/task.yaml +++ b/tasks/pypi/task.yaml @@ -7,38 +7,83 @@ spec: - name: build-artifact-path type: string description: Path to the built artifact directory from python-build + - name: python-version type: string description: Python version to use (e.g., 3.9, 3.11) default: "3.9" + - name: pypi-username type: string - description: PyPI username (e.g., __token__ for token-based auth) + description: PyPI username (fallback) + default: "" + - name: pypi-password type: string - description: PyPI password or token - - name: pypi-repository-url + description: PyPI password or token (fallback) + default: "" + + - name: pypi-hosted-url type: string - description: PyPI repository URL + description: PyPI repository URL (upload endpoint) default: https://upload.pypi.org/legacy/ + + - name: pypi-group-url + type: string + description: PyPI repository URL (install endpoint) + default: https://upload.pypi.org/legacy/ + workspaces: - name: source description: Workspace containing the built artifacts + - name: pypi-auth + optional: true + description: | + Optional workspace containing: + - username + - password + steps: - name: upload-to-pypi image: python:$(params.python-version)-slim + workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e - pip install twine + pip install --upgrade pip + pip install poetry twine + + # 기본값 (params) + TWINE_USERNAME="$(params.pypi-username)" + TWINE_PASSWORD="$(params.pypi-password)" + HOSTED_URL="$(params.pypi-hosted-url)" + GROUP_URL="$(params.pypi-group-url)" + + # pypi-auth workspace에 있으면 override + if [ -f /workspace/pypi-auth/username ]; then + TWINE_USERNAME=$(cat /workspace/pypi-auth/username) + fi + if [ -f /workspace/pypi-auth/password ]; then + TWINE_PASSWORD=$(cat /workspace/pypi-auth/password) + fi + + echo "[INFO] Twine Upload URL: $HOSTED_URL" + + # poetry config (install용 group-url 사용) + if [ -f pyproject.toml ]; then + REPO_NAME=$(echo "$GROUP_URL" | sed -E 's#https?://([^/]+)/repository/([^/]+)/?.*#\1_\2#' | tr -cd '[:alnum:]_') + echo "[INFO] Configuring poetry install repo: $REPO_NAME -> $GROUP_URL" + + poetry config repositories."$REPO_NAME" "$GROUP_URL" + poetry config http-basic."$REPO_NAME" "$TWINE_USERNAME" "$TWINE_PASSWORD" + fi + + echo "[INFO] Uploading artifacts with Twine..." twine upload \ - --repository-url "$(params.pypi-repository-url)" \ - --username "$(params.pypi-username)" \ - --password "$(params.pypi-password)" \ + --repository-url "$HOSTED_URL" \ + --username "$TWINE_USERNAME" \ + --password "$TWINE_PASSWORD" \ "$(params.build-artifact-path)"/* - if [ $? -eq 0 ]; then - echo "Successfully uploaded to PyPI" - else - echo "Failed to upload to PyPI" - exit 1 - fi \ No newline at end of file + + echo "[INFO] Successfully uploaded to PyPI" diff --git a/tasks/pytest/task.yaml b/tasks/pytest/task.yaml index 969692f..aa77712 100644 --- a/tasks/pytest/task.yaml +++ b/tasks/pytest/task.yaml @@ -7,34 +7,82 @@ spec: - name: subdirectory type: string description: Subdirectory within the workspace where the tests are located - default: "" # 기본값을 빈 문자열로 설정, 필요 시 repo로 변경 + default: "" + - name: python-version type: string description: Python version to use (e.g., 3.9, 3.11) default: "3.9" + + - name: pypi-username + type: string + description: PyPI username (fallback) + default: "" + + - name: pypi-password + type: string + description: PyPI password or token (fallback) + default: "" + + - name: pypi-group-url + type: string + description: PyPI repository URL (install endpoint) + default: https://upload.pypi.org/legacy/ + workspaces: - name: source description: Workspace containing the cloned Git repository from git-clone-checkout + + - name: pypi-auth + optional: true + description: | + A workspace containing authentication credentials for a private PyPI repository. + Should include: + - username + - password + steps: - name: install-dependencies image: python:$(params.python-version)-slim workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi pip install --upgrade pip pip install pytest if [ -f pyproject.toml ]; then + echo "[INFO] Using Poetry to install dependencies" pip install poetry poetry config virtualenvs.in-project true poetry lock --no-cache --regenerate + + PYPI_USER="$(params.pypi-username)" + PYPI_PASS="$(params.pypi-password)" + PYPI_URL="$(params.pypi-group-url)" + + if [ -f /workspace/pypi-auth/username ]; then + PYPI_USER=$(cat /workspace/pypi-auth/username) + fi + if [ -f /workspace/pypi-auth/password ]; then + PYPI_PASS=$(cat /workspace/pypi-auth/password) + fi + + if [ -n "$PYPI_URL" ]; then + REPO_NAME=$(echo "$PYPI_URL" | sed -E 's#https?://([^/]+)/repository/([^/]+)/?.*#\1_\2#' | tr -cd '[:alnum:]_') + echo "[INFO] Configuring poetry source '$REPO_NAME': $PYPI_URL" + poetry config repositories."$REPO_NAME" "$PYPI_URL" + poetry config http-basic."$REPO_NAME" "$PYPI_USER" "$PYPI_PASS" + fi + poetry install --no-root elif [ -f requirements.txt ]; then + echo "[INFO] Using pip to install dependencies" pip install -r requirements.txt fi @@ -43,9 +91,10 @@ spec: workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -n "$(params.subdirectory)" ]; then - cd $(params.subdirectory) + cd "$(params.subdirectory)" fi if [ -f pyproject.toml ]; then @@ -60,6 +109,7 @@ spec: workingDir: /workspace/source script: | #!/usr/bin/env bash + set -e if [ -f pytest-results.xml ]; then echo "Test results generated: pytest-results.xml" @@ -67,4 +117,4 @@ spec: else echo "No test results found." exit 1 - fi \ No newline at end of file + fi