Skip to content
Open
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
324 changes: 324 additions & 0 deletions .github/workflows/autonomous-cross-repo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
# .github/workflows/autonomous-cross-repo.yml
# Cross-repository coordination for synchronized changes

name: "Autonomous Cross-Repo Coordinator"

on:
push:
branches: [main, master]
paths:
- 'shared/**'
- 'packages/**'
- 'lib/**'
- '*.config.*'
workflow_dispatch:
inputs:
sync_type:
description: 'Type of sync'
required: true
type: choice
options:
- config
- dependencies
- workflows
- all
target_repos:
description: 'Target repos (comma-separated, or "all")'
required: false
default: 'all'
dry_run:
description: 'Dry run (no actual changes)'
required: false
default: true
type: boolean

permissions:
contents: write
pull-requests: write

env:
BLACKROAD_AGENT_API: https://blackroad-agents.amundsonalexa.workers.dev

jobs:
# ============================================
# Identify Affected Repositories
# ============================================
identify-repos:
name: "Identify Affected Repos"
runs-on: ubuntu-latest
outputs:
repos: ${{ steps.find.outputs.repos }}
sync_files: ${{ steps.changes.outputs.files }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Get Changed Files
id: changes
run: |
FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | head -50 || echo "")
echo "files<<EOF" >> $GITHUB_OUTPUT
echo "$FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Find Related Repositories
id: find
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Default BlackRoad repos that should stay in sync
CORE_REPOS='[
"BlackRoad-OS/blackroad-os-web",
"BlackRoad-OS/blackroad-os-docs",
"BlackRoad-OS/blackroad-cli",
"BlackRoad-OS/blackroad-agents",
"BlackRoad-OS/blackroad-os-mesh",
"BlackRoad-OS/blackroad-os-helper",
"BlackRoad-OS/blackroad-os-core"
]'

if [ "${{ github.event.inputs.target_repos }}" = "all" ] || [ -z "${{ github.event.inputs.target_repos }}" ]; then
REPOS="$CORE_REPOS"
else
# Convert comma-separated to JSON array
REPOS=$(echo '${{ github.event.inputs.target_repos }}' | jq -R 'split(",") | map(gsub("^\\s+|\\s+$";""))')
fi

echo "repos=$REPOS" >> $GITHUB_OUTPUT
echo "Repos to sync: $REPOS"
Comment on lines +66 to +90
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The cross-repo workflow hardcodes a list of specific BlackRoad repositories and attempts to sync workflows to them using a CROSS_REPO_TOKEN or fallback to GITHUB_TOKEN. However, the standard GITHUB_TOKEN doesn't have permissions to push to other repositories, so the fallback will always fail. Additionally, the workflow will attempt to sync to all seven hardcoded repositories regardless of whether this workflow is deployed in one of those repositories or in a completely different project, which could cause unexpected behavior or failures.

When deployed to non-BlackRoad repositories, this should either:

  1. Skip execution entirely with a clear message
  2. Use a configurable list of target repositories via repository variables
  3. Require explicit configuration before running

The workflow should also validate that CROSS_REPO_TOKEN exists and has appropriate permissions before attempting cross-repo operations, and fail with a clear error message if it's missing.

Copilot uses AI. Check for mistakes.

# ============================================
# Sync Workflows
# ============================================
sync-workflows:
name: "Sync Workflows"
needs: identify-repos
if: github.event.inputs.sync_type == 'workflows' || github.event.inputs.sync_type == 'all' || contains(needs.identify-repos.outputs.sync_files, '.github/workflows')
runs-on: ubuntu-latest
strategy:
matrix:
repo: ${{ fromJSON(needs.identify-repos.outputs.repos) }}
fail-fast: false
max-parallel: 5

steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
path: source

- name: Checkout Target
uses: actions/checkout@v4
with:
repository: ${{ matrix.repo }}
path: target
token: ${{ secrets.CROSS_REPO_TOKEN || secrets.GITHUB_TOKEN }}

- name: Sync Workflow Files
run: |
# Copy autonomous workflows
mkdir -p target/.github/workflows

# Copy the orchestrator and self-healer
for workflow in autonomous-orchestrator.yml autonomous-self-healer.yml blackroad-agents.yml; do
if [ -f "source/.github/workflows-autonomous/$workflow" ]; then
cp "source/.github/workflows-autonomous/$workflow" "target/.github/workflows/"
elif [ -f "source/.github/workflows/$workflow" ]; then
Comment on lines +126 to +128
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The workflow sync job looks for workflow files in source/.github/workflows-autonomous/ first, but this directory doesn't exist based on the PR changes (workflows are in .github/workflows/). This means the first condition will always fail, and it will fall back to the second path. The fallback works, but the first check is dead code that serves no purpose and may confuse future maintainers.

Remove the check for source/.github/workflows-autonomous/$workflow since this directory doesn't exist, or document why this alternate path is checked if it's intended for future use.

Suggested change
if [ -f "source/.github/workflows-autonomous/$workflow" ]; then
cp "source/.github/workflows-autonomous/$workflow" "target/.github/workflows/"
elif [ -f "source/.github/workflows/$workflow" ]; then
if [ -f "source/.github/workflows/$workflow" ]; then

Copilot uses AI. Check for mistakes.
cp "source/.github/workflows/$workflow" "target/.github/workflows/"
fi
done

echo "Synced workflows to ${{ matrix.repo }}"

- name: Create PR
if: github.event.inputs.dry_run != 'true'
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The cross-repo workflow has a dry_run input parameter that defaults to true, but the condition checking for dry run uses github.event.inputs.dry_run != 'true'. For scheduled or push-triggered runs (not workflow_dispatch), github.event.inputs.dry_run will be empty/null, which != 'true', so the workflow will proceed with actual changes. This means the "safety" of dry_run being true by default only applies to manual runs, not automated ones.

Change the default behavior to be safe for automated runs. Use a condition like github.event.inputs.dry_run == 'false' so that changes only happen when explicitly set to false, or add a separate check to ensure automated runs don't make changes without explicit configuration.

Suggested change
if: github.event.inputs.dry_run != 'true'
if: github.event.inputs.dry_run == 'false'

Copilot uses AI. Check for mistakes.
working-directory: target
env:
GH_TOKEN: ${{ secrets.CROSS_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
if [ -n "$(git status --porcelain)" ]; then
BRANCH="sync-workflows-$(date +%Y%m%d-%H%M%S)"
git config user.name "BlackRoad Cross-Repo Bot"
git config user.email "crossrepo@blackroad.ai"

git checkout -b "$BRANCH"
git add -A
git commit -m "chore(workflows): Sync autonomous workflows from central repo

Synced workflows:
- autonomous-orchestrator.yml
- autonomous-self-healer.yml
- blackroad-agents.yml

Source: ${{ github.repository }}

Co-Authored-By: BlackRoad Bot <bot@blackroad.ai>"

git push -u origin "$BRANCH"

gh pr create \
--title "chore(workflows): Sync autonomous workflows" \
--body "## Workflow Sync

Synced autonomous workflows from central repository.

**Source:** ${{ github.repository }}
**Sync Type:** workflows

### Changes
- Updated autonomous-orchestrator.yml
- Updated autonomous-self-healer.yml
- Updated blackroad-agents.yml

---
*Automated by BlackRoad Cross-Repo Coordinator*" \
--label "automated,infrastructure"
else
echo "No workflow changes needed for ${{ matrix.repo }}"
fi

# ============================================
# Sync Configurations
# ============================================
sync-config:
name: "Sync Configurations"
needs: identify-repos
if: github.event.inputs.sync_type == 'config' || github.event.inputs.sync_type == 'all'
runs-on: ubuntu-latest
strategy:
matrix:
repo: ${{ fromJSON(needs.identify-repos.outputs.repos) }}
fail-fast: false
max-parallel: 5

steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
path: source

- name: Checkout Target
uses: actions/checkout@v4
with:
repository: ${{ matrix.repo }}
path: target
token: ${{ secrets.CROSS_REPO_TOKEN || secrets.GITHUB_TOKEN }}

- name: Sync Config Files
run: |
# Sync common configs that should be consistent
SYNC_FILES=(
".eslintrc.js"
".prettierrc"
".editorconfig"
"tsconfig.base.json"
".github/CODEOWNERS"
".github/ISSUE_TEMPLATE/bug_report.yml"
".github/ISSUE_TEMPLATE/feature_request.yml"
)

for file in "${SYNC_FILES[@]}"; do
if [ -f "source/$file" ]; then
mkdir -p "target/$(dirname $file)"
cp "source/$file" "target/$file"
fi
done

- name: Create PR
if: github.event.inputs.dry_run != 'true'
working-directory: target
env:
GH_TOKEN: ${{ secrets.CROSS_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
if [ -n "$(git status --porcelain)" ]; then
BRANCH="sync-config-$(date +%Y%m%d-%H%M%S)"
git config user.name "BlackRoad Cross-Repo Bot"
git config user.email "crossrepo@blackroad.ai"

git checkout -b "$BRANCH"
git add -A
git commit -m "chore(config): Sync configurations from central repo

Co-Authored-By: BlackRoad Bot <bot@blackroad.ai>"

git push -u origin "$BRANCH"

gh pr create \
--title "chore(config): Sync configurations" \
--body "## Configuration Sync

Synced common configurations from central repository.

---
*Automated by BlackRoad Cross-Repo Coordinator*" \
--label "automated,config"
fi

# ============================================
# Sync Dependencies
# ============================================
sync-deps:
name: "Sync Dependencies"
needs: identify-repos
if: github.event.inputs.sync_type == 'dependencies' || github.event.inputs.sync_type == 'all'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Analyze Dependencies
id: deps
run: |
# Extract common dependencies and their versions
if [ -f "package.json" ]; then
DEPS=$(jq -r '.dependencies // {} | to_entries[] | "\(.key)@\(.value)"' package.json | head -20)
echo "deps<<EOF" >> $GITHUB_OUTPUT
echo "$DEPS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi

- name: Report Dependencies
run: |
echo "## Dependencies to Sync"
echo "${{ steps.deps.outputs.deps }}"

# Log to coordination API
curl -s -X POST "${{ env.BLACKROAD_AGENT_API }}/coordinate" \
-H "Content-Type: application/json" \
-d '{
"action": "sync_deps",
"source": "${{ github.repository }}",
"repos": ${{ needs.identify-repos.outputs.repos }},
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}' 2>/dev/null || true

# ============================================
# Broadcast Changes
# ============================================
broadcast:
name: "Broadcast Changes"
needs: [sync-workflows, sync-config, sync-deps]
if: always()
runs-on: ubuntu-latest

steps:
- name: Notify Coordination System
run: |
curl -s -X POST "${{ env.BLACKROAD_AGENT_API }}/broadcast" \
-H "Content-Type: application/json" \
-d '{
"event": "cross_repo_sync_complete",
"source": "${{ github.repository }}",
"sync_type": "${{ github.event.inputs.sync_type || 'auto' }}",
"repos": ${{ needs.identify-repos.outputs.repos || '[]' }},
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}' 2>/dev/null || echo "Broadcast queued"

- name: Summary
run: |
echo "## Cross-Repo Sync Complete"
echo "- Source: ${{ github.repository }}"
echo "- Sync Type: ${{ github.event.inputs.sync_type || 'auto' }}"
echo "- Dry Run: ${{ github.event.inputs.dry_run || 'false' }}"
Loading
Loading