Add sync.yml workflow to propagate workflow updates across repos #2

Closed
opened 2026-05-24 07:59:04 -06:00 by Xeplosion · 7 comments
Owner

What problem does this solve?

When a workflow file in .forgejo is updated, it must currently be manually copied into every affected repo. This is error-prone and time-consuming at scale.

Proposed solution

A sync.yml workflow that triggers on changes to workflows/ or scripts/ on main, reads a list of target repos from a config file, and opens a PR in each affected repo with the updated file. PRs not auto-merges — each repo gets a manual review gate.

Alternatives considered

Auto-merge across all repos — rejected because a buggy workflow would propagate everywhere instantly with no safety valve.

Additional context

No response

Checklist

  • I have searched for existing issues or discussions before opening this one
  • I have described the problem, not just the solution
### What problem does this solve? When a workflow file in `.forgejo` is updated, it must currently be manually copied into every affected repo. This is error-prone and time-consuming at scale. ### Proposed solution A `sync.yml` workflow that triggers on changes to `workflows/` or `scripts/` on main, reads a list of target repos from a config file, and opens a PR in each affected repo with the updated file. PRs not auto-merges — each repo gets a manual review gate. ### Alternatives considered Auto-merge across all repos — rejected because a buggy workflow would propagate everywhere instantly with no safety valve. ### Additional context _No response_ ### Checklist - [x] I have searched for existing issues or discussions before opening this one - [x] I have described the problem, not just the solution
Author
Owner

Blocking on the submodule investigation (tracked separately). If git submodules can be used to reference .forgejo directly from template repos, sync.yml becomes unnecessary — files would no longer be duplicated and there would be nothing to sync. Building sync.yml before that investigation concludes risks doing work that gets thrown away. Leaving this open pending the outcome of the submodule spike.

Blocking on the submodule investigation ([tracked separately](https://git.xegames.online/XeplosionGames/org/issues/12)). If git submodules can be used to reference `.forgejo` directly from template repos, `sync.yml` becomes unnecessary — files would no longer be duplicated and there would be nothing to sync. Building `sync.yml` before that investigation concludes risks doing work that gets thrown away. Leaving this open pending the outcome of the submodule spike.
Author
Owner

After further thought, the preferred approach is as follows: .forgejo is the source of truth. Each stack template has a corresponding branch in .forgejo (e.g. template/dotnet, template/script) containing the full contents of that template. .forgejo push mirrors each template/* branch to the corresponding template repo's main branch using Forgejo's native branch filter mirroring. A lightweight workflow in each template repo triggers on push to main (from the mirror) to handle any post-sync steps if needed. This eliminates file duplication, makes .forgejo the single place to update workflows and scripts, and propagates changes to template repos automatically. Supersedes the sync.yml approach — updating that issue accordingly. Implementation blocked on confirming Forgejo supports branch-to-branch push mirroring with rename (i.e. template/dotnetmain), which needs verification on our instance.

After further thought, the preferred approach is as follows: `.forgejo` is the source of truth. Each stack template has a corresponding branch in `.forgejo` (e.g. `template/dotnet`, `template/script`) containing the full contents of that template. `.forgejo` push mirrors each `template/*` branch to the corresponding template repo's `main` branch using Forgejo's native branch filter mirroring. A lightweight workflow in each template repo triggers on push to `main` (from the mirror) to handle any post-sync steps if needed. This eliminates file duplication, makes `.forgejo` the single place to update workflows and scripts, and propagates changes to template repos automatically. Supersedes the `sync.yml` approach — updating that issue accordingly. Implementation blocked on confirming Forgejo supports branch-to-branch push mirroring with rename (i.e. `template/dotnet` → `main`), which needs verification on our instance.
Xeplosion added spent time 2026-05-25 02:30:18 -06:00
24 minutes
Author
Owner

Additional consideration: shared files (issue templates, common workflows like release.yml, shared scripts like build.sh) should not be duplicated across template branches. A sync-shared.yml workflow on main will detect which shared files changed and copy them to the relevant template/* branches based on a mapping defined in a sync-config.yml file at the repo root. A separate sync-template.yml workflow then mirrors each template/* branch to its corresponding template repo. This means changes to shared files only need to happen once on main and propagate automatically to all relevant templates. The sync-config.yml mapping defines which files belong in which template branches, making it easy to add new files or stacks without touching the workflow itself.

Additional consideration: shared files (issue templates, common workflows like `release.yml`, shared scripts like `build.sh`) should not be duplicated across template branches. A `sync-shared.yml` workflow on `main` will detect which shared files changed and copy them to the relevant `template/*` branches based on a mapping defined in a `sync-config.yml` file at the repo root. A separate `sync-template.yml` workflow then mirrors each `template/*` branch to its corresponding template repo. This means changes to shared files only need to happen once on `main` and propagate automatically to all relevant templates. The `sync-config.yml` mapping defines which files belong in which template branches, making it easy to add new files or stacks without touching the workflow itself.
Xeplosion stopped working 2026-05-25 02:45:10 -06:00
12 minutes 2 seconds
Author
Owner

Blocking on the .forgejo mirror sync system being designed and implemented (tracked separately). Template branches in .forgejo and the corresponding push mirror configuration cannot be set up until the sync workflows (sync-shared.yml and sync-template.yml) and the sync-config.yml mapping are defined. Until then, template repos remain the manual source of truth and changes must be copied by hand.

Blocking on the `.forgejo` mirror sync system being designed and implemented ([tracked separately](https://git.xegames.online/XeplosionGames/.forgejo/issues/3)). Template branches in `.forgejo` and the corresponding push mirror configuration cannot be set up until the sync workflows (`sync-shared.yml` and `sync-template.yml`) and the `sync-config.yml` mapping are defined. Until then, template repos remain the manual source of truth and changes must be copied by hand.
Author
Owner

Unblocking on the grounds that enough template repos have been created to facilitate sufficient testing of the .foregjo mirror sync system.

Unblocking on the grounds that enough template repos have been created to facilitate sufficient testing of the `.foregjo` mirror sync system.
Xeplosion stopped working 2026-05-25 05:44:19 -06:00
2 hours 12 minutes
Xeplosion stopped working 2026-05-26 09:02:44 -06:00
21 minutes 56 seconds
Author
Owner

Progress update: all five template branches (template-script, template-dotnet, template-node, template-php, template-python) have been created in .forgejo. template-php and template-python repos still need to be created on Forgejo and marked as template repos. Once those exist, the next steps are configuring the push mirrors in .forgejo Settings → Mirror Settings (one per template repo with the corresponding branch filter), adding promote.yml to each template repo's .forgejo/workflows/, and doing an end-to-end test of the full sync flow — push a change to a template branch on .forgejo, verify the mirror triggers, and confirm promote.yml successfully promotes it to main in the target template repo.

Progress update: all five template branches (`template-script`, `template-dotnet`, `template-node`, `template-php`, `template-python`) have been created in `.forgejo`. `template-php` and `template-python` repos still need to be created on Forgejo and marked as template repos. Once those exist, the next steps are configuring the push mirrors in `.forgejo` Settings → Mirror Settings (one per template repo with the corresponding branch filter), adding `promote.yml` to each template repo's `.forgejo/workflows/`, and doing an end-to-end test of the full sync flow — push a change to a template branch on `.forgejo`, verify the mirror triggers, and confirm `promote.yml` successfully promotes it to `main` in the target template repo.
Xeplosion stopped working 2026-05-26 10:01:12 -06:00
34 minutes 32 seconds
Xeplosion stopped working 2026-05-27 11:24:52 -06:00
2 hours 57 minutes
Xeplosion stopped working 2026-05-30 05:04:11 -06:00
1 hour 33 minutes
Xeplosion stopped working 2026-06-15 16:34:49 -06:00
1 day 11 hours
Xeplosion deleted spent time 2026-06-15 16:34:58 -06:00
- 1 day 11 hours
Xeplosion added spent time 2026-06-15 16:35:07 -06:00
3 hours
Author
Owner

The sync system this issue originally tracked is fully implemented — shared files propagate to template branches via sync-shared.yml and from there to template repos via sync-templates.yml.

During the process of documenting the sync architecture, two security gaps in the CI/CD deployment model were identified and broken out into dedicated tracking issues:

  • #6Forgejo-side security hardening: per-repo deploy keys, moving SSH_PRIVATE_KEY and SSH_USER out of org-level secrets, scoping RELEASE_TOKEN and SYNC_TOKEN, CODEOWNERS and branch protection on template branches
  • #7Server-side security hardening: per-service Linux users, root-owned deploy scripts, authorized_keys command= restrictions, sudoers entries, runner migration

#7 is a prerequisite for the deploy key steps in #6. Both are tracked at Priority/High.

Closing this issue as the original sync workflow work is complete. Remaining security work continues in #6 and #7.

The sync system this issue originally tracked is fully implemented — shared files propagate to template branches via `sync-shared.yml` and from there to template repos via `sync-templates.yml`. During the process of documenting the sync architecture, two security gaps in the CI/CD deployment model were identified and broken out into dedicated tracking issues: - #6 — **Forgejo-side security hardening**: per-repo deploy keys, moving `SSH_PRIVATE_KEY` and `SSH_USER` out of org-level secrets, scoping `RELEASE_TOKEN` and `SYNC_TOKEN`, CODEOWNERS and branch protection on template branches - #7 — **Server-side security hardening**: per-service Linux users, root-owned deploy scripts, `authorized_keys` `command=` restrictions, sudoers entries, runner migration #7 is a prerequisite for the deploy key steps in #6. Both are tracked at `Priority/High`. Closing this issue as the original sync workflow work is complete. Remaining security work continues in #6 and #7.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Total time spent: 11 hours 15 minutes
Xeplosion
11 hours 15 minutes
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
XeplosionGames/.forgejo#2
No description provided.