Skip to content

Update sync.yaml

Update sync.yaml #55

Workflow file for this run

name: Update Workflow Files Across Repos
on:
push:
branches: [main]
workflow_dispatch:
env:
IMAGE_NAME: template-files
jobs:
changesets:
name: Changesets
runs-on: ubuntu-latest
outputs:
hasChangesets: ${{ steps.changesets.outputs.hasChangesets }}
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup PNPM
uses: pnpm/action-setup@v3
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- name: Install Dependencies
run: pnpm i
- name: Create Release Pull Request
id: changesets
uses: changesets/action@v1
with:
commit: "[ci] release"
title: "[ci] release"
env:
GITHUB_TOKEN: ${{ secrets.PUBLIC_GITHUB_TOKEN }}
prepare-matrix:
name: Prepare Matrix
runs-on: ubuntu-latest
outputs:
repo-matrix: ${{ env.REPO_MATRIX }}
steps:
- name: Checkout current repository
uses: actions/checkout@v4
- name: Install jq
run: sudo apt-get install -y jq
- name: Read Repositories from JSON
id: set-matrix
run: |
repos=$(jq -c '.repositories[] | {name: .name, files: .files}' repos.json | jq -s .)
echo "$repos"
echo "REPO_MATRIX=$repos" >> $GITHUB_ENV
- name: Debug Matrix Output
run: |
echo "Matrix from jq:"
echo "${{ env.REPO_MATRIX }}"
sync-workflows:
runs-on: ubuntu-latest
needs: [changesets, prepare-matrix]
strategy:
matrix:
repo: ${{ fromJson(needs.prepare-matrix.outputs.repo-matrix) }}
if: >
(
needs.changesets.outputs.hasChangesets == 'false' &&
(
contains(github.event.head_commit.message, 'deploy') ||
contains(github.event.head_commit.message, '[ci] release')
)
) ||
github.event_name == 'workflow_dispatch'
steps:
- name: Checkout current repository
uses: actions/checkout@v4
- name: Install jq
run: sudo apt-get install -y jq
- name: Update workflows in target repository
env:
GH_TOKEN: ${{ secrets.PUBLIC_GITHUB_TOKEN }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
repo_name="${{ matrix.repo.name }}"
files='${{ toJson(matrix.repo.files) }}'
echo "Processing repository: $repo_name"
# Clone the target repository
echo "Cloning repository $repo_name..."
git clone --depth 1 "https://x-access-token:${GH_TOKEN}@github.com/${repo_name}.git" target-repo
cd target-repo
# Create or switch to the branch
branch_name="update-workflows"
echo "Creating branch $branch_name..."
git checkout -b "$branch_name" || git checkout "$branch_name"
# Sync specified workflow files
for file_config in $(echo "$files" | jq -c '.'); do
src_file=$(echo "$file_config" | jq -r '.path')
dest_file=$(echo "$file_config" | jq -r '.targetPath')
echo "Processing file: $src_file"
# Check if the file exists in the template-files directory
if [ ! -f "../$src_file" ]; then
echo "Warning: File $src_file not found in /template-files."
continue
fi
# Prepare the destination directory
mkdir -p "$(dirname "$dest_file")"
# Handle dynamic content replacement if "props" is specified
props=$(echo "$file_config" | jq -c '.props // empty')
if [ -n "$props" ]; then
echo "Applying dynamic replacements for $src_file..."
temp_file=$(mktemp)
cp "../$src_file" "$temp_file"
# Replace placeholders with their respective values from props
for key in $(echo "$props" | jq -r 'keys[]'); do
value=$(echo "$props" | jq -r --arg key "$key" '.[$key]')
placeholder="<%= $key %>"
echo "Replacing $placeholder with $value in $src_file..."
sed -i "s|$placeholder|$value|g" "$temp_file"
done
# Move the processed file to the target location
mv "$temp_file" "$dest_file"
else
# If no props, copy the file directly
cp "../$src_file" "$dest_file"
fi
done
# Commit and push changes if any
echo "Checking for changes..."
git add .
if git diff --cached --quiet; then
echo "No changes detected for $repo_name."
else
echo "Committing and pushing changes for $repo_name..."
git commit -m "Update GitHub workflow files"
git push --force origin "$branch_name"
cd ..
latest_commit_hash=$(git rev-parse HEAD)
latest_commit_url="https://github.com/$GITHUB_REPOSITORY/commit/$latest_commit_hash"
latest_commit_message=$(git log -1 --pretty=%s)
latest_commit_entry="- $latest_commit_message - ([$(git rev-parse --short HEAD)]($latest_commit_url))"
cd target-repo
# Check for existing pull request
echo "Checking for an open PR for branch $branch_name..."
existing_pr=$(gh pr list --base main --head "$branch_name" --json number --jq '.[0].number')
if [ -n "$existing_pr" ]; then
echo "Found existing PR #$existing_pr. Updating it..."
current_body=$(gh pr view "$existing_pr" --json body --jq '.body')
updated_body=$(printf "%s\n%s" "$current_body" "$latest_commit_entry")
gh pr edit "$existing_pr" --body "$updated_body"
gh pr comment "$existing_pr" --body "The branch has been updated with the [latest changes]($latest_commit_url)."
else
echo "No existing PR found. Creating a new one..."
gh pr create \
--base main \
--head "$branch_name" \
--title "Sync workflow files" \
--body "This PR syncs the specified GitHub workflow files from the [central repository](https://github.com/trueberryless-org/template-files).\n\n### Changes:\n$latest_commit_entry"
fi
fi
# Cleanup
cd ..
echo "Cleaning up repository clone for $repo_name..."
rm -rf target-repo
image-tag:
name: Image Tag
runs-on: ubuntu-latest
outputs:
IMAGE_TAG: ${{ env.IMAGE_TAG }}
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Read version from package.json
id: get_version
run: |
VERSION=$(jq -r '.version' package.json)
echo "IMAGE_TAG=$VERSION" >> $GITHUB_ENV
release:
name: Release
needs: [sync-workflows, image-tag]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
- id: extract-changelog
uses: sean0x42/[email protected]
with:
file: CHANGELOG.md
pattern: ${{ needs.image-tag.outputs.IMAGE_TAG }}
- uses: ncipollo/release-action@v1
id: create_release
with:
tag: ${{ env.IMAGE_NAME }}@${{ needs.image-tag.outputs.IMAGE_TAG }}
makeLatest: true
body: ${{ steps.extract-changelog.outputs.markdown }}
- name: Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
uses: Ilshidur/[email protected]
with:
args: "# ${{ env.IMAGE_NAME }}@${{ needs.image-tag.outputs.IMAGE_TAG }}\n\n${{ steps.extract-changelog.outputs.markdown }}"