Skip to content

Commit 92a7ff8

Browse files
author
Your Name
committed
smol
1 parent b7405d6 commit 92a7ff8

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

scripts/release.ps1

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<#
2+
.pynstal/scripts/release.ps1
3+
4+
Builds the project, pushes to GitHub, and uploads to PyPI.
5+
6+
Usage (PowerShell):
7+
# required: set PYPI_API_TOKEN in environment (a PyPI API token starting with pypi-...)
8+
.\scripts\release.ps1 -Tag v0.1.1 -Branch main -Message "Release v0.1.1"
9+
10+
Parameters:
11+
-Tag : Git tag to create and push (e.g. v0.1.1). If omitted, the script will prompt.
12+
-Branch : Branch to push (default: main)
13+
-Message : Tag message (default: "Release <Tag>")
14+
-DryRun : If present, show commands without executing uploads/pushes
15+
-Force : Force actions even if working tree is dirty
16+
17+
Environment:
18+
- PYPI_API_TOKEN : required to upload to PyPI. Twine will use __token__ / $env:PYPI_API_TOKEN
19+
20+
Notes:
21+
- Run from repository root. Ensure Python (3.8+) is on PATH.
22+
- This script uses `python -m build` and `python -m twine upload`.
23+
#>
24+
25+
param(
26+
[string]$Tag,
27+
[string]$Branch = 'main',
28+
[string]$Message,
29+
[switch]$DryRun,
30+
[switch]$Force
31+
)
32+
33+
function Exec([string]$cmd) {
34+
Write-Host "> $cmd"
35+
if (-not $DryRun) {
36+
$rc = & cmd /c $cmd
37+
if ($LASTEXITCODE -ne 0) { throw "Command failed: $cmd" }
38+
}
39+
}
40+
41+
try {
42+
# Ensure we're at repo root (where .git exists)
43+
if (-not (Test-Path .git)) {
44+
throw "Run this script from the repository root (where .git exists)."
45+
}
46+
47+
# Ensure PYPI token present for upload
48+
if (-not $env:PYPI_API_TOKEN) {
49+
Write-Warning "Environment variable PYPI_API_TOKEN is not set. Upload to PyPI will fail."
50+
}
51+
52+
# Check working tree
53+
$status = git status --porcelain
54+
if ($status -and -not $Force) {
55+
Write-Host "Working tree is not clean. Commit or use -Force to proceed."
56+
Write-Host $status
57+
exit 1
58+
}
59+
60+
# Prompt for tag if not provided
61+
if (-not $Tag) {
62+
$Tag = Read-Host "Enter git tag to create (e.g. v0.1.1)"
63+
if (-not $Tag) { throw "Tag is required." }
64+
}
65+
66+
if (-not $Message) { $Message = "Release $Tag" }
67+
68+
# Clean previous builds
69+
if (Test-Path dist) { if (-not $DryRun) { Remove-Item -Recurse -Force dist } else { Write-Host "DRY RUN: would remove dist/" } }
70+
71+
# Build package
72+
Exec "python -m pip install --upgrade build twine"
73+
Exec "python -m build"
74+
75+
# Push branch
76+
Exec "git push origin $Branch"
77+
78+
# Create annotated tag and push it
79+
Exec "git tag -a $Tag -m \"$Message\""
80+
Exec "git push origin $Tag"
81+
82+
# Upload to PyPI using twine and PYPI_API_TOKEN
83+
if (-not $env:PYPI_API_TOKEN) {
84+
Write-Warning "PYPI_API_TOKEN is not set; skipping upload to PyPI."
85+
} else {
86+
# Use __token__ username and token as password
87+
if (-not $DryRun) {
88+
$env:TWINE_USERNAME = "__token__"
89+
$env:TWINE_PASSWORD = $env:PYPI_API_TOKEN
90+
} else {
91+
Write-Host "DRY RUN: TWINE_USERNAME=__token__ TWINE_PASSWORD=<redacted> python -m twine upload dist/*"
92+
}
93+
Exec "python -m twine check dist/*"
94+
Exec "python -m twine upload dist/*"
95+
}
96+
97+
Write-Host "Release script completed successfully."
98+
} catch {
99+
Write-Error "Release failed: $_"
100+
exit 1
101+
}

triggerupload.bat

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)