Skip to content

Update release workflow to use existing CHANGELOG #59

Update release workflow to use existing CHANGELOG

Update release workflow to use existing CHANGELOG #59

Workflow file for this run

name: Release JetstreamBridge
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
id-token: write # Required for OIDC
env:
# Force Bundler to ignore platform-specific precompiled variants (e.g., arm64-darwin)
BUNDLER_FORCE_RUBY_PLATFORM: "true"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Derive version from tag
id: ver
shell: bash
run: |
set -euo pipefail
RAW="${GITHUB_REF_NAME}" # e.g. v0.3.2
if [[ ! "$RAW" =~ ^v[0-9]+(\.[0-9]+){2}(-[0-9A-Za-z\.-]+)?$ ]]; then
echo "Tag must look like vX.Y.Z (optionally -rcN). Got: $RAW"
exit 1
fi
VERSION="${RAW#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Using version: $VERSION"
# Install Ruby and run tests BEFORE any release-specific changes
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true
- name: Run tests
id: tests
run: bundle exec rspec
- name: Run RuboCop
id: rubocop
run: bundle exec rubocop
- name: Run security audit
id: security
run: bundle exec bundle-audit check --update
- name: Read version.rb
id: file
shell: bash
run: |
set -euo pipefail
FILE_VERSION=$(ruby -e "puts(File.read('lib/jetstream_bridge/version.rb')[/VERSION\\s*=\\s*['\"]([^'\"]+)['\"]/,1])")
echo "file_version=$FILE_VERSION" >> "$GITHUB_OUTPUT"
echo "version.rb currently: $FILE_VERSION"
- name: Patch version.rb to match tag (no commit)
if: ${{ steps.ver.outputs.version != steps.file.outputs.file_version }}
shell: bash
run: |
set -euo pipefail
echo "Patching version.rb from '${{ steps.file.outputs.file_version }}' to '${{ steps.ver.outputs.version }}' for this build…"
sed -i "s/VERSION\\s*=\\s*['\"][^'\"]\\+['\"]/VERSION = '${{ steps.ver.outputs.version }}'/" lib/jetstream_bridge/version.rb
grep VERSION lib/jetstream_bridge/version.rb
- name: Add platforms to Gemfile.lock
run: |
bundle lock --add-platform x86_64-linux
bundle lock --add-platform ruby
- name: Build gem
id: build
shell: bash
run: |
set -euo pipefail
gem build jetstream_bridge.gemspec
GEMFILE=$(ls -1 *.gem | tail -n1)
echo "gemfile=${GEMFILE}" >> "$GITHUB_OUTPUT"
ls -l "$GEMFILE"
- name: Extract release notes from CHANGELOG
id: changelog
shell: bash
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME}"
VERSION="${TAG#v}"
# Extract release notes for this version from CHANGELOG.md
awk "/^## \[${VERSION}\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md > RELEASE_NOTES.md
# If extraction failed or empty, generate from git log
if [[ ! -s RELEASE_NOTES.md ]]; then
echo "No CHANGELOG entry found for ${VERSION}, generating from git log..."
PREV_TAG=$(git tag --sort=-v:refname | sed -n '2p' || true)
if [[ -z "$PREV_TAG" ]]; then
FIRST_COMMIT=$(git rev-list --max-parents=0 HEAD)
RANGE="$FIRST_COMMIT..$TAG"
else
RANGE="$PREV_TAG..$TAG"
fi
{
echo "## Changes"
git log --no-merges --format='- %s (%h)' "$RANGE" || echo "- Initial release"
} > RELEASE_NOTES.md
fi
echo "Release notes for ${TAG}:"
cat RELEASE_NOTES.md
PREV_TAG=$(git tag --sort=-v:refname | sed -n '2p' || true)
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
- name: Create/Update GitHub Release and upload .gem
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: "JetstreamBridge ${{ github.ref_name }}"
files: |
${{ steps.build.outputs.gemfile }}
RELEASE_NOTES.md
draft: false
generate_release_notes: false
body_path: RELEASE_NOTES.md
prerelease: ${{ contains(steps.ver.outputs.version, '-') }}
- name: Configure RubyGems credentials with OIDC
uses: rubygems/[email protected]
- name: Push gem to RubyGems
run: gem push ${{ steps.build.outputs.gemfile }}
cleanup-failed-release:
runs-on: ubuntu-latest
needs: release
if: failure()
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Delete GitHub Release and Tag
continue-on-error: true
uses: dev-drprasad/[email protected]
with:
tag_name: ${{ github.ref_name }}
github_token: ${{ secrets.GITHUB_TOKEN }}
delete_release: true