Skip to content

Fix/remove otel deadlock (#39) #326

Fix/remove otel deadlock (#39)

Fix/remove otel deadlock (#39) #326

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
bump:
description: "major | minor | patch | auto"
default: "auto"
required: true
dry_run:
description: "Do everything except tag/release/publish"
type: boolean
default: false
push:
branches:
- main
- master
- clean-main
permissions:
contents: write
issues: write
discussions: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Verify readiness
run: |
test -z "$(git status --porcelain)" || { echo "Uncommitted changes found"; exit 1; }
if [ -f package.json ] && jq -e ".scripts.test" package.json >/dev/null 2>&1; then
echo "Test script found, running tests..."
npm ci || true
npm test || echo "Tests failed but continuing with release"
fi
- name: Determine previous tag
id: prev
run: |
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "prev=$PREV_TAG" >> $GITHUB_OUTPUT
- name: Check if release needed
id: check
run: |
PREV="${{ steps.prev.outputs.prev }}"
if [ "$PREV" = "v0.0.0" ]; then
echo "needed=true" >> $GITHUB_OUTPUT
exit 0
fi
# Check if there are new commits since last tag
NEW_COMMITS=$(git rev-list $PREV..HEAD --count)
if [ "$NEW_COMMITS" -gt 0 ]; then
echo "needed=true" >> $GITHUB_OUTPUT
echo "Found $NEW_COMMITS new commits since $PREV"
else
echo "needed=false" >> $GITHUB_OUTPUT
echo "No new commits since $PREV, skipping release"
fi
- name: Decide bump
if: steps.check.outputs.needed == 'true'
id: bump
run: |
INPUT="${{ github.event.inputs.bump || '' }}"
if [ "$INPUT" != "" ] && [ "$INPUT" != "auto" ]; then
echo "type=$INPUT" >> $GITHUB_OUTPUT
exit 0
fi
RANGE="${{ steps.prev.outputs.prev }}..HEAD"
BRK=$(git log --pretty=%B $RANGE | grep -ciE "BREAKING CHANGE" || true)
FEAT=$(git log --pretty=%s $RANGE | grep -ciE "^feat(\(|: )" || true)
if [ "$BRK" -gt 0 ]; then T=major
elif [ "$FEAT" -gt 0 ]; then T=minor
else T=patch
fi
echo "type=$T" >> $GITHUB_OUTPUT
- name: Compute next version
if: steps.check.outputs.needed == 'true'
id: ver
run: |
PREV="${{ steps.prev.outputs.prev }}"
PREV="${PREV#v}"
IFS=. read -r MA MI PA <<< "$PREV"
case "${{ steps.bump.outputs.type }}" in
major) MA=$((MA+1)); MI=0; PA=0 ;;
minor) MI=$((MI+1)); PA=0 ;;
patch) PA=$((PA+1)) ;;
*) echo "Invalid bump"; exit 1 ;;
esac
NEW="$MA.$MI.$PA"
echo "new=$NEW" >> $GITHUB_OUTPUT
echo "tag=v$NEW" >> $GITHUB_OUTPUT
- name: Update version files
if: steps.check.outputs.needed == 'true'
run: |
set -e
NEW="${{ steps.ver.outputs.new }}"
touched=0
if [ -f package.json ]; then
jq --arg v "$NEW" ".version=\$v" package.json > package.tmp && mv package.tmp package.json
if [ -f package-lock.json ]; then npm i --package-lock-only >/dev/null 2>&1 || true; fi
touched=1
fi
if [ -f version.txt ]; then echo "$NEW" > version.txt; touched=1; fi
if [ "$touched" -eq 0 ]; then echo "$NEW" > version.txt; fi
git add -A
git diff --staged --quiet || git commit -m "chore: release v$NEW [skip ci]" || echo "No content change"
- name: Generate changelog entry
if: steps.check.outputs.needed == 'true'
id: clog
run: |
set -e
NEW="${{ steps.ver.outputs.new }}"
PREV="${{ steps.prev.outputs.prev }}"
DATE=$(date +%Y-%m-%d)
NOTES=$(mktemp)
{
echo "# Release v$NEW"
echo
echo "**Release Date**: $DATE"
echo
echo "## Changes since $PREV"
echo
git log --pretty="- %s (%h)" "$PREV"..HEAD
} > "$NOTES"
if [ -f CHANGELOG.md ]; then
tmp=$(mktemp)
cat "$NOTES" > "$tmp"
echo -e "\n---\n" >> "$tmp"
cat CHANGELOG.md >> "$tmp"
mv "$tmp" CHANGELOG.md
else
cp "$NOTES" CHANGELOG.md
fi
git add CHANGELOG.md
git diff --staged --quiet || git commit -m "docs: update changelog for v$NEW [skip ci]" || echo "No changelog delta"
echo "notes=$NOTES" >> $GITHUB_OUTPUT
- name: Sync README version references
if: steps.check.outputs.needed == 'true'
run: |
NEW="${{ steps.ver.outputs.new }}"
[ -f README.md ] && sed -i "s/\\bv[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+\\b/v$NEW/g" README.md || true
git add README.md 2>/dev/null || true
git diff --staged --quiet || git commit -m "docs: README version sync v$NEW [skip ci]" || echo "No README delta"
- name: Create tag and push
if: steps.check.outputs.needed == 'true' && github.event.inputs.dry_run != 'true'
run: |
TAG="${{ steps.ver.outputs.tag }}"
if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
echo "::warning::Tag $TAG already exists on remote — skipping tag creation"
else
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG" || echo "Tag push may have failed"
fi
git push origin HEAD || echo "Branch push may have failed"
- name: Create GitHub Release
if: steps.check.outputs.needed == 'true' && github.event.inputs.dry_run != 'true'
run: |
TAG="${{ steps.ver.outputs.tag }}"
gh release create "$TAG" \
--title "$TAG" \
--notes-file "${{ steps.clog.outputs.notes }}" || echo "Release creation may have failed"