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
601 lines
25 KiB
YAML
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.
|