Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor sync template workflow to work in a whitelist setting #78

Draft
wants to merge 21 commits into
base: development
Choose a base branch
from
Draft
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
136 changes: 136 additions & 0 deletions .github/workflows/sync-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
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:
actions: write
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
token: ${{ secrets.PAT }} # Personal Access Token (PAT) with repo scope

- 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 }}
zugdev marked this conversation as resolved.
Show resolved Hide resolved
BLACKLIST_FILES: ".github/workflows/sync-template.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/zugdev/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
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"
mkdir -p "$file"
cp -f "template-repo/$file" "$file"
file_list+=$'\n'"- \`${file}\`"
else
echo "Removing missing file or directory: $file"
rm -rf "$file"
file_list+=$'\n'"- \`${file}\` (removed)"
fi
done

# Check for blacklisted files and revert changes
echo "Checking for blacklisted files..."
for blacklisted in "${blacklist_files[@]}"; do
if [[ -e "$blacklisted" ]]; then
echo "Reverting blacklisted file or directory: $blacklisted"
git restore "$blacklisted"
fi
done

# Clean up
rm -rf template-repo/

# Commit changes
git add .
git commit -m "chore: sync template" || echo "No changes to commit."

# Push changes to the remote repository (force is to be incremental)
git push "$original_remote" "$pr_branch" --force

# Check for existing pull requests
existing_pr=$(gh pr list --base "$branch_name" --head "$pr_branch" --state open --json id --jq '.[0].id')

# Include blacklist info in PR body if present
if [[ -n "$blacklist_list" ]]; then
file_list+=$'\n\n**Blacklisted Files**:'"$blacklist_list"
fi

# Create or update the pull request
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 "$pr_branch" --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