1+ # .github/workflows/publish.yml
2+ name : Publish to PyPI
3+
4+ on :
5+ # Manual trigger ONLY - requires explicit action
6+ workflow_dispatch :
7+ inputs :
8+ publish_to_pypi :
9+ description : ' Publish to PyPI? Type "yes" to confirm'
10+ required : true
11+ default : ' no'
12+ type : choice
13+ options :
14+ - ' no'
15+ - ' yes'
16+ version_tag :
17+ description : ' Version tag (e.g., v0.0.1)'
18+ required : false
19+ type : string
20+
21+ jobs :
22+ test :
23+ name : Run Tests
24+ runs-on : ubuntu-latest
25+
26+ steps :
27+ - uses : actions/checkout@v4
28+
29+ - name : Set up Python
30+ uses : actions/setup-python@v5
31+ with :
32+ python-version : ' 3.11'
33+
34+ - name : Install dependencies
35+ run : |
36+ python -m pip install --upgrade pip
37+ pip install .[dev]
38+ pip install pytest pytest-cov
39+
40+ - name : Run linting
41+ run : |
42+ black --check devops_agent
43+ isort --check-only devops_agent
44+ flake8 devops_agent --max-line-length=100
45+
46+ - name : Test CLI installation
47+ run : |
48+ pip install -e .
49+ devops-agent --version
50+
51+ build-and-publish :
52+ name : Build and Publish
53+ needs : test
54+ runs-on : ubuntu-latest
55+ if : github.event_name == 'workflow_dispatch'
56+
57+ steps :
58+ - uses : actions/checkout@v4
59+
60+ - name : Set up Python
61+ uses : actions/setup-python@v5
62+ with :
63+ python-version : ' 3.11'
64+
65+ - name : Install build tools
66+ run : |
67+ python -m pip install --upgrade pip
68+ pip install build twine
69+
70+ - name : Build package
71+ run : python -m build
72+
73+ - name : Check package
74+ run : |
75+ twine check dist/*
76+ ls -la dist/
77+ echo "📦 Package version: $(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")"
78+
79+ - name : Confirm before publish
80+ if : github.event.inputs.publish_to_pypi == 'yes'
81+ run : |
82+ echo "⚠️ About to publish to PyPI (PRODUCTION)"
83+ echo "📦 Package contents:"
84+ ls -la dist/
85+ echo "✅ Proceeding with PyPI upload..."
86+
87+ - name : Publish to PyPI
88+ if : github.event.inputs.publish_to_pypi == 'yes'
89+ env :
90+ TWINE_USERNAME : __token__
91+ TWINE_PASSWORD : ${{ secrets.PYPI_TOKEN }}
92+ run : |
93+ if [ -z "$TWINE_PASSWORD" ]; then
94+ echo "❌ Error: PYPI_TOKEN secret is not configured!"
95+ echo "Please add your PyPI token to GitHub Secrets"
96+ exit 1
97+ fi
98+
99+ twine upload dist/*
100+ echo "✅ Published to PyPI successfully!"
101+ echo "📦 View at: https://pypi.org/project/devops-agent/"
102+ echo "📥 Install: pip install devops-agent"
103+
104+ - name : Skip publish message
105+ if : github.event.inputs.publish_to_pypi != 'yes'
106+ run : |
107+ echo "📦 Package built successfully but NOT published to PyPI"
108+ echo "ℹ️ This was a test run. To publish, run the workflow again with 'Publish to PyPI' set to 'yes'"
109+
110+ - name : Create version tag
111+ if : github.event.inputs.publish_to_pypi == 'yes' && github.event.inputs.version_tag != ''
112+ run : |
113+ git config user.name github-actions
114+ git config user.email github-actions@github.com
115+ git tag ${{ github.event.inputs.version_tag }}
116+ git push origin ${{ github.event.inputs.version_tag }}
117+ echo "🏷️ Created tag: ${{ github.event.inputs.version_tag }}"
0 commit comments