Skip to content

Commit 6acb50f

Browse files
authored
Also sync content to composefs GH org (#125)
* ci: Add composefs org to sync-common and sync-labels targets The composefs org has significant overlap with bootc-dev contributors, so keep CI infrastructure in sync across both. This adds a second GitHub App token scoped to the composefs org and discovers repos from both orgs to build the sync matrix. Each matrix entry now includes an 'owner' field so the sync job generates a correctly-scoped token for the target repo's org. Prerequisite: the bootc-bot GitHub App must be installed on the composefs GitHub organization. Closes: #119 Assisted-by: OpenCode (Claude claude-opus-4-6) Signed-off-by: Colin Walters <walters@verbum.org> * ci: Add composefs org to Renovate and update shared config Run Renovate as a matrix job across both bootc-dev and composefs orgs, each with its own scoped GitHub App token. Autodiscovery works per-token so each run finds the correct repos. Change inheritConfigRepoName from '{{parentOrg}}/infra' to the explicit 'bootc-dev/infra' so that composefs repos also inherit the shared Renovate config from this repository (the repo is public so cross-org reads work). Add composefs/composefs and composefs/composefs-rs to the matchRepositories list for ignorePaths, preventing Renovate from creating conflicting PRs for files managed by sync-common. Closes: #119 Assisted-by: OpenCode (Claude claude-opus-4-6) Signed-off-by: Colin Walters <walters@verbum.org> --------- Signed-off-by: Colin Walters <walters@verbum.org>
1 parent a8bd70f commit 6acb50f

5 files changed

Lines changed: 110 additions & 49 deletions

File tree

.github/workflows/renovate.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ jobs:
3232
runs-on: ubuntu-latest
3333
needs: validate
3434
if: github.event_name != 'pull_request'
35+
strategy:
36+
fail-fast: false
37+
matrix:
38+
include:
39+
- owner: bootc-dev
40+
- owner: composefs
3541
steps:
3642
- name: Generate Actions Token
3743
id: token
@@ -40,7 +46,7 @@ jobs:
4046
with:
4147
app-id: ${{ secrets.APP_ID }}
4248
private-key: ${{ secrets.APP_PRIVATE_KEY }}
43-
owner: ${{ github.repository_owner }}
49+
owner: ${{ matrix.owner }}
4450

4551
- name: Checkout
4652
uses: actions/checkout@v6

.github/workflows/sync-common.yml

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,45 +55,70 @@ jobs:
5555
private-key: ${{ secrets.APP_PRIVATE_KEY }}
5656
owner: ${{ github.repository_owner }}
5757

58+
- name: Generate Actions Token (composefs)
59+
id: token-composefs
60+
uses: actions/create-github-app-token@v2
61+
with:
62+
app-id: ${{ secrets.APP_ID }}
63+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
64+
owner: composefs
65+
5866
- name: Checkout
5967
uses: actions/checkout@v6
6068

6169
- name: Get repository list
6270
id: get-repos
6371
uses: actions/github-script@v8
72+
env:
73+
COMPOSEFS_TOKEN: ${{ steps.token-composefs.outputs.token }}
6474
with:
6575
github-token: ${{ steps.token.outputs.token }}
6676
script: |
67-
const repos = await github.paginate(github.rest.repos.listForOrg, {
68-
org: context.repo.owner,
69-
type: 'all',
70-
per_page: 100
71-
});
72-
73-
// Filter out archived repos and this repo itself
74-
let activeRepos = repos.filter(repo =>
75-
!repo.archived &&
76-
repo.name !== context.repo.repo &&
77-
!repo.name.startsWith('.')
78-
);
77+
const composefsGithub = require('@actions/github').getOctokit(process.env.COMPOSEFS_TOKEN);
78+
79+
const orgs = [
80+
{ name: context.repo.owner, octokit: github },
81+
{ name: 'composefs', octokit: composefsGithub },
82+
];
83+
84+
let allRepos = [];
85+
for (const org of orgs) {
86+
const repos = await org.octokit.paginate(org.octokit.rest.repos.listForOrg, {
87+
org: org.name,
88+
type: 'all',
89+
per_page: 100
90+
});
91+
92+
// Filter out archived repos, this repo itself (for home org), and dot-prefixed repos
93+
const activeRepos = repos.filter(repo =>
94+
!repo.archived &&
95+
!(org.name === context.repo.owner && repo.name === context.repo.repo) &&
96+
!repo.name.startsWith('.')
97+
);
98+
99+
for (const repo of activeRepos) {
100+
allRepos.push({
101+
repo: repo.name,
102+
full_name: repo.full_name,
103+
owner: org.name
104+
});
105+
}
106+
}
79107
80108
// Test mode - only sync to ci-sandbox
81109
const testMode = '${{ github.event.inputs.test_mode }}' === 'true';
82110
if (testMode) {
83111
console.log('Test mode enabled - only syncing to ci-sandbox');
84-
activeRepos = activeRepos.filter(repo => repo.name === 'ci-sandbox');
112+
allRepos = allRepos.filter(repo =>
113+
repo.owner === context.repo.owner && repo.name === 'ci-sandbox'
114+
);
85115
}
86116
87-
const matrix = activeRepos.map(repo => ({
88-
repo: repo.name,
89-
full_name: repo.full_name
90-
}));
91-
92-
console.log('Discovered repositories:', matrix);
93-
core.setOutput('matrix', JSON.stringify(matrix));
117+
console.log('Discovered repositories:', allRepos);
118+
core.setOutput('matrix', JSON.stringify(allRepos));
94119
95120
sync:
96-
name: Sync to ${{ matrix.repo }}
121+
name: Sync to ${{ matrix.full_name }}
97122
needs: [build, init]
98123
if: needs.init.outputs.matrix != '[]'
99124
runs-on: ubuntu-latest
@@ -108,7 +133,7 @@ jobs:
108133
with:
109134
app-id: ${{ secrets.APP_ID }}
110135
private-key: ${{ secrets.APP_PRIVATE_KEY }}
111-
owner: ${{ github.repository_owner }}
136+
owner: ${{ matrix.owner }}
112137
repositories: ${{ matrix.repo }}
113138

114139
- name: Checkout infra repository

.github/workflows/sync-labels.yml

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,41 +59,66 @@ jobs:
5959
private-key: ${{ secrets.APP_PRIVATE_KEY }}
6060
owner: ${{ github.repository_owner }}
6161

62+
- name: Generate Actions Token (composefs)
63+
id: token-composefs
64+
uses: actions/create-github-app-token@v2
65+
with:
66+
app-id: ${{ secrets.APP_ID }}
67+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
68+
owner: composefs
69+
6270
- name: Get repository list
6371
id: get-repos
6472
uses: actions/github-script@v8
73+
env:
74+
COMPOSEFS_TOKEN: ${{ steps.token-composefs.outputs.token }}
6575
with:
6676
github-token: ${{ steps.token.outputs.token }}
6777
script: |
68-
const repos = await github.paginate(github.rest.repos.listForOrg, {
69-
org: context.repo.owner,
70-
type: 'all',
71-
per_page: 100
72-
});
73-
74-
// Filter out archived repos
75-
let activeRepos = repos.filter(repo =>
76-
!repo.archived &&
77-
!repo.name.startsWith('.')
78-
);
78+
const composefsGithub = require('@actions/github').getOctokit(process.env.COMPOSEFS_TOKEN);
79+
80+
const orgs = [
81+
{ name: context.repo.owner, octokit: github },
82+
{ name: 'composefs', octokit: composefsGithub },
83+
];
84+
85+
let allRepos = [];
86+
for (const org of orgs) {
87+
const repos = await org.octokit.paginate(org.octokit.rest.repos.listForOrg, {
88+
org: org.name,
89+
type: 'all',
90+
per_page: 100
91+
});
92+
93+
// Filter out archived repos and dot-prefixed repos
94+
const activeRepos = repos.filter(repo =>
95+
!repo.archived &&
96+
!repo.name.startsWith('.')
97+
);
98+
99+
for (const repo of activeRepos) {
100+
allRepos.push({
101+
repo: repo.name,
102+
full_name: repo.full_name,
103+
owner: org.name
104+
});
105+
}
106+
}
79107
80108
// Test mode - only sync to ci-sandbox
81109
const testMode = '${{ github.event.inputs.test_mode }}' === 'true';
82110
if (testMode) {
83111
console.log('Test mode enabled - only syncing to ci-sandbox');
84-
activeRepos = activeRepos.filter(repo => repo.name === 'ci-sandbox');
112+
allRepos = allRepos.filter(repo =>
113+
repo.owner === context.repo.owner && repo.name === 'ci-sandbox'
114+
);
85115
}
86116
87-
const matrix = activeRepos.map(repo => ({
88-
repo: repo.name,
89-
full_name: repo.full_name
90-
}));
91-
92-
console.log('Discovered repositories:', matrix);
93-
core.setOutput('matrix', JSON.stringify(matrix));
117+
console.log('Discovered repositories:', allRepos);
118+
core.setOutput('matrix', JSON.stringify(allRepos));
94119
95120
sync:
96-
name: Sync to ${{ matrix.repo }}
121+
name: Sync to ${{ matrix.full_name }}
97122
needs: init
98123
if: needs.init.outputs.matrix != '[]'
99124
runs-on: ubuntu-24.04
@@ -108,7 +133,7 @@ jobs:
108133
with:
109134
app-id: ${{ secrets.APP_ID }}
110135
private-key: ${{ secrets.APP_PRIVATE_KEY }}
111-
owner: ${{ github.repository_owner }}
136+
owner: ${{ matrix.owner }}
112137
repositories: ${{ matrix.repo }}
113138

114139
- name: Sync labels
@@ -119,7 +144,7 @@ jobs:
119144
github-token: ${{ steps.token.outputs.token }}
120145
script: |
121146
const labels = JSON.parse(process.env.LABELS_JSON);
122-
const owner = context.repo.owner;
147+
const owner = '${{ matrix.owner }}';
123148
const repo = '${{ matrix.repo }}';
124149
125150
console.log(`Syncing labels to ${owner}/${repo}`);

renovate-config.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ module.exports = {
1111
// Centralise all Renovate configuration into this repository
1212
//
1313
// This allows for easier management of Renovate settings across multiple
14-
// repositories. Each individual repository can still contain their own
15-
// configuration.
14+
// repositories and organisations. Each individual repository can still
15+
// contain their own configuration.
16+
//
17+
// Note: this uses an explicit repo name rather than {{parentOrg}}/infra
18+
// so that repos in other orgs (e.g. composefs) also inherit from here.
1619
inheritConfig: true,
17-
inheritConfigRepoName: '{{parentOrg}}/infra',
20+
inheritConfigRepoName: 'bootc-dev/infra',
1821
inheritConfigFileName: "renovate-shared-config.json",
1922
inheritConfigStrict: true,
2023

renovate-shared-config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@
8181
"bootc-dev/bcvk",
8282
"bootc-dev/ci-sandbox",
8383
"bootc-dev/containers-image-proxy-rs",
84-
"bootc-dev/bootc-dev.github.io"
84+
"bootc-dev/bootc-dev.github.io",
85+
"composefs/composefs",
86+
"composefs/composefs-rs"
8587
],
8688
"ignorePaths": [
8789
".github/workflows/rebase.yml",

0 commit comments

Comments
 (0)