Skip to content

Sync Config Files from dadavidtseng/ConfigCommon #4

Sync Config Files from dadavidtseng/ConfigCommon

Sync Config Files from dadavidtseng/ConfigCommon #4

#-----------------------------------------------------------------------------------------------------
# sync-config-common.yml
#-----------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------
name: Sync Config Files from dadavidtseng/ConfigCommon
#-----------------------------------------------------------------------------------------------------
# Grant write permissions to allow committing changes back to the repository
permissions:
contents: write
#-----------------------------------------------------------------------------------------------------
on:
workflow_dispatch:
inputs:
# Option to sync .gitignore file
sync_gitignore:
description: 'sync .gitignore'
required: false
default: true
type: boolean
# Source filename for .gitignore in the remote repository
gitignore_source:
description: '.gitignore source file name'
required: false
default: 'unreal-engine.gitignore'
type: string
# Option to sync .gitattributes file
sync_gitattributes:
description: 'sync .gitattributes'
required: false
default: true
type: boolean
# Source filename for .gitattributes in the remote repository
gitattributes_source:
description: '.gitattributes source file name'
required: false
default: 'unreal-engine.gitattributes'
type: string
# Option to sync .editorconfig file
sync_editorconfig:
description: 'sync .editorconfig'
required: false
default: true
type: boolean
# Source filename for .editorconfig in the remote repository
editorconfig_source:
description: '.editorconfig source file name'
required: false
default: '.editorconfig'
type: string
# Option to sync .clang-format file (disabled by default)
sync_clangformat:
description: 'sync .clang-format'
required: false
default: false
type: boolean
# Source filename for .clang-format in the remote repository
clangformat_source:
description: '.clang-format source file name'
required: false
default: '.clang-format'
type: string
# Additional files to sync
# Format: local_file:remote_file, comma-separated
# Examples:
# Single file: README.md:template-readme.md
# Multiple files: LICENSE:MIT-license.txt,.pre-commit-config.yaml:.pre-commit-config.yaml
# Mixed examples: my-config.json:default-config.json,docker-compose.yml:development-docker-compose.yml
# Notes:
# - Colon (:) separates local filename from remote filename
# - Comma (,) separates multiple file pairs
# - No spaces around colons or commas
# - If remote file doesn't exist, it will be skipped
additional_files:
description: '額外檔案 (格式: 本地檔案:遠端檔案,用逗號分隔)'
required: false
default: ''
type: string
# Automatic trigger - runs every Monday at 2:00 AM UTC
# Cron expression: minute hour day month day_of_week
schedule:
- cron: '0 2 * * 1'
#-----------------------------------------------------------------------------------------------------
jobs:
sync-config-files:
runs-on: ubuntu-latest
steps:
# Step 1: Check out the current repository
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Step 2: Download and sync config files
- name: Download and sync config files
id: sync_files
run: |
# Initialize array to store file pairs (local:remote)
FILES=()
# Add files to sync based on input parameters or default values
# Check if .gitignore should be synced (default: true)
if [ "${{ github.event.inputs.sync_gitignore || 'true' }}" = "true" ]; then
FILES+=(".gitignore:${{ github.event.inputs.gitignore_source || 'unreal-engine.gitignore' }}")
fi
# Check if .gitattributes should be synced (default: true)
if [ "${{ github.event.inputs.sync_gitattributes || 'true' }}" = "true" ]; then
FILES+=(".gitattributes:${{ github.event.inputs.gitattributes_source || 'unreal-engine.gitattributes' }}")
fi
# Check if .editorconfig should be synced (default: true)
if [ "${{ github.event.inputs.sync_editorconfig || 'true' }}" = "true" ]; then
FILES+=(".editorconfig:${{ github.event.inputs.editorconfig_source || '.editorconfig' }}")
fi
# Check if .clang-format should be synced (default: false)
if [ "${{ github.event.inputs.sync_clangformat || 'false' }}" = "true" ]; then
FILES+=(".clang-format:${{ github.event.inputs.clangformat_source || '.clang-format' }}")
fi
# Process additional files if specified
# Split comma-separated additional files
if [ -n "${{ github.event.inputs.additional_files }}" ]; then
IFS=',' read -ra EXTRA_FILES <<< "${{ github.event.inputs.additional_files }}"
for file in "${EXTRA_FILES[@]}"; do
FILES+=("$file")
done
fi
# Base URL for downloading files from the remote repository
BASE_URL="https://raw.githubusercontent.com/dadavidtseng/ConfigCommon/main"
CHANGED_FILES=""
ANY_CHANGED=false
# Process each file pair in the FILES array
for FILE_PAIR in "${FILES[@]}"; do
# Split local and remote file names using colon as delimiter
IFS=':' read -r LOCAL_FILE REMOTE_FILE <<< "$FILE_PAIR"
# Remove leading and trailing whitespace
LOCAL_FILE=$(echo "$LOCAL_FILE" | xargs)
REMOTE_FILE=$(echo "$REMOTE_FILE" | xargs)
echo "Processing $LOCAL_FILE (from $REMOTE_FILE)"
# Attempt to download the file
SUCCESS=false
if curl -fsSL "$BASE_URL/$REMOTE_FILE" -o "${LOCAL_FILE}.temp"; then
# Check if the downloaded file is not empty
if [ -s "${LOCAL_FILE}.temp" ]; then
echo "Successfully downloaded $REMOTE_FILE"
SUCCESS=true
fi
fi
# Skip file if download failed
if [ "$SUCCESS" = false ]; then
echo "Failed to download $REMOTE_FILE, skipping..."
rm -f "${LOCAL_FILE}.temp"
continue
fi
# Check for changes between existing and downloaded file
if [ -f "$LOCAL_FILE" ]; then
# Compare files byte by byte
if ! cmp -s "$LOCAL_FILE" "${LOCAL_FILE}.temp"; then
echo "Changes detected in $LOCAL_FILE"
mv "${LOCAL_FILE}.temp" "$LOCAL_FILE"
CHANGED_FILES="$CHANGED_FILES $LOCAL_FILE"
ANY_CHANGED=true
else
echo "No changes in $LOCAL_FILE"
rm -f "${LOCAL_FILE}.temp"
fi
else
# Create new file if it doesn't exist
echo "Creating new $LOCAL_FILE"
mv "${LOCAL_FILE}.temp" "$LOCAL_FILE"
CHANGED_FILES="$CHANGED_FILES $LOCAL_FILE"
ANY_CHANGED=true
fi
done
# Clean up any remaining temporary files
rm -f *.temp
# Set output variables for subsequent steps
if [ "$ANY_CHANGED" = true ]; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
# Step 3: Commit and push changes (only if files were changed)
- name: Commit and push changes
if: steps.sync_files.outputs.changed == 'true'
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add .
git commit -m "chore: update config files from dadavidtseng/ConfigCommon
Updated files:${{ steps.sync_files.outputs.changed_files }}"
git push
# Step 4: Display summary of the operation
- name: Summary
run: |
if [ "${{ steps.sync_files.outputs.changed }}" = "true" ]; then
echo "✅ Config files have been updated and committed"
echo "📝 Updated files:${{ steps.sync_files.outputs.changed_files }}"
else
echo "✅ All config files are already up to date"
fi