Skip to content
Merged
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
84 changes: 31 additions & 53 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name: Auto Release on Push
# Manual patch release: bump version, push to default branch + tag, then PyPI + GitHub Release.
# `master` is often protected — set secret RELEASE_PUSH_TOKEN (PAT with contents:write + bypass)
# or use PR + tag flow via publish.yml instead of this workflow.
name: Auto Release

on:
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- '.github/**'
- 'CHANGELOG.md'
workflow_dispatch:

jobs:
auto-release:
Expand All @@ -19,9 +17,6 @@ jobs:
with:
fetch-depth: 0
ssh-strict: false
# Omit token: uses repo default GITHUB_TOKEN (same as github.token).
# Optional PAT secret AI_GITHUB_TOKEN with contents:write if pushes must
# trigger other workflows (GITHUB_TOKEN pushes skip downstream workflows).

- name: Set up Python
uses: actions/setup-python@v4
Expand Down Expand Up @@ -65,13 +60,11 @@ jobs:
run: |
CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}"

# Split version into components
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
PATCH="${VERSION_PARTS[2]}"

# Always bump patch version for auto-releases
NEW_MAJOR=$MAJOR
NEW_MINOR=$MINOR
NEW_PATCH=$((PATCH + 1))
Expand All @@ -80,64 +73,57 @@ jobs:
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION"

- name: Update version in setup.py and package __init__.py
- name: Update version in setup.py, __init__.py, and client User-Agent
run: |
NEW="${{ steps.new_version.outputs.new_version }}"
sed -i "s/version=\"[^\"]*\"/version=\"${NEW}\"/" setup.py
sed -i "s/__version__ = \"[^\"]*\"/__version__ = \"${NEW}\"/" cost_katana/__init__.py
echo "Updated version to ${NEW}"
sed -i "s/cost-katana-python\/[0-9.]*\"/cost-katana-python\/${NEW}\"/" cost_katana/client.py

- name: Build package
run: |
rm -rf dist build cost_katana.egg-info
python setup.py sdist bdist_wheel

# Same secret name as publish.yml and manual-release.yml
- name: Publish to PyPI
- name: Create and push commit and tag
env:
PYPI_SECRET: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ -z "$PYPI_SECRET" ]; then
echo "::error::Add repository secret PYPI_API_TOKEN (PyPI API token with upload scope)."
exit 1
fi
echo "[pypi]" > ~/.pypirc
echo "username = __token__" >> ~/.pypirc
echo "password = $PYPI_SECRET" >> ~/.pypirc
python -m twine upload --repository pypi dist/*
echo "Successfully published cost-katana@${{ steps.new_version.outputs.new_version }} to PyPI"

- name: Create and push tag
# PAT optional: bypass protected-branch pushes; otherwise falls back to github.token (often blocked on master).
PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN || github.token }}
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${{ github.repository }}.git"

# Configure git to use the token for authentication
git remote set-url origin https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git

# Verify the remote URL is set correctly
echo "Remote URL: $(git remote get-url origin)"

# Add and commit changes
git add setup.py cost_katana/__init__.py
git add setup.py cost_katana/__init__.py cost_katana/client.py
git commit -m "Auto-release: Bump version to ${{ steps.new_version.outputs.new_version }}"

# Create tag
git tag -a "v${{ steps.new_version.outputs.new_version }}" -m "Auto-release version ${{ steps.new_version.outputs.new_version }}"

# Push with explicit authentication
if ! git push origin HEAD:${{ github.ref }}; then
if ! git push origin "HEAD:${{ github.ref }}"; then
echo "Git push failed, trying with GitHub CLI..."
gh auth login --with-token <<< "${{ github.token }}"
git push origin HEAD:${{ github.ref }}
echo "$PUSH_TOKEN" | gh auth login --with-token
git push origin "HEAD:${{ github.ref }}"
fi

if ! git push origin "v${{ steps.new_version.outputs.new_version }}"; then
echo "Tag push failed, trying with GitHub CLI..."
gh auth login --with-token <<< "${{ github.token }}"
echo "$PUSH_TOKEN" | gh auth login --with-token
git push origin "v${{ steps.new_version.outputs.new_version }}"
fi

- name: Publish to PyPI
env:
PYPI_SECRET: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ -z "$PYPI_SECRET" ]; then
echo "::error::Add repository secret PYPI_API_TOKEN (PyPI API token with upload scope)."
exit 1
fi
echo "[pypi]" > ~/.pypirc
echo "username = __token__" >> ~/.pypirc
echo "password = $PYPI_SECRET" >> ~/.pypirc
python -m twine upload --repository pypi dist/*
echo "Successfully published cost-katana@${{ steps.new_version.outputs.new_version }} to PyPI"

- name: Create GitHub Release
uses: actions/create-release@v1
env:
Expand All @@ -148,17 +134,9 @@ jobs:
body: |
## Auto-release v${{ steps.new_version.outputs.new_version }}

This is an automatic release triggered by changes to the main branch.

### Installation
```bash
pip install cost-katana==${{ steps.new_version.outputs.new_version }}
```

### Changes
- Automatic version bump and release
- Updated dependencies and improvements
- Enhanced Python package structure
- Better error handling
draft: false
prerelease: false
prerelease: false
40 changes: 9 additions & 31 deletions .github/workflows/version-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,18 @@ on:
- patch
- minor
- major
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- '.github/**'

jobs:
version-bump:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
actions: write
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Uses default GITHUB_TOKEN from checkout for subsequent git push.

- name: Set up Python
uses: actions/setup-python@v4
Expand All @@ -53,15 +45,9 @@ jobs:
- name: Calculate new version
id: new_version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
BUMP_TYPE="${{ github.event.inputs.bump_type }}"
else
BUMP_TYPE="patch"
fi

BUMP_TYPE="${{ github.event.inputs.bump_type }}"
CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}"

# Split version into components
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
Expand Down Expand Up @@ -89,31 +75,23 @@ jobs:
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION"

- name: Update version in setup.py and package __init__.py
- name: Update version in setup.py, __init__.py, and client User-Agent
run: |
OLD="${{ steps.current_version.outputs.current_version }}"
NEW="${{ steps.new_version.outputs.new_version }}"
sed -i "s/version=\"${OLD}\"/version=\"${NEW}\"/" setup.py
sed -i "s/__version__ = \"${OLD}\"/__version__ = \"${NEW}\"/" cost_katana/__init__.py
echo "Updated version to ${NEW}"
sed -i "s/cost-katana-python\/${OLD}\"/cost-katana-python\/${NEW}\"/" cost_katana/client.py

- name: Create and push tag
- name: Create and push commit and tag
env:
PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN || github.token }}
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add setup.py cost_katana/__init__.py
git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${{ github.repository }}.git"
git add setup.py cost_katana/__init__.py cost_katana/client.py
git commit -m "Bump version to ${{ steps.new_version.outputs.new_version }}"
git tag -a "v${{ steps.new_version.outputs.new_version }}" -m "Release version ${{ steps.new_version.outputs.new_version }}"
git push origin HEAD:${{ github.ref }}
git push origin "HEAD:${{ github.ref }}"
git push origin "v${{ steps.new_version.outputs.new_version }}"

- name: Trigger publish workflow
uses: actions/github-script@v7
with:
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'publish.yml',
ref: context.ref
})
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to Cost Katana Python SDK will be documented in this file.

## [Unreleased]

## [2.5.7] - 2026-04-30

### Fixed

- **Source ↔ PyPI**: Align repo metadata with **2.5.7** already on PyPI after an Auto Release run could upload but not push to protected `master`.
- **Auto Release**: Workflow is **`workflow_dispatch` only**; **PyPI upload runs only after** commit + tag push succeed; bumps **`cost_katana/client.py`** User-Agent; optional secret **`RELEASE_PUSH_TOKEN`** (PAT with `contents:write` and branch bypass) when `github.token` cannot push `master`.
- **Version Bump**: **`workflow_dispatch` only** (no push hook); same **`RELEASE_PUSH_TOKEN`** / User-Agent handling; redundant **`publish.yml` dispatch** removed — tag push triggers **Build and Publish**.

## [2.5.6] - 2026-04-29

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion cost_katana/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
get_provider_from_model,
)

__version__ = "2.5.6"
__version__ = "2.5.7"


def track(entry: Dict[str, Any]) -> None:
Expand Down
2 changes: 1 addition & 1 deletion cost_katana/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def __init__(
headers: Dict[str, str] = {
"Authorization": f"Bearer {self.config.api_key}",
"Content-Type": "application/json",
"User-Agent": "cost-katana-python/2.5.6",
"User-Agent": "cost-katana-python/2.5.7",
}
if self.config.project_id:
headers["x-project-id"] = self.config.project_id
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

setup(
name="cost-katana",
version="2.5.6",
version="2.5.7",
author="Cost Katana Team",
author_email="support@costkatana.com",
description="The simplest way to use AI in Python with automatic cost tracking and optimization",
Expand Down
Loading