From f2932741bdd5969f41f0b2566aad821e0de52969 Mon Sep 17 00:00:00 2001 From: Bret Mogilefsky Date: Wed, 8 Jul 2026 00:01:11 -0700 Subject: [PATCH 1/3] feat: add workflow to distribute shared/ files across org repos - New shared/ directory with org-wide files: CODE_OF_CONDUCT.md, CONTRIBUTING.md, LICENSE.md, and ISSUE_TEMPLATE/config.yml - distribute-shared.yml workflow (workflow_dispatch only, pushes to main) - Fix --destination . bug in propagate-files.sh (rm -rf . would delete the entire cloned checkout) --- .github/workflows/distribute-shared.yml | 37 +++++++ PLAN-distribute-files.md | 134 +++++++++++++++++++++++ scripts/propagate-files.sh | 8 +- shared/.github/ISSUE_TEMPLATE/config.yml | 8 ++ shared/CODE_OF_CONDUCT.md | 63 +++++++++++ shared/CONTRIBUTING.md | 47 ++++++++ shared/LICENSE.md | 21 ++++ 7 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/distribute-shared.yml create mode 100644 PLAN-distribute-files.md create mode 100644 shared/.github/ISSUE_TEMPLATE/config.yml create mode 100644 shared/CODE_OF_CONDUCT.md create mode 100644 shared/CONTRIBUTING.md create mode 100644 shared/LICENSE.md diff --git a/.github/workflows/distribute-shared.yml b/.github/workflows/distribute-shared.yml new file mode 100644 index 0000000..63c4147 --- /dev/null +++ b/.github/workflows/distribute-shared.yml @@ -0,0 +1,37 @@ +name: Distribute shared files + +on: + workflow_dispatch: + inputs: + repo_name: + description: "Single repo to target (empty = all)" + required: false + +jobs: + distribute: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout .github + uses: actions/checkout@v7 + + - name: Propagate shared/ to all org repos + env: + GH_TOKEN: ${{ secrets.PROPAGATION_TOKEN }} + ORG: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.inputs.repo_name }} + run: | + if [ -n "$REPO_NAME" ]; then + bash scripts/propagate-files.sh \ + --source shared/ \ + --destination . \ + --repo "$REPO_NAME" \ + --message "Sync shared files from .github" + else + bash scripts/propagate-files.sh \ + --source shared/ \ + --destination . \ + --all \ + --message "Sync shared files from .github" + fi diff --git a/PLAN-distribute-files.md b/PLAN-distribute-files.md new file mode 100644 index 0000000..7d92068 --- /dev/null +++ b/PLAN-distribute-files.md @@ -0,0 +1,134 @@ +# Plan: Distribute a Directory of Files Across Org Repos + +## Goal + +A `workflow_dispatch`-only workflow in `got-feedback/.github` that copies files from `shared/` into every org repo including `.github` itself — pushes direct to `main`, no PRs. + +## What exists today (recent changes to reconcile) + +Since the first draft of this plan, two things landed in `.github`: + +- **`.github/workflows/reusable-ci.yml`** — a reusable CI workflow that other repos call via `workflow_call`. It lives at `.github/workflows/` only to be referenceable by path from other repos. It should **not** be in `shared/` — it's not a file to copy, it's a service to call. +- **`.github/ISSUE_TEMPLATE/config.yml`** — redirects issue submitters to the central `feedback` repo. This **is** a candidate for `shared/` so every repo gets the same redirect. + +## Proposed `shared/` contents + +``` +shared/ +├── .github/ +│ └── ISSUE_TEMPLATE/ +│ └── config.yml ← redirect all issues to central feedback repo +├── CODE_OF_CONDUCT.md ← org-wide code of conduct +├── CONTRIBUTING.md ← org-wide contributing guide +└── LICENSE.md ← MIT license (if all repos share it) +``` + +Files that are **not** candidates for `shared/`: + +| File/dir | Reason | +|----------|--------| +| `profile/` | Org profile page — only `.github` can serve it | +| `scripts/`, `runbooks/`, `docs/` | Org admin tooling — doesn't belong in every repo | +| `.github/workflows/reusable-ci.yml` | Called by reference, never copied | +| `.github/workflows/propagate-rulesets.yml` | Admin workflow, not useful in other repos | + +### Reconciliation question — `docs/` files + +The `.github` repo has `docs/branching.md`, `docs/pipeline.md`, `docs/guidelines.md`, `docs/plugins.md`, and `docs/github-setup.md`. These describe the org's development process. Every repo's contributors need this context. You have two options: + +| Option | Pro | Con | +|--------|-----|-----| +| **A: Keep docs only in `.github`** | Single source of truth; everyone knows to go there | Contributors may not find them | +| **B: Put docs in `shared/` → auto-distribute** | Every repo has a local copy | Stale copies if a repo gets out of sync (auto-propagation fixes this, but only on manual dispatch); contributors might edit the local copy instead of the source | + +I'd suggest Option A for now — `.github` is GitHub's well-known convention for this purpose. If contributors aren't finding the docs, you can always add them to `shared/` later. + +## Pre-requisite: fix `propagate-files.sh` for `--destination .` + +The script has a bug when `--destination .` is used (which is what we want: copy `shared/` into the repo root): + +```bash +# Current (buggy) — rm -rf would delete the entire cloned checkout: +rm -rf "${TARGET:?}/$DEST" + +# Fix — handle "." as a special case, copy items individually: +if [ "$DEST" = "." ]; then + for item in "$ROOT/$SOURCE"/* "$ROOT/$SOURCE"/.[!.]*; do + [ -e "$item" ] || continue + cp -r "$item" "$TARGET/" + done +elif [ -d "$ROOT/$SOURCE" ]; then + rm -rf "${TARGET:?}/$DEST" + cp -r "$ROOT/$SOURCE" "$TARGET/$DEST" +else + cp "$ROOT/$SOURCE" "$TARGET/$DEST" +fi +``` + +This fix needs to land before the workflow runs. + +## Workflow + +`.github/workflows/distribute-shared.yml`: + +```yaml +name: Distribute shared files + +on: + workflow_dispatch: + inputs: + repo_name: + description: "Single repo to target (empty = all)" + required: false + +jobs: + distribute: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout .github + uses: actions/checkout@v4 + + - name: Propagate shared/ to all org repos + env: + GH_TOKEN: ${{ secrets.PROPAGATION_TOKEN }} + ORG: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.inputs.repo_name }} + run: | + if [ -n "$REPO_NAME" ]; then + bash scripts/propagate-files.sh \ + --source shared/ \ + --destination . \ + --repo "$REPO_NAME" \ + --message "Sync shared files from .github" + else + bash scripts/propagate-files.sh \ + --source shared/ \ + --destination . \ + --all \ + --message "Sync shared files from .github" + fi +``` + +Key differences from the previous draft: + +| Before | Now | Why | +|--------|-----|-----| +| `push` + `workflow_dispatch` | `workflow_dispatch` only | You want a manual gate | +| `--exclude .github` | no exclude | You want `.github` to receive its own shared files | +| `--exclude community-code-review` | not shown (add if desired) | Can be added per your preference | + +## Execution order + +1. Fix the `--destination .` bug in `scripts/propagate-files.sh` +2. Create `shared/` with the initial files (see proposed contents above) +3. Create `.github/workflows/distribute-shared.yml` with the workflow YAML +4. Test: run the workflow with `repo_name: community-code-review` (smallest target first) +5. Run with `repo_name: feedBack` (one real repo) +6. Run targeting all repos +7. Verify each target repo received the expected files + +## Open question — Node 20 deprecation + +The workflow YAML above uses `actions/checkout@v4` (current), which triggers a Node 20 deprecation warning. You can bump it to `v7` the same way we did in the other repos, or leave it as-is since it still works — just noisy. diff --git a/scripts/propagate-files.sh b/scripts/propagate-files.sh index 4a37f37..3972ad3 100644 --- a/scripts/propagate-files.sh +++ b/scripts/propagate-files.sh @@ -93,7 +93,13 @@ for repo in "${REPOS[@]}"; do mkdir -p "$(dirname "$TARGET/$DEST")" # Copy — support both file and directory sources - if [ -d "$ROOT/$SOURCE" ]; then + if [ "$DEST" = "." ]; then + # Destination is the repo root — copy items individually to avoid rm -rf . + for item in "$ROOT/$SOURCE"/* "$ROOT/$SOURCE"/.[!.]*; do + [ -e "$item" ] || continue + cp -r "$item" "$TARGET/" + done + elif [ -d "$ROOT/$SOURCE" ]; then rm -rf "${TARGET:?}/$DEST" cp -r "$ROOT/$SOURCE" "$TARGET/$DEST" else diff --git a/shared/.github/ISSUE_TEMPLATE/config.yml b/shared/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..2300392 --- /dev/null +++ b/shared/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: 📢 Report an Issue / Submit Feedback / Request a Feature + url: https://github.com/got-feedback/feedback/issues/new/choose + about: Please submit all issues, feature requests, and bug reports in our central repository. + - name: 💬 Come chat with our boisterous and helpful community and devs + url: https://discord.gg/TzPVK8fNBm + about: Over 2000 people are chatting in Discord and you could be next diff --git a/shared/CODE_OF_CONDUCT.md b/shared/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e07a0fb --- /dev/null +++ b/shared/CODE_OF_CONDUCT.md @@ -0,0 +1,63 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. All complaints +will be reviewed and investigated promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +[homepage]: https://www.contributor-covenant.org diff --git a/shared/CONTRIBUTING.md b/shared/CONTRIBUTING.md new file mode 100644 index 0000000..dabf58c --- /dev/null +++ b/shared/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Contributing + +Thanks for wanting to contribute! This org uses a release-centric workflow. +Start here for the basics; each repo may have additional project-specific +guides. + +## Getting started + +1. Find the right repo — most issues belong in `got-feedback/feedback`. + Plugin-specific issues go in the plugin's repo. +2. Read the org's development docs at `got-feedback/.github`: + - [Branching model](https://github.com/got-feedback/.github/blob/main/docs/branching.md) + - [CI/CD pipeline](https://github.com/got-feedback/.github/blob/main/docs/pipeline.md) + - [Daily workflow and commit rules](https://github.com/got-feedback/.github/blob/main/docs/guidelines.md) +3. Check the target repo's own `CONTRIBUTING.md` for license terms, DCO + requirements, and project-specific setup. + +## Developer Certificate of Origin + +We use the [Developer Certificate of Origin](https://developercertificate.org/) +(DCO) to track contribution provenance. Every commit must be signed off: + +```bash +git commit -s -m "your commit message" +``` + +This appends a line like: + +``` +Signed-off-by: Jane Developer +``` + +If you forget to sign off, amend the most recent commit with +`git commit --amend -s` and force-push to your PR branch. + +## PR workflow + +- Never push directly to `main`. +- Create a feature branch on your fork. +- Open a PR against the target repo's `main` branch. +- Keep commits scoped and well-described; short imperative subject line, + blank line, then body explaining *why*. + +## Questions + +Open an issue or start a Discussion in the relevant repo if you're unsure +whether a contribution fits. diff --git a/shared/LICENSE.md b/shared/LICENSE.md new file mode 100644 index 0000000..8436350 --- /dev/null +++ b/shared/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 got-feedback + +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. From fe947b38488dc57502b5895bc65cb68d684c6179 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 07:20:49 +0000 Subject: [PATCH 2/3] fix: apply CodeRabbit auto-fixes Fixed 2 file(s) based on 3 unresolved review comments. Co-authored-by: CodeRabbit --- PLAN-distribute-files.md | 2 +- shared/CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PLAN-distribute-files.md b/PLAN-distribute-files.md index 7d92068..7f1eb30 100644 --- a/PLAN-distribute-files.md +++ b/PLAN-distribute-files.md @@ -13,7 +13,7 @@ Since the first draft of this plan, two things landed in `.github`: ## Proposed `shared/` contents -``` +```text shared/ ├── .github/ │ └── ISSUE_TEMPLATE/ diff --git a/shared/CONTRIBUTING.md b/shared/CONTRIBUTING.md index dabf58c..586c058 100644 --- a/shared/CONTRIBUTING.md +++ b/shared/CONTRIBUTING.md @@ -26,7 +26,7 @@ git commit -s -m "your commit message" This appends a line like: -``` +```text Signed-off-by: Jane Developer ``` From 2a1ce9058fb6b5f45a12715cee56dd423a223eef Mon Sep 17 00:00:00 2001 From: Bret Mogilefsky Date: Wed, 8 Jul 2026 00:22:50 -0700 Subject: [PATCH 3/3] Don't persist credentials after checkout action --- .github/workflows/distribute-shared.yml | 3 +- PLAN-distribute-files.md | 134 ------------------------ 2 files changed, 2 insertions(+), 135 deletions(-) delete mode 100644 PLAN-distribute-files.md diff --git a/.github/workflows/distribute-shared.yml b/.github/workflows/distribute-shared.yml index 63c4147..d0a63d9 100644 --- a/.github/workflows/distribute-shared.yml +++ b/.github/workflows/distribute-shared.yml @@ -15,7 +15,8 @@ jobs: steps: - name: Checkout .github uses: actions/checkout@v7 - + with: + persist-credentials: false - name: Propagate shared/ to all org repos env: GH_TOKEN: ${{ secrets.PROPAGATION_TOKEN }} diff --git a/PLAN-distribute-files.md b/PLAN-distribute-files.md deleted file mode 100644 index 7f1eb30..0000000 --- a/PLAN-distribute-files.md +++ /dev/null @@ -1,134 +0,0 @@ -# Plan: Distribute a Directory of Files Across Org Repos - -## Goal - -A `workflow_dispatch`-only workflow in `got-feedback/.github` that copies files from `shared/` into every org repo including `.github` itself — pushes direct to `main`, no PRs. - -## What exists today (recent changes to reconcile) - -Since the first draft of this plan, two things landed in `.github`: - -- **`.github/workflows/reusable-ci.yml`** — a reusable CI workflow that other repos call via `workflow_call`. It lives at `.github/workflows/` only to be referenceable by path from other repos. It should **not** be in `shared/` — it's not a file to copy, it's a service to call. -- **`.github/ISSUE_TEMPLATE/config.yml`** — redirects issue submitters to the central `feedback` repo. This **is** a candidate for `shared/` so every repo gets the same redirect. - -## Proposed `shared/` contents - -```text -shared/ -├── .github/ -│ └── ISSUE_TEMPLATE/ -│ └── config.yml ← redirect all issues to central feedback repo -├── CODE_OF_CONDUCT.md ← org-wide code of conduct -├── CONTRIBUTING.md ← org-wide contributing guide -└── LICENSE.md ← MIT license (if all repos share it) -``` - -Files that are **not** candidates for `shared/`: - -| File/dir | Reason | -|----------|--------| -| `profile/` | Org profile page — only `.github` can serve it | -| `scripts/`, `runbooks/`, `docs/` | Org admin tooling — doesn't belong in every repo | -| `.github/workflows/reusable-ci.yml` | Called by reference, never copied | -| `.github/workflows/propagate-rulesets.yml` | Admin workflow, not useful in other repos | - -### Reconciliation question — `docs/` files - -The `.github` repo has `docs/branching.md`, `docs/pipeline.md`, `docs/guidelines.md`, `docs/plugins.md`, and `docs/github-setup.md`. These describe the org's development process. Every repo's contributors need this context. You have two options: - -| Option | Pro | Con | -|--------|-----|-----| -| **A: Keep docs only in `.github`** | Single source of truth; everyone knows to go there | Contributors may not find them | -| **B: Put docs in `shared/` → auto-distribute** | Every repo has a local copy | Stale copies if a repo gets out of sync (auto-propagation fixes this, but only on manual dispatch); contributors might edit the local copy instead of the source | - -I'd suggest Option A for now — `.github` is GitHub's well-known convention for this purpose. If contributors aren't finding the docs, you can always add them to `shared/` later. - -## Pre-requisite: fix `propagate-files.sh` for `--destination .` - -The script has a bug when `--destination .` is used (which is what we want: copy `shared/` into the repo root): - -```bash -# Current (buggy) — rm -rf would delete the entire cloned checkout: -rm -rf "${TARGET:?}/$DEST" - -# Fix — handle "." as a special case, copy items individually: -if [ "$DEST" = "." ]; then - for item in "$ROOT/$SOURCE"/* "$ROOT/$SOURCE"/.[!.]*; do - [ -e "$item" ] || continue - cp -r "$item" "$TARGET/" - done -elif [ -d "$ROOT/$SOURCE" ]; then - rm -rf "${TARGET:?}/$DEST" - cp -r "$ROOT/$SOURCE" "$TARGET/$DEST" -else - cp "$ROOT/$SOURCE" "$TARGET/$DEST" -fi -``` - -This fix needs to land before the workflow runs. - -## Workflow - -`.github/workflows/distribute-shared.yml`: - -```yaml -name: Distribute shared files - -on: - workflow_dispatch: - inputs: - repo_name: - description: "Single repo to target (empty = all)" - required: false - -jobs: - distribute: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout .github - uses: actions/checkout@v4 - - - name: Propagate shared/ to all org repos - env: - GH_TOKEN: ${{ secrets.PROPAGATION_TOKEN }} - ORG: ${{ github.repository_owner }} - REPO_NAME: ${{ github.event.inputs.repo_name }} - run: | - if [ -n "$REPO_NAME" ]; then - bash scripts/propagate-files.sh \ - --source shared/ \ - --destination . \ - --repo "$REPO_NAME" \ - --message "Sync shared files from .github" - else - bash scripts/propagate-files.sh \ - --source shared/ \ - --destination . \ - --all \ - --message "Sync shared files from .github" - fi -``` - -Key differences from the previous draft: - -| Before | Now | Why | -|--------|-----|-----| -| `push` + `workflow_dispatch` | `workflow_dispatch` only | You want a manual gate | -| `--exclude .github` | no exclude | You want `.github` to receive its own shared files | -| `--exclude community-code-review` | not shown (add if desired) | Can be added per your preference | - -## Execution order - -1. Fix the `--destination .` bug in `scripts/propagate-files.sh` -2. Create `shared/` with the initial files (see proposed contents above) -3. Create `.github/workflows/distribute-shared.yml` with the workflow YAML -4. Test: run the workflow with `repo_name: community-code-review` (smallest target first) -5. Run with `repo_name: feedBack` (one real repo) -6. Run targeting all repos -7. Verify each target repo received the expected files - -## Open question — Node 20 deprecation - -The workflow YAML above uses `actions/checkout@v4` (current), which triggers a Node 20 deprecation warning. You can bump it to `v7` the same way we did in the other repos, or leave it as-is since it still works — just noisy.