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
325 changes: 169 additions & 156 deletions .github/workflows/sync-issues.yml
Original file line number Diff line number Diff line change
@@ -1,156 +1,169 @@
# Sincroniza archivos .md en .github/issues/ con GitHub Issues
# - Crea issues cuando se agregan archivos .md
# - Elimina archivos cuando los issues se cierran

name: Sync Issues from Files

env:
PROTOCOL_VERSION: "1.3.0"

on:
# Cuando se modifican archivos en la carpeta de issues
push:
paths:
- ".github/issues/*.md"
branches:
- main

# Cuando se cierra un issue
issues:
types: [closed, deleted]

# Manual trigger
workflow_dispatch:
inputs:
action:
description: "Action to perform"
required: true
default: "sync"
type: choice
options:
- sync
- push-only
- pull-only

# Periódicamente para limpiar issues cerrados
# Using minute 23 to avoid hourly peak congestion
schedule:
- cron: "23 */6 * * *" # Every 6 hours at minute 23

permissions:
contents: write
issues: write

jobs:
sync-issues:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup jq
run: sudo apt-get install -y jq

- name: Initialize mapping file
run: |
mkdir -p .github/issues
if [[ ! -f .github/issues/.issue-mapping.json ]]; then
echo "{}" > .github/issues/.issue-mapping.json
fi

# ========== Ensure labels exist ==========
- name: Create missing labels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Define labels that might be needed
declare -A LABELS=(
["ai-agents"]="AI agent related tasks:#5319E7"
["research"]="Research tasks:#D4C5F9"
["workflow"]="Workflow improvements:#0E8A16"
["bug"]="Something isn't working:#D73A4A"
["documentation"]="Improvements or additions to documentation:#0075CA"
["feature"]="New feature request:#A2EEEF"
["enhancement"]="New feature or improvement:#A2EEEF"
["protocol"]="Git-Core Protocol related:#1D76DB"
["dependencies"]="Dependency updates:#0366D6"
["copilot"]="Assigned to GitHub Copilot:#6F42C1"
)

for label in "${!LABELS[@]}"; do
IFS=':' read -r desc color <<< "${LABELS[$label]}"
gh label create "$label" --description "$desc" --color "$color" 2>/dev/null || true
done
echo "✅ Labels verificados"

# ========== Rust Binary Check ==========
# Rust implementation provides 10-20x speedup over PowerShell/Bash:
# - Parsing: 6.3-14.2μs vs 2-10ms (352K-794K faster)
# - Mapping: 25-38ns lookups vs 1-2ms (40M ops/sec vs 500-1000 ops/sec)
# - Full sync: <500ms vs 5-10s (10-20x overall speedup)
- name: Check for Rust binary
id: check_rust
run: |
if [[ -f "bin/issue-syncer-linux" ]]; then
echo "rust_available=true" >> $GITHUB_OUTPUT
echo "✅ Rust binary found - using high-performance syncer"
else
echo "rust_available=false" >> $GITHUB_OUTPUT
echo "⚠️ Rust binary not found - using PowerShell fallback"
fi

# ========== RUST PATH: High-Performance Sync ==========
- name: Run Rust Issue Syncer
if: steps.check_rust.outputs.rust_available == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Determine action based on trigger
ACTION="sync"
if [[ "${{ github.event.inputs.action }}" == "push-only" ]]; then
ACTION="push"
elif [[ "${{ github.event.inputs.action }}" == "pull-only" ]]; then
ACTION="pull"
elif [[ "${{ github.event_name }}" == "issues" ]]; then
ACTION="pull" # Only clean when issue closed
fi

echo "🚀 Running Rust syncer: $ACTION"
chmod +x bin/issue-syncer-linux
./bin/issue-syncer-linux "$ACTION" --verbose

# ========== FALLBACK PATH: PowerShell/Bash Scripts ==========
# ========== FALLBACK PATH: PowerShell Script ==========
- name: Sync Issues (PowerShell)
if: steps.check_rust.outputs.rust_available == 'false' && github.event_name != 'issues'
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./scripts/sync-issues.ps1 -Verbose

- name: Clean Closed Issues (PowerShell)
if: steps.check_rust.outputs.rust_available == 'false' && (github.event.inputs.action == 'pull-only' || github.event.inputs.action == '' || github.event_name == 'issues')
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./scripts/sync-issues.ps1 -Pull -Verbose

# ========== Commit cambios ==========
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

git add .github/issues/

if git diff --staged --quiet; then
echo "No hay cambios que commitear"
else
git commit -m "chore(issues): sync issue files with GitHub Issues [skip ci]"
git push
fi
# Sincroniza archivos .md en .github/issues/ con GitHub Issues
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Normalize file line endings to LF (\n).

YAMLlint reports newline-style failure (expected \n). This can break lint gates and should be normalized.

🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 1-1: wrong new line character: expected \n

(new-lines)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sync-issues.yml at line 1, The workflow file containing
the header "# Sincroniza archivos .md en .github/issues/ con GitHub Issues" uses
non-LF line endings and fails YAML lint; convert its line endings to LF (\n)
(e.g., open and save with LF endings or run a one-time conversion), and
add/update a .gitattributes entry (e.g., for *.yml/*.yaml set text=eol=lf) or
ensure core.autocrlf is configured so future commits preserve LF; targeted file:
the sync-issues.yml workflow whose first line is the Spanish header comment.

# - Crea issues cuando se agregan archivos .md
# - Elimina archivos cuando los issues se cierran

name: Sync Issues from Files

env:
PROTOCOL_VERSION: "1.3.0"

on:
# Cuando se modifican archivos en la carpeta de issues
push:
paths:
- ".github/issues/*.md"
branches:
- main

# Cuando se cierra un issue
issues:
types: [closed, deleted]

# Manual trigger
workflow_dispatch:
inputs:
action:
description: "Action to perform"
required: true
default: "sync"
type: choice
options:
- sync
- push-only
- pull-only

# Periódicamente para limpiar issues cerrados
# Using minute 23 to avoid hourly peak congestion
schedule:
- cron: "23 */6 * * *" # Every 6 hours at minute 23

permissions:
contents: write
issues: write

Comment on lines +40 to +43
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

What repository token permissions are required to create a pull request from a GitHub Actions workflow using gh pr create?

💡 Result:

To create a pull request from a GitHub Actions workflow using gh pr create, the GITHUB_TOKEN requires the following permissions in the workflow YAML: permissions: contents: write pull-requests: write Additionally, ensure that repository settings allow GitHub Actions workflows to create pull requests: Repository Settings > Actions > General > Workflow permissions > "Read and write permissions" is selected, and if applicable, "Allow GitHub Actions to create and approve pull requests". The contents: write permission is needed because gh pr create typically involves pushing a branch (if not already pushed), which requires write access to repository contents. The pull-requests: write permission is required to create the pull request itself via the GitHub API. Set GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} (or GITHUB_TOKEN) in the step environment for authentication. Examples from working workflows and Stack Overflow confirm this combination resolves "Resource not accessible by integration" errors.

Citations:


🏁 Script executed:

cd /tmp/repo 2>/dev/null || cd . && cat -n .github/workflows/sync-issues.yml | head -60

Repository: iberi22/synapse-protocol

Length of output: 1854


🏁 Script executed:

wc -l .github/workflows/sync-issues.yml && cat -n .github/workflows/sync-issues.yml | tail -n +60

Repository: iberi22/synapse-protocol

Length of output: 5634


Add pull-requests: write permission for PR creation.

The workflow calls gh pr create at lines 163–168, but the permissions block lacks explicit pull-request write access. Without this permission, the PR creation step will fail with a "Resource not accessible by integration" error, blocking the primary workflow objective.

Suggested fix
permissions:
  contents: write
  issues: write
+  pull-requests: write
📝 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
permissions:
contents: write
issues: write
permissions:
contents: write
issues: write
pull-requests: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sync-issues.yml around lines 40 - 43, The workflow's
permissions block is missing pull-request write access which prevents the gh pr
create step from working; update the permissions map (the existing permissions:
contents: write, issues: write) to include pull-requests: write so the GitHub
CLI command (gh pr create) can succeed, ensuring you add the pull-requests:
write entry at the same indentation level under permissions.

jobs:
sync-issues:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup jq
run: sudo apt-get install -y jq

- name: Initialize mapping file
run: |
mkdir -p .github/issues
if [[ ! -f .github/issues/.issue-mapping.json ]]; then
echo "{}" > .github/issues/.issue-mapping.json
fi

# ========== Ensure labels exist ==========
- name: Create missing labels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Define labels that might be needed
declare -A LABELS=(
["ai-agents"]="AI agent related tasks:#5319E7"
["research"]="Research tasks:#D4C5F9"
["workflow"]="Workflow improvements:#0E8A16"
["bug"]="Something isn't working:#D73A4A"
["documentation"]="Improvements or additions to documentation:#0075CA"
["feature"]="New feature request:#A2EEEF"
["enhancement"]="New feature or improvement:#A2EEEF"
["protocol"]="Git-Core Protocol related:#1D76DB"
["dependencies"]="Dependency updates:#0366D6"
["copilot"]="Assigned to GitHub Copilot:#6F42C1"
)

for label in "${!LABELS[@]}"; do
IFS=':' read -r desc color <<< "${LABELS[$label]}"
gh label create "$label" --description "$desc" --color "$color" 2>/dev/null || true
done
Comment on lines +65 to +86
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

skip ci label is used but not guaranteed to exist.

The workflow applies --label "skip ci" when creating the PR, but this label is not provisioned in the label bootstrap list. If absent in the repo, PR creation fails.

Suggested patch
           declare -A LABELS=(
             ["ai-agents"]="AI agent related tasks:`#5319E7`"
             ["research"]="Research tasks:`#D4C5F9`"
             ["workflow"]="Workflow improvements:`#0E8A16`"
             ["bug"]="Something isn't working:`#D73A4A`"
             ["documentation"]="Improvements or additions to documentation:`#0075CA`"
             ["feature"]="New feature request:`#A2EEEF`"
             ["enhancement"]="New feature or improvement:`#A2EEEF`"
             ["protocol"]="Git-Core Protocol related:`#1D76DB`"
             ["dependencies"]="Dependency updates:`#0366D6`"
             ["copilot"]="Assigned to GitHub Copilot:`#6F42C1`"
+            ["skip ci"]="Skip CI-triggered automation PRs:`#BFD4F2`"
           )

Also applies to: 163-167

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sync-issues.yml around lines 65 - 86, The workflow is
missing provisioning for the "skip ci" label which is applied later when
creating PRs; update the label bootstrap list (the declare -A LABELS array used
in the "Create missing labels" step) to include an entry for "skip ci" with an
appropriate description and color so the gh label create loop (for label in
"${!LABELS[@]}"; do ...) will ensure the label exists before any PR creation
uses --label "skip ci".

echo "✅ Labels verificados"

# ========== Rust Binary Check ==========
# Rust implementation provides 10-20x speedup over PowerShell/Bash:
# - Parsing: 6.3-14.2μs vs 2-10ms (352K-794K faster)
# - Mapping: 25-38ns lookups vs 1-2ms (40M ops/sec vs 500-1000 ops/sec)
# - Full sync: <500ms vs 5-10s (10-20x overall speedup)
- name: Check for Rust binary
id: check_rust
run: |
if [[ -f "bin/issue-syncer-linux" ]]; then
echo "rust_available=true" >> $GITHUB_OUTPUT
echo "✅ Rust binary found - using high-performance syncer"
else
echo "rust_available=false" >> $GITHUB_OUTPUT
echo "⚠️ Rust binary not found - using PowerShell fallback"
fi

# ========== RUST PATH: High-Performance Sync ==========
- name: Run Rust Issue Syncer
if: steps.check_rust.outputs.rust_available == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Determine action based on trigger
ACTION="sync"
if [[ "${{ github.event.inputs.action }}" == "push-only" ]]; then
ACTION="push"
elif [[ "${{ github.event.inputs.action }}" == "pull-only" ]]; then
ACTION="pull"
elif [[ "${{ github.event_name }}" == "issues" ]]; then
ACTION="pull" # Only clean when issue closed
fi

echo "🚀 Running Rust syncer: $ACTION"
chmod +x bin/issue-syncer-linux
./bin/issue-syncer-linux "$ACTION" --verbose

# ========== FALLBACK PATH: PowerShell/Bash Scripts ==========
# ========== FALLBACK PATH: PowerShell Script ==========
- name: Sync Issues (PowerShell)
if: steps.check_rust.outputs.rust_available == 'false' && github.event_name != 'issues'
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./scripts/sync-issues.ps1 -Verbose

- name: Clean Closed Issues (PowerShell)
if: steps.check_rust.outputs.rust_available == 'false' && (github.event.inputs.action == 'pull-only' || github.event.inputs.action == '' || github.event_name == 'issues')
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./scripts/sync-issues.ps1 -Pull -Verbose

# ========== Commit cambios (via PR) ==========
- name: Commit changes via PR
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

git add .github/issues/


if git diff --staged --quiet; then
echo "No hay cambios que commitear"
else
# Create a unique branch for this commit
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BRANCH_NAME="sync-issues/$TIMESTAMP"
git checkout -b "$BRANCH_NAME"
git commit -m "chore(issues): sync issue files with GitHub Issues [skip ci]"
git push -u origin "$BRANCH_NAME"

# Create PR with [skip ci] label to avoid re-triggering the workflow
gh pr create \
--title "chore(issues): sync issue files with GitHub Issues" \
--body "Automated sync of issue files. [skip ci]" \
--label "skip ci" \
--base main \
--head "$BRANCH_NAME"
Comment on lines +144 to +168
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In GitHub Actions, does gh pr createrequireGH_TOKEN/GITHUB_TOKEN to be explicitly set in the step environment for reliable authentication?

💡 Result:

Yes, gh pr create requires GH_TOKEN or GITHUB_TOKEN to be explicitly set in the step's environment for reliable authentication in GitHub Actions workflows.

Citations:


🏁 Script executed:

# Find and read the sync-issues.yml workflow file
find . -path "./.github/workflows/sync-issues.yml" -type f 2>/dev/null | head -1 | xargs cat -n | head -200

Repository: iberi22/synapse-protocol

Length of output: 7311


Add GH_TOKEN to the PR creation step for reliable authentication.

The gh pr create command requires explicit GH_TOKEN environment variable to authenticate reliably with GitHub's API. While earlier steps in this workflow properly set GH_TOKEN (lines 67, 131, 139), the "Commit changes via PR" step (line 144) omits it. This inconsistency risks intermittent authentication failures.

Suggested patch
       - name: Commit changes via PR
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
           git config user.name "github-actions[bot]"
           git config user.email "github-actions[bot]@users.noreply.github.com"
📝 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: Commit changes via PR
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .github/issues/
if git diff --staged --quiet; then
echo "No hay cambios que commitear"
else
# Create a unique branch for this commit
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BRANCH_NAME="sync-issues/$TIMESTAMP"
git checkout -b "$BRANCH_NAME"
git commit -m "chore(issues): sync issue files with GitHub Issues [skip ci]"
git push -u origin "$BRANCH_NAME"
# Create PR with [skip ci] label to avoid re-triggering the workflow
gh pr create \
--title "chore(issues): sync issue files with GitHub Issues" \
--body "Automated sync of issue files. [skip ci]" \
--label "skip ci" \
--base main \
--head "$BRANCH_NAME"
- name: Commit changes via PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .github/issues/
if git diff --staged --quiet; then
echo "No hay cambios que commitear"
else
# Create a unique branch for this commit
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BRANCH_NAME="sync-issues/$TIMESTAMP"
git checkout -b "$BRANCH_NAME"
git commit -m "chore(issues): sync issue files with GitHub Issues [skip ci]"
git push -u origin "$BRANCH_NAME"
# Create PR with [skip ci] label to avoid re-triggering the workflow
gh pr create \
--title "chore(issues): sync issue files with GitHub Issues" \
--body "Automated sync of issue files. [skip ci]" \
--label "skip ci" \
--base main \
--head "$BRANCH_NAME"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sync-issues.yml around lines 144 - 168, The "Commit
changes via PR" step is missing the GH_TOKEN environment variable needed for
reliable authentication when running the gh pr create command; update that step
(the block titled "Commit changes via PR" that runs gh pr create) to export or
pass GH_TOKEN into the environment before invoking gh (e.g., set GH_TOKEN from
the workflow secret or include env: GH_TOKEN: ${{ secrets.GH_TOKEN }}) so gh pr
create uses the provided token for authentication.

fi
2 changes: 1 addition & 1 deletion crates/synapse-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ lazy_static = "1.5.0"

[dev-dependencies]
tokio = { workspace = true }
synapse-infra = { path = "../synapse-infra" }
synapse-infra = { path = "../synapse-infra", default-features = false }
16 changes: 9 additions & 7 deletions crates/synapse-core/src/entities/secure_holo_packet.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use serde::{Deserialize, Serialize};
use serde_json;

use crate::entities::holo_packet::HoloPacket;
use crate::error::{Error, Result};
use crate::ports::signer_port::{HoloSignature, Signer, Verifier};

#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SecureHoloPacket {
pub holo_packet: HoloPacket,
pub signature: Signature,
pub signature: HoloSignature,
pub public_key: Vec<u8>,
}

impl SecureHoloPacket {
pub fn new(holo_packet: HoloPacket, signing_key: &SigningKey) -> Result<Self> {
pub fn new(holo_packet: HoloPacket, signer: &dyn Signer, public_key: Vec<u8>) -> Result<Self> {
let message = serde_json::to_vec(&holo_packet)
.map_err(|e| Error::System(format!("Failed to serialize HoloPacket: {}", e)))?;
let signature = signing_key.sign(&message);
let signature = signer.sign(&message);
Ok(Self {
holo_packet,
signature,
public_key,
})
}
Comment on lines +16 to 25
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider whether public_key should be derived from Signer rather than passed separately.

The current API requires callers to pass both signer and public_key independently. If they don't correspond, verification will silently fail. Consider adding a public_key() method to the Signer trait or documenting this contract clearly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/synapse-core/src/entities/secure_holo_packet.rs` around lines 16 - 25,
The constructor SecureHoloPacket::new currently takes a Signer and a separate
public_key which can mismatch; change the API so public_key is obtained from the
signer (add a public_key() -> Vec<u8> or &[u8] method to the Signer trait) and
use that returned key when constructing SecureHoloPacket in new (remove the
public_key parameter), or if you must keep the parameter, add a clear runtime
check in SecureHoloPacket::new that compares signer.public_key() to the passed
public_key and returns an error on mismatch; update the Signer trait and all
implementations accordingly and adjust any call sites to stop passing the
public_key manually.


pub fn verify(&self, verifying_key: &VerifyingKey) -> Result<bool> {
pub fn verify(&self, verifier: &dyn Verifier) -> Result<bool> {
let message = serde_json::to_vec(&self.holo_packet)
.map_err(|e| Error::System(format!("Failed to serialize HoloPacket: {}", e)))?;
Ok(verifying_key.verify(&message, &self.signature).is_ok())
Ok(verifier.verify(&message, &self.signature, &self.public_key))
}
}
Loading