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
182 lines
6.3 KiB
YAML
182 lines
6.3 KiB
YAML
name: Reusable GitHub Release Workflow
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
tag_name:
|
|
description: "Git tag name (e.g., computer-v0.5.0)"
|
|
required: true
|
|
type: string
|
|
release_name:
|
|
description: "Release display name (e.g., cua-computer v0.5.0)"
|
|
required: true
|
|
type: string
|
|
module_path:
|
|
description: "Path to the module for filtering commits (e.g., libs/python/agent)"
|
|
required: false
|
|
type: string
|
|
default: ""
|
|
generate_notes:
|
|
description: "Auto-generate release notes with attribution"
|
|
required: false
|
|
type: boolean
|
|
default: true
|
|
body:
|
|
description: "Custom release notes content (appended to auto-generated notes)"
|
|
required: false
|
|
type: string
|
|
default: ""
|
|
attach_artifacts:
|
|
description: "Whether to download and attach workflow artifacts to the release"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
draft:
|
|
description: "Create as draft release"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
prerelease:
|
|
description: "Mark as pre-release"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
create-release:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Generate path-filtered release notes
|
|
if: inputs.module_path != '' && inputs.generate_notes
|
|
id: release-notes
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# Extract tag prefix to find previous release (e.g., "pypi-agent-v" from "pypi-agent-v0.5.0")
|
|
TAG_PREFIX=$(echo "${{ inputs.tag_name }}" | sed 's/[0-9]*\.[0-9]*\.[0-9]*$//')
|
|
|
|
# Find previous tag with same prefix
|
|
PREV_TAG=$(git tag -l "${TAG_PREFIX}*" --sort=-v:refname | grep -v "^${{ inputs.tag_name }}$" | head -n 1 || echo "")
|
|
|
|
echo "Current tag: ${{ inputs.tag_name }}"
|
|
echo "Tag prefix: $TAG_PREFIX"
|
|
echo "Previous tag: $PREV_TAG"
|
|
|
|
# Generate release notes with GitHub username attribution
|
|
NOTES=""
|
|
|
|
if [ -n "$PREV_TAG" ]; then
|
|
echo "Generating notes for commits between $PREV_TAG and HEAD in ${{ inputs.module_path }}"
|
|
COMMIT_RANGE="${PREV_TAG}..HEAD"
|
|
else
|
|
echo "No previous tag found, generating notes for all commits in ${{ inputs.module_path }}"
|
|
COMMIT_RANGE="HEAD"
|
|
fi
|
|
|
|
# Get commits and process each one to fetch GitHub username
|
|
while IFS='|' read -r sha subject; do
|
|
# Skip automated bump commits (e.g., "Bump cua-agent to v0.7.22")
|
|
if [[ "$subject" =~ ^Bump\ cua- ]]; then
|
|
continue
|
|
fi
|
|
|
|
# Try to get GitHub username via API
|
|
USERNAME=$(gh api repos/${{ github.repository }}/commits/${sha} --jq '.author.login' 2>/dev/null || echo "")
|
|
|
|
# If API call fails or no author found (empty or "null"), fall back to commit author email
|
|
if [ -z "$USERNAME" ] || [ "$USERNAME" = "null" ]; then
|
|
AUTHOR_EMAIL=$(git show -s --format='%ae' ${sha})
|
|
# Try to extract username from GitHub noreply email format
|
|
if [[ "$AUTHOR_EMAIL" =~ ^([0-9]+\+)?([^@]+)@users\.noreply\.github\.com$ ]]; then
|
|
USERNAME="${BASH_REMATCH[2]}"
|
|
else
|
|
# Last resort: use author name without @ symbol
|
|
USERNAME=$(git show -s --format='%an' ${sha})
|
|
fi
|
|
fi
|
|
|
|
# Link PR numbers: (#123) -> ([#123](https://github.com/REPO/pull/123))
|
|
LINKED_SUBJECT=$(echo "$subject" | sed 's~(#\([0-9]*\))~([#\1](https://github.com/${{ github.repository }}/pull/\1))~g')
|
|
|
|
SHORT_SHA=$(echo ${sha} | cut -c1-7)
|
|
NOTES="${NOTES}* ${LINKED_SUBJECT} (${SHORT_SHA}) by @${USERNAME}"$'\n'
|
|
done < <(git log ${COMMIT_RANGE} --pretty=format:"%H|%s" -- "${{ inputs.module_path }}" | head -50)
|
|
|
|
if [ -z "$NOTES" ]; then
|
|
NOTES="Maintenance release — dependency updates only."
|
|
fi
|
|
|
|
# Store notes in output (handle multiline)
|
|
echo "RELEASE_NOTES<<EOF" >> $GITHUB_OUTPUT
|
|
echo "## What's Changed" >> $GITHUB_OUTPUT
|
|
echo "" >> $GITHUB_OUTPUT
|
|
echo "$NOTES" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
|
|
- name: Download artifacts
|
|
if: inputs.attach_artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: release-assets
|
|
merge-multiple: true
|
|
|
|
- name: List downloaded artifacts
|
|
if: inputs.attach_artifacts
|
|
run: |
|
|
echo "Downloaded artifacts:"
|
|
ls -lah release-assets/
|
|
|
|
- name: Prepare release body
|
|
id: prepare-body
|
|
env:
|
|
# Use env vars to avoid shell interpretation of backticks in commit messages
|
|
RELEASE_NOTES: ${{ steps.release-notes.outputs.RELEASE_NOTES }}
|
|
CUSTOM_BODY: ${{ inputs.body }}
|
|
run: |
|
|
# Combine path-filtered notes with custom body
|
|
BODY=""
|
|
|
|
# Add path-filtered notes if available
|
|
if [ -n "$RELEASE_NOTES" ]; then
|
|
BODY="$RELEASE_NOTES"
|
|
fi
|
|
|
|
# Add custom body if provided
|
|
if [ -n "$CUSTOM_BODY" ]; then
|
|
if [ -n "$BODY" ]; then
|
|
BODY="$BODY
|
|
|
|
$CUSTOM_BODY"
|
|
else
|
|
BODY="$CUSTOM_BODY"
|
|
fi
|
|
fi
|
|
|
|
# Store in output
|
|
echo "BODY<<EOF" >> $GITHUB_OUTPUT
|
|
echo "$BODY" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
|
|
- name: Create Release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ inputs.tag_name }}
|
|
name: ${{ inputs.release_name }}
|
|
body: ${{ steps.prepare-body.outputs.BODY }}
|
|
draft: ${{ inputs.draft }}
|
|
prerelease: ${{ inputs.prerelease }}
|
|
# Only use GitHub auto-generated notes if module_path is not specified
|
|
generate_release_notes: ${{ inputs.module_path == '' && inputs.generate_notes }}
|
|
files: |
|
|
release-assets/*
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|