# Source file: https://github.com/rootstrap/react-native-template/blob/master/.github/project-workflows/sync-with-template.yml
# This workflow is used to keep the project up to date with the latest version of the template.
# 🚨 GITHUB SECRETS REQUIRED:
# - UPDATE_FROM_TEMPLATE_PAT: A fine-grained Personal Access Token.
# This token is used to commit and push to the project repository.
# You can generate one from here: https://github.com/settings/tokens?type=beta
# Set the Repository access to "Only select repositories" and select the project repository.
# Set the following Repo permissions:
# - Contents: Read & write (to commit and push the update branch to the project repository)
# - Metadata: Read-only (mandatory by GitHub)
# - Workflows: Read and write (to create, update and delete workflows in the project repository)
# Make sure to add it to the repo secrets with the name UPDATE_FROM_TEMPLATE_PAT:
# - Go to Repository Settings > Secrets and variables > Actions > New repository secret
# - Name: UPDATE_FROM_TEMPLATE_PAT
# - Value: The Personal Access Token you created
# ℹ️ Environment variables:
# - TEMPLATE_REPOSITORY: Repository to sync with
# - DIFF_EXCLUDED_ROUTES: List of files or directories to exclude from the diff.
# Any changes in these files or directories will be ignored
# and won't be incorporated to the Pull Request.
name: 🔄 Sync with template
- cron: '0 12 * * 1-5' # At 12:00 UTC on every day-of-week from Monday through Friday
description: 'Template release version to sync with (e.g. v1.0.0). Leave empty to sync with the latest release.'
TEMPLATE_REPOSITORY: rootstrap/react-native-template
.github/workflows/deploy-docs.yml
.github/workflows/new-template-version.yml
.github/workflows/upstream-to-pr.yml
.github/workflows/sync-with-upstream.yml
- name: Check if Personal Access Token exists
PAT: ${{ secrets.UPDATE_FROM_TEMPLATE_PAT }}
echo "UPDATE_FROM_TEMPLATE_PAT secret not found. Please create a fine-grained Personal Access Token following the instructions in the workflow file."
- name: Checkout project repository
uses: actions/checkout@v3
token: ${{ secrets.UPDATE_FROM_TEMPLATE_PAT }}
- name: Get template version used in project from package.json
echo "PROJECT_TEMPLATE_VERSION=v$(jq -r 'if has("rsMetadata") then .rsMetadata.templateVersion else .osMetadata.initVersion end' project/package.json | sed 's/^.*@//')" >> $GITHUB_ENV
- name: Set template version to sync with
if [ -z "${{ inputs.template-version }}" ]; then
TEMPLATE_UPDATE_VERSION=$(curl -s https://api.github.com/repos/${{ env.TEMPLATE_REPOSITORY }}/releases/latest | jq '.tag_name' | sed 's/\"//g')
TEMPLATE_UPDATE_VERSION=${{ inputs.template-version }}
echo "TEMPLATE_UPDATE_VERSION=$TEMPLATE_UPDATE_VERSION" >> $GITHUB_ENV
- name: Check if the project is up to date
if [[ $TEMPLATE_UPDATE_VERSION == $PROJECT_TEMPLATE_VERSION ]]; then
echo "Template is up to date"
gh run cancel ${{ github.run_id }}
gh run watch ${{ github.run_id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check if branch already exists
BRANCH_NAME=update-template-${{ env.TEMPLATE_UPDATE_VERSION }}
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
git branch -r | grep -q "origin/$BRANCH_NAME" && echo "BRANCH_EXISTS=true" >> $GITHUB_ENV || echo "BRANCH_EXISTS=false" >> $GITHUB_ENV
- name: Check if PR already exists
echo "PR_EXISTS=true" >> $GITHUB_ENV
echo "PR_EXISTS=false" >> $GITHUB_ENV
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
if: ${{ env.BRANCH_EXISTS == 'false' }}
- name: Checkout update release of template
if: ${{ env.BRANCH_EXISTS == 'false' }}
uses: actions/checkout@v3
repository: ${{ env.TEMPLATE_REPOSITORY }}
ref: ${{ env.TEMPLATE_UPDATE_VERSION }}
path: react-native-template
- name: Get diff between latest release and used release
if: ${{ env.BRANCH_EXISTS == 'false' }}
for route in $DIFF_EXCLUDED_ROUTES; do
EXCLUDED_ROUTES="$EXCLUDED_ROUTES ':(exclude)$route'"
git diff ${{ env.PROJECT_TEMPLATE_VERSION }} -- . $(echo $EXCLUDED_ROUTES | xargs) > ../update.patch
- name: Update template version in package.json
if: ${{ env.BRANCH_EXISTS == 'false' }}
jq 'del(.osMetadata)' package.json > tmp.json && mv tmp.json package.json
PLAIN_VERSION=${TEMPLATE_UPDATE_VERSION#v}
jq --arg version $PLAIN_VERSION '.rsMetadata.templateVersion = $version' package.json > tmp.json && mv tmp.json package.json
- name: Apply diff to project repository
if: ${{ env.BRANCH_EXISTS == 'false' }}
git apply --reject ../update.patch
- name: Solve conflicts with wiggle
if: ${{ env.BRANCH_EXISTS == 'false' }}
find . -iname '*.rej' -exec sh -c 'printf "%s\n" "${0%.*}"' {} ';' | xargs -I _ wiggle --replace --merge _ _.rej
- name: Remove wiggle's backup and .rej files
if: ${{ env.BRANCH_EXISTS == 'false' }}
find . -not -path './.git/*' -type f -name '*.porig' -delete
find . -not -path './.git/*' -type f -name '*.rej' -delete
- name: Commit and push changes to the update branch
if: ${{ env.BRANCH_EXISTS == 'false' }}
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git checkout -b ${{ env.BRANCH_NAME }}
git commit -m "chore: update template to ${{ env.TEMPLATE_UPDATE_VERSION }}"
git push origin ${{ env.BRANCH_NAME }}
echo "BRANCH_EXISTS=true" >> $GITHUB_ENV
- name: 🎉 Create PR with changes
if: ${{ env.BRANCH_EXISTS == 'true' && env.PR_EXISTS == 'false' }}
gh pr create --title "chore: update template to ${{ env.TEMPLATE_UPDATE_VERSION }}" --body "Integrating latest changes from [rootstrap/react-native-template@${{ env.TEMPLATE_UPDATE_VERSION }}](https://github.com/rootstrap/react-native-template/releases/tag/${{ env.TEMPLATE_UPDATE_VERSION }})" --head ${{ env.BRANCH_NAME }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}