Files
trycua--cua/.github/workflows/release-bump-version.yml
wehub-resource-sync 91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:19 +08:00

601 lines
25 KiB
YAML

name: "CD: Bump Version"
on:
workflow_dispatch:
inputs:
service:
description: "Service/Package to bump"
required: true
type: choice
options:
- pypi/cua
- pypi/agent
- pypi/auto
- pypi/bench
- pypi/bench-ui
- pypi/cli
- pypi/computer
- pypi/computer-server
- pypi/cloud
- pypi/core
- pypi/mcp-server
- pypi/sandbox
- pypi/sandbox-apps
- pypi/som
- pypi/train
- npm/cli
- npm/computer
- npm/core
- npm/playground
- npm/cuabot
- lume
- cua-driver
- cua-driver-rs
- docker/cuabot
- docker/kasm
- docker/xfce
- docker/lumier
- docker/qemu-android
- docker/qemu-linux
- docker/qemu-windows
bump_type:
description: "Version bump type"
required: true
type: choice
options:
- patch
- minor
- major
target_branch:
description: "Branch to push the bump commit + tag to"
required: false
type: string
default: "main"
permissions:
contents: write
jobs:
bump-version:
runs-on: ubuntu-latest
steps:
- name: Set package directory and type
id: package
run: |
case "${{ inputs.service }}" in
"pypi/cua")
echo "directory=libs/python/cua" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/agent")
echo "directory=libs/python/agent" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/auto")
echo "directory=libs/python/cua-auto" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/bench")
echo "directory=libs/cua-bench" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/bench-ui")
echo "directory=libs/python/bench-ui" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/cli")
echo "directory=libs/python/cua-cli" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/computer")
echo "directory=libs/python/computer" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/cloud")
echo "directory=libs/python/cua-cloud" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/computer-server")
echo "directory=libs/python/computer-server" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/core")
echo "directory=libs/python/core" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/mcp-server")
echo "directory=libs/python/mcp-server" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/sandbox")
echo "directory=libs/python/cua-sandbox" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/sandbox-apps")
echo "directory=libs/python/cua-sandbox-apps" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/som")
echo "directory=libs/python/som" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"pypi/train")
echo "directory=libs/python/cua-train" >> $GITHUB_OUTPUT
echo "type=python" >> $GITHUB_OUTPUT
;;
"npm/cli")
echo "directory=libs/typescript/cua-cli" >> $GITHUB_OUTPUT
echo "type=npm" >> $GITHUB_OUTPUT
;;
"npm/computer")
echo "directory=libs/typescript/computer" >> $GITHUB_OUTPUT
echo "type=npm" >> $GITHUB_OUTPUT
;;
"npm/core")
echo "directory=libs/typescript/core" >> $GITHUB_OUTPUT
echo "type=npm" >> $GITHUB_OUTPUT
;;
"npm/playground")
echo "directory=libs/typescript/playground" >> $GITHUB_OUTPUT
echo "type=npm" >> $GITHUB_OUTPUT
;;
"npm/cuabot")
echo "directory=libs/cuabot" >> $GITHUB_OUTPUT
echo "type=npm" >> $GITHUB_OUTPUT
;;
"lume")
echo "directory=libs/lume" >> $GITHUB_OUTPUT
echo "type=lume" >> $GITHUB_OUTPUT
;;
"cua-driver")
echo "directory=libs/cua-driver" >> $GITHUB_OUTPUT
echo "type=cua-driver" >> $GITHUB_OUTPUT
;;
"cua-driver-rs")
echo "directory=libs/cua-driver/rust" >> $GITHUB_OUTPUT
echo "type=cua-driver-rs" >> $GITHUB_OUTPUT
;;
"docker/cuabot")
echo "directory=libs/cuabot" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
echo "bumpversion_config=.bumpversion.docker.cfg" >> $GITHUB_OUTPUT
;;
"docker/kasm")
echo "directory=libs/kasm" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
"docker/xfce")
echo "directory=libs/xfce" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
"docker/lumier")
echo "directory=libs/lumier" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
"docker/qemu-android")
echo "directory=libs/qemu-docker/android" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
"docker/qemu-linux")
echo "directory=libs/qemu-docker/linux" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
"docker/qemu-windows")
echo "directory=libs/qemu-docker/windows" >> $GITHUB_OUTPUT
echo "type=docker" >> $GITHUB_OUTPUT
;;
*)
echo "Unknown service: ${{ inputs.service }}"
exit 1
;;
esac
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.target_branch || 'main' }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install bump2version
run: pip install bump2version
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Reconcile cua-driver-rs bump base with Cargo.toml (drift guard)
if: ${{ inputs.service == 'cua-driver-rs' }}
run: |
# Cargo.toml is the single source of truth for the cua-driver-rs
# version. bump2version keeps a duplicate current_version in
# .bumpversion.cfg, and that copy has silently drifted before and cut
# a release at the wrong version (binary reported a stale version,
# tag could downgrade). Reconcile the cfg to Cargo.toml here, before
# the dry-run tag-clean and the real bump both read it, so a bump can
# never start from a stale base again no matter what the committed
# cfg says.
cd "${{ steps.package.outputs.directory }}"
CARGO_VERSION=$(grep -m1 '^version[[:space:]]*=' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
CFG_VERSION=$(grep -m1 '^current_version[[:space:]]*=' .bumpversion.cfg | sed -E 's/.*=[[:space:]]*//')
if [ -z "$CARGO_VERSION" ]; then
echo "::error::could not read version from libs/cua-driver/rust/Cargo.toml"
exit 1
fi
if [ "$CARGO_VERSION" != "$CFG_VERSION" ]; then
echo "::warning::.bumpversion.cfg current_version ($CFG_VERSION) drifted from Cargo.toml ($CARGO_VERSION); reconciling to Cargo.toml before bump."
sed -i.bak -E "s/^current_version[[:space:]]*=.*/current_version = ${CARGO_VERSION}/" .bumpversion.cfg
rm -f .bumpversion.cfg.bak
fi
echo "cua-driver-rs bump base: $(grep -m1 '^current_version' .bumpversion.cfg)"
- name: Clean existing tags if present
run: |
# Function to clean a tag for a given package directory
clean_tag() {
local dir=$1
local config_file=${2:-.bumpversion.cfg}
cd "$dir"
NEW_VERSION=$(bump2version --config-file "$config_file" --dry-run --list ${{ inputs.bump_type }} 2>/dev/null | grep -m1 '^new_version=' | sed 's/new_version=//')
TAG_NAME=$(grep -m1 '^tag_name' "$config_file" | sed 's/tag_name *= *//' | sed "s|{new_version}|$NEW_VERSION|")
echo "Checking for existing tag: $TAG_NAME"
git tag -d "$TAG_NAME" 2>/dev/null || true
git push origin ":refs/tags/$TAG_NAME" 2>/dev/null || true
cd - > /dev/null
}
# Clean tag for the primary package
BUMPVERSION_CONFIG="${{ steps.package.outputs.bumpversion_config }}"
clean_tag "${{ steps.package.outputs.directory }}" "${BUMPVERSION_CONFIG:-.bumpversion.cfg}"
# No cascade tag cleaning — each package is bumped independently.
# Dependent packages use version ranges and resolve deps at publish time.
- name: Run bump2version
run: |
cd ${{ steps.package.outputs.directory }}
CONFIG_FLAG=""
if [ -n "${{ steps.package.outputs.bumpversion_config }}" ]; then
CONFIG_FLAG="--config-file ${{ steps.package.outputs.bumpversion_config }}"
fi
bump2version $CONFIG_FLAG ${{ inputs.bump_type }}
- name: Sync Cargo.lock into the cua-driver-rs bump commit
# bump2version edits only `[workspace.package] version` in Cargo.toml,
# leaving Cargo.lock's workspace-member versions stale. The next plain
# `cargo build` anyone runs then re-locks them and diverges from the
# committed lockfile — which used to break the nix build's cargoHash.
# Re-lock the members now and fold the change into the bump commit so the
# lockfile never ships out of sync with the manifest. (cargo is
# preinstalled on ubuntu runners; `--workspace` touches members only, not
# registry deps, so this never silently bumps dependencies.)
if: ${{ inputs.service == 'cua-driver-rs' }}
run: |
cd ${{ steps.package.outputs.directory }}
cargo update --workspace
if ! git diff --quiet Cargo.lock; then
TAG=$(git tag --points-at HEAD | head -1)
git add Cargo.lock
git commit --amend --no-edit
# bump2version tagged the pre-amend commit; move the tag onto the
# amended commit so the release pipeline builds the synced lockfile.
[ -n "$TAG" ] && git tag -f "$TAG" HEAD
echo "Re-locked Cargo.lock and moved tag ${TAG:-<none>} to the amended bump commit."
else
echo "Cargo.lock already in sync; nothing to fold in."
fi
- name: Collect created tag
id: collect_tags
run: |
# Only one tag is created per bump (no cascades)
ALL_TAGS=$(git tag --points-at HEAD | tr '\n' ' ' | xargs)
echo "Tags to push: $ALL_TAGS"
echo "tags=$ALL_TAGS" >> $GITHUB_OUTPUT
- name: Capture bumped cua version
if: ${{ inputs.service == 'pypi/cua' }}
id: cua_version
run: |
cd libs/python/cua
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "cua version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped agent version
if: ${{ inputs.service == 'pypi/agent' }}
id: agent_version
run: |
cd libs/python/agent
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Agent version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped auto version
if: ${{ inputs.service == 'pypi/auto' }}
id: auto_version
run: |
cd libs/python/cua-auto
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Auto version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped bench version
if: ${{ inputs.service == 'pypi/bench' }}
id: bench_version
run: |
cd libs/cua-bench
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Bench version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped bench-ui version
if: ${{ inputs.service == 'pypi/bench-ui' }}
id: bench_ui_version
run: |
cd libs/python/bench-ui
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Bench-ui version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped cli version
if: ${{ inputs.service == 'pypi/cli' }}
id: cli_version
run: |
cd libs/python/cua-cli
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "CLI version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped computer version
if: ${{ inputs.service == 'pypi/computer' }}
id: computer_version
run: |
cd libs/python/computer
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Computer version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped cloud version
if: ${{ inputs.service == 'pypi/cloud' }}
id: cloud_version
run: |
cd libs/python/cua-cloud
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Cloud version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped computer-server version
if: ${{ inputs.service == 'pypi/computer-server' }}
id: computer_server_version
run: |
cd libs/python/computer-server
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Computer-server version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped core version
if: ${{ inputs.service == 'pypi/core' }}
id: core_version
run: |
cd libs/python/core
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Core version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped mcp-server version
if: ${{ inputs.service == 'pypi/mcp-server' }}
id: mcp_server_version
run: |
cd libs/python/mcp-server
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "MCP-server version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped sandbox version
if: ${{ inputs.service == 'pypi/sandbox' }}
id: sandbox_version
run: |
cd libs/python/cua-sandbox
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Sandbox version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped sandbox-apps version
if: ${{ inputs.service == 'pypi/sandbox-apps' }}
id: sandbox_apps_version
run: |
cd libs/python/cua-sandbox-apps
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Sandbox-apps version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped som version
if: ${{ inputs.service == 'pypi/som' }}
id: som_version
run: |
cd libs/python/som
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "SOM version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped train version
if: ${{ inputs.service == 'pypi/train' }}
id: train_version
run: |
cd libs/python/cua-train
VERSION=$(python -c "import tomllib; from pathlib import Path; data = tomllib.loads(Path('pyproject.toml').read_text()); print(data['project']['version'])")
echo "Train version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped npm/cli version
if: ${{ inputs.service == 'npm/cli' }}
id: npm_cli_version
run: |
VERSION=$(grep -oP '"version": "\K[^"]+' libs/typescript/cua-cli/package.json)
echo "npm/cli version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped npm/computer version
if: ${{ inputs.service == 'npm/computer' }}
id: npm_computer_version
run: |
VERSION=$(grep -oP '"version": "\K[^"]+' libs/typescript/computer/package.json)
echo "npm/computer version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped npm/core version
if: ${{ inputs.service == 'npm/core' }}
id: npm_core_version
run: |
VERSION=$(grep -oP '"version": "\K[^"]+' libs/typescript/core/package.json)
echo "npm/core version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped npm/playground version
if: ${{ inputs.service == 'npm/playground' }}
id: npm_playground_version
run: |
VERSION=$(grep -oP '"version": "\K[^"]+' libs/typescript/playground/package.json)
echo "npm/playground version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped lume version
if: ${{ inputs.service == 'lume' }}
id: lume_version
run: |
VERSION=$(grep -oP 'static let current: String = "\K[^"]+' libs/lume/src/Main.swift)
echo "lume version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped cua-driver version
if: ${{ inputs.service == 'cua-driver' }}
id: cua_driver_version
run: |
VERSION=$(grep -oP 'public static let version = "\K[^"]+' libs/cua-driver/Sources/CuaDriverCore/CuaDriverCore.swift)
echo "cua-driver version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped cua-driver-rs version
if: ${{ inputs.service == 'cua-driver-rs' }}
id: cua_driver_rs_version
run: |
VERSION=$(grep -m1 -oP '^version = "\K[^"]+' libs/cua-driver/rust/Cargo.toml)
echo "cua-driver-rs version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Capture bumped cuabot version
if: ${{ inputs.service == 'npm/cuabot' }}
id: cuabot_version
run: |
VERSION=$(grep -oP '"version": "\K[^"]+' libs/cuabot/package.json)
echo "cuabot version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: ${{ github.event.repository.name }}
- name: Push release to target branch
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
TARGET_BRANCH: ${{ inputs.target_branch || 'main' }}
run: |
# Configure git to use the app token
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
# Verify the token works
echo "Verifying GitHub App token..."
gh auth status
# Get all tags created by bump2version
ALL_TAGS="${{ steps.collect_tags.outputs.tags }}"
echo "Tags to push: $ALL_TAGS"
# Use the first tag for naming the temp branch
FIRST_TAG=$(echo "$ALL_TAGS" | awk '{print $1}')
TEMP_BRANCH="temp-release-${FIRST_TAG}"
echo "Temp branch: $TEMP_BRANCH"
# Retry loop for handling concurrent bumps
MAX_RETRIES=5
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
RETRY_COUNT=$((RETRY_COUNT + 1))
echo ""
echo "=== Attempt $RETRY_COUNT/$MAX_RETRIES ==="
# Fetch latest target branch to check if we need to rebase
git fetch origin "${TARGET_BRANCH}"
# Check if our HEAD is a descendant of origin/<branch> (fast-forward possible)
if ! git merge-base --is-ancestor "origin/${TARGET_BRANCH}" HEAD; then
echo "Branch ${TARGET_BRANCH} has moved forward, rebasing..."
# Rebase our commit(s) onto the latest branch
git rebase "origin/${TARGET_BRANCH}"
# Update the tag to point to the rebased commit
for tag in $ALL_TAGS; do
git tag -f "$tag" HEAD
echo "Updated tag $tag to rebased HEAD"
done
fi
# Get the current commit SHA (may have changed after rebase)
COMMIT_SHA=$(git rev-parse HEAD)
echo "Commit SHA: $COMMIT_SHA"
# Push to temp branch
echo "Pushing to temp branch..."
git push origin "HEAD:refs/heads/${TEMP_BRANCH}" --force
# Try to update target branch via API
echo "Updating ${TARGET_BRANCH} branch via API..."
if gh api -X PATCH "/repos/${{ github.repository }}/git/refs/heads/${TARGET_BRANCH}" \
-f sha="${COMMIT_SHA}" \
-F force=false 2>&1; then
echo "Successfully updated ${TARGET_BRANCH} branch!"
# Create tag via API (only after main is successfully updated)
echo "Creating tag via API..."
for tag in $ALL_TAGS; do
echo "Creating tag: $tag"
gh api -X DELETE /repos/${{ github.repository }}/git/refs/tags/${tag} 2>/dev/null || true
gh api /repos/${{ github.repository }}/git/refs \
-f ref="refs/tags/${tag}" \
-f sha="${COMMIT_SHA}"
echo "Tag $tag created successfully!"
done
# Clean up temp branch
echo "Cleaning up temp branch..."
git push origin --delete "${TEMP_BRANCH}" || true
exit 0
fi
echo "Failed to update ${TARGET_BRANCH} (not a fast-forward), will retry..."
sleep 2
done
echo "ERROR: Failed to update ${TARGET_BRANCH} branch after $MAX_RETRIES attempts"
exit 1
# NOTE: Publishing is handled by tag-triggered workflows (cd-py-*.yml, cd-ts-*.yml, cd-swift-lume.yml)
# When bump-version pushes a tag (e.g., agent-v0.7.10), the corresponding CD workflow
# is automatically triggered by the tag push event. No need to call them here.