Skip to content

Commit a061adc

Browse files
committed
Add scipoptsuite-deploy integration to release script
1 parent 5a5189f commit a061adc

1 file changed

Lines changed: 138 additions & 22 deletions

File tree

release.sh

Lines changed: 138 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ set -euo pipefail
33

44
VERSION_FILE="src/pyscipopt/_version.py"
55
SETUP_FILE="setup.py"
6+
PYPROJECT="pyproject.toml"
67
CHANGELOG="CHANGELOG.md"
78
REPO="scipopt/PySCIPOpt"
9+
DEPLOY_REPO="scipopt/scipoptsuite-deploy"
810

911
# --- Pre-flight checks ---
1012

@@ -31,17 +33,74 @@ fi
3133

3234
git pull --ff-only
3335

34-
# --- Read current version ---
36+
# --- Helper functions ---
37+
38+
validate_version() {
39+
if [[ ! "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
40+
echo "Error: '$1' is not a valid version (expected X.Y.Z)"
41+
exit 1
42+
fi
43+
}
44+
45+
prompt_version() {
46+
local label="$1" current="$2"
47+
read -rp "${label} [${current}]: " value
48+
value="${value:-$current}"
49+
validate_version "$value"
50+
echo "$value"
51+
}
52+
53+
# --- Collect all inputs ---
54+
55+
# 1. New SCIP binaries?
56+
57+
CURRENT_DEPLOY_VERSION=$(grep -o 'scipoptsuite-deploy/releases/download/v[0-9.]*' "$PYPROJECT" | head -1 | sed 's|.*/||')
58+
59+
echo "Current scipoptsuite-deploy version: ${CURRENT_DEPLOY_VERSION}"
60+
read -rp "Does this release need new SCIP binaries? [y/N] " need_deploy
61+
62+
NEED_DEPLOY=false
63+
if [[ "${need_deploy:-N}" =~ ^[Yy] ]]; then
64+
NEED_DEPLOY=true
65+
66+
echo ""
67+
echo "Enter component versions (press enter to keep current):"
68+
69+
# Fetch current defaults from the deploy workflow
70+
DEPLOY_WORKFLOW=$(gh api repos/${DEPLOY_REPO}/contents/.github/workflows/build_binaries.yml --jq '.content' | base64 -d)
71+
current_deploy_default() {
72+
echo "$DEPLOY_WORKFLOW" | sed -n "/${1}:/,/default:/{s/.*default: \"\(.*\)\"/\1/p;}" | head -1
73+
}
74+
75+
CUR_SCIP=$(current_deploy_default "scip_version")
76+
CUR_SOPLEX=$(current_deploy_default "soplex_version")
77+
CUR_GCG=$(current_deploy_default "gcg_version")
78+
CUR_IPOPT=$(current_deploy_default "ipopt_version")
79+
80+
SCIP_VERSION=$(prompt_version "SCIP" "$CUR_SCIP")
81+
SOPLEX_VERSION=$(prompt_version "SoPlex" "$CUR_SOPLEX")
82+
GCG_VERSION=$(prompt_version "GCG" "$CUR_GCG")
83+
IPOPT_VERSION=$(prompt_version "IPOPT" "$CUR_IPOPT")
84+
85+
# Bump deploy version (increment minor)
86+
DEPLOY_MAJOR=$(echo "$CURRENT_DEPLOY_VERSION" | sed 's/^v//' | cut -d. -f1)
87+
DEPLOY_MINOR=$(echo "$CURRENT_DEPLOY_VERSION" | sed 's/^v//' | cut -d. -f2)
88+
DEPLOY_PATCH=$(echo "$CURRENT_DEPLOY_VERSION" | sed 's/^v//' | cut -d. -f3)
89+
SUGGESTED_DEPLOY="v$((DEPLOY_MAJOR)).$((DEPLOY_MINOR + 1)).$((DEPLOY_PATCH))"
90+
91+
read -rp "New deploy release tag [${SUGGESTED_DEPLOY}]: " NEW_DEPLOY_VERSION
92+
NEW_DEPLOY_VERSION="${NEW_DEPLOY_VERSION:-$SUGGESTED_DEPLOY}"
93+
fi
94+
95+
# 2. PySCIPOpt version bump
3596

3697
CURRENT_VERSION=$(sed -n "s/^__version__.*'\(.*\)'/\1/p" "$VERSION_FILE")
3798
MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
3899
MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
39100
PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)
40101

41-
echo "Current version: ${CURRENT_VERSION}"
42-
43-
# --- Prompt for bump type ---
44-
102+
echo ""
103+
echo "Current PySCIPOpt version: ${CURRENT_VERSION}"
45104
echo ""
46105
echo "Release type:"
47106
echo " 1) patch -> $((MAJOR)).$((MINOR)).$((PATCH + 1))"
@@ -57,34 +116,88 @@ case "$bump_type" in
57116
*) echo "Error: invalid selection '${bump_type}'"; exit 1 ;;
58117
esac
59118

60-
# --- Check tag doesn't already exist ---
61-
62119
if git rev-parse "v${NEW_VERSION}" &>/dev/null; then
63120
echo "Error: tag 'v${NEW_VERSION}' already exists."
64121
exit 1
65122
fi
66123

67-
# --- Show changelog preview ---
124+
# --- Show summary and confirm ---
68125

69126
echo ""
70127
echo "Unreleased changelog entries:"
71128
echo "-----------------------------"
72-
# Print lines between "## Unreleased" and the next "## " header
73129
sed -n '/^## Unreleased$/,/^## [0-9]/{/^## [0-9]/!p;}' "$CHANGELOG" | head -30
74130
echo "-----------------------------"
75-
echo ""
76131

77132
TODAY=$(date +%Y.%m.%d)
78133
echo ""
79134
echo "This script will:"
80-
echo " 1. Update version ${CURRENT_VERSION} -> ${NEW_VERSION} in _version.py and setup.py"
81-
echo " 2. Update CHANGELOG.md (${NEW_VERSION} - ${TODAY})"
82-
echo " 3. Commit, tag v${NEW_VERSION}, and push to origin"
83-
echo " 4. Trigger the build wheels workflow (test-pypi)"
135+
if [[ "$NEED_DEPLOY" == true ]]; then
136+
echo " 1. Build new SCIP binaries (SCIP=${SCIP_VERSION} SoPlex=${SOPLEX_VERSION} GCG=${GCG_VERSION} IPOPT=${IPOPT_VERSION})"
137+
echo " 2. Create scipoptsuite-deploy release ${NEW_DEPLOY_VERSION}"
138+
echo " 3. Update deploy version ${CURRENT_DEPLOY_VERSION} -> ${NEW_DEPLOY_VERSION} in pyproject.toml"
139+
echo " 4. Update PySCIPOpt version ${CURRENT_VERSION} -> ${NEW_VERSION} in _version.py and setup.py"
140+
echo " 5. Update CHANGELOG.md (${NEW_VERSION} - ${TODAY})"
141+
echo " 6. Commit, tag v${NEW_VERSION}, and push to origin"
142+
echo " 7. Trigger the build wheels workflow (test-pypi)"
143+
else
144+
echo " 1. Update version ${CURRENT_VERSION} -> ${NEW_VERSION} in _version.py and setup.py"
145+
echo " 2. Update CHANGELOG.md (${NEW_VERSION} - ${TODAY})"
146+
echo " 3. Commit, tag v${NEW_VERSION}, and push to origin"
147+
echo " 4. Trigger the build wheels workflow (test-pypi)"
148+
fi
84149
echo ""
85150
read -rp "Proceed? [Y/n] " confirm
86151
[[ "${confirm:-Y}" =~ ^[Nn] ]] && exit 0
87152

153+
# ============================================================
154+
# From here on, everything runs without further prompts.
155+
# ============================================================
156+
157+
# --- Build and release SCIP binaries (if needed) ---
158+
159+
if [[ "$NEED_DEPLOY" == true ]]; then
160+
echo ""
161+
echo "Triggering SCIP binary build..."
162+
gh workflow run build_binaries.yml --repo "$DEPLOY_REPO" \
163+
-f scip_version="$SCIP_VERSION" \
164+
-f soplex_version="$SOPLEX_VERSION" \
165+
-f gcg_version="$GCG_VERSION" \
166+
-f ipopt_version="$IPOPT_VERSION"
167+
168+
# Wait for the run to appear
169+
sleep 5
170+
RUN_ID=$(gh run list --workflow=build_binaries.yml --repo "$DEPLOY_REPO" --limit 1 --json databaseId --jq '.[0].databaseId')
171+
172+
echo "Waiting for build to complete (run ${RUN_ID})..."
173+
echo " https://github.com/${DEPLOY_REPO}/actions/runs/${RUN_ID}"
174+
gh run watch "$RUN_ID" --repo "$DEPLOY_REPO" --exit-status
175+
176+
# Download artifacts and create release
177+
TMPDIR=$(mktemp -d)
178+
echo "Downloading artifacts..."
179+
gh run download "$RUN_ID" --repo "$DEPLOY_REPO" --dir "$TMPDIR"
180+
181+
RELEASE_NAME="SCIP ${SCIP_VERSION} SOPLEX ${SOPLEX_VERSION} GCG ${GCG_VERSION} IPOPT ${IPOPT_VERSION}"
182+
echo "Creating release ${NEW_DEPLOY_VERSION}..."
183+
gh release create "$NEW_DEPLOY_VERSION" \
184+
--repo "$DEPLOY_REPO" \
185+
--title "$RELEASE_NAME" \
186+
--notes "$RELEASE_NAME" \
187+
"$TMPDIR"/linux/*.zip \
188+
"$TMPDIR"/linux-arm/*.zip \
189+
"$TMPDIR"/macos-arm/*.zip \
190+
"$TMPDIR"/macos-intel/*.zip \
191+
"$TMPDIR"/windows/*.zip
192+
193+
rm -rf "$TMPDIR"
194+
195+
# Update deploy version in pyproject.toml
196+
sed -i.bak "s|scipoptsuite-deploy/releases/download/${CURRENT_DEPLOY_VERSION}|scipoptsuite-deploy/releases/download/${NEW_DEPLOY_VERSION}|g" "$PYPROJECT"
197+
rm -f "${PYPROJECT}.bak"
198+
echo "Updated pyproject.toml: ${CURRENT_DEPLOY_VERSION} -> ${NEW_DEPLOY_VERSION}"
199+
fi
200+
88201
# --- Update version files ---
89202

90203
sed -i.bak "s/__version__.*=.*'.*'/__version__: str = '${NEW_VERSION}'/" "$VERSION_FILE"
@@ -97,24 +210,27 @@ echo "Updated version: ${CURRENT_VERSION} -> ${NEW_VERSION}"
97210

98211
# --- Update changelog ---
99212

100-
UNRELEASED_HEADER="## Unreleased"
101-
NEW_HEADER="## ${NEW_VERSION} - ${TODAY}"
102-
EMPTY_UNRELEASED="## Unreleased\n### Added\n### Fixed\n### Changed\n### Removed\n"
103-
104-
sed -i.bak "s/^${UNRELEASED_HEADER}$/${NEW_HEADER}/" "$CHANGELOG"
213+
sed -i.bak "s/^## Unreleased$/## ${NEW_VERSION} - ${TODAY}/" "$CHANGELOG"
105214
rm -f "${CHANGELOG}.bak"
106215

107-
# Add empty Unreleased section at the top (after "# CHANGELOG" line)
108216
sed -i.bak "/^# CHANGELOG$/a\\
109217
\\
110-
${EMPTY_UNRELEASED}" "$CHANGELOG"
218+
## Unreleased\\
219+
### Added\\
220+
### Fixed\\
221+
### Changed\\
222+
### Removed\\
223+
" "$CHANGELOG"
111224
rm -f "${CHANGELOG}.bak"
112225

113226
echo "Updated CHANGELOG.md"
114227

115228
# --- Commit, tag, and push ---
116229

117-
git add "$VERSION_FILE" "$SETUP_FILE" "$CHANGELOG"
230+
FILES_TO_COMMIT=("$VERSION_FILE" "$SETUP_FILE" "$CHANGELOG")
231+
[[ "$NEED_DEPLOY" == true ]] && FILES_TO_COMMIT+=("$PYPROJECT")
232+
233+
git add "${FILES_TO_COMMIT[@]}"
118234
git commit -m "release v${NEW_VERSION}"
119235
git tag "v${NEW_VERSION}"
120236
git push origin master

0 commit comments

Comments
 (0)