Skip to content
Closed
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
77 changes: 77 additions & 0 deletions .github/workflows/email-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: 📧 Email Notification Cleanup

on:
schedule:
# Ejecutar cada hora
- cron: "0 * * * *"
workflow_dispatch:
inputs:
max_emails:
description: "Maximum emails to process"
required: false
default: "50"
type: string

permissions:
contents: read

jobs:
cleanup-notifications:
runs-on: ubuntu-latest

steps:
- name: 🔍 Checkout
uses: actions/checkout@v4

- name: 🐍 Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: 📦 Install Dependencies
run: |
cd tools/email-handler
pip install -r requirements.txt

- name: 🔐 Setup Gmail Credentials
env:
GMAIL_CREDENTIALS: ${{ secrets.GMAIL_CREDENTIALS }}
GMAIL_TOKEN: ${{ secrets.GMAIL_TOKEN }}
run: |
cd tools/email-handler

# Crear credentials.json desde secret
echo "$GMAIL_CREDENTIALS" > credentials.json

# Crear token.json desde secret si existe
if [ -n "$GMAIL_TOKEN" ]; then
echo "$GMAIL_TOKEN" > token.json
fi

- name: 📧 Process Notifications
env:
GH_TOKEN: ${{ github.token }}
MAX_EMAILS: ${{ github.event.inputs.max_emails || '50' }}
run: |
cd tools/email-handler
python src/main.py --max-emails $MAX_EMAILS

- name: 💾 Update Token (if refreshed)
if: always()
run: |
cd tools/email-handler
if [ -f token.json ]; then
echo "Token file exists, should be updated in secrets manually"
# Note: GitHub Actions cannot update secrets automatically
# User must copy the new token.json content to GMAIL_TOKEN secret
fi

- name: 📊 Summary
if: always()
run: |
echo "## 📧 Email Cleanup Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ Email handler executed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Check logs for details on processed emails." >> $GITHUB_STEP_SUMMARY
89 changes: 89 additions & 0 deletions .github/workflows/global-self-healing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Global Self-Healing Monitor

on:
schedule:
- cron: '*/30 * * * *'
workflow_dispatch:

permissions:
contents: read
issues: write # Required to create/update issues
pull-requests: read # Required to read PR status

jobs:
monitor-repos:
runs-on: ubuntu-latest

strategy:
matrix:
repo:
- iberi22/Git-Core-Protocol
- iberi22/software-factory
- iberi22/domus-otec
- iberi22/less-colegio
- iberi22/synapse-protocol
- iberi22/gara-g
- iberi22/AI-Chef
- iberi22/contratafacil
- iberi22/bestof-opensorce
- iberi22/obs-studio-agent
- iberi22/pocket_cerebro
fail-fast: false
max-parallel: 3

steps:
- name: Check Failures
id: check
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || github.token }}
run: |
echo "Checking ${{ matrix.repo }} for failures..."

# Check the last 10 runs to find any recent failures
RUN_ID=$(gh run list \
--repo ${{ matrix.repo }} \
--limit 10 \
--json databaseId,conclusion \
--jq 'map(select(.conclusion == "failure")) | .[0].databaseId' 2>/dev/null || echo "")

if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
echo "No failures found in last 10 runs"
echo "has_failure=false" >> $GITHUB_OUTPUT
else
echo "Found failure: Run ID $RUN_ID"
echo "has_failure=true" >> $GITHUB_OUTPUT
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
fi

- name: Create Issue
if: steps.check.outputs.has_failure == 'true'
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || github.token }}
run: |
RUN_ID="${{ steps.check.outputs.run_id }}"
REPO="${{ matrix.repo }}"

WORKFLOW_NAME=$(gh run view $RUN_ID \
--repo $REPO \
--json name \
--jq '.name' 2>/dev/null || echo "Unknown Workflow")

EXISTING=$(gh issue list \
--repo $REPO \
--label "bug" \
--search "in:title $WORKFLOW_NAME" \
--state open \
--json number \
--jq '.[0].number' 2>/dev/null || echo "")

if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ]; then
echo "Updating issue #$EXISTING"
gh issue comment $EXISTING --repo $REPO --body "New failure: https://github.com/$REPO/actions/runs/$RUN_ID"
else
echo "Creating new issue"
gh issue create \
--repo $REPO \
--title "CI Failure: $WORKFLOW_NAME" \
--body "Workflow failed. Run: https://github.com/$REPO/actions/runs/$RUN_ID" \
--label "bug,ai-plan" || echo "Could not create issue"
fi
167 changes: 167 additions & 0 deletions .github/workflows/protocol-propagation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Protocol Propagation

on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
inputs:
update_type:
description: "Update type"
required: true
type: choice
options:
- workflows
- agents
- scripts
- full
default: "workflows"

permissions:
contents: read

jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Get Version
id: version
run: |
if [ -f VERSION ]; then
VERSION=$(cat VERSION)
else
VERSION=${GITHUB_REF#refs/tags/v}
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

propagate:
needs: detect-changes
runs-on: ubuntu-latest

strategy:
matrix:
repo:
- iberi22/software-factory
- iberi22/domus-otec
- iberi22/less-colegio
- iberi22/synapse-protocol
- iberi22/gara-g
- iberi22/AI-Chef
- iberi22/contratafacil
- iberi22/bestof-opensorce
- iberi22/obs-studio-agent
- iberi22/pocket_cerebro
fail-fast: false
max-parallel: 3

steps:
- name: Checkout Protocol Repo
uses: actions/checkout@v4

- name: Clone Target Repo
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
# Configure git to use the token for authentication
git config --global credential.helper store
echo "https://x-access-token:${GH_TOKEN}@github.com" > ~/.git-credentials

# Clone using https with token
git clone https://github.com/${{ matrix.repo }}.git target-repo || {
echo "Cannot access ${{ matrix.repo }}, skipping..."
exit 0
}
Comment on lines +77 to +80
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Clone failure exits silently instead of failing the job.

When cloning the target repo fails (line 77–80), the step exits with code 0 (success) instead of propagating the error. This hides access issues or network failures from CI logs.

Either fail the step explicitly (to alert that a repo is inaccessible) or use a separate skip flag to log the reason more clearly. Currently, silent success masks problems.

Consider this approach instead:

         git clone https://github.com/${{ matrix.repo }}.git target-repo || {
-          echo "Cannot access ${{ matrix.repo }}, skipping..."
-          exit 0
+          echo "⚠️  Cannot access ${{ matrix.repo }}, skipping..." >&2
+          exit 0  # OK to skip for this matrix job only
         }

Or fail the job:

         git clone https://github.com/${{ matrix.repo }}.git target-repo || {
-          echo "Cannot access ${{ matrix.repo }}, skipping..."
-          exit 0
+          echo "❌ Failed to clone ${{ matrix.repo }}" >&2
+          exit 1
         }

The choice depends on whether unreachable repos are expected. If expected, use the first approach with stderr redirection (>&2) to ensure the skip is logged conspicuously.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git clone https://github.com/${{ matrix.repo }}.git target-repo || {
echo "Cannot access ${{ matrix.repo }}, skipping..."
exit 0
}
git clone https://github.com/${{ matrix.repo }}.git target-repo || {
echo "⚠️ Cannot access ${{ matrix.repo }}, skipping..." >&2
exit 0 # OK to skip for this matrix job only
}
🤖 Prompt for AI Agents
In .github/workflows/protocol-propagation.yml around lines 77–80, the git clone
failure branch currently echoes a message and exits with 0, which makes the job
report success even when cloning fails; change the branch so it either (A)
explicitly fails the step by exiting non‑zero (e.g., exit 1) so CI surfaces the
error, or (B) if unreachable repos are expected, make the skip visible by
writing the message to stderr and still exit 0 (use stderr redirection) and
include a clear log message indicating the repo was skipped; pick one behavior
and update the clone error block accordingly.


- name: Prepare Update
id: package
run: |
UPDATE_TYPE="${{ github.event.inputs.update_type || 'workflows' }}"
VERSION="${{ needs.detect-changes.outputs.version }}"

cd target-repo

BRANCH_NAME="protocol-update-v${VERSION}"
git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME"

case "$UPDATE_TYPE" in
workflows)
echo "Updating workflows..."
mkdir -p .github/workflows
cp -r ../.github/workflows/* .github/workflows/ 2>/dev/null || true
;;
agents)
echo "Updating agent configs..."
cp ../AGENTS.md . 2>/dev/null || true
cp ../.cursorrules . 2>/dev/null || true
cp -r ../.github/copilot-instructions.md .github/ 2>/dev/null || true
;;
scripts)
echo "Updating scripts..."
mkdir -p scripts
cp -r ../scripts/* scripts/ 2>/dev/null || true
;;
full)
echo "Full protocol update..."
cp ../AGENTS.md . 2>/dev/null || true
cp ../.cursorrules . 2>/dev/null || true
mkdir -p .github/workflows scripts
cp -r ../.github/workflows/* .github/workflows/ 2>/dev/null || true
cp -r ../.github/copilot-instructions.md .github/ 2>/dev/null || true
cp -r ../scripts/* scripts/ 2>/dev/null || true
;;
esac

if git diff --quiet; then
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "No changes detected"
else
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "Changes detected"

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "chore: update Git-Core Protocol to v${VERSION}"
fi

echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT

- name: Push Changes
if: steps.package.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
cd target-repo
git push -u origin ${{ steps.package.outputs.branch }} --force
Comment on lines +136 to +142
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Unconditional force push creates race condition risk.

Line 142 uses git push --force without conditions or safeguards. If the workflow triggers multiple times concurrently or if the branch exists from a previous run, this could overwrite legitimate commits in the target repository.

Consider using --force-with-lease (safer, fails if branch changed remotely) or verifying the branch state before force-pushing.

Apply this diff for safer behavior:

         cd target-repo
-        git push -u origin ${{ steps.package.outputs.branch }} --force
+        git push -u origin ${{ steps.package.outputs.branch }} --force-with-lease
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Push Changes
if: steps.package.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
cd target-repo
git push -u origin ${{ steps.package.outputs.branch }} --force
- name: Push Changes
if: steps.package.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
cd target-repo
git push -u origin ${{ steps.package.outputs.branch }} --force-with-lease
🤖 Prompt for AI Agents
In .github/workflows/protocol-propagation.yml around lines 136 to 142, the
workflow uses an unconditional git push --force which can overwrite remote
changes if multiple runs or existing commits are present; replace the force push
with a safer approach such as using git push --force-with-lease to fail if the
remote branch has been updated, or add a pre-push check to fetch the remote
branch and compare commit SHAs (abort if they differ) before forcing; update the
run step to either use --force-with-lease or implement the
fetch/compare-and-conditional-push logic so the workflow will not blindly
overwrite remote commits.


- name: Create PR
if: steps.package.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.MULTI_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
cd target-repo

VERSION="${{ needs.detect-changes.outputs.version }}"
UPDATE_TYPE="${{ github.event.inputs.update_type || 'workflows' }}"
REPO="${{ matrix.repo }}"

# Try to create PR without labels first, then add labels if they exist
gh pr create \
--title "Git-Core Protocol v${VERSION} Update" \
--body "Updates from Git-Core Protocol v${VERSION}. Type: ${UPDATE_TYPE}. See: https://github.com/iberi22/Git-Core-Protocol/releases/tag/v${VERSION}" \
--base main \
--head ${{ steps.package.outputs.branch }} || echo "PR may already exist"

# Try to add labels (ignore if they don't exist)
PR_NUMBER=$(gh pr list --head ${{ steps.package.outputs.branch }} --json number --jq '.[0].number' 2>/dev/null || echo "")
if [ -n "$PR_NUMBER" ]; then
gh pr edit $PR_NUMBER --add-label "dependencies" 2>/dev/null || true
gh pr edit $PR_NUMBER --add-label "protocol-update" 2>/dev/null || true
fi
Loading
Loading