Skip to content

Release

Release #46

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
version:
description: "Version number for this release"
required: true
dry_run:
description: "Test workflow without publishing to CocoaPods"
type: boolean
default: false
required: false
publish_only:
description: "Publish to CocoaPods without version updates or tagging"
type: boolean
default: false
required: false
jobs:
release:
runs-on: macos-15
outputs:
commit_sha: ${{ steps.save_commit_info.outputs.commit_sha }}
version: ${{ github.event.inputs.version }}
dry_run: ${{ github.event.inputs.dry_run }}
tag_name: ${{ steps.create_tag.outputs.tag_name }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2.2"
- name: Install Ruby Gems
run: sudo bundle install
- name: Use Latest Stable Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Ensure Platforms are Downloaded
run: |
xcodebuild -runFirstLaunch
xcrun simctl list
for platform in iOS watchOS tvOS visionOS; do
echo "Downloading $platform platform..."
xcodebuild -downloadPlatform $platform
xcodebuild -runFirstLaunch
done
- name: Update version in podspec
run: sed -i '' 's/s.version = "[^"]*"/s.version = "${{ github.event.inputs.version }}"/' KSCrash.podspec
- name: Update version in source code
run: |
formatted_version_number=$(echo "${{ github.event.inputs.version }}" | awk -F. '{printf("%d.%02d%02d\n", $1, $2, $3)}')
sed -i '' 's/const double KSCrashFrameworkVersionNumber = [^;]*/const double KSCrashFrameworkVersionNumber = '"$formatted_version_number"'/' Sources/KSCrashRecording/KSCrash.m
sed -i '' 's/const unsigned char KSCrashFrameworkVersionString\[\] = "[^"]*"/const unsigned char KSCrashFrameworkVersionString[] = "${{ github.event.inputs.version }}"/' Sources/KSCrashRecording/KSCrash.m
- name: Update README
run: |
# Update SPM version
sed -i '' "s/\.package(url: \"https:\/\/github.com\/kstenerud\/KSCrash.git\", .upToNextMajor(from: \"[^\"]*\"))/\.package(url: \"https:\/\/github.com\/kstenerud\/KSCrash.git\", .upToNextMajor(from: \"${{ github.event.inputs.version }}\"))/" README.md
# Update CocoaPods version
VERSION="${{ github.event.inputs.version }}"
if [[ "$VERSION" == *"-"* ]]; then
# It's a pre-release version, use the full version
sed -i '' "s/pod 'KSCrash'.*$/pod 'KSCrash', '~> $VERSION'/" README.md
else
# It's a release version, use major.minor
sed -i '' "s/pod 'KSCrash'.*$/pod 'KSCrash', '~> ${VERSION%.*}'/" README.md
fi
echo "README.md updated with version ${{ github.event.inputs.version }}"
- name: Commit version update
id: commit_version
if: ${{ github.event.inputs.publish_only != 'true' }}
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add .
git commit -m "Update version to ${{ github.event.inputs.version }}"
git push
- name: Save commit information
id: save_commit_info
if: ${{ github.event.inputs.publish_only != 'true' }}
run: |
COMMIT_SHA=$(git rev-parse HEAD)
echo "commit_sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
- name: Create git tag
id: create_tag
if: ${{ github.event.inputs.publish_only != 'true' }}
run: |
if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
TAG_NAME="${{ github.event.inputs.version }}-dryrun"
else
TAG_NAME="${{ github.event.inputs.version }}"
fi
git tag $TAG_NAME
git push origin $TAG_NAME
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
- name: Publish to CocoaPods
if: ${{ github.event.inputs.dry_run != 'true' }}
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_PASSWORD }}
run: pod trunk push KSCrash.podspec --verbose
rollback:
runs-on: macos-15
needs: release
if: failure() && github.event.inputs.publish_only != 'true'
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch all tags
run: |
git fetch --tags
- name: Delete git tag locally
run: |
# Use tag from outputs or construct it
if [[ -n "${{ needs.release.outputs.tag_name }}" ]]; then
TAG_TO_DELETE="${{ needs.release.outputs.tag_name }}"
elif [[ "${{ needs.release.outputs.dry_run }}" == "true" ]]; then
TAG_TO_DELETE="${{ needs.release.outputs.version }}-dryrun"
else
TAG_TO_DELETE="${{ needs.release.outputs.version }}"
fi
git tag -d $TAG_TO_DELETE || echo "Tag not found locally"
echo "TAG_TO_DELETE=$TAG_TO_DELETE" >> $GITHUB_ENV
- name: Delete git tag remotely
run: |
git push --delete origin ${{ env.TAG_TO_DELETE }} || echo "Tag not found on remote"
- name: Pull latest changes
run: |
git pull origin "$(git branch --show-current)"
- name: Check for version commit
id: check_commit
run: |
if [[ -n "${{ needs.release.outputs.commit_sha }}" ]]; then
echo "Version commit found from outputs: ${{ needs.release.outputs.commit_sha }}"
echo "SHOULD_REVERT=true" >> $GITHUB_ENV
echo "COMMIT_SHA=${{ needs.release.outputs.commit_sha }}" >> $GITHUB_ENV
else
# Fallback: search by commit message
SEARCH_MSG="Update version to ${{ needs.release.outputs.version || github.event.inputs.version }}"
FOUND_COMMIT=$(git log --format="%H" --grep="$SEARCH_MSG" -n 1)
if [[ -n "$FOUND_COMMIT" ]]; then
echo "Found commit by message: $FOUND_COMMIT"
echo "SHOULD_REVERT=true" >> $GITHUB_ENV
echo "COMMIT_SHA=$FOUND_COMMIT" >> $GITHUB_ENV
else
echo "No version commit found, nothing to revert."
echo "SHOULD_REVERT=false" >> $GITHUB_ENV
fi
fi
- name: Revert version commit
if: env.SHOULD_REVERT == 'true'
run: |
echo "Reverting commit ${{ env.COMMIT_SHA }}..."
git log --oneline -n 3
git revert --no-commit ${{ env.COMMIT_SHA }}
git status -s
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git commit -m "Revert version update due to failed release"
- name: Push revert
if: env.SHOULD_REVERT == 'true'
run: |
git push || { git status; exit 1; }