aae8d0a379
In-progress work committed to unblock the config import/export plan: - prompts: FILE_REFERENCES section for workspace-relative file citation - backends: resolve quoted virtual absolute paths onto the sandbox workspace - middleware: read_file_images middleware; message_budget extensions - image_gen/model_registry: image model 'enabled' flag refactor - memory/launch, gateway/background_runs, tools/image follow-ons - scripts: dev_backend.sh, release.sh - tests for the above
77 lines
2.7 KiB
Bash
Executable File
77 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Release EvoScientist to git.foksai.com.
|
|
#
|
|
# Usage:
|
|
# scripts/release.sh 0.2.3 "Release notes text" # bump pyproject, tag, publish
|
|
# scripts/release.sh 0.2.2 "Release notes text" # version == pyproject: reuse existing tag
|
|
#
|
|
# Requires: GITEA_TOKEN (write:repository), uv, shasum, jq, curl.
|
|
# Optional: GITEA_BASE_URL (default https://git.foksai.com), GITEA_REPO (default ouyangbo/EvoScientist).
|
|
#
|
|
# The wheel/sdist are built in a temporary git worktree at the tag so dirty
|
|
# working trees never leak into published artifacts.
|
|
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:?usage: release.sh <version> <notes>}"
|
|
NOTES="${2:?usage: release.sh <version> <notes>}"
|
|
TAG="v${VERSION}"
|
|
BASE="${GITEA_BASE_URL:-https://git.foksai.com}"
|
|
REPO="${GITEA_REPO:-ouyangbo/EvoScientist}"
|
|
: "${GITEA_TOKEN:?export GITEA_TOKEN with write:repository scope}"
|
|
|
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
cd "$REPO_ROOT"
|
|
|
|
PYPROJECT_VERSION="$(grep -m1 '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')"
|
|
|
|
if [[ "$VERSION" != "$PYPROJECT_VERSION" ]]; then
|
|
echo "==> bump pyproject $PYPROJECT_VERSION -> $VERSION"
|
|
sed -i '' "s/^version = \"$PYPROJECT_VERSION\"/version = \"$VERSION\"/" pyproject.toml
|
|
uv lock
|
|
git add pyproject.toml uv.lock
|
|
git commit -m "chore(release): $TAG"
|
|
git tag "$TAG"
|
|
else
|
|
git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null || {
|
|
echo "error: pyproject is already $VERSION but tag $TAG does not exist" >&2
|
|
exit 1
|
|
}
|
|
echo "==> reusing existing tag $TAG"
|
|
fi
|
|
|
|
echo "==> pushing tag $TAG"
|
|
git push origin "$TAG"
|
|
|
|
WORKTREE="$(mktemp -d)/build"
|
|
trap 'git worktree remove --force "$WORKTREE" 2>/dev/null || true' EXIT
|
|
echo "==> building from clean worktree at $TAG"
|
|
git worktree add --detach "$WORKTREE" "$TAG"
|
|
( cd "$WORKTREE" && uv build )
|
|
DIST="$WORKTREE/dist"
|
|
|
|
( cd "$DIST" && shasum -a 256 ./*.whl ./*.tar.gz > checksums.txt )
|
|
|
|
echo "==> creating release $TAG"
|
|
RELEASE_ID="$(curl -sS -f -X POST \
|
|
-H "Authorization: token $GITEA_TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "$(jq -n --arg tag "$TAG" --arg body "$NOTES" \
|
|
'{tag_name: $tag, name: "Release \($tag)", body: $body}')" \
|
|
"$BASE/api/v1/repos/$REPO/releases" | jq -r .id)"
|
|
echo " release id: $RELEASE_ID"
|
|
|
|
for f in "$DIST"/*.whl "$DIST"/*.tar.gz "$DIST/checksums.txt"; do
|
|
echo "==> uploading $(basename "$f")"
|
|
curl -sS -f -X POST \
|
|
-H "Authorization: token $GITEA_TOKEN" \
|
|
-H 'Content-Type: application/octet-stream' \
|
|
--data-binary "@$f" \
|
|
"$BASE/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=$(basename "$f")" \
|
|
| jq -r '.browser_download_url'
|
|
done
|
|
|
|
echo "==> verify"
|
|
curl -sS -f "$BASE/api/v1/repos/$REPO/releases/latest" | jq -r '.tag_name'
|
|
echo "done: $TAG published"
|