Skip to content

chore(@tutur3u/types): bump version to 0.1.2 #47

chore(@tutur3u/types): bump version to 0.1.2

chore(@tutur3u/types): bump version to 0.1.2 #47

name: Check and Bump Package Versions
on:
pull_request:
paths:
- 'packages/**'
workflow_dispatch:
jobs:
check-and-bump:
env:
# Use Vercel Remote Caching
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
# Configure production Supabase client
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }}
# Configure infrastructure
PROXY_API_KEY: ${{ secrets.PROXY_API_KEY }}
NEXT_PUBLIC_PROXY_API_KEY: ${{ secrets.NEXT_PUBLIC_PROXY_API_KEY }}
# Set GitHub token for CLI operations
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
GH_TOKEN: ${{ secrets.GH_PAT }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
token: ${{ secrets.GH_PAT }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- name: Configure Git
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Configure Tiptap Pro
run: |
pnpm config set "@tiptap-pro:registry" https://registry.tiptap.dev/
pnpm config set "//registry.tiptap.dev/:_authToken" ${{ secrets.TIPTAP_PRO_TOKEN }}
- name: Install dependencies
run: pnpm install
- name: Check changed packages
id: changed-packages
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
CHANGED_PACKAGES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} | grep "^packages/" | cut -d/ -f2 | grep -v -E "^(transactional|crawler)$" | sort -u | tr '\n' ' ' | xargs)
else
CHANGED_PACKAGES=$(git diff --name-only HEAD~1 HEAD | grep "^packages/" | cut -d/ -f2 | grep -v -E "^(transactional|crawler)$" | sort -u | tr '\n' ' ' | xargs)
fi
echo "Changed packages: $CHANGED_PACKAGES"
echo "packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT
- name: Check and bump versions
if: steps.changed-packages.outputs.packages != ''
run: |
# Ensure GitHub CLI is authenticated
gh auth setup-git
for package in ${{ steps.changed-packages.outputs.packages }}; do
if [ -f "packages/$package/package.json" ]; then
cd "packages/$package"
# Get current version
CURRENT_VERSION=$(node -p "require('./package.json').version")
# Check if there's an existing PR for this package
EXISTING_PRS=$(gh pr list --search "in:title bump-${package}" --json number --jq length)
if [ "$EXISTING_PRS" -gt "0" ]; then
echo "Found existing PR for package ${package}, skipping..."
cd ../..
continue
fi
# Calculate new checksum excluding build artifacts and handling binary files
NEW_CHECKSUM=$(find . -type f \
-not -path "./node_modules/*" \
-not -path "./dist/*" \
-not -path "./.next/*" \
-not -path "./build/*" \
-not -path "./.turbo/*" \
-not -name "package-lock.json" \
-not -name "yarn.lock" \
-not -name "pnpm-lock.yaml" \
-not -name ".checksum" \
-not -name "*.log" \
-print0 | LC_ALL=C sort -z | xargs -0 sha256sum | sha256sum | cut -d ' ' -f1)
# Enhanced checksum detection with better error handling
OLD_CHECKSUM=""
if [ -f ".checksum" ]; then
if [ "${{ github.event_name }}" = "pull_request" ]; then
# For PRs, compare against base branch
OLD_CHECKSUM=$(git show ${{ github.event.pull_request.base.sha }}:.checksum 2>/dev/null || cat .checksum)
else
# For direct pushes, compare against previous commit
OLD_CHECKSUM=$(git show HEAD^:.checksum 2>/dev/null || cat .checksum)
fi
OLD_CHECKSUM=$(echo "$OLD_CHECKSUM" | tr -d '[:space:]')
fi
# Enhanced git checksum retrieval with branch handling
get_checksum_from_git() {
local ref="$1"
local filepath="$2"
# Try to get checksum from the specified git ref
local checksum
checksum=$(git show "${ref}:${filepath}" 2>/dev/null || echo "")
# If failed, try to get it from the current branch
if [ -z "$checksum" ] && [ -f "$filepath" ]; then
checksum=$(cat "$filepath" 2>/dev/null || echo "")
fi
echo "$checksum" | tr -d '[:space:]'
}
# Get old checksum with better branch handling
OLD_CHECKSUM=""
if [ "${{ github.event_name }}" = "pull_request" ]; then
OLD_CHECKSUM=$(get_checksum_from_git "${{ github.event.pull_request.base.sha }}" ".checksum")
else
OLD_CHECKSUM=$(get_checksum_from_git "HEAD^" ".checksum")
fi
# Fetch actual file content if git show fails
if [ -z "$OLD_CHECKSUM" ] && [ -f ".checksum" ]; then
OLD_CHECKSUM=$(cat .checksum 2>/dev/null | tr -d '[:space:]')
fi
echo "Checksum details:"
echo "• Old checksum source: ${OLD_CHECKSUM:+Found in repo}"
echo "• Old checksum value: ${OLD_CHECKSUM:-Not found}"
echo "• New checksum value: $NEW_CHECKSUM"
# Normalize checksum to ensure consistent comparison
normalize_checksum() {
local checksum="$1"
echo "$checksum" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]'
}
NEW_CHECKSUM=$(normalize_checksum "$NEW_CHECKSUM")
if [ -n "$OLD_CHECKSUM" ]; then
OLD_CHECKSUM=$(normalize_checksum "$OLD_CHECKSUM")
fi
echo "📦 Package details:"
echo " • Package: $package"
echo " • Current version: $CURRENT_VERSION"
echo " • Old checksum: ${OLD_CHECKSUM:-None}"
echo " • New checksum: $NEW_CHECKSUM"
# Improved checksum verification
verify_checksum() {
local checksum="$1"
echo "$checksum" | grep -E "^[a-f0-9]{64}$" >/dev/null 2>&1
}
if [ -n "$OLD_CHECKSUM" ]; then
if ! verify_checksum "$OLD_CHECKSUM"; then
echo "Warning: Old checksum format is invalid, treating as empty"
OLD_CHECKSUM=""
fi
fi
if ! verify_checksum "$NEW_CHECKSUM"; then
echo "Error: New checksum calculation failed"
exit 1
fi
if [ -n "$OLD_CHECKSUM" ]; then
echo "Comparing checksums:"
echo "$OLD_CHECKSUM" > old_checksum_temp
echo "$NEW_CHECKSUM" > new_checksum_temp
if cmp -s old_checksum_temp new_checksum_temp; then
echo "✓ Checksums match exactly"
else
echo "! Checksums differ"
fi
rm old_checksum_temp new_checksum_temp
fi
# Compare checksums with better error handling
compare_checksums() {
local old="$1"
local new="$2"
if [ -z "$old" ]; then
echo "NEW"
elif [ "$old" = "$new" ]; then
echo "MATCH"
else
echo "DIFFERENT"
fi
}
CHECKSUM_STATUS=$(compare_checksums "$OLD_CHECKSUM" "$NEW_CHECKSUM")
# Utility functions for checksum handling
log_checksum_status() {
echo "🔍 Checksum Analysis:"
if [ -n "$1" ] && [ "$1" = "$2" ]; then
echo " ✅ Checksums match"
elif [ -n "$1" ]; then
echo " ⚠️ Checksums differ"
echo " - Old: $1"
echo " + New: $2"
else
echo " ℹ️ No previous checksum available"
echo " + Initial: $2"
fi
}
# Log checksum comparison
log_checksum_status "$OLD_CHECKSUM" "$NEW_CHECKSUM"
# Add debug outputs for checksum comparison
echo "DEBUG: Git reference details:"
echo "• Event type: ${{ github.event_name }}"
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "• Base SHA: ${{ github.event.pull_request.base.sha }}"
echo "• Head SHA: ${{ github.event.pull_request.head.sha }}"
else
echo "• Current SHA: $(git rev-parse HEAD)"
echo "• Parent SHA: $(git rev-parse HEAD^)"
fi
echo "DEBUG: Checksum file state:"
if [ -f ".checksum" ]; then
echo "• File exists: yes"
echo "• File size: $(wc -c < .checksum) bytes"
echo "• File permissions: $(stat -f "%Sp" .checksum)"
else
echo "• File exists: no"
fi
# Log final checksum comparison
echo "DEBUG: Final checksum comparison:"
echo "• Old checksum (${#OLD_CHECKSUM} chars): ${OLD_CHECKSUM:-<empty>}"
echo "• New checksum (${#NEW_CHECKSUM} chars): $NEW_CHECKSUM"
echo "• Match status: $([ "$OLD_CHECKSUM" = "$NEW_CHECKSUM" ] && echo "identical" || echo "different")"
# Compare checksums and create PR if needed
if [ "$NEW_CHECKSUM" != "$OLD_CHECKSUM" ]; then
# Check for new package or source changes
if [ -z "$OLD_CHECKSUM" ]; then
echo "New package detected, will create initial version"
SHOULD_BUMP=true
else
# Improved source file detection
if [ "${{ github.event_name }}" = "pull_request" ]; then
SOURCE_FILES_CHANGED=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep "^packages/$package/" | grep -E "\.(ts|tsx|js|jsx|json|css|scss|md)$" || true)
else
SOURCE_FILES_CHANGED=$(git diff --name-only HEAD~1 HEAD | grep "^packages/$package/" | grep -E "\.(ts|tsx|js|jsx|json|css|scss|md)$" || true)
fi
if [ -n "$SOURCE_FILES_CHANGED" ]; then
echo "Source files changed:"
echo "$SOURCE_FILES_CHANGED"
SHOULD_BUMP=true
else
echo "No source files changed"
# Update checksum even if we don't bump version, but only if not on default branch
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "$NEW_CHECKSUM" > .checksum
if [ -n "$(git status --porcelain .checksum)" ]; then
git add .checksum
git commit -m "chore(@tutur3u/${package}): update checksum [skip ci]"
git push origin HEAD
fi
fi
SHOULD_BUMP=false
fi
fi
# If changes detected, bump version and create PR
if [ "$SHOULD_BUMP" = true ]; then
# Version bump logic and PR creation
NEW_VERSION=$(echo "$CURRENT_VERSION" | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g')
echo "Meaningful changes detected, bumping version to: $NEW_VERSION"
sed -i "s/\"version\": \"$CURRENT_VERSION\"/\"version\": \"$NEW_VERSION\"/" package.json
echo "$NEW_CHECKSUM" > .checksum
BRANCH_NAME="bump-${package}-${NEW_VERSION}"
git checkout -b "$BRANCH_NAME"
git add package.json .checksum
git commit -m "chore(@tutur3u/${package}): bump version to ${NEW_VERSION}"
git push origin "$BRANCH_NAME"
# Create PR with enhanced description
PR_BODY="## 📦 Automated Version Bump<br /><br />"
if [ -n "$OLD_CHECKSUM" ]; then
if [ "$OLD_CHECKSUM" = "$NEW_CHECKSUM" ]; then
PR_BODY="${PR_BODY}> ✅ **Status:** No changes in package content<br /><br />"
else
PR_BODY="${PR_BODY}> 🔄 **Status:** Package content modified<br /><br />"
fi
else
PR_BODY="${PR_BODY}> 🆕 **Status:** New package<br /><br />"
fi
# Add package information summary
SUMMARY="### 📊 Package Information<br />"
SUMMARY="${SUMMARY}<table><tr><th>Detail</th><th>Value</th></tr>"
SUMMARY="${SUMMARY}<tr><td>Package</td><td><code>@tutur3u/${package}</code></tr>"
SUMMARY="${SUMMARY}<tr><td>Current Version</td><td><code>${CURRENT_VERSION}</code></tr>"
SUMMARY="${SUMMARY}<tr><td>New Version</td><td><code>${NEW_VERSION}</code></tr>"
SUMMARY="${SUMMARY}</table><br />"
PR_BODY="${PR_BODY}${SUMMARY}"
# Add changed files section
if [ -n "$SOURCE_FILES_CHANGED" ]; then
PR_BODY="${PR_BODY}### 📝 Changed Files<br />"
PR_BODY="${PR_BODY}<details open><summary>Modified files in this update</summary><br />"
while IFS= read -r file; do
if [ -n "$file" ]; then
cleaned_path=$(echo "$file" | sed "s|packages/$package/||g")
PR_BODY="${PR_BODY}• \`$cleaned_path\`<br />"
fi
done <<< "$SOURCE_FILES_CHANGED"
PR_BODY="${PR_BODY}</details><br />"
fi
# Add checksum information
PR_BODY="${PR_BODY}### 🔐 Package Integrity<br />"
PR_BODY="${PR_BODY}<details><summary>View checksums</summary><br />"
PR_BODY="${PR_BODY}**New Checksum:**<br />\`\`\`<br />$NEW_CHECKSUM<br />\`\`\`<br /><br />"
if [ -n "$OLD_CHECKSUM" ]; then
PR_BODY="${PR_BODY}**Previous Checksum:**<br />\`\`\`<br />$OLD_CHECKSUM<br />\`\`\`<br />"
if [ "$OLD_CHECKSUM" = "$NEW_CHECKSUM" ]; then
PR_BODY="${PR_BODY}<br />✅ Checksums match exactly<br />"
else
PR_BODY="${PR_BODY}<br />⚠️ Checksums differ<br />"
fi
else
PR_BODY="${PR_BODY}> 📝 No previous checksum available - new package or first tracking<br />"
fi
PR_BODY="${PR_BODY}</details>"
# Create PR
gh pr create \
--title "chore(@tutur3u/${package}): bump version to ${NEW_VERSION}" \
--body "$PR_BODY" \
--base "${GITHUB_BASE_REF:-main}" \
--head "$BRANCH_NAME" \
--repo "$GITHUB_REPOSITORY" || {
echo "Failed to create PR for $BRANCH_NAME. This may be because a PR already exists."
}
else
echo "No meaningful source file changes detected, skipping version bump"
fi
fi
cd ../..
fi
done