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
282 changes: 18 additions & 264 deletions .github/workflows/ecosystem-cicd.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ChittyOS Ecosystem CI/CD with Codex Review
name: CI/CD

on:
push:
Expand All @@ -8,278 +8,32 @@ on:
workflow_dispatch:

env:
CHITTY_API_KEY: ${{ secrets.CHITTY_API_KEY }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Comment on lines 11 to 12

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep production Cloudflare credentials out of the PR lint job.

Workflow-level env injects this token into lint, where PR code runs npm ci and npm run lint. A same-repository PR can exfiltrate the production token through a modified lifecycle or lint script. Move these variables under deploy only.

Proposed fix
-env:
-  CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
-  CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
-
   deploy:
+    env:
+      CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+      CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
📝 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
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ecosystem-cicd.yml around lines 11 - 12, Move
CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID from the workflow-level env into
the deploy job’s env, keeping them available only to deploy and absent from the
lint job.


jobs:
# Phase 1: Codex Code Review
codex-review:
lint:
name: Lint
runs-on: ubuntu-latest
name: Codex Code Review & Analysis
outputs:
review-status: ${{ steps.codex.outputs.status }}
security-score: ${{ steps.codex.outputs.security }}

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install Dependencies & Lint
run: |
npm install
npm run lint || echo "Linting completed with warnings"
npm install -g @modelcontextprotocol/cli

- name: Run Codex Security Analysis
id: codex
run: |
echo "Starting Codex security analysis..."

# Initialize Codex MCP server
codex mcp --init

# Run comprehensive code review
codex review \
--security \
--performance \
--architecture \
--chittyid-compliance \
--output-format json > codex-review.json

# Extract security score
SECURITY_SCORE=$(jq -r '.security.score' codex-review.json)
echo "security=$SECURITY_SCORE" >> $GITHUB_OUTPUT

# Check if review passes
if [ "$SECURITY_SCORE" -ge 85 ]; then
echo "status=passed" >> $GITHUB_OUTPUT
echo "✅ Codex review passed with score: $SECURITY_SCORE"
else
echo "status=failed" >> $GITHUB_OUTPUT
echo "❌ Codex review failed with score: $SECURITY_SCORE"
exit 1
fi

- name: Upload Codex Report
uses: actions/upload-artifact@v4
with:
name: codex-review-report
path: codex-review.json

- name: Comment PR with Codex Results
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = JSON.parse(fs.readFileSync('codex-review.json', 'utf8'));

const comment = `## 🤖 Codex Review Results

**Security Score**: ${review.security.score}/100
**Performance Score**: ${review.performance.score}/100
**Architecture Score**: ${review.architecture.score}/100
**ChittyID Compliance**: ${review.chittyid.compliant ? '✅ Compliant' : '❌ Non-compliant'}

### Key Findings:
${review.findings.map(f => `- ${f.severity}: ${f.message}`).join('\n')}

### Recommendations:
${review.recommendations.map(r => `- ${r}`).join('\n')}
`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});

# Phase 2: ChittyOS Ecosystem Validation
ecosystem-validation:
runs-on: ubuntu-latest
name: ChittyOS Ecosystem Validation
needs: codex-review
if: needs.codex-review.outputs.review-status == 'passed'

steps:
- uses: actions/checkout@v4

- name: ChittyID Compliance Check
run: |
echo "Running ChittyID compliance validation..."
./chittycheck-enhanced.sh --ci-mode

# Ensure no local ID generation (exclude submodules and build artifacts)
if grep -r "CHITTY-.*-.*-.*" . \
--exclude-dir=node_modules \
--exclude-dir=.git \
--exclude-dir=chittychronicle \
--exclude-dir=chittychain \
--exclude-dir=chittyforce \
--exclude-dir=nevershitty-github \
--exclude-dir=dist \
--exclude-dir=build \
--exclude="*.json" \
--exclude="*.md"; then
echo "❌ Found hardcoded ChittyIDs in source code - all IDs must come from id.chitty.cc"
exit 1
fi

- name: Cross-Service Integration Test
run: |
echo "Testing cross-service integration..."

# Test ChittyMCP connectivity
curl -f https://mcp.chitty.cc/health || echo "ChittyMCP not yet deployed"

# Test service registry
curl -f https://registry.chitty.cc/health || echo "Registry not yet deployed"

# Test gateway
curl -f https://gateway.chitty.cc/health || echo "Gateway not yet deployed"

- name: Evidence Chain Validation
run: |
echo "Validating evidence chain integrity..."
node -e "
const fs = require('fs');
const crypto = require('crypto');

// Validate evidence files have proper ChittyID linking
const evidenceFiles = fs.readdirSync('.', {recursive: true})
.filter(f => f.includes('evidence') && f.endsWith('.json'));

for (const file of evidenceFiles) {
const evidence = JSON.parse(fs.readFileSync(file));
if (!evidence.chittyId || !evidence.chittyId.startsWith('CHITTY-')) {
console.error('Invalid evidence file:', file);
process.exit(1);
}
}
console.log('✅ Evidence chain validated');
"

# Phase 3: Multi-Service Deployment
deploy-ecosystem:
node-version: '20'
cache: npm
- run: npm ci
- run: npm run lint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Make the lint gate reject failures

On every PR and main-branch push, this step reports success without guaranteeing that lint ran: the root dependencies do not install ESLint, the repository has no ESLint configuration, and package.json ends the lint command with || echo 'Linting complete', which converts missing-tool, configuration, and lint errors to exit code 0. Because the production deployment only needs: lint, a main push can therefore deploy after a false-green gate; install/configure ESLint and stop swallowing its exit status.

Useful? React with 👍 / 👎.


deploy:
name: Deploy to Cloudflare
needs: lint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Gate deployment on security and compliance checks

For a direct push to main, this job now depends only on lint and can deploy while the repository's security-review.yml and path-scoped chittyos-compliance.yml workflows are still running or have failed; separate GitHub Actions workflows cannot satisfy this needs. This removes the previous in-pipeline compliance dependency, so a commit containing a hardcoded ChittyID or another security violation can reach production despite a red security workflow; make the required checks part of this dependency chain before deploying.

Useful? React with 👍 / 👎.

if: github.ref == 'refs/heads/main' && github.event_name == 'push'
Comment on lines +27 to +30

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Serialize production deployments

When two commits are pushed to main close together, these deployment jobs can run concurrently because the workflow defines no concurrency group or stale-run cancellation. If the older run spends longer in npm ci or Wrangler, its deployment can finish after the newer run and roll the shared Cloudflare production worker and routes back to the older commit; serialize this job or cancel superseded main-branch deployments.

Useful? React with 👍 / 👎.

runs-on: ubuntu-latest
name: Deploy ChittyOS Ecosystem
needs: [codex-review, ecosystem-validation]
if: needs.codex-review.outputs.review-status == 'passed'
strategy:
matrix:
service:
- chittychat
- chittymcp
- chittyrouter
- chittyschema
- chittyregistry

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
- uses: actions/setup-node@v4
with:
node-version: '18'

- name: Deploy ${{ matrix.service }}
run: |
SERVICE_DIR="/Users/nb/.claude/projects/-/${{ matrix.service }}"

if [ -d "$SERVICE_DIR" ]; then
echo "Deploying ${{ matrix.service }}..."
cd "$SERVICE_DIR"

# Install dependencies if package.json exists
if [ -f "package.json" ]; then
npm ci
fi

# Run service-specific deployment
if [ -f "wrangler.toml" ]; then
npx wrangler deploy --env production
elif [ -f "deploy.sh" ]; then
chmod +x deploy.sh && ./deploy.sh
else
echo "No deployment configuration found for ${{ matrix.service }}"
fi
else
echo "Service directory not found: ${{ matrix.service }}"
fi

# Phase 4: Integration Smoke Tests
smoke-tests:
runs-on: ubuntu-latest
name: Ecosystem Smoke Tests
needs: deploy-ecosystem

steps:
- name: Test ChittyOS Services
run: |
echo "Running ecosystem smoke tests..."

# Test core services
SERVICES=(
"https://gateway.chitty.cc/health"
"https://mcp.chitty.cc/health"
"https://id.chitty.cc/health"
"https://registry.chitty.cc/health"
"https://schema.chitty.cc/health"
)

for service in "${SERVICES[@]}"; do
echo "Testing $service..."
if curl -f "$service" --max-time 30; then
echo "✅ $service is healthy"
else
echo "❌ $service failed health check"
# Don't fail immediately - collect all results
fi
done

- name: Test ChittyID Integration
run: |
echo "Testing ChittyID service integration..."

# Test ID minting
CHITTY_ID=$(curl -X POST https://id.chitty.cc/v1/mint \
-H "Authorization: Bearer $CHITTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"entity_type": "EVNT"}' \
--max-time 30 | jq -r '.chittyId')

if [[ "$CHITTY_ID" =~ ^CHITTY-EVNT-.* ]]; then
echo "✅ ChittyID minting successful: $CHITTY_ID"
else
echo "❌ ChittyID minting failed"
exit 1
fi

- name: Final Status Report
run: |
echo "🎯 ChittyOS Ecosystem Deployment Complete!"
echo "✅ Codex Review: Passed (Score: ${{ needs.codex-review.outputs.security-score }})"
echo "✅ Ecosystem Validation: Passed"
echo "✅ Multi-Service Deployment: Completed"
echo "✅ Smoke Tests: All services operational"

# Update deployment status
curl -X POST https://registry.chitty.cc/api/deployments \
-H "Authorization: Bearer $CHITTY_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"deployment_id\": \"$GITHUB_RUN_ID\",
\"status\": \"completed\",
\"services\": [\"chittychat\", \"chittymcp\", \"chittyrouter\", \"chittyschema\", \"chittyregistry\"],
\"codex_score\": ${{ needs.codex-review.outputs.security-score }},
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
}" || echo "Registry update failed (non-critical)"
node-version: '20'
cache: npm
- run: npm ci
- run: npm run deploy:production
Loading
Loading