From a52737272c5076442ba4b9e11e690e4d7b87ff72 Mon Sep 17 00:00:00 2001 From: Alexis Placet Date: Mon, 20 Oct 2025 11:09:31 +0200 Subject: [PATCH] Add release workflow --- .github/workflows/release.yaml | 173 +++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..ed7835d --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,173 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version_type: + description: 'Type of version bump' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + custom_version: + description: 'Custom version (optional, overrides version_type)' + required: false + type: string + prerelease: + description: 'Create a prerelease' + required: false + default: false + type: boolean + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Determine version + id: version + run: | + if [ -n "${{ github.event.inputs.custom_version }}" ]; then + BASE_VERSION="${{ github.event.inputs.custom_version }}" + else + # Get current version from header file + if [ ! -f "include/sparrow_ipc/config/sparrow_ipc_version.hpp" ]; then + echo "Error: sparrow_ipc_version.hpp not found" + exit 1 + fi + + CURRENT_MAJOR=$(grep "constexpr int SPARROW_IPC_VERSION_MAJOR" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + CURRENT_MINOR=$(grep "constexpr int SPARROW_IPC_VERSION_MINOR" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + CURRENT_PATCH=$(grep "constexpr int SPARROW_IPC_VERSION_PATCH" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + + # Verify version numbers were found + if [ -z "$CURRENT_MAJOR" ] || [ -z "$CURRENT_MINOR" ] || [ -z "$CURRENT_PATCH" ]; then + echo "Error: Could not parse current version from header file" + exit 1 + fi + + echo "Current version: ${CURRENT_MAJOR}.${CURRENT_MINOR}.${CURRENT_PATCH}" + + case "${{ github.event.inputs.version_type }}" in + "major") + BASE_VERSION="$((CURRENT_MAJOR + 1)).0.0" + ;; + "minor") + BASE_VERSION="${CURRENT_MAJOR}.$((CURRENT_MINOR + 1)).0" + ;; + "patch") + BASE_VERSION="${CURRENT_MAJOR}.${CURRENT_MINOR}.$((CURRENT_PATCH + 1))" + ;; + esac + fi + + # Handle prerelease + if [ "${{ github.event.inputs.prerelease }}" = "true" ]; then + # Find existing prerelease tags for this version + EXISTING_TAGS=$(git tag -l "${BASE_VERSION}_r*" | sort -V) + + if [ -z "$EXISTING_TAGS" ]; then + # No existing prereleases, start with _r0 + PRERELEASE_NUM=0 + else + # Get the highest prerelease number and increment + LAST_TAG=$(echo "$EXISTING_TAGS" | tail -n 1) + PRERELEASE_NUM=$(echo "$LAST_TAG" | sed "s/${BASE_VERSION}_r//" | sed 's/^0*//') + if [ -z "$PRERELEASE_NUM" ]; then + PRERELEASE_NUM=0 + fi + PRERELEASE_NUM=$((PRERELEASE_NUM + 1)) + fi + + FINAL_VERSION="${BASE_VERSION}_r${PRERELEASE_NUM}" + echo "is_prerelease=true" >> $GITHUB_OUTPUT + else + FINAL_VERSION="$BASE_VERSION" + echo "is_prerelease=false" >> $GITHUB_OUTPUT + fi + + echo "Final version: $FINAL_VERSION" + echo "version=$FINAL_VERSION" >> $GITHUB_OUTPUT + echo "base_version=$BASE_VERSION" >> $GITHUB_OUTPUT + + - name: Update version in header file + run: | + BASE_VERSION="${{ steps.version.outputs.base_version }}" + IFS='.' read -r NEW_MAJOR NEW_MINOR NEW_PATCH <<< "$BASE_VERSION" + + # Only update header file for non-prerelease versions + if [ "${{ steps.version.outputs.is_prerelease }}" = "false" ]; then + # Get current binary version numbers + CURRENT_BINARY=$(grep "constexpr int SPARROW_IPC_BINARY_CURRENT" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + CURRENT_REVISION=$(grep "constexpr int SPARROW_IPC_BINARY_REVISION" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + CURRENT_AGE=$(grep "constexpr int SPARROW_IPC_BINARY_AGE" include/sparrow_ipc/config/sparrow_ipc_version.hpp | awk '{print $5}' | tr -d ';') + + echo "Current binary version: $CURRENT_BINARY:$CURRENT_REVISION:$CURRENT_AGE" + + # Apply libtool versioning rules based on version bump type + case "${{ github.event.inputs.version_type }}" in + "patch") + # Patch release: only increment revision (compatible changes) + NEW_BINARY_CURRENT=$CURRENT_BINARY + NEW_BINARY_REVISION=$((CURRENT_REVISION + 1)) + NEW_BINARY_AGE=$CURRENT_AGE + ;; + "minor") + # Minor release: new APIs added, increment current and age, reset revision + NEW_BINARY_CURRENT=$((CURRENT_BINARY + 1)) + NEW_BINARY_REVISION=0 + NEW_BINARY_AGE=$((CURRENT_AGE + 1)) + ;; + "major") + # Major release: breaking changes, increment current, reset revision and age + NEW_BINARY_CURRENT=$((CURRENT_BINARY + 1)) + NEW_BINARY_REVISION=0 + NEW_BINARY_AGE=0 + ;; + esac + + echo "New binary version: $NEW_BINARY_CURRENT:$NEW_BINARY_REVISION:$NEW_BINARY_AGE" + + # Update version numbers in header file + sed -i "s/constexpr int SPARROW_IPC_VERSION_MAJOR = [0-9]*/constexpr int SPARROW_IPC_VERSION_MAJOR = $NEW_MAJOR/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + sed -i "s/constexpr int SPARROW_IPC_VERSION_MINOR = [0-9]*/constexpr int SPARROW_IPC_VERSION_MINOR = $NEW_MINOR/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + sed -i "s/constexpr int SPARROW_IPC_VERSION_PATCH = [0-9]*/constexpr int SPARROW_IPC_VERSION_PATCH = $NEW_PATCH/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + sed -i "s/constexpr int SPARROW_IPC_BINARY_CURRENT = [0-9]*/constexpr int SPARROW_IPC_BINARY_CURRENT = $NEW_BINARY_CURRENT/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + sed -i "s/constexpr int SPARROW_IPC_BINARY_REVISION = [0-9]*/constexpr int SPARROW_IPC_BINARY_REVISION = $NEW_BINARY_REVISION/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + sed -i "s/constexpr int SPARROW_IPC_BINARY_AGE = [0-9]*/constexpr int SPARROW_IPC_BINARY_AGE = $NEW_BINARY_AGE/" include/sparrow_ipc/config/sparrow_ipc_version.hpp + + git config --local user.name "GitHub Action" + git add include/sparrow_ipc/config/sparrow_ipc_version.hpp + git commit -m "Release version ${{ steps.version.outputs.version }}" + else + echo "Skipping header file update for prerelease" + git config --local user.name "GitHub Action" + fi + + - name: Create tag + run: | + git tag -a "${{ steps.version.outputs.version }}" -m "Release version ${{ steps.version.outputs.version }}" + + - name: Push changes and tag + run: | + git push origin main + git push origin "${{ steps.version.outputs.version }}" + + - name: Create GitHub Release + uses: elgohr/Github-Release-Action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + title: "Release ${{ steps.version.outputs.version }}" + tag: "${{ steps.version.outputs.version }}" + prerelease: ${{ steps.version.outputs.is_prerelease }}