Skip to content

Commit e905f34

Browse files
authored
ci: Add sync-common workflow (#26)
Initial goal is get our Gemini review config out to all repos. But after that of course we can use this for a lot more stuff. Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: Colin Walters <[email protected]>
1 parent f775bf5 commit e905f34

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

.github/workflows/sync-common.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: Sync common files
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'common/**'
9+
- '.github/workflows/sync-common.yml'
10+
11+
# Prevent multiple workflow runs from racing
12+
concurrency: ${{ github.workflow }}
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
init:
19+
name: Discover repositories
20+
runs-on: ubuntu-latest
21+
outputs:
22+
matrix: ${{ steps.get-repos.outputs.matrix }}
23+
steps:
24+
- name: Generate Actions Token
25+
id: token
26+
uses: actions/create-github-app-token@v2
27+
with:
28+
app-id: ${{ secrets.APP_ID }}
29+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
30+
owner: ${{ github.repository_owner }}
31+
32+
- name: Checkout
33+
uses: actions/checkout@v5
34+
35+
- name: Get repository list
36+
id: get-repos
37+
uses: actions/github-script@v8
38+
with:
39+
github-token: ${{ steps.token.outputs.token }}
40+
script: |
41+
const repos = await github.paginate(github.rest.repos.listForOrg, {
42+
org: context.repo.owner,
43+
type: 'all',
44+
per_page: 100
45+
});
46+
47+
// Filter out archived repos and this repo itself
48+
const activeRepos = repos.filter(repo =>
49+
!repo.archived &&
50+
repo.name !== context.repo.repo &&
51+
!repo.name.startsWith('.')
52+
);
53+
54+
const matrix = activeRepos.map(repo => ({
55+
repo: repo.name,
56+
full_name: repo.full_name
57+
}));
58+
59+
console.log('Discovered repositories:', matrix);
60+
core.setOutput('matrix', JSON.stringify(matrix));
61+
62+
- name: Upload common files
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: common-files
66+
path: common/
67+
68+
sync:
69+
name: Sync to ${{ matrix.repo }}
70+
needs: init
71+
if: needs.init.outputs.matrix != '[]'
72+
runs-on: ubuntu-latest
73+
strategy:
74+
fail-fast: false
75+
matrix:
76+
include: ${{ fromJSON(needs.init.outputs.matrix) }}
77+
steps:
78+
- name: Generate Actions Token
79+
id: token
80+
uses: actions/create-github-app-token@v2
81+
with:
82+
app-id: ${{ secrets.APP_ID }}
83+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
84+
owner: ${{ github.repository_owner }}
85+
repositories: ${{ matrix.repo }}
86+
87+
- name: Checkout target repository
88+
uses: actions/checkout@v5
89+
with:
90+
repository: ${{ matrix.full_name }}
91+
token: ${{ steps.token.outputs.token }}
92+
path: repo
93+
94+
- name: Download common files
95+
uses: actions/download-artifact@v4
96+
with:
97+
name: common-files
98+
path: common-files
99+
100+
- name: Get bot user info
101+
id: bot-user
102+
uses: actions/github-script@v8
103+
with:
104+
github-token: ${{ steps.token.outputs.token }}
105+
script: |
106+
const user = await github.rest.users.getAuthenticated();
107+
console.log('Bot user:', user.data);
108+
core.setOutput('name', user.data.login);
109+
core.setOutput('email', `${user.data.id}+${user.data.login}@users.noreply.github.com`);
110+
111+
- name: Sync common files to repository
112+
run: |
113+
# Create target directory if it doesn't exist
114+
mkdir -p repo/.gemini
115+
116+
# Copy files from common to repo
117+
if [ -d common-files/.gemini ]; then
118+
cp -r common-files/.gemini/* repo/.gemini/
119+
fi
120+
121+
- name: Open pull request
122+
uses: peter-evans/create-pull-request@v7
123+
with:
124+
token: ${{ steps.token.outputs.token }}
125+
path: repo
126+
branch: sync-common-files
127+
commit-message: |
128+
Sync common files from infra repository
129+
130+
Synchronized from ${{ github.repository }}@${{ github.sha }}.
131+
title: Sync common files from infra repository
132+
body: |
133+
Created by [GitHub workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/sync-common.yml) ([source](${{ github.server_url }}/${{ github.repository }}/blob/main/.github/workflows/sync-common.yml)).
134+
135+
This PR synchronizes common files from the [infra repository](${{ github.server_url }}/${{ github.repository }}/tree/main/common).
136+
137+
Synchronized from ${{ github.repository }}@${{ github.sha }}.
138+
committer: "${{ steps.bot-user.outputs.name }} <${{ steps.bot-user.outputs.email }}>"
139+
author: "${{ steps.bot-user.outputs.name }} <${{ steps.bot-user.outputs.email }}>"

common/.gemini/config.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# This config mainly overrides `summary: false` by default
2+
# as it's really noisy.
3+
have_fun: true
4+
code_review:
5+
disable: false
6+
comment_severity_threshold: MEDIUM
7+
max_review_comments: -1
8+
pull_request_opened:
9+
help: false
10+
summary: false # turned off by default
11+
code_review: true
12+
ignore_patterns: []

common/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Common synchronized files
2+
3+
Files placed in this repository are automatically
4+
synchronized (via a pull request) to all repositories
5+
in the bootc-dev organization.

0 commit comments

Comments
 (0)