Skip to content

Commit e06b186

Browse files
committed
Add release script
1 parent ad7648b commit e06b186

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

scripts/release.sh

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Release script for ai-hedge-fund
5+
# Usage: bash scripts/release.sh [version]
6+
# If no version is provided, defaults to today's date as YYYY.M.D
7+
8+
VERSION="${1:-$(date +%Y.%-m.%-d)}"
9+
TAG="v${VERSION}"
10+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
11+
12+
cd "$REPO_ROOT"
13+
14+
# Ensure gh CLI is available
15+
if ! command -v gh &>/dev/null; then
16+
echo "Error: gh CLI is required. Install it: https://cli.github.com"
17+
exit 1
18+
fi
19+
20+
# Ensure working tree is clean
21+
if [[ -n "$(git status --porcelain)" ]]; then
22+
echo "Error: working tree is dirty. Commit or stash changes first."
23+
exit 1
24+
fi
25+
26+
# Find the previous tag (most recent), or use root commit if none exist
27+
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
28+
if [[ -z "$PREV_TAG" ]]; then
29+
RANGE="HEAD"
30+
else
31+
RANGE="${PREV_TAG}..HEAD"
32+
fi
33+
34+
echo "Releasing ${TAG}"
35+
echo "Commits: ${RANGE}"
36+
echo ""
37+
38+
# Collect commits and categorize into Changes and Fixes
39+
CHANGES=""
40+
FIXES=""
41+
42+
while IFS= read -r line; do
43+
[[ -z "$line" ]] && continue
44+
# Extract subject (everything after the short hash + space)
45+
subject="${line#* }"
46+
if echo "$subject" | grep -qi "^fix"; then
47+
FIXES="${FIXES}- ${subject}\n"
48+
else
49+
CHANGES="${CHANGES}- ${subject}\n"
50+
fi
51+
done < <(git log --oneline --no-merges "$RANGE" | grep -v "^.*Bump version$")
52+
53+
# Build release body
54+
BODY=""
55+
if [[ -n "$CHANGES" ]]; then
56+
BODY+="### Changes\n\n${CHANGES}\n"
57+
fi
58+
if [[ -n "$FIXES" ]]; then
59+
BODY+="### Fixes\n\n${FIXES}\n"
60+
fi
61+
62+
if [[ -z "$BODY" ]]; then
63+
echo "Error: no commits found for release notes."
64+
exit 1
65+
fi
66+
67+
# Preview
68+
echo "--- Release notes ---"
69+
echo -e "$BODY"
70+
echo "---------------------"
71+
echo ""
72+
73+
# Prompt for confirmation
74+
read -rp "Create release ${TAG}? [y/N] " confirm
75+
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
76+
echo "Aborted."
77+
exit 0
78+
fi
79+
80+
# Bump version in pyproject.toml
81+
CURRENT_VERSION=$(python3 -c "import re; print(re.search(r'^version\s*=\s*\"([^\"]+)\"', open('pyproject.toml').read(), re.M).group(1))")
82+
if [[ "$CURRENT_VERSION" != "$VERSION" ]]; then
83+
python3 -c "
84+
import re
85+
with open('pyproject.toml', 'r') as f:
86+
content = f.read()
87+
content = re.sub(r'^version\s*=\s*\"[^\"]+\"', 'version = \"${VERSION}\"', content, count=1, flags=re.M)
88+
with open('pyproject.toml', 'w') as f:
89+
f.write(content)
90+
"
91+
git add pyproject.toml
92+
git commit -m "Bump version to ${VERSION}"
93+
git push origin HEAD
94+
fi
95+
96+
# Create tag
97+
git tag "$TAG"
98+
99+
# Push tag
100+
git push origin "$TAG"
101+
102+
# Create GitHub release
103+
echo -e "$BODY" | gh release create "$TAG" \
104+
--title "ai-hedge-fund ${VERSION}" \
105+
--notes-file -
106+
107+
echo ""
108+
echo "Released ${TAG}: https://github.com/virattt/ai-hedge-fund/releases/tag/${TAG}"

0 commit comments

Comments
 (0)