Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 184 additions & 31 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,196 @@ permissions:
pull-requests: write

jobs:
release-please:
name: Release Please
release:
name: Auto Release
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
pr: ${{ steps.release.outputs.pr }}
steps:
- name: Release Please
id: release
uses: googleapis/release-please-action@v4
with:
release-type: simple
include-v-in-tag: true
changelog-types: >
[
{"type": "feat", "section": "Features", "hidden": false},
{"type": "fix", "section": "Bug Fixes", "hidden": false},
{"type": "perf", "section": "Performance", "hidden": false},
{"type": "docs", "section": "Documentation", "hidden": false},
{"type": "chore", "section": "Maintenance", "hidden": true},
{"type": "style", "section": "Styles", "hidden": true},
{"type": "refactor", "section": "Refactoring", "hidden": true}
]

validate:
name: Validate Release
runs-on: ubuntu-latest
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
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

- name: Validate Scripts
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: |
echo "🚀 Validating ${{ needs.release-please.outputs.tag_name }}..."
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

while IFS='|' read -r msg hash; do
if 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 "$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: 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 }}"

# 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
COMMENTED_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 comments
if [[ ! "$COMMENTED_PRS" =~ "$PR_DATA" ]]; then
gh pr comment "$PR_DATA" --body "🚀 Released in [$NEW_VERSION](https://github.com/${{ github.repository }}/releases/tag/$NEW_VERSION)" 2>/dev/null || true
COMMENTED_PRS="${COMMENTED_PRS} ${PR_DATA}"
echo "Commented on PR #$PR_DATA"
fi
fi
done <<< "$COMMITS"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}