Sync branch to template #48
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Sync branch to template | |
on: | |
workflow_dispatch: | |
inputs: | |
additional_files: | |
description: 'Comma-separated list of extra paths to sync, for example: .eslintrc,.prettierrc,.github' | |
required: false | |
schedule: | |
- cron: '14 0 1 * *' | |
jobs: | |
sync: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
steps: | |
- name: Check if repository is ts-template | |
run: | | |
if [[ "${{ github.repository }}" == "ubiquity/ts-template" ]]; then | |
echo "Skipping sync: this is the template repository." | |
exit 0 | |
fi | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Get GitHub App token | |
uses: tibdex/github-app-token@v1.7.0 | |
id: get_installation_token | |
with: | |
app_id: ${{ secrets.APP_ID }} | |
private_key: ${{ secrets.APP_PRIVATE_KEY }} | |
- name: Sync branch to template | |
env: | |
GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} | |
WHITELIST_FILES: ".github/ .husky/ .eslintrc .nvmrc .prettierrc .yarnrc.yml tsconfig.json" | |
ADDITIONAL_FILES: ${{ github.event.inputs.additional_files }} | |
BLACKLIST_FILES: ".github/workflows/deploy.yml" | |
run: | | |
branch_name=$(git rev-parse --abbrev-ref HEAD) | |
original_remote=$(git remote get-url origin) | |
pr_branch="sync-template/${branch_name}" | |
git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
git config --global user.name "github-actions[bot]" | |
# Check if the sync branch already exists | |
if git ls-remote --exit-code --heads origin "$pr_branch"; then | |
echo "Branch $pr_branch already exists. Fetching and updating." | |
git fetch origin "$pr_branch" | |
git checkout "$pr_branch" | |
git rebase "origin/$branch_name" | |
else | |
echo "Creating new branch $pr_branch." | |
git checkout -b "$pr_branch" | |
fi | |
git clone https://github.com/ubiquity/ts-template template-repo | |
# Convert WHITELIST_FILES to array | |
whitelist_files=() | |
IFS=' ' read -r -a whitelist_files <<< "$WHITELIST_FILES" | |
# Convert ADDITIONAL_FILES inputs to array | |
additional_files=() | |
if [[ -n "$ADDITIONAL_FILES" ]]; then | |
IFS=',' read -r -a additional_files <<< "$ADDITIONAL_FILES" | |
fi | |
# Convert BLACKLIST_FILES to array | |
blacklist_files=() | |
if [[ -n "$BLACKLIST_FILES" ]]; then | |
IFS=',' read -r -a blacklist_files <<< "$BLACKLIST_FILES" | |
echo "Blacklist files: ${blacklist_files[@]}" | |
fi | |
# Prepare file list for the PR body and process each whitelist file | |
file_list="" | |
for file in "${whitelist_files[@]}" "${additional_files[@]}"; do | |
# BLACKLIST_FILES check | |
skip_file=false | |
for blacklisted in "${blacklist_files[@]}"; do | |
echo "Checking if $file matches blacklist entry $blacklisted..." | |
if [[ "$file" == "$blacklisted" || "$file" == */"$blacklisted" ]]; then | |
echo "$file matches blacklist entry $blacklisted. Skipping." | |
skip_file=true | |
break | |
fi | |
done | |
if [[ "$skip_file" == true ]]; then | |
echo "Skipping blacklisted file: $file" | |
continue | |
fi | |
# Process files | |
if [[ -d "template-repo/$file" ]]; then | |
echo "Processing directory: $file" | |
mkdir -p "$file" | |
rsync -a --delete "template-repo/$file/" "$file/" | |
file_list+=$'\n'"- \`${file}\` (directory)" | |
elif [[ -e "template-repo/$file" ]]; then | |
echo "Processing file: $file" | |
cp -f "template-repo/$file" "$file" | |
file_list+=$'\n'"- \`${file}\`" | |
else | |
echo "Removing file/directory: $file" | |
rm -rf "$file" | |
file_list+=$'\n'"- \`${file}\` (removed)" | |
fi | |
done | |
# Clean up | |
rm -rf template-repo/ | |
# Commit | |
git add . | |
git commit -m "chore: sync template" | |
# Push | |
git push "$original_remote" "$pr_branch" | |
# Check for existing pull requests | |
existing_pr=$(gh pr list --base "$branch_name" --head "$pr_branch" --state open --json id --jq '.[0].id') | |
if [[ -z "$existing_pr" ]]; then | |
gh pr create --title "Sync branch to template" --body "This pull request merges changes from the template repository, overwriting or removing the following files:${file_list}" --head "$pr_branch" --base "$branch_name" | |
else | |
gh pr edit "$existing_pr" --body "This pull request merges changes from the template repository, overwriting or removing the following files:${file_list}" | |
echo "Updated the existing pull request #$existing_pr." | |
fi |