Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion agent_sdks/python/a2ui_core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

[project]
name = "a2ui-core"
version = "0.1.0"
dynamic = ["version"]
description = "A2UI Python SDK - Core Library"
readme = "README.md"
requires-python = ">=3.14"
Expand All @@ -35,6 +35,9 @@ dev = [
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.version]
path = "src/a2ui/core/version.py"

[tool.hatch.build.targets.wheel]
packages = ["src/a2ui"]

Expand Down
15 changes: 15 additions & 0 deletions agent_sdks/python/a2ui_core/src/a2ui/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from a2ui.core.version import __version__ as __version__
20 changes: 20 additions & 0 deletions agent_sdks/python/a2ui_core/src/a2ui/core/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# File-based dynamic versioning
# - The next release version
# - Version format: major.minor.patch
# - Update the version in this file before releasing
#
__version__ = "0.0.3"
1 change: 0 additions & 1 deletion agent_sdks/python/a2ui_core/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,35 @@
# See the License for the specific language governing permissions and
# limitations under the License.


set -e # Exit on error
#set -x # Echo commands

PACKAGE_NAME="a2ui-agent-sdk"
# Check arguments
if [ -z "$1" ]; then
echo "Usage: $0 <a2ui_agent|a2ui_core>"
exit 1
fi

SCRIPT_DIR=$(dirname "$(readlink -f "$0")")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using readlink -f is not portable because the -f option is not supported by the default readlink implementation on macOS. This will cause the script to fail when run on macOS.

A more portable way to get the script's directory in Bash is to use cd and pwd -P.

Suggested change
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd -P)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a good idea - would be great for this to work on macos

TARGET_DIR="${SCRIPT_DIR}/${1}"

if [ ! -d "$TARGET_DIR" ]; then
echo "Error: Directory '$TARGET_DIR' does not exist."
exit 1
fi

cd "$TARGET_DIR"

# Read package name from pyproject.toml
if [ ! -f "pyproject.toml" ]; then
echo "Error: pyproject.toml not found in '$TARGET_DIR'."
exit 1
fi

PACKAGE_NAME=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

tomllib was introduced in Python 3.11. Since a2ui-agent-sdk supports Python >=3.10 (as specified in its pyproject.toml), running this script on a system with Python 3.10 will fail with a ModuleNotFoundError.

We can make this robust by using uv run --with tomli and falling back to tomli if tomllib is not available.

Suggested change
PACKAGE_NAME=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])")
PACKAGE_NAME=$(uv run --with tomli python3 -c "import sys; tomllib = __import__('tomllib') if sys.version_info >= (3, 11) else __import__('tomli'); print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])")

VERSION=$(uv run --with hatch hatch version)

echo "Releasing package: $PACKAGE_NAME ($VERSION) from folder: $TARGET_DIR"

REPOSITORY="a2ui--pypi"
PROJECT="oss-exit-gate-prod"
LOCATION="us"
Expand All @@ -36,29 +60,27 @@ echo "--- Uploading the package ---"
twine --version
twine check dist/*
Comment on lines 60 to 61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Run twine via uv tool run to ensure it is executed with the correct keyring plugins and doesn't rely on ~/.local/bin being in the PATH.

Suggested change
twine --version
twine check dist/*
uv tool run --with keyrings.google-artifactregistry-auth --with keyring twine --version
uv tool run --with keyrings.google-artifactregistry-auth --with keyring twine check dist/*


version=$(uv run python -c "import a2ui; print(a2ui.__version__)")

# Authenticate with Google Cloud
if ! gcloud auth application-default print-access-token --quiet > /dev/null; then
gcloud auth application-default login
fi

# Check if the version already exists in the staging repository
if gcloud artifacts versions describe "$version" --package=$PACKAGE_NAME --repository=$REPOSITORY --location=$LOCATION --project=$PROJECT > /dev/null 2>&1; then
echo "Version $version already exists in Artifact Registry. Skip the release."
echo "Hint: If you intended to release a new version, please update 'src/a2ui/version.py'."
if gcloud artifacts versions describe "$VERSION" --package="$PACKAGE_NAME" --repository="$REPOSITORY" --location="$LOCATION" --project="$PROJECT" > /dev/null 2>&1; then
echo "Version $VERSION of $PACKAGE_NAME already exists in Artifact Registry. Skip the release."
echo "Hint: If you intended to release a new version, please update its version in pyproject.toml or version.py."
exit 0
fi

twine upload --repository-url $REPOSITORY_URL dist/*
echo "Version $version uploaded to Artifact Registry."
twine upload --repository-url "$REPOSITORY_URL" dist/*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Run twine upload via uv tool run to ensure it is executed with the correct keyring plugins and doesn't rely on ~/.local/bin being in the PATH.

Suggested change
twine upload --repository-url "$REPOSITORY_URL" dist/*
uv tool run --with keyrings.google-artifactregistry-auth --with keyring twine upload --repository-url "$REPOSITORY_URL" dist/*

echo "Version $VERSION of $PACKAGE_NAME uploaded to Artifact Registry."

echo "--- Creating manifest.json ---"
MANIFEST_FILE="manifest.json"
echo '{ "publish_all": true }' > $MANIFEST_FILE

echo "--- Uploading manifest to GCS to trigger OSS Exit Gate ---"
MANIFEST_NAME="manifest-${version}-$(date +%Y%m%d%H%M%S).json"
MANIFEST_NAME="manifest-${VERSION}-$(date +%Y%m%d%H%M%S).json"
gcloud storage cp $MANIFEST_FILE "${GCS_URI}/${MANIFEST_NAME}"
rm -rf $MANIFEST_FILE

Expand Down
Loading