Public Access
DEVX-1: Fix post-merge job failures #10
@@ -4,6 +4,12 @@ on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Tag to publish (e.g. v0.9.11)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
@@ -34,7 +40,7 @@ jobs:
|
||||
PYTHONPATH: src
|
||||
run: |
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
python3 -m devx.ci.publish "${{ github.ref_name }}" "${{ github.repository }}"
|
||||
python3 -m devx.ci.publish "${{ github.event.inputs.tag || github.ref_name }}" "${{ github.repository }}"
|
||||
- name: Notify on failure
|
||||
if: failure()
|
||||
env:
|
||||
|
||||
@@ -23,6 +23,7 @@ import os
|
||||
import shutil
|
||||
import subprocess # nosec B404
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
from dotenv import load_dotenv # pyright: ignore[reportMissingImports,reportUnknownVariableType]
|
||||
@@ -60,6 +61,12 @@ def generate_release_notes(tag: str) -> str:
|
||||
|
||||
def build_package() -> None:
|
||||
"""Build the Python package using python -m build."""
|
||||
# Clean dist/ to avoid uploading stale packages from previous builds
|
||||
# (Gitea PyPI returns 409 Conflict for already-published versions).
|
||||
dist_dir = Path("dist")
|
||||
if dist_dir.exists():
|
||||
shutil.rmtree(dist_dir)
|
||||
|
||||
result = subprocess.run( # nosec B603
|
||||
[sys.executable, "-m", "build"],
|
||||
capture_output=True,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Unit tests for devx.ci.publish."""
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import click
|
||||
@@ -64,7 +65,8 @@ class TestGenerateReleaseNotes:
|
||||
|
||||
class TestBuildPackage:
|
||||
@patch("devx.ci.publish.subprocess.run")
|
||||
def test_success(self, mock_run: MagicMock) -> None:
|
||||
@patch("devx.ci.publish.Path.exists", return_value=False)
|
||||
def test_success(self, mock_exists: MagicMock, mock_run: MagicMock) -> None:
|
||||
mock_run.return_value = MagicMock(returncode=0, stderr="")
|
||||
build_package()
|
||||
args, _ = mock_run.call_args
|
||||
@@ -72,12 +74,23 @@ class TestBuildPackage:
|
||||
assert args[0][2] == "build"
|
||||
|
||||
@patch("devx.ci.publish.subprocess.run")
|
||||
def test_failure_raises(self, mock_run: MagicMock) -> None:
|
||||
@patch("devx.ci.publish.Path.exists", return_value=False)
|
||||
def test_failure_raises(self, mock_exists: MagicMock, mock_run: MagicMock) -> None:
|
||||
mock_run.return_value = MagicMock(returncode=1, stderr="build error")
|
||||
with pytest.raises(click.ClickException) as exc:
|
||||
build_package()
|
||||
assert "build" in str(exc.value)
|
||||
|
||||
@patch("devx.ci.publish.subprocess.run")
|
||||
@patch("devx.ci.publish.shutil.rmtree")
|
||||
@patch("devx.ci.publish.Path.exists", return_value=True)
|
||||
def test_cleans_dist_before_build(
|
||||
self, mock_exists: MagicMock, mock_rmtree: MagicMock, mock_run: MagicMock
|
||||
) -> None:
|
||||
mock_run.return_value = MagicMock(returncode=0, stderr="")
|
||||
build_package()
|
||||
mock_rmtree.assert_called_once_with(Path("dist"))
|
||||
|
||||
|
||||
class TestPublishToPypi:
|
||||
@patch("devx.ci.publish.subprocess.run")
|
||||
|
||||
Reference in New Issue
Block a user