name: Beta Release (PyPI Pre-release) concurrency: group: beta-release cancel-in-progress: true on: push: branches: - beta paths: - "Server/**" - "MCPForUnity/**" jobs: update_unity_beta_version: name: Update Unity package to beta version runs-on: ubuntu-latest # Avoid running when the workflow's own automation merges the PR # created by this workflow (prevents a version-bump loop). if: github.actor != 'github-actions[bot]' permissions: contents: write pull-requests: write outputs: unity_beta_version: ${{ steps.version.outputs.unity_beta_version }} version_updated: ${{ steps.commit.outputs.updated }} steps: - uses: actions/checkout@v6 with: fetch-depth: 0 ref: beta - name: Generate beta version for Unity package id: version shell: bash run: | set -euo pipefail # Read current Unity package version CURRENT_VERSION=$(jq -r '.version' MCPForUnity/package.json) echo "Current Unity package version: $CURRENT_VERSION" # Strip any existing pre-release suffix for safe parsing # e.g., "9.3.1-beta.1" -> "9.3.1" BASE_VERSION=$(echo "$CURRENT_VERSION" | sed -E 's/-[a-zA-Z]+\.[0-9]+$//') # Validate we have a proper X.Y.Z format before arithmetic if ! [[ "$BASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Error: Could not parse version '$CURRENT_VERSION' -> '$BASE_VERSION'" >&2 exit 1 fi # Check if already a beta version if [[ "$CURRENT_VERSION" == *"-beta."* ]]; then echo "Already a beta version, keeping: $CURRENT_VERSION" echo "unity_beta_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" echo "already_beta=true" >> "$GITHUB_OUTPUT" else # Create beta version with semver format (e.g., 9.4.0-beta.1) # Bump minor version to ensure beta is "newer" than stable IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION" NEXT_MINOR=$((MINOR + 1)) BETA_VERSION="${MAJOR}.${NEXT_MINOR}.0-beta.1" echo "Generated Unity beta version: $BETA_VERSION" echo "unity_beta_version=$BETA_VERSION" >> "$GITHUB_OUTPUT" echo "already_beta=false" >> "$GITHUB_OUTPUT" fi - name: Update Unity package.json with beta version if: steps.version.outputs.already_beta != 'true' env: BETA_VERSION: ${{ steps.version.outputs.unity_beta_version }} shell: bash run: | set -euo pipefail # Update package.json version jq --arg v "$BETA_VERSION" '.version = $v' MCPForUnity/package.json > tmp.json mv tmp.json MCPForUnity/package.json echo "Updated MCPForUnity/package.json:" jq '.version' MCPForUnity/package.json - name: Commit to temporary branch and create PR id: commit if: steps.version.outputs.already_beta != 'true' env: GH_TOKEN: ${{ github.token }} BETA_VERSION: ${{ steps.version.outputs.unity_beta_version }} shell: bash run: | set -euo pipefail git config user.name "GitHub Actions" git config user.email "actions@github.com" if git diff --quiet MCPForUnity/package.json; then echo "No changes to commit" echo "updated=false" >> "$GITHUB_OUTPUT" exit 0 fi # Create a temporary branch for the version update BRANCH="beta-version-${BETA_VERSION}-${GITHUB_RUN_ID}" echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" git checkout -b "$BRANCH" git add MCPForUnity/package.json git commit -m "chore: update Unity package to beta version ${BETA_VERSION}" git push origin "$BRANCH" # Check if PR already exists if gh pr view "$BRANCH" >/dev/null 2>&1; then echo "PR already exists for $BRANCH" else PR_URL=$(gh pr create \ --base beta \ --head "$BRANCH" \ --title "chore: update Unity package to beta version ${BETA_VERSION}" \ --body "Automated beta version bump for the Unity package.") echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT" fi echo "updated=true" >> "$GITHUB_OUTPUT" publish_pypi_prerelease: name: Publish beta to PyPI (pre-release) runs-on: ubuntu-latest # Avoid double-publish when the bot merges the version bump PR if: github.actor != 'github-actions[bot]' environment: name: pypi url: https://pypi.org/p/mcpforunityserver permissions: contents: read id-token: write steps: - uses: actions/checkout@v6 with: fetch-depth: 0 ref: beta - name: Install uv uses: astral-sh/setup-uv@v7 with: version: "latest" enable-cache: true cache-dependency-glob: "Server/uv.lock" - name: Generate beta version id: version shell: bash run: | set -euo pipefail RAW_VERSION=$(grep -oP '(?<=version = ")[^"]+' Server/pyproject.toml) # Strip any existing pre-release suffix (a, b, rc, dev, post) for safe parsing # e.g., "9.2.0b1" -> "9.2.0", "9.2.0.dev1" -> "9.2.0" BASE_VERSION=$(echo "$RAW_VERSION" | sed -E 's/(a|b|rc|\.dev|\.post)[0-9]+$//') # Validate we have a proper X.Y.Z format if ! [[ "$BASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Error: Could not parse version '$RAW_VERSION' -> '$BASE_VERSION'" >&2 exit 1 fi # Bump minor version and use beta suffix (PEP 440 compliant: X.Y+1.0bN) # This ensures beta is "newer" than the stable release IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION" NEXT_MINOR=$((MINOR + 1)) BETA_NUMBER="$(date +%Y%m%d%H%M%S)" BETA_VERSION="${MAJOR}.${NEXT_MINOR}.0b${BETA_NUMBER}" echo "Raw version: $RAW_VERSION" echo "Base version: $BASE_VERSION" echo "Beta version: $BETA_VERSION" echo "beta_version=$BETA_VERSION" >> "$GITHUB_OUTPUT" - name: Update version for beta release env: BETA_VERSION: ${{ steps.version.outputs.beta_version }} shell: bash run: | set -euo pipefail sed -i "s/^version = .*/version = \"${BETA_VERSION}\"/" Server/pyproject.toml echo "Updated pyproject.toml:" grep "^version" Server/pyproject.toml - name: Build a binary wheel and a source tarball shell: bash run: uv build working-directory: ./Server - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: Server/dist/