Two issues causing all builds to fail: 1. Cleanup steps deleted git tags along with releases. Since builds are dispatched asynchronously, they tried to checkout tags that had already been deleted. Now cleanup only deletes releases (which frees storage by removing assets) but preserves git tags. 2. Linux/macOS build workflows used $GITHUB_OUTPUT step outputs for the tag, which is unreliable on Gitea runners. Switched to the same job-level env var pattern (RELEASE_TAG) that works on Windows. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
173 lines
6.5 KiB
YAML
173 lines
6.5 KiB
YAML
name: Sidecar Release
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'client/**'
|
|
- 'server/**'
|
|
- 'backend/**'
|
|
- 'pyproject.toml'
|
|
- 'local-transcription-headless.spec'
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
test:
|
|
name: Run Tests
|
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install uv
|
|
run: |
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
|
|
- name: Python tests
|
|
run: |
|
|
uv venv .testvenv
|
|
VIRTUAL_ENV=.testvenv uv pip install pytest httpx pytest-asyncio anyio fastapi pydantic pyyaml uvicorn requests
|
|
.testvenv/bin/python -m pytest backend/tests/ client/tests/ -v --tb=short
|
|
|
|
bump-sidecar-version:
|
|
name: Bump sidecar version and tag
|
|
needs: test
|
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.bump.outputs.version }}
|
|
tag: ${{ steps.bump.outputs.tag }}
|
|
has_changes: ${{ steps.check_changes.outputs.has_changes }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 2
|
|
|
|
- name: Check for backend changes
|
|
id: check_changes
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
exit 0
|
|
fi
|
|
CHANGED=$(git diff --name-only HEAD~1 HEAD -- client/ server/ backend/ pyproject.toml local-transcription-headless.spec 2>/dev/null || echo "")
|
|
if [ -n "$CHANGED" ]; then
|
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
echo "Backend changes detected: $CHANGED"
|
|
else
|
|
echo "has_changes=false" >> $GITHUB_OUTPUT
|
|
echo "No backend changes detected, skipping sidecar build"
|
|
fi
|
|
|
|
- name: Configure git
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
run: |
|
|
git config user.name "Gitea Actions"
|
|
git config user.email "actions@gitea.local"
|
|
|
|
- name: Bump sidecar patch version
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
id: bump
|
|
run: |
|
|
CURRENT=$(grep '^version = ' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
|
echo "Current sidecar version: ${CURRENT}"
|
|
|
|
MAJOR=$(echo "${CURRENT}" | cut -d. -f1)
|
|
MINOR=$(echo "${CURRENT}" | cut -d. -f2)
|
|
PATCH=$(echo "${CURRENT}" | cut -d. -f3)
|
|
NEW_PATCH=$((PATCH + 1))
|
|
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"
|
|
echo "New sidecar version: ${NEW_VERSION}"
|
|
|
|
sed -i "s/^version = \"${CURRENT}\"/version = \"${NEW_VERSION}\"/" pyproject.toml
|
|
|
|
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
|
|
echo "tag=sidecar-v${NEW_VERSION}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Commit and tag
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
env:
|
|
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
|
|
run: |
|
|
NEW_VERSION="${{ steps.bump.outputs.version }}"
|
|
TAG="${{ steps.bump.outputs.tag }}"
|
|
git add pyproject.toml
|
|
git commit -m "chore: bump sidecar version to ${NEW_VERSION} [skip ci]"
|
|
git tag "${TAG}"
|
|
|
|
REMOTE_URL=$(git remote get-url origin | sed "s|://|://gitea-actions:${BUILD_TOKEN}@|")
|
|
git pull --rebase "${REMOTE_URL}" main || true
|
|
git push "${REMOTE_URL}" HEAD:main
|
|
git push "${REMOTE_URL}" "${TAG}"
|
|
|
|
- name: Create Gitea release
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
env:
|
|
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
|
|
run: |
|
|
REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
|
TAG="${{ steps.bump.outputs.tag }}"
|
|
VERSION="${{ steps.bump.outputs.version }}"
|
|
RELEASE_NAME="Sidecar v${VERSION}"
|
|
|
|
curl -s -X POST \
|
|
-H "Authorization: token ${BUILD_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"tag_name\": \"${TAG}\", \"name\": \"${RELEASE_NAME}\", \"body\": \"Automated sidecar build.\", \"draft\": false, \"prerelease\": false}" \
|
|
"${REPO_API}/releases"
|
|
echo "Created release: ${RELEASE_NAME}"
|
|
|
|
- name: Trigger per-OS sidecar builds
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
env:
|
|
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
|
|
run: |
|
|
REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
|
TAG="${{ steps.bump.outputs.tag }}"
|
|
|
|
for workflow in build-sidecar-linux.yml build-sidecar-windows.yml build-sidecar-macos.yml; do
|
|
echo "Dispatching ${workflow} for ${TAG}..."
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
|
-H "Authorization: token ${BUILD_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"ref\": \"main\", \"inputs\": {\"tag\": \"${TAG}\"}}" \
|
|
"${REPO_API}/actions/workflows/${workflow}/dispatches")
|
|
echo " -> HTTP ${HTTP_CODE}"
|
|
done
|
|
|
|
- name: Clean up old sidecar releases
|
|
if: steps.check_changes.outputs.has_changes == 'true'
|
|
env:
|
|
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
|
|
run: |
|
|
REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
|
KEEP=2
|
|
|
|
echo "Cleaning up old sidecar releases (keeping latest ${KEEP})..."
|
|
|
|
# Get all sidecar releases (sidecar-v* tags)
|
|
RELEASES=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \
|
|
"${REPO_API}/releases?limit=50" | jq -c '[.[] | select(.tag_name | startswith("sidecar-v"))]')
|
|
|
|
TOTAL=$(echo "$RELEASES" | jq 'length')
|
|
echo "Found ${TOTAL} sidecar releases"
|
|
|
|
if [ "$TOTAL" -le "$KEEP" ]; then
|
|
echo "Nothing to clean up"
|
|
exit 0
|
|
fi
|
|
|
|
# Skip the newest KEEP releases, delete the rest
|
|
echo "$RELEASES" | jq -c ".[$KEEP:][]" | while read -r release; do
|
|
ID=$(echo "$release" | jq -r '.id')
|
|
TAG=$(echo "$release" | jq -r '.tag_name')
|
|
|
|
echo " Deleting sidecar release ${TAG} (ID: ${ID})..."
|
|
curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \
|
|
"${REPO_API}/releases/${ID}"
|
|
# Keep the git tag -- only delete the release (assets).
|
|
# Deleting tags breaks builds that haven't checked out yet.
|
|
done
|
|
echo "Cleanup complete"
|