Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/sync-github-org-settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Sync Org Settings

on:
push:
branches: ['main']
pull_request:
branches: ['main']
workflow_dispatch:
inputs:
dry-run:
description: 'Dry run (preview changes without applying)'
type: boolean
default: true

jobs:
sync:
name: Sync Organization Settings
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
permissions:
contents: read

steps:
- uses: actions/checkout@v6

- name: install prettier
run: npm install -g prettier

- name: run prettier
run: npx prettier --check .

- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: joshjohanning-org

- name: Sync Organization Settings
uses: joshjohanning/bulk-github-org-settings-sync-action@v1
with:
github-token: ${{ steps.app-token.outputs.token }}
organizations-file: './orgs.yml'
dry-run: ${{ github.event_name == 'pull_request' || inputs.dry-run == true }}
72 changes: 0 additions & 72 deletions .github/workflows/sync.yml

This file was deleted.

5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# OS generated files
.DS_Store

# js
node_modules
3 changes: 3 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ignore-scripts=true
allow-git=none
min-release-age=3
13 changes: 13 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "none",
"bracketSpacing": true,
"bracketSameLine": true,
"arrowParens": "avoid",
"endOfLine": "lf"
}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Josh Johanning

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
34 changes: 10 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
# bulk-github-org-settings-sync
# sync-github-org-settings

Manages GitHub organization settings for `joshjohanning-org` using [bulk-github-org-settings-sync-action](https://github.com/joshjohanning/bulk-github-org-settings-sync-action).
🔄 Syncs configuration across a set of organizations using the [bulk-github-org-settings-sync-action](https://github.com/joshjohanning/bulk-github-org-settings-sync-action) 🚀

## What's synced
## How It Works

| Feature | Config |
|---|---|
| Member privileges | Inline in workflow |
| Org profile | Inline in workflow |
| Actions policy | `config/actions-allow-list.yml` |
| Custom repo roles | `config/custom-repo-roles.yml` |
A GitHub Actions workflow runs the sync action, which reads [`orgs.yml`](orgs.yml) and pushes the referenced config files to each listed repository. This keeps org settings in sync and consistent across orgs without manual updates.

## Setup
Each entry in `orgs.yml` maps a organization to its settings and configuration. Adding a new org or changing a shared config is a single PR in this repo.

The workflow uses a GitHub App for auth. Set these repo-level values:
## Folder Structure

| Name | Type | Value |
|---|---|---|
| `APP_CLIENT_ID` | Variable | App client ID (`Iv1.xxx`) |
| `APP_PRIVATE_KEY` | Secret | App private key (PEM) |

## Running

The workflow runs automatically:
- **On push** to `main` (e.g., when you update config files)
- **Weekly** on Monday at 2am UTC
- **Manually** via `workflow_dispatch` (with optional dry-run toggle)

To preview changes without applying, use the manual trigger with **Dry run** enabled.
```text
orgs.yml # List of orgs to sync
config/ # Configuration files used by the sync (contents may vary)
```
64 changes: 64 additions & 0 deletions config/custom-properties.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
- name: app_ci
value-type: string
required: true
default-value: 'abc'
values-editable-by: org_actors

- name: App_name
value-type: single_select
required: true
default-value: 'b'
allowed-values:
- b
- a
values-editable-by: org_actors

- name: business-unit
value-type: string
required: true
default-value: 'abc'
values-editable-by: org_and_repo_actors

- name: group-name
value-type: single_select
required: false
allowed-values:
- ccs
- abc
values-editable-by: org_and_repo_actors

- name: project
value-type: multi_select
required: false
allowed-values:
- finance
- accounting
- legal
- app dev
values-editable-by: org_actors

- name: repo_type
value-type: single_select
required: false
allowed-values:
- scripts
- testing
- demo
values-editable-by: org_and_repo_actors

- name: RepoType
value-type: single_select
required: false
allowed-values:
- IssueOps
- Actions
- Other
values-editable-by: org_and_repo_actors

- name: test-174-selector
value-type: single_select
required: false
allowed-values:
- include
- exclude
values-editable-by: org_actors
3 changes: 0 additions & 3 deletions config/custom-repo-roles.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Custom repository roles for joshjohanning-org
# Sourced from existing roles via API on initial setup

- name: Security Engineers
description: ''
base-role: maintain
Expand Down
2 changes: 0 additions & 2 deletions config/orgs.yml

This file was deleted.

35 changes: 35 additions & 0 deletions orgs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
orgs:
- org: joshjohanning-org
custom-properties-file: './config/custom-properties.yml'
custom-repo-roles-file: './config/custom-repo-roles.yml'
actions-allow-list-file: './config/actions-allow-list.yml'
actions-policy:
allowed-actions: selected
github-owned-allowed: true
verified-allowed: true
default-workflow-permissions: read
actions-can-approve-pull-request-reviews: false
org-profile:
org-description: "@joshjohanning's samples"
org-location: 'United States of America'
org-blog: 'https://josh-ops.com'
member-privileges:
default-repository-permission: none
members-can-create-repositories: false
members-can-create-public-repositories: false
members-can-create-private-repositories: false
members-can-fork-private-repositories: true
web-commit-signoff-required: false
members-can-create-pages: true
members-can-create-public-pages: true
members-can-create-private-pages: true
members-can-invite-outside-collaborators: true
members-can-create-teams: true
members-can-delete-repositories: true
members-can-change-repo-visibility: true
members-can-delete-issues: true
default-repository-branch: main
deploy-keys-enabled-for-repositories: true
readers-can-create-discussions: true
members-can-view-dependency-insights: true
display-commenter-full-name-setting-enabled: true