Skip to content

Deploy to example repo on every MR to validate CI works with default settings. #5

Deploy to example repo on every MR to validate CI works with default settings.

Deploy to example repo on every MR to validate CI works with default settings. #5

name: Update Example Repo
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main]
permissions:
pull-requests: write
jobs:
update-example:
runs-on: ubuntu-latest
environment: cookiecutter-uv-example
# Forks don't have access to secrets, skip them
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- name: Check out
uses: actions/checkout@v4
- name: Set up the environment
uses: ./.github/actions/setup-python-env
- name: Determine target branch
id: branch
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "name=preview/pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
else
echo "name=main" >> $GITHUB_OUTPUT
fi
- name: Bake example project
run: |
uv run cookiecutter --no-input . --overwrite-if-exists \
author="Example User" \
email="example@osprey-oss.org" \
author_github_handle="osprey-oss" \
project_name="cookiecutter-uv-example"
- name: Patch baked workflow to trigger on preview branches
if: github.event_name == 'pull_request'
run: |
python -c "
import pathlib
f = pathlib.Path('cookiecutter-uv-example/.github/workflows/main.yml')
f.write_text(f.read_text().replace(
' - main\n',
' - main\n - \"preview/**\"\n',
1
))
"
- name: Push to cookiecutter-uv-example
env:
BRANCH: ${{ steps.branch.outputs.name }}
TOKEN: ${{ secrets.EXAMPLE_REPO_PUSH_TOKEN }}
run: |
cd cookiecutter-uv-example
uv sync
git init
git checkout -b "$BRANCH"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
uv run pre-commit run -a || true
git add .
git commit -m "chore: sync from cookiecutter-uv@${{ github.sha }}"
git remote add origin "https://x-access-token:${TOKEN}@github.com/osprey-oss/cookiecutter-uv-example.git"
git push -f origin "$BRANCH"
- name: Post or update PR comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const branch = '${{ steps.branch.outputs.name }}';
const sha = '${{ github.sha }}';
const marker = '<!-- cookiecutter-example-bot -->';
const encodedBranch = branch.split('/').map(encodeURIComponent).join('/');
const repoUrl = 'https://github.com/osprey-oss/cookiecutter-uv-example';
const body = [
marker,
'### 🍪 Example repo updated',
'',
`The baked example for this PR has been pushed to [osprey-oss/cookiecutter-uv-example](${repoUrl}/tree/${branch}).`,
'',
'| | |',
'|---|---|',
`| Branch | [\`${branch}\`](${repoUrl}/tree/${branch}) |`,
`| CI | [View Actions →](${repoUrl}/actions?query=branch%3A${encodedBranch}) |`,
`| Synced at | \`${sha.slice(0, 7)}\` |`,
'',
'_Uses default configuration. Non-default options are validated by the slow tests in this repo\'s CI._',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c => c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}