mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 10:23:27 +00:00
381 lines
18 KiB
YAML
381 lines
18 KiB
YAML
name: Sync Components from Main Repository
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
sync_directories:
|
||
description: "Directories to sync (comma-separated)"
|
||
required: false
|
||
default: "components,hooks,utils,styles"
|
||
type: string
|
||
sync_mode:
|
||
description: "Sync mode"
|
||
required: false
|
||
default: "all"
|
||
type: choice
|
||
options:
|
||
- all
|
||
- existing-only
|
||
|
||
jobs:
|
||
sync-components:
|
||
runs-on: ubuntu-latest
|
||
permissions:
|
||
contents: write
|
||
pull-requests: write
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
with:
|
||
token: ${{ secrets.GITHUB_TOKEN }}
|
||
fetch-depth: 0
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: "18"
|
||
|
||
- name: Configure git
|
||
run: |
|
||
git config --global user.name "github-actions[bot]"
|
||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||
|
||
- name: Fetch main repository and get commit info
|
||
id: fetch-main-repo
|
||
run: |
|
||
echo "Fetching main repository..."
|
||
|
||
# Create a temporary directory for cloning
|
||
mkdir -p /tmp/main-repo
|
||
cd /tmp/main-repo
|
||
|
||
# Clone the main repository
|
||
git clone https://github.com/untitleduico/react.git .
|
||
|
||
# Get latest commit info
|
||
LATEST_COMMIT_HASH=$(git rev-parse HEAD)
|
||
LATEST_COMMIT_SHORT=$(git rev-parse --short HEAD)
|
||
LATEST_COMMIT_MESSAGE=$(git log -1 --pretty=format:"%s")
|
||
LATEST_COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an")
|
||
LATEST_COMMIT_DATE=$(git log -1 --pretty=format:"%ci")
|
||
|
||
echo "LATEST_COMMIT_HASH=$LATEST_COMMIT_HASH" >> $GITHUB_ENV
|
||
echo "LATEST_COMMIT_SHORT=$LATEST_COMMIT_SHORT" >> $GITHUB_ENV
|
||
echo "LATEST_COMMIT_MESSAGE=$LATEST_COMMIT_MESSAGE" >> $GITHUB_ENV
|
||
echo "LATEST_COMMIT_AUTHOR=$LATEST_COMMIT_AUTHOR" >> $GITHUB_ENV
|
||
echo "LATEST_COMMIT_DATE=$LATEST_COMMIT_DATE" >> $GITHUB_ENV
|
||
|
||
echo "Latest commit: $LATEST_COMMIT_SHORT - $LATEST_COMMIT_MESSAGE"
|
||
|
||
# Get the directory structure (main repo has directories at root level, not in src/)
|
||
# Exclude demo and story files
|
||
find components hooks utils styles -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" 2>/dev/null | sort > /tmp/main-repo-files.txt || echo "Some directories may not exist"
|
||
|
||
echo "Files to sync:"
|
||
cat /tmp/main-repo-files.txt
|
||
|
||
- name: Get last synced commit
|
||
id: get-last-sync
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
|
||
# Check if we have a previous sync record
|
||
if [ -f ".github/last-sync-commit" ] && [ -s ".github/last-sync-commit" ]; then
|
||
# Read the first line and trim whitespace, ignore comments
|
||
LAST_SYNC_COMMIT=$(head -n 1 .github/last-sync-commit | xargs | grep -v '^#' || echo "")
|
||
|
||
if [ -n "$LAST_SYNC_COMMIT" ] && [ "$LAST_SYNC_COMMIT" != "" ]; then
|
||
echo "LAST_SYNC_COMMIT=$LAST_SYNC_COMMIT" >> $GITHUB_ENV
|
||
echo "Found previous sync commit: $LAST_SYNC_COMMIT"
|
||
else
|
||
echo "LAST_SYNC_COMMIT=" >> $GITHUB_ENV
|
||
echo "Sync file exists but no valid commit hash found"
|
||
fi
|
||
else
|
||
echo "LAST_SYNC_COMMIT=" >> $GITHUB_ENV
|
||
echo "No previous sync record found"
|
||
fi
|
||
|
||
- name: Get commits since last sync
|
||
id: get-commits-since-sync
|
||
run: |
|
||
cd /tmp/main-repo
|
||
|
||
if [ -n "$LAST_SYNC_COMMIT" ]; then
|
||
echo "Getting commits since $LAST_SYNC_COMMIT..."
|
||
|
||
# Get commit log since last sync
|
||
git log --oneline "$LAST_SYNC_COMMIT".."$LATEST_COMMIT_HASH" > /tmp/commits-since-sync.txt || echo "Could not get commit range"
|
||
|
||
# Count commits
|
||
COMMIT_COUNT=$(wc -l < /tmp/commits-since-sync.txt)
|
||
echo "COMMIT_COUNT=$COMMIT_COUNT" >> $GITHUB_ENV
|
||
|
||
echo "Commits since last sync ($COMMIT_COUNT):"
|
||
cat /tmp/commits-since-sync.txt
|
||
else
|
||
echo "COMMIT_COUNT=unknown" >> $GITHUB_ENV
|
||
echo "No previous sync - this is the first sync"
|
||
echo "First sync - syncing from latest commit" > /tmp/commits-since-sync.txt
|
||
fi
|
||
|
||
- name: Create sync branch
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
BRANCH_NAME="sync/$(date +%Y-%m-%d-%H%M%S)-$LATEST_COMMIT_SHORT"
|
||
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
|
||
|
||
# Delete branch if it exists locally
|
||
git branch -D "$BRANCH_NAME" 2>/dev/null || true
|
||
|
||
# Delete branch if it exists remotely
|
||
git push origin --delete "$BRANCH_NAME" 2>/dev/null || true
|
||
|
||
# Create fresh branch
|
||
git checkout -b "$BRANCH_NAME"
|
||
echo "Created branch: $BRANCH_NAME"
|
||
|
||
- name: Sync files from main repository
|
||
run: |
|
||
cd /tmp/main-repo
|
||
|
||
# Read the sync directories from input
|
||
IFS=',' read -ra DIRS <<< "${{ github.event.inputs.sync_directories }}"
|
||
|
||
# Create sync summary file
|
||
echo "# Sync Summary" > /tmp/sync-summary.md
|
||
echo "" >> /tmp/sync-summary.md
|
||
|
||
for dir in "${DIRS[@]}"; do
|
||
dir=$(echo "$dir" | xargs) # trim whitespace
|
||
echo "## Syncing $dir directory" >> /tmp/sync-summary.md
|
||
|
||
# Main repo has directories at root level, target repo has them in src/
|
||
if [ -d "$dir" ]; then
|
||
# Create directory in target repo if it doesn't exist
|
||
mkdir -p "$GITHUB_WORKSPACE/src/$dir"
|
||
|
||
# Find all files in the directory from main repo, excluding demo and story files
|
||
find "$dir" -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" | while read -r file; do
|
||
target_file="$GITHUB_WORKSPACE/src/$file"
|
||
|
||
# Check sync mode
|
||
if [ "${{ github.event.inputs.sync_mode }}" = "existing-only" ]; then
|
||
# Only process if target file already exists
|
||
if [ ! -f "$target_file" ]; then
|
||
echo "Skipping new file: $file (existing-only mode)"
|
||
continue
|
||
fi
|
||
fi
|
||
|
||
echo "Processing $file..."
|
||
|
||
# Copy file content and process it
|
||
content=$(cat "$file")
|
||
|
||
# Remove "use client" directive if present (including double newlines after it)
|
||
# This handles both double quotes and single quotes, with optional semicolon
|
||
processed_content=$(echo "$content" | sed -E '
|
||
/^"use client";?\s*$/{
|
||
N
|
||
N
|
||
s/"use client";?\s*\n\s*\n//
|
||
}
|
||
/^'\''use client'\'';?\s*$/{
|
||
N
|
||
N
|
||
s/'\''use client'\'';?\s*\n\s*\n//
|
||
}
|
||
')
|
||
|
||
# Target file goes in src/ directory
|
||
target_dir=$(dirname "$target_file")
|
||
mkdir -p "$target_dir"
|
||
|
||
# Write processed content to target file
|
||
echo "$processed_content" > "$target_file"
|
||
|
||
echo "- src/$file" >> /tmp/sync-summary.md
|
||
done
|
||
|
||
# Log skipped files for transparency
|
||
DEMO_STORY_SKIPPED=$(find "$dir" -type f \( -name "*.demo.tsx" -o -name "*.story.tsx" -o -name "*.stories.tsx" \) | wc -l)
|
||
|
||
if [ "${{ github.event.inputs.sync_mode }}" = "existing-only" ]; then
|
||
# Count new files that were skipped
|
||
NEW_FILES_SKIPPED=0
|
||
find "$dir" -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" | while read -r file; do
|
||
target_file="$GITHUB_WORKSPACE/src/$file"
|
||
if [ ! -f "$target_file" ]; then
|
||
NEW_FILES_SKIPPED=$((NEW_FILES_SKIPPED + 1))
|
||
fi
|
||
done
|
||
|
||
if [ "$NEW_FILES_SKIPPED" -gt 0 ]; then
|
||
echo "Skipped $NEW_FILES_SKIPPED new files (existing-only mode)"
|
||
echo "- Skipped $NEW_FILES_SKIPPED new files (existing-only mode)" >> /tmp/sync-summary.md
|
||
fi
|
||
fi
|
||
|
||
if [ "$DEMO_STORY_SKIPPED" -gt 0 ]; then
|
||
echo "Skipped $DEMO_STORY_SKIPPED demo/story files"
|
||
echo "- Skipped $DEMO_STORY_SKIPPED demo/story files" >> /tmp/sync-summary.md
|
||
fi
|
||
else
|
||
echo "Directory $dir not found in main repository" >> /tmp/sync-summary.md
|
||
fi
|
||
done
|
||
|
||
- name: Check for changes
|
||
id: check-changes
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
if git diff --quiet; then
|
||
echo "changes=false" >> $GITHUB_OUTPUT
|
||
echo "No changes detected"
|
||
else
|
||
echo "changes=true" >> $GITHUB_OUTPUT
|
||
echo "Changes detected"
|
||
fi
|
||
|
||
- name: Generate detailed diff summary
|
||
if: steps.check-changes.outputs.changes == 'true'
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
|
||
echo "# Component sync changes" > /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "This PR synchronizes components from the main repository [untitleduico/react](https://github.com/untitleduico/react)." >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
|
||
# Add commits since last sync section
|
||
echo "## 📝 Commits since last sync" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ]; then
|
||
if [ "$COMMIT_COUNT" -gt 0 ]; then
|
||
echo "**$COMMIT_COUNT new commits** from [\`$LAST_SYNC_COMMIT\`](https://github.com/untitleduico/react/commit/$LAST_SYNC_COMMIT) to [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH):" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "<details>" >> /tmp/pr-description.md
|
||
echo "<summary>View commit history</summary>" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
while IFS= read -r commit_line; do
|
||
if [ -n "$commit_line" ]; then
|
||
commit_hash=$(echo "$commit_line" | cut -d' ' -f1)
|
||
commit_msg=$(echo "$commit_line" | cut -d' ' -f2-)
|
||
echo "- [\`$commit_hash\`](https://github.com/untitleduico/react/commit/$commit_hash) $commit_msg" >> /tmp/pr-description.md
|
||
fi
|
||
done < /tmp/commits-since-sync.txt
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "</details>" >> /tmp/pr-description.md
|
||
else
|
||
echo "✅ **Repository is up to date** - no new commits since last sync [\`$LAST_SYNC_COMMIT\`](https://github.com/untitleduico/react/commit/$LAST_SYNC_COMMIT)" >> /tmp/pr-description.md
|
||
fi
|
||
else
|
||
echo "🎉 **First sync** - syncing from latest commit [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH)" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "**Latest commit**: $LATEST_COMMIT_MESSAGE" >> /tmp/pr-description.md
|
||
echo "**Author**: $LATEST_COMMIT_AUTHOR" >> /tmp/pr-description.md
|
||
echo "**Date**: $LATEST_COMMIT_DATE" >> /tmp/pr-description.md
|
||
fi
|
||
echo "" >> /tmp/pr-description.md
|
||
|
||
echo "## 📁 Modified files" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
|
||
# Get file statistics
|
||
TOTAL_FILES=$(git diff --name-only | wc -l)
|
||
echo "**$TOTAL_FILES files modified**" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
|
||
# List all changed files
|
||
git diff --name-only | while read -r file; do
|
||
if [ -n "$file" ]; then
|
||
echo "- \`$file\`" >> /tmp/pr-description.md
|
||
fi
|
||
done
|
||
echo "" >> /tmp/pr-description.md
|
||
|
||
echo "## 🔧 Sync details" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "- **Source repository**: [untitleduico/react](https://github.com/untitleduico/react)" >> /tmp/pr-description.md
|
||
echo "- **Latest commit**: [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH)" >> /tmp/pr-description.md
|
||
echo "- **Sync date**: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> /tmp/pr-description.md
|
||
echo "- **Directories synced**: ${{ github.event.inputs.sync_directories }}" >> /tmp/pr-description.md
|
||
echo "- **Sync mode**: ${{ github.event.inputs.sync_mode }}" >> /tmp/pr-description.md
|
||
echo "- **Automated processing**: Removed \`\"use client\";\` directives, excluded demo/story files" >> /tmp/pr-description.md
|
||
echo "" >> /tmp/pr-description.md
|
||
echo "---" >> /tmp/pr-description.md
|
||
echo "*This PR was automatically generated by the sync-components workflow.*" >> /tmp/pr-description.md
|
||
|
||
- name: Store sync commit record
|
||
if: steps.check-changes.outputs.changes == 'true'
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
|
||
# Create .github directory if it doesn't exist
|
||
mkdir -p .github
|
||
|
||
# Store the latest commit hash for next sync
|
||
echo "$LATEST_COMMIT_HASH" > .github/last-sync-commit
|
||
|
||
echo "Stored sync commit: $LATEST_COMMIT_HASH"
|
||
|
||
- name: Commit changes
|
||
if: steps.check-changes.outputs.changes == 'true'
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
git add .
|
||
|
||
# Create commit message
|
||
if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ] && [ "$COMMIT_COUNT" -gt 0 ]; then
|
||
COMMIT_MSG="sync: Update components from main repository ($COMMIT_COUNT commits)
|
||
|
||
Synced from: $LAST_SYNC_COMMIT..$LATEST_COMMIT_SHORT
|
||
Latest commit: $LATEST_COMMIT_MESSAGE
|
||
Directories: ${{ github.event.inputs.sync_directories }}
|
||
Source: https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH
|
||
Automated processing: Removed 'use client' directives"
|
||
else
|
||
COMMIT_MSG="sync: Initial sync from main repository
|
||
|
||
Latest commit: $LATEST_COMMIT_SHORT - $LATEST_COMMIT_MESSAGE
|
||
Author: $LATEST_COMMIT_AUTHOR
|
||
Directories: ${{ github.event.inputs.sync_directories }}
|
||
Source: https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH
|
||
Automated processing: Removed 'use client' directives"
|
||
fi
|
||
|
||
git commit -m "$COMMIT_MSG"
|
||
|
||
- name: Push changes and create PR
|
||
if: steps.check-changes.outputs.changes == 'true'
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
cd $GITHUB_WORKSPACE
|
||
git push origin "$BRANCH_NAME"
|
||
|
||
# Create PR title based on sync type
|
||
if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ] && [ "$COMMIT_COUNT" -gt 0 ]; then
|
||
PR_TITLE="🔄 Sync components ($COMMIT_COUNT commits) → $LATEST_COMMIT_SHORT"
|
||
else
|
||
PR_TITLE="🎉 Initial sync from main repository → $LATEST_COMMIT_SHORT"
|
||
fi
|
||
|
||
# Create PR using GitHub CLI
|
||
gh pr create \
|
||
--title "$PR_TITLE" \
|
||
--body-file /tmp/pr-description.md \
|
||
--head "$BRANCH_NAME" \
|
||
--base main
|
||
|
||
- name: Output results
|
||
run: |
|
||
if [ "${{ steps.check-changes.outputs.changes }}" == "true" ]; then
|
||
echo "✅ Sync completed successfully. PR created."
|
||
echo "Branch: $BRANCH_NAME"
|
||
else
|
||
echo "ℹ️ No changes detected. Repository is already in sync."
|
||
fi
|