Skip to content

fix: Improve upgrade error detection, three-way merge, and UI alignme… #21

fix: Improve upgrade error detection, three-way merge, and UI alignme…

fix: Improve upgrade error detection, three-way merge, and UI alignme… #21

Workflow file for this run

name: Release
on:
push:
branches:
- latest
permissions:
contents: write
pull-requests: write
jobs:
release:
name: Auto Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest tag
id: get_tag
run: |
# Get latest semver tag (v*.*.*)
LATEST_TAG=$(git tag -l "v[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -1)
if [ -z "$LATEST_TAG" ]; then
LATEST_TAG="v0.0.0"
fi
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "Latest tag: $LATEST_TAG"
- name: Analyze commits and determine version
id: version
run: |
LATEST_TAG="${{ steps.get_tag.outputs.latest_tag }}"
# Get commits since last tag
if [ "$LATEST_TAG" = "v0.0.0" ]; then
COMMITS=$(git log --pretty=format:"%s" HEAD)
else
COMMITS=$(git log --pretty=format:"%s" ${LATEST_TAG}..HEAD)
fi
if [ -z "$COMMITS" ]; then
echo "No new commits since $LATEST_TAG"
echo "skip=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "Commits since $LATEST_TAG:"
echo "$COMMITS"
# Determine version bump from conventional commits
MAJOR=0
MINOR=0
PATCH=0
while IFS= read -r commit; do
if echo "$commit" | grep -qE "^feat(\(.+\))?!:|^fix(\(.+\))?!:|^refactor(\(.+\))?!:|BREAKING CHANGE"; then
MAJOR=1
elif echo "$commit" | grep -qE "^feat(\(.+\))?:"; then
MINOR=1
elif echo "$commit" | grep -qE "^fix(\(.+\))?:|^perf(\(.+\))?:|^refactor(\(.+\))?:"; then
PATCH=1
fi
done <<< "$COMMITS"
# Parse current version
VERSION="${LATEST_TAG#v}"
IFS='.' read -r CUR_MAJOR CUR_MINOR CUR_PATCH <<< "$VERSION"
# Calculate new version
if [ "$MAJOR" -eq 1 ]; then
NEW_VERSION="$((CUR_MAJOR + 1)).0.0"
BUMP_TYPE="major"
elif [ "$MINOR" -eq 1 ]; then
NEW_VERSION="${CUR_MAJOR}.$((CUR_MINOR + 1)).0"
BUMP_TYPE="minor"
elif [ "$PATCH" -eq 1 ]; then
NEW_VERSION="${CUR_MAJOR}.${CUR_MINOR}.$((CUR_PATCH + 1))"
BUMP_TYPE="patch"
else
echo "No releasable commits (need feat:, fix:, perf:, refactor:, or breaking change)"
echo "skip=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "new_version=v${NEW_VERSION}" >> $GITHUB_OUTPUT
echo "bump_type=$BUMP_TYPE" >> $GITHUB_OUTPUT
echo "skip=false" >> $GITHUB_OUTPUT
echo "New version: v${NEW_VERSION} ($BUMP_TYPE bump)"
- name: Generate release notes
if: steps.version.outputs.skip != 'true'
id: notes
run: |
LATEST_TAG="${{ steps.get_tag.outputs.latest_tag }}"
NEW_VERSION="${{ steps.version.outputs.new_version }}"
# Generate notes from commits
NOTES=""
FEATURES=""
FIXES=""
PERF=""
OTHER=""
if [ "$LATEST_TAG" = "v0.0.0" ]; then
COMMITS=$(git log --pretty=format:"%s|%h" HEAD)
else
COMMITS=$(git log --pretty=format:"%s|%h" ${LATEST_TAG}..HEAD)
fi
BREAKING=""
while IFS='|' read -r msg hash; do
# Check for breaking changes first (feat!, fix!, etc.)
if echo "$msg" | grep -qE "^(feat|fix|refactor)(\(.+\))?!:"; then
CLEAN_MSG=$(echo "$msg" | sed -E 's/^(feat|fix|refactor)(\([^)]+\))?!:\s*//')
BREAKING="${BREAKING}- ${CLEAN_MSG} (${hash})\n"
elif echo "$msg" | grep -qE "^feat(\(.+\))?:"; then
CLEAN_MSG=$(echo "$msg" | sed -E 's/^feat(\([^)]+\))?:\s*//')
FEATURES="${FEATURES}- ${CLEAN_MSG} (${hash})\n"
elif echo "$msg" | grep -qE "^fix(\(.+\))?:"; then
CLEAN_MSG=$(echo "$msg" | sed -E 's/^fix(\([^)]+\))?:\s*//')
FIXES="${FIXES}- ${CLEAN_MSG} (${hash})\n"
elif echo "$msg" | grep -qE "^perf(\(.+\))?:"; then
CLEAN_MSG=$(echo "$msg" | sed -E 's/^perf(\([^)]+\))?:\s*//')
PERF="${PERF}- ${CLEAN_MSG} (${hash})\n"
fi
done <<< "$COMMITS"
# Build release notes
if [ -n "$BREAKING" ]; then
NOTES="${NOTES}## ⚠️ Breaking Changes\n${BREAKING}\n"
fi
if [ -n "$FEATURES" ]; then
NOTES="${NOTES}## Features\n${FEATURES}\n"
fi
if [ -n "$FIXES" ]; then
NOTES="${NOTES}## Bug Fixes\n${FIXES}\n"
fi
if [ -n "$PERF" ]; then
NOTES="${NOTES}## Performance\n${PERF}\n"
fi
# Add installation instructions
NOTES="${NOTES}## Installation\n\`\`\`bash\ncurl -fsSL https://raw.githubusercontent.com/draphy/draphyOS/latest/install.sh | bash\n\`\`\`"
# Save to file (handle multiline)
echo -e "$NOTES" > /tmp/release_notes.md
echo "Generated release notes"
- name: Validate scripts
if: steps.version.outputs.skip != 'true'
run: |
echo "Validating shell scripts..."
bash -n install.sh
bash -n uninstall.sh
echo "✅ Scripts are valid"
- name: Create tag and release
if: steps.version.outputs.skip != 'true'
run: |
NEW_VERSION="${{ steps.version.outputs.new_version }}"
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Create and push tag
git tag "$NEW_VERSION"
git push origin "$NEW_VERSION"
# Create GitHub release
gh release create "$NEW_VERSION" \
--title "$NEW_VERSION" \
--notes-file /tmp/release_notes.md \
--latest
echo "✅ Released $NEW_VERSION"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Label and comment on merged PRs
if: steps.version.outputs.skip != 'true'
run: |
LATEST_TAG="${{ steps.get_tag.outputs.latest_tag }}"
NEW_VERSION="${{ steps.version.outputs.new_version }}"
# Ensure "released" label exists
gh label create "released" --color "9ab87c" --description "Included in a release" 2>/dev/null || true
# Get PR numbers from commits since last tag
if [ "$LATEST_TAG" = "v0.0.0" ]; then
COMMITS=$(git log --pretty=format:"%H" HEAD)
else
COMMITS=$(git log --pretty=format:"%H" ${LATEST_TAG}..HEAD)
fi
# Find PRs associated with these commits
LABELED_PRS=""
while IFS= read -r sha; do
# Get PR number for this commit
PR_DATA=$(gh pr list --state merged --search "$sha" --json number --jq '.[0].number' 2>/dev/null || echo "")
if [ -n "$PR_DATA" ] && [ "$PR_DATA" != "null" ]; then
# Avoid duplicate actions
if [[ ! "$LABELED_PRS" =~ "$PR_DATA" ]]; then
# Add "released" label
gh pr edit "$PR_DATA" --add-label "released" 2>/dev/null || true
# Add comment with release link
gh pr comment "$PR_DATA" --body "🚀 Released in [$NEW_VERSION](https://github.com/${{ github.repository }}/releases/tag/$NEW_VERSION)" 2>/dev/null || true
LABELED_PRS="${LABELED_PRS} ${PR_DATA}"
echo "Labeled and commented on PR #$PR_DATA"
fi
fi
done <<< "$COMMITS"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}