diff --git a/.github/workflows/sync-github-org-settings.yml b/.github/workflows/sync-github-org-settings.yml new file mode 100644 index 0000000..44e45f4 --- /dev/null +++ b/.github/workflows/sync-github-org-settings.yml @@ -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 }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml deleted file mode 100644 index 99e9efd..0000000 --- a/.github/workflows/sync.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Sync Org Settings - -on: - pull_request: - branches: - - main - push: - branches: - - main - schedule: - - cron: '0 2 * * 1' # Weekly, Monday at 2am UTC - 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 - permissions: - contents: read - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - 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: './config/orgs.yml' - custom-repo-roles-file: './config/custom-repo-roles.yml' - actions-policy-allowed-actions: selected - actions-policy-github-owned-allowed: true - actions-policy-verified-allowed: true - actions-allow-list-file: './config/actions-allow-list.yml' - actions-policy-default-workflow-permissions: read - actions-policy-actions-can-approve-pull-request-reviews: false - org-description: "@joshjohanning's samples" - org-location: 'United States of America' - org-blog: 'https://josh-ops.com' - 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 - dry-run: ${{ github.event_name == 'pull_request' || inputs.dry-run == true }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4458d8e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# OS generated files +.DS_Store + +# js +node_modules diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..573f360 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +ignore-scripts=true +allow-git=none +min-release-age=3 diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..c087c23 --- /dev/null +++ b/.prettierrc.json @@ -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" +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2c8158e --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 7e79e7f..91b10f4 100644 --- a/README.md +++ b/README.md @@ -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) +``` diff --git a/config/custom-properties.yml b/config/custom-properties.yml new file mode 100644 index 0000000..7d05d42 --- /dev/null +++ b/config/custom-properties.yml @@ -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 diff --git a/config/custom-repo-roles.yml b/config/custom-repo-roles.yml index 8f83636..176c934 100644 --- a/config/custom-repo-roles.yml +++ b/config/custom-repo-roles.yml @@ -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 diff --git a/config/orgs.yml b/config/orgs.yml deleted file mode 100644 index 9b5ac4c..0000000 --- a/config/orgs.yml +++ /dev/null @@ -1,2 +0,0 @@ -orgs: - - org: joshjohanning-org diff --git a/orgs.yml b/orgs.yml new file mode 100644 index 0000000..7313187 --- /dev/null +++ b/orgs.yml @@ -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