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
28 changes: 28 additions & 0 deletions .deployignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Files and directories to exclude from deploy
.git
.gitignore
.github/
.env
*.env
venv/
.venv/
env/
__pycache__/
*.pyc
local_markets_db/
local_db*
*.sqlite
*.db
logs/
*.log
*.pem
*.key
node_modules/
coverage/
dist/
build/
.idea/
.vscode/
*.egg-info/

# Add any other local artifacts you don't want deployed
31 changes: 31 additions & 0 deletions .github/automation/README_AUTOMATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Automations‑Guide (semi‑automatic workflow)

Kurz:
- Workflow `.github/workflows/bot-auto-pr.yml` erstellt automatisch einen Draft‑PR (`automation/bot-auto-pr`) nachdem Lint/Tests gelaufen sind.
- Du reviewst den PR manuell und mergest nach Freigabe.

Empfohlene Einstellungen:
1) Branch‑Protection auf `main`
- Require pull request reviews before merging (1 reviewer)
- Require status checks to pass (CI)
- Include administrators (optional)

2) Secrets / Tokens
- Der Workflow nutzt das automatisch bereitgestellte `GITHUB_TOKEN` — kein PAT nötig für PR‑Erstellung.
- Falls du später Aktionen brauchst, die externen Zugriff benötigen (z.B. Deployment), erstelle einen separaten PAT mit minimalen Scopes und lege ihn in Repository → Settings → Secrets → Actions.
Empfohlene minimale Scopes für Deploy (wenn nötig):
- repo (only if pushing tags/branches required)
- workflow (if triggering workflows)
- Weitere Scopes nur bei Bedarf.

3) Review‑Prozess
- PR wird als Entwurf erstellt. Prüfe Änderungen lokal oder in GitHub UI, führe Tests aus und merge erst nach Review.

4) Sicherheit
- Niemals Tokens in Code oder Issue‑Vorlagen einchecken.
- Revoke/drehe Tokens sofort, falls sie versehentlich veröffentlicht wurden.

Wenn du möchtest, kann ich:
- eine einfache Deploy‑Action (nur beim Merge) anlegen, die nach Merge automatisch in ein staging Verzeichnis deployed (benötigt Secret).
- oder zusätzliche PR‑Templates/labels für automatisierte PRs erstellen.

40 changes: 40 additions & 0 deletions .github/automation/README_AUTOMATION_EXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Ergänzung: Deploy‑Secrets und Schnellstart

Kurz: Diese Anleitung erklärt, wie du die optionalen Deploy‑Secrets sicher anlegst, damit der Deploy‑Workflow nach Merge funktioniert.

1) SSH‑Key erzeugen (lokal)
ssh-keygen -t rsa -b 4096 -C "deploy@yourhost" -f ~/.ssh/agents_deploy_key
- Public: ~/.ssh/agents_deploy_key.pub
- Private: ~/.ssh/agents_deploy_key

2) Public key auf Zielserver installieren
- Melde dich auf dem Zielserver als Deploy‑User an und füge die Public key zu `~/.ssh/authorized_keys`.
- Setze korrekte Rechte: `chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys`

3) Secrets in GitHub setzen
Repository → Settings → Secrets and variables → Actions → New repository secret
Erstelle folgende Secrets (Namen exakt verwenden):
- DEPLOY_HOST (z. B. example.com)
- DEPLOY_USER (z. B. deployuser)
- DEPLOY_PORT (optional, wenn nicht gesetzt: 22)
- DEPLOY_TARGET (Zielpfad, z. B. /var/www/agents)
- DEPLOY_SSH_KEY (Inhalt der privaten Key‑Datei `~/.ssh/agents_deploy_key` — ganze Datei einfügen)

4) Sicherheitshinweise
- Verwende einen dedizierten Deploy‑User mit minimalen Rechten.
- Lege keine Secrets in Repo‑Dateien oder Chatnachrichten ab.
- Rotiere oder widerrufe Keys sofort, falls sie kompromittiert wurden.

5) Testen
- Merge oder push auf `main` (oder simuliere lokal). Deploy‑Job läuft nur, wenn die oben genannten Secrets vorhanden sind.

Optional: Ich kann ein kurzes Shell‑Testscript hinzufügen, das vor dem ersten Merge die SSH‑Verbindung prüft (ssh -i KEY -p PORT USER@HOST echo ok). Soll ich das zusätzlich anlegen? (ja/nein)

Hinweis zum Testscript:
- Datei: `scripts/test_deploy_ssh.sh` (bereits vorhanden im Repo)
- Beispielaufruf:
- `./scripts/test_deploy_ssh.sh -h example.com -u deployuser -k ~/.ssh/agents_deploy_key -p 22 -t /var/www/agents`
- Das Script prüft SSH‑Login und optionales SCP eines kleinen Testfiles in das angegebene Zielverzeichnis.

Führe das Script lokal aus, bevor du Secrets in GitHub setzt, um sicherzustellen, dass der Deploy‑User korrekt konfiguriert ist.

87 changes: 87 additions & 0 deletions .github/workflows/bot-auto-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Bot — Auto PRs (semi-automatic)

on:
push:
branches:
- 'bot/**'
schedule:
- cron: '0 2 * * *' # daily at 02:00 UTC
workflow_dispatch:

jobs:
test-and-lint:
name: Test & Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install dependencies (if any)
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
pip install black==23.12.0 flake8 pytest || true

- name: Run black (check)
run: |
if command -v black >/dev/null 2>&1; then
black --check . || true
fi

- name: Run flake8
run: |
if command -v flake8 >/dev/null 2>&1; then
flake8 || true
fi

- name: Run tests (pytest)
run: |
if command -v pytest >/dev/null 2>&1; then
pytest -q || true
Copy link

Choose a reason for hiding this comment

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

Test failures do not block PR creation

Medium Severity

The lint and test steps use || true, so failures in black, flake8, or pytest do not fail the test-and-lint job. create-pr still runs via needs, allowing automated PRs to be created even when checks fail.

Fix in Cursor Fix in Web

fi
# flake8 already run above in "Run flake8" step; avoid duplicate execution.

create-pr:
name: Create Pull Request
runs-on: ubuntu-latest
needs: test-and-lint
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Configure git for auto-commits
run: |
git config user.name "automation-bot"
git config user.email "automation-bot@users.noreply.github.com"

- name: Autoformat with black (if installed)
run: |
if python -c "import importlib.util,sys; sys.exit(0 if importlib.util.find_spec('black') else 1)"; then
python -m black . || true
git add -A
git diff --quiet --cached || (git commit -m "style: autoformat with black" || true)
fi

# This action will create a PR from branch `automation/bot-auto-pr` when changes exist.
- name: Create Pull Request (draft)
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'chore(ci): automated fixes / checks'
branch: automation/bot-auto-pr
title: "chore(ci): automated bot PR"
body: |
This pull request was created automatically by the repository automation workflow.
It contains automated lint/test fixes or CI suggestions. Please review before merging.
labels: automated
draft: true

53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:

jobs:
tests:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
python-version: ["3.11"]

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

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"

- name: Install dependencies
shell: bash
run: |
python -m pip install --upgrade pip

# Prefer editable install if pyproject/setup exists
if [ -f pyproject.toml ]; then
pip install -e ".[dev]" || pip install -e .
fi

# Fallback to requirements files if present
if [ -f requirements.txt ]; then
pip install -r requirements.txt
fi
if [ -f requirements-dev.txt ]; then
pip install -r requirements-dev.txt
fi

# Ensure pytest is available even if not in deps
pip show pytest >/dev/null 2>&1 || pip install pytest pytest-asyncio

- name: Run tests
env:
PYTHONUNBUFFERED: "1"
run: |
pytest -q

4 changes: 2 additions & 2 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ permissions:

jobs:
dependency-review:
if: ${{ github.event.pull_request.head.repo.fork == false }}
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v4
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
# Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options.
with:
comment-summary-in-pr: always
# Avoid PR comment write requirement that often fails on restricted tokens/forks
# fail-on-severity: moderate
# deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later
# retry-on-snapshot-warnings: true
100 changes: 100 additions & 0 deletions .github/workflows/deploy-on-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Deploy on Merge (optional)

# This workflow performs an optional SSH/SCP deploy when code is merged to `main`.
# It only runs the deploy step if the required secrets are provided in the repository:
# - DEPLOY_HOST
# - DEPLOY_USER
# - DEPLOY_SSH_KEY
# - DEPLOY_TARGET
# - DEPLOY_PORT (optional, defaults to 22)
#
# To enable: add the above secrets in GitHub → Settings → Secrets → Actions.

on:
push:
branches:
- main

jobs:
build:
name: Build / Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install deps (if any)
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

- name: Run quick tests (if pytest)
run: |
if command -v pytest >/dev/null 2>&1; then pytest -q || true; fi

deploy:
name: Deploy (conditional)
runs-on: ubuntu-latest
needs: build
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
DEPLOY_TARGET: ${{ secrets.DEPLOY_TARGET }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check deploy secrets
id: check-secrets
run: |
if [ -n "$DEPLOY_HOST" ] && [ -n "$DEPLOY_SSH_KEY" ]; then
echo "has_secrets=true" >> $GITHUB_OUTPUT
Copy link

Choose a reason for hiding this comment

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

Deploy secret validation misses required fields

Medium Severity

The deploy gate only checks DEPLOY_HOST and DEPLOY_SSH_KEY, but deployment later requires DEPLOY_USER and DEPLOY_TARGET too. The workflow can proceed with incomplete configuration and run rsync with empty destination components, causing avoidable deploy failures.

Additional Locations (1)

Fix in Cursor Fix in Web

else
echo "has_secrets=false" >> $GITHUB_OUTPUT
fi

- name: Prepare SSH key
if: steps.check-secrets.outputs.has_secrets == 'true'
run: |
mkdir -p ~/.ssh
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa

- name: Ensure known_hosts (optional)
if: steps.check-secrets.outputs.has_secrets == 'true'
run: |
PORT="${DEPLOY_PORT:-22}"
ssh-keyscan -p "$PORT" -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts || true

- name: Copy files to target via scp
if: steps.check-secrets.outputs.has_secrets == 'true'
run: |
PORT="${DEPLOY_PORT:-22}"
echo "Deploying to $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_TARGET (port $PORT) using rsync with .deployignore"
# Prefer using .deployignore in repo root to control excludes.
if [ -f .deployignore ]; then
rsync -az --delete --exclude-from='.deployignore' -e "ssh -p $PORT -o StrictHostKeyChecking=yes" . "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_TARGET"
Copy link

Choose a reason for hiding this comment

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

Deploy rsync --delete destroys runtime state files on target

High Severity

The rsync --delete command removes target-side files that aren't in the source checkout and aren't excluded. Runtime state files like position_state.json, paper_trades.jsonl, pending_confirmations.json, and data/risk_state.json are not listed in .deployignore, are not in git (gitignored), and therefore don't exist in the source. Every deploy would wipe all active trade state, paper trade history, risk kill-switch state, and pending confirmations from the production server.

Additional Locations (1)

Fix in Cursor Fix in Web

else
echo ".deployignore not found, using conservative inline excludes"
rsync -az --delete \
--exclude='.git' \
--exclude='.env' \
--exclude='*.env' \
--exclude='venv/' \
--exclude='.venv/' \
--exclude='env/' \
--exclude='__pycache__/' \
--exclude='*.pyc' \
--exclude='local_markets_db/' \
--exclude='*.sqlite' \
--exclude='*.db' \
--exclude='logs/' \
-e "ssh -p $PORT -o StrictHostKeyChecking=yes" . "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_TARGET"
fi
Loading