Skip to content

[WIP] Ensure updates are pushing to other orgs and repos#5

Open
Copilot wants to merge 17 commits intomainfrom
copilot/test-update-push-to-orgs
Open

[WIP] Ensure updates are pushing to other orgs and repos#5
Copilot wants to merge 17 commits intomainfrom
copilot/test-update-push-to-orgs

Conversation

Copy link

Copilot AI commented Jan 27, 2026

Implementation Plan: Test & Ensure Updates Push to Orgs

Understanding

This repository (.github) is a central coordination hub for 15 BlackRoad organizations. The implementation adds:

  1. Mechanism to push updates TO other org repositories
  2. Tests to validate sync functionality
  3. Automated PR merge to main

Implementation Checklist

  • Create workflow to sync .github files to other orgs
    • Add sync-to-orgs.yml workflow that pushes workflow templates
    • Configure to run on push to main
    • Add manual dispatch for testing
    • Support dry-run mode for testing
    • Improve error handling and reporting
    • Support cross-org dispatches with DISPATCH_TOKEN
  • Add comprehensive tests for sync functionality
    • Create test script to verify sync workflow
    • Add tests for registry validation
    • Add tests for dispatch payload format
    • Add tests for workflow triggers
    • Add integration test for end-to-end flow
  • Add automated PR merge workflow
    • Create auto-merge.yml for approved PRs
    • Add status checks requirement
    • Configure to merge to main after CI passes
    • Add PR commenting on auto-merge
    • Remove overly broad triggers (check_suite, status)
    • Improve error handling when PR not found
  • Update CI workflow to test sync functionality
    • Add sync validation step
    • Integrate test_sync.py into CI pipeline
    • Update summary job to include sync results
  • Add documentation
    • Create comprehensive SYNC.md guide
    • Update README.md with sync information
    • Add workflow templates for target repos
    • Add security notes about DISPATCH_TOKEN
    • Add warnings about direct commits and permissions
  • Validate implementation
    • Run tests locally (all pass ✅)
    • Verify workflow YAML is valid (all valid ✅)
    • Check all files are committed (✅)
  • Request code review (✅)
  • Address review feedback (✅)
  • Run security scan
Original prompt

lets actually be testing and ensuring that updates here are actually pushing to the other orgs and repos and once you submit the pull request ensure it hits main


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
PR_NUMBER="${{ github.event.pull_request.number }}"
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ github.event.workflow_run.head_branch }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI about 1 hour ago

In general, to fix this type of problem in GitHub Actions, you should avoid using ${{ ... }} expressions with untrusted values directly inside run: scripts. Instead, pass the value into the step via env: and then consume it using the shell’s variable expansion syntax (e.g., $HEAD_BRANCH) or via process.env in JavaScript. This ensures that the shell does not reinterpret the value as code, regardless of its contents.

For this specific workflow, the risky part is line 41:

PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)

The best fix that preserves existing functionality is:

  1. Add an environment variable (e.g., HEAD_BRANCH) to this step, assigned from ${{ github.event.workflow_run.head_branch }}.
  2. Update the run: script to reference $HEAD_BRANCH inside the jq filter, using shell variable expansion, while preserving the required quoting so that jq receives the correct string and the branch name is not interpreted as code.

Concretely:

  • Extend the env: block in the “Get PR info” step with HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}.
  • Change the PR_NUMBER assignment to use $HEAD_BRANCH instead of an inlined ${{ ... }}. Because the script is single-quoted with an internal double-quoted jq string, the safest approach is to break out of single quotes just around the $HEAD_BRANCH reference: first build the jq filter in a shell variable using proper quoting, then pass that variable to gh pr list --jq.

All changes are within .github/workflows/auto-merge.yml, in the shown step.

Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -32,13 +32,15 @@
         id: pr
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
         run: |
           # Get PR number from the event
           if [ "${{ github.event_name }}" == "pull_request_review" ]; then
             PR_NUMBER="${{ github.event.pull_request.number }}"
           elif [ "${{ github.event_name }}" == "workflow_run" ]; then
             # Extract PR number from workflow run
-            PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
+            JQ_FILTER=".[] | select(.headRefName==\"$HEAD_BRANCH\") | .number"
+            PR_NUMBER=$(gh pr list --json number,headRefName --jq "$JQ_FILTER" | head -1)
           else
             echo "No PR found for event type: ${{ github.event_name }}"
             exit 1
EOF
@@ -32,13 +32,15 @@
id: pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
run: |
# Get PR number from the event
if [ "${{ github.event_name }}" == "pull_request_review" ]; then
PR_NUMBER="${{ github.event.pull_request.number }}"
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
JQ_FILTER=".[] | select(.headRefName==\"$HEAD_BRANCH\") | .number"
PR_NUMBER=$(gh pr list --json number,headRefName --jq "$JQ_FILTER" | head -1)
else
echo "No PR found for event type: ${{ github.event_name }}"
exit 1
Copilot is powered by AI and may make mistakes. Always verify output.
- name: Check merge conditions
id: check
run: |
STATE="${{ steps.pr.outputs.state }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI about 1 hour ago

To fix this, we should stop using GitHub expression syntax (${{ ... }}) directly inside the shell script body for values that originate from workflow inputs/outputs. Instead, we should bind those values to environment variables at the step level (env:) and then reference them using standard shell variable expansion (e.g., $STATE) inside the script. This aligns with GitHub’s guidance and breaks the taint flow into the shell command parser.

Concretely, for the “Check merge conditions” step (lines 67–87), we will:

  • Add an env: section that maps STATE, MERGEABLE, and REVIEW_DECISION to ${{ steps.pr.outputs.state }}, ${{ steps.pr.outputs.mergeable }}, and ${{ steps.pr.outputs.review_decision }} respectively.
  • Simplify the run: script so it relies solely on $STATE, $MERGEABLE, and $REVIEW_DECISION, removing the inline ${{ ... }} assignments in the script body.

No other steps need modification to address this particular alert, and this change preserves existing behavior: the variables in the script will contain exactly the same values as before, but are populated in a safer way by the runner rather than the shell parsing interpolated expressions.


Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -66,11 +66,11 @@
 
       - name: Check merge conditions
         id: check
+        env:
+          STATE: ${{ steps.pr.outputs.state }}
+          MERGEABLE: ${{ steps.pr.outputs.mergeable }}
+          REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
         run: |
-          STATE="${{ steps.pr.outputs.state }}"
-          MERGEABLE="${{ steps.pr.outputs.mergeable }}"
-          REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
-          
           echo "PR State: $STATE"
           echo "Mergeable: $MERGEABLE"
           echo "Review Decision: $REVIEW_DECISION"
EOF
@@ -66,11 +66,11 @@

- name: Check merge conditions
id: check
env:
STATE: ${{ steps.pr.outputs.state }}
MERGEABLE: ${{ steps.pr.outputs.mergeable }}
REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

echo "PR State: $STATE"
echo "Mergeable: $MERGEABLE"
echo "Review Decision: $REVIEW_DECISION"
Copilot is powered by AI and may make mistakes. Always verify output.
id: check
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.mergeable }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.mergeable }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI about 1 hour ago

In general, to fix this class of problems in GitHub Actions, any untrusted or potentially untrusted data that needs to be used in a shell script should be assigned to an environment variable at the workflow level (using ${{ ... }} only in the env: mapping), and then referenced inside the script using the shell’s own variable syntax ($VAR), not ${{ env.VAR }} or similar expression syntax.

For this workflow, the problematic use is in the “Check merge conditions” step, where the script begins with:

run: |
  STATE="${{ steps.pr.outputs.state }}"
  MERGEABLE="${{ steps.pr.outputs.mergeable }}"
  REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

The safest fix, without altering behavior, is:

  1. Add an env: section to that step, mapping:
    • STATE: ${{ steps.pr.outputs.state }}
    • MERGEABLE: ${{ steps.pr.outputs.mergeable }}
    • REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
  2. Remove the three assignment lines inside the run: block and instead rely on those environment variables directly ($STATE, $MERGEABLE, $REVIEW_DECISION) everywhere in the script, which is already the case for subsequent references.

This keeps functionality identical (the variables have the same names and contents) while complying with the recommended pattern: untrusted values are injected only into environment variables via expressions, and the shell script reads them with native syntax. No additional imports or external dependencies are required, and no other steps need to change.

Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -66,11 +66,11 @@
 
       - name: Check merge conditions
         id: check
+        env:
+          STATE: ${{ steps.pr.outputs.state }}
+          MERGEABLE: ${{ steps.pr.outputs.mergeable }}
+          REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
         run: |
-          STATE="${{ steps.pr.outputs.state }}"
-          MERGEABLE="${{ steps.pr.outputs.mergeable }}"
-          REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
-          
           echo "PR State: $STATE"
           echo "Mergeable: $MERGEABLE"
           echo "Review Decision: $REVIEW_DECISION"
EOF
@@ -66,11 +66,11 @@

- name: Check merge conditions
id: check
env:
STATE: ${{ steps.pr.outputs.state }}
MERGEABLE: ${{ steps.pr.outputs.mergeable }}
REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

echo "PR State: $STATE"
echo "Mergeable: $MERGEABLE"
echo "Review Decision: $REVIEW_DECISION"
Copilot is powered by AI and may make mistakes. Always verify output.
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.review_decision }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.review_decision }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI about 1 hour ago

General approach: Avoid using ${{ steps.pr.outputs.review_decision }} directly inside the run: script. Instead, pass the value into the step via env: and use standard shell variable expansion ($REVIEW_DECISION) within the script. This aligns with the recommended pattern of copying untrusted expressions into environment variables and only using native shell syntax in the command body.

Concrete fix for this workflow:

  • In the Check merge conditions step (lines 67–96), add an env: section that maps a new environment variable (e.g., STATE, MERGEABLE, REVIEW_DECISION) from the step outputs:
    REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}.

  • In the run: script of that same step, stop reassigning these variables using ${{ ... }}. Instead, rely on the environment variables already populated by env:. So remove or simplify the lines:

    STATE="${{ steps.pr.outputs.state }}"
    MERGEABLE="${{ steps.pr.outputs.mergeable }}"
    REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

    and use $STATE, $MERGEABLE, and $REVIEW_DECISION directly.

  • No other steps need to change, because the CodeQL alert is specific to ${{ steps.pr.outputs.review_decision }} at line 72.

This preserves behavior (the logic still checks the same values) while ensuring no GitHub Actions expressions are present inside the actual shell script body.


Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -66,11 +66,11 @@
 
       - name: Check merge conditions
         id: check
+        env:
+          STATE: ${{ steps.pr.outputs.state }}
+          MERGEABLE: ${{ steps.pr.outputs.mergeable }}
+          REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
         run: |
-          STATE="${{ steps.pr.outputs.state }}"
-          MERGEABLE="${{ steps.pr.outputs.mergeable }}"
-          REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
-          
           echo "PR State: $STATE"
           echo "Mergeable: $MERGEABLE"
           echo "Review Decision: $REVIEW_DECISION"
EOF
@@ -66,11 +66,11 @@

- name: Check merge conditions
id: check
env:
STATE: ${{ steps.pr.outputs.state }}
MERGEABLE: ${{ steps.pr.outputs.mergeable }}
REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

echo "PR State: $STATE"
echo "Mergeable: $MERGEABLE"
echo "Review Decision: $REVIEW_DECISION"
Copilot is powered by AI and may make mistakes. Always verify output.
echo "🎯 Auto-merge Summary"
echo ""
echo "PR: #${{ steps.pr.outputs.pr_number }}"
echo "State: ${{ steps.pr.outputs.state }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI about 1 hour ago

General fix approach: avoid using ${{ ... }} directly inside shell scripts for values derived from external data. Instead, assign those expression values to environment variables in the step configuration (env:) and then reference them in the script using the shell’s native $VAR syntax.

Best concrete fix here: in the Summary step, move all ${{ steps.* }} and ${{ job.status }} references out of the run: body into env: variables, then reference them with $VAR inside the script. This removes the vulnerable pattern and also addresses any related variants (not only state but pr_number, can_merge, job.status) in one place.

Specifically, in .github/workflows/auto-merge.yml:

  • For the Summary step (lines 124–132), add an env: section with variables like SUMMARY_PR_NUMBER, SUMMARY_STATE, SUMMARY_CAN_MERGE, and SUMMARY_JOB_STATUS, each assigned from the corresponding ${{ ... }} expression.
  • Update the run: block to echo using $SUMMARY_PR_NUMBER, $SUMMARY_STATE, $SUMMARY_CAN_MERGE, and $SUMMARY_JOB_STATUS instead of interpolated expressions.
    No new methods or imports are required; this is purely a YAML/workflow configuration change.
Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -123,10 +123,15 @@
 
       - name: Summary
         if: always()
+        env:
+          SUMMARY_PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
+          SUMMARY_STATE: ${{ steps.pr.outputs.state }}
+          SUMMARY_CAN_MERGE: ${{ steps.check.outputs.can_merge }}
+          SUMMARY_JOB_STATUS: ${{ job.status }}
         run: |
           echo "🎯 Auto-merge Summary"
           echo ""
-          echo "PR: #${{ steps.pr.outputs.pr_number }}"
-          echo "State: ${{ steps.pr.outputs.state }}"
-          echo "Can merge: ${{ steps.check.outputs.can_merge }}"
-          echo "Status: ${{ job.status }}"
+          echo "PR: #$SUMMARY_PR_NUMBER"
+          echo "State: $SUMMARY_STATE"
+          echo "Can merge: $SUMMARY_CAN_MERGE"
+          echo "Status: $SUMMARY_JOB_STATUS"
EOF
@@ -123,10 +123,15 @@

- name: Summary
if: always()
env:
SUMMARY_PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
SUMMARY_STATE: ${{ steps.pr.outputs.state }}
SUMMARY_CAN_MERGE: ${{ steps.check.outputs.can_merge }}
SUMMARY_JOB_STATUS: ${{ job.status }}
run: |
echo "🎯 Auto-merge Summary"
echo ""
echo "PR: #${{ steps.pr.outputs.pr_number }}"
echo "State: ${{ steps.pr.outputs.state }}"
echo "Can merge: ${{ steps.check.outputs.can_merge }}"
echo "Status: ${{ job.status }}"
echo "PR: #$SUMMARY_PR_NUMBER"
echo "State: $SUMMARY_STATE"
echo "Can merge: $SUMMARY_CAN_MERGE"
echo "Status: $SUMMARY_JOB_STATUS"
Copilot is powered by AI and may make mistakes. Always verify output.
Copilot AI and others added 2 commits January 27, 2026 21:06
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
…ocumentation

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
@blackboxprogramming blackboxprogramming marked this pull request as ready for review January 31, 2026 12:39
Copilot AI review requested due to automatic review settings January 31, 2026 12:39
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 46f5a4b8ef

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 47 to 49
if [ -z "$PR_NUMBER" ]; then
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"
exit 1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard workflow_run when no PR exists

On workflow_run events, CI also runs for direct pushes to main/develop (see .github/workflows/ci.yml on.push.branches), so there is often no associated PR. In that case PR_NUMBER will be empty and this step exits 1, causing the auto-merge workflow to fail on every push/merge to those branches. Consider skipping the job when github.event.workflow_run.pull_requests is empty or explicitly gating workflow_run to PR-triggered runs to avoid persistent failures.

Useful? React with 👍 / 👎.

Comment on lines +81 to +83
if [ "$STATE" == "OPEN" ] && \
[ "$MERGEABLE" == "MERGEABLE" ] && \
[ "$REVIEW_DECISION" == "APPROVED" ]; then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce base branch before auto-merge

The merge gate only checks state, mergeable, and reviewDecision and never verifies the PR’s base branch. Because CI also runs on develop, an approved PR targeting develop will satisfy these checks and be auto-merged, despite the workflow’s stated intent to merge only to main. Add a base-branch condition (e.g., github.event.pull_request.base.ref == 'main' or equivalent for workflow_run) to prevent unintended merges to non-main branches.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive sync system to push updates from the central .github repository (The Bridge) to other BlackRoad organization repositories. The implementation adds automated sync workflows, comprehensive testing, auto-merge functionality, and documentation.

Changes:

  • Adds sync-to-orgs workflow that dispatches repository events to active organization repositories
  • Implements auto-merge workflow to automatically merge approved PRs after CI passes
  • Integrates sync testing into the CI pipeline
  • Provides comprehensive documentation and receiver workflow templates

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/test_sync.py Test suite validating sync workflow configuration and registry structure
tests/test_integration.py End-to-end integration test simulating the complete sync flow
.github/workflows/sync-to-orgs.yml Main workflow dispatching sync events to target organization repositories
.github/workflows/auto-merge.yml Workflow automating PR merges after approval and successful CI
.github/workflows/ci.yml Updated CI pipeline including sync functionality tests
templates/workflows/sync-receiver.yml Template workflow for target repositories to receive and process sync events
docs/SYNC.md Comprehensive documentation covering sync architecture, usage, and troubleshooting
README.md Updated overview with sync features and quick start instructions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 48 to 49
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"
exit 1
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow will fail with "exit 1" when no PR number is found for a branch in workflow_run events. However, this is normal behavior when CI runs on direct commits to main (not from a PR). The workflow should handle this case gracefully by exiting early without error, rather than failing the entire workflow. Consider checking if this is a PR-related run before attempting to find the PR number, or exit with success (exit 0) when no PR is found.

Suggested change
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"
exit 1
if [ "${{ github.event_name }}" == "workflow_run" ]; then
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}; this workflow_run is not associated with a PR. Exiting successfully."
exit 0
else
echo "No PR number found for event type: ${{ github.event_name }}"
exit 1
fi

Copilot uses AI. Check for mistakes.
blackboxprogramming and others added 3 commits February 27, 2026 12:10
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
blackboxprogramming and others added 3 commits February 27, 2026 12:11
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

blackboxprogramming and others added 6 commits February 27, 2026 12:17
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +67 to +69
# Should trigger on push to main
if "push" in triggers:
branches = triggers["push"].get("branches", [])
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the workflow YAML ever omits the push trigger entirely, this test won't record an error because it only validates branches when "push" in triggers. Consider adding an else path that calls self.error(...) when the push trigger is missing so regressions are caught.

Copilot uses AI. Check for mistakes.
sync:
name: Sync Updates
runs-on: ubuntu-latest

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This template pushes commits back to the default branch, but it doesn't request contents: write permissions. In repos/orgs where the default GITHUB_TOKEN permission is read-only, the git push step will fail. Add explicit workflow/job permissions: contents: write (and keep pull-requests etc. off unless needed).

Suggested change
permissions:
contents: write

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +75
# Output for next steps
with open('$GITHUB_OUTPUT', 'a') as f:
f.write(f'orgs={json.dumps(orgs)}\\n')
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this Python step, open('$GITHUB_OUTPUT', 'a') writes to a literal file named $GITHUB_OUTPUT rather than the Actions output file path. As a result, steps.registry.outputs.orgs will be empty and the dispatch step will likely fail when it tries to json.loads the missing/empty env var. Use the GITHUB_OUTPUT environment variable (e.g., via os.environ['GITHUB_OUTPUT']) or write the output from the shell instead.

Copilot uses AI. Check for mistakes.

- name: Dispatch to target orgs
env:
GITHUB_TOKEN: ${{ secrets.DISPATCH_TOKEN || secrets.GITHUB_TOKEN }}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

secrets.GITHUB_TOKEN is repository-scoped and typically cannot call repository_dispatch on other repositories (even within the same org). Falling back to it will make sync appear configured but fail at runtime; consider requiring DISPATCH_TOKEN (fail fast if missing) or only using the fallback when dispatching to the current repo.

Suggested change
GITHUB_TOKEN: ${{ secrets.DISPATCH_TOKEN || secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.DISPATCH_TOKEN }}

Copilot uses AI. Check for mistakes.
Comment on lines +180 to +184
if failures:
print(f'⚠️ {len(failures)} dispatch(es) failed:')
for failure in failures:
print(f' - {failure}')
print('')
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dispatch script collects failures but never exits non-zero when dispatches fail, so the workflow can report success even when nothing was synced. Consider failing the job when failures is non-empty (and potentially exempting dry_run) so broken dispatches surface immediately.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +22
if: |
(github.event_name == 'pull_request_review' && github.event.review.state == 'approved') ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The job condition runs on any successful workflow_run of CI, including CI runs triggered by direct pushes to main/develop (where there is no PR). That will cause this workflow to error (no PR found) and may also risk selecting the wrong PR when matching by branch name. Gate workflow_run handling to PR-triggered runs only (e.g., require github.event.workflow_run.event == 'pull_request' and/or a non-empty workflow_run.pull_requests list), and ensure the PR targets main before enabling auto-merge.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +41
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For workflow_run, deriving the PR number by listing PRs and matching headRefName to workflow_run.head_branch is ambiguous and can return the wrong PR if multiple PRs share the same head branch name (or return nothing and fail). Prefer using the PR number(s) provided in the workflow_run event payload (when present) to identify the exact PR that triggered CI.

Suggested change
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
# Extract PR number directly from workflow_run payload
if [ -n "${{ github.event.workflow_run.pull_requests[0].number }}" ]; then
PR_NUMBER="${{ github.event.workflow_run.pull_requests[0].number }}"
else
echo "Workflow run is not associated with a pull request."
exit 1
fi

Copilot uses AI. Check for mistakes.
with open('routes/registry.yaml') as f:
reg = yaml.safe_load(f)
active = [code for code, org in reg['orgs'].items() if org.get('status') == 'active']
print(f'Active orgs: {', '.join(active)}')
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Python example is syntactically invalid because the f-string contains nested single quotes: print(f'Active orgs: {', '.join(active)}'). Adjust the quoting (or build the joined string separately) so the snippet can be copied/pasted and run as shown.

Suggested change
print(f'Active orgs: {', '.join(active)}')
joined = ', '.join(active)
print(f'Active orgs: {joined}')

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants