* feat: add security logging and fix framework regressions This commit implements comprehensive security event logging and resolves critical regressions in the core framework. Security Logging: - Enhanced `pkg/log` with a `Security` level and helper. - Added `log.Username()` to consistently identify the executing user. - Instrumented GitHub CLI auth, Agentic configuration, filesystem sandbox, MCP handlers, and MCP TCP transport with security logs. - Added `SecurityStyle` to the CLI for consistent visual representation of security events. UniFi Security (CodeQL): - Refactored `pkg/unifi` to remove hardcoded `InsecureSkipVerify`, resolving a high-severity alert. - Added a `--verify-tls` flag and configuration option to control TLS verification. - Updated command handlers to support the new verification parameter. Framework Fixes: - Restored original signatures for `MustServiceFor`, `Config()`, and `Display()` in `pkg/framework/core`, which had been corrupted during a merge. - Fixed `pkg/framework/framework.go` and `pkg/framework/core/runtime_pkg.go` to match the restored signatures. - These fixes resolve project-wide compilation errors caused by the signature mismatches. I encountered significant blockers due to a corrupted state of the `dev` branch after a merge, which introduced breaking changes in the core framework's DI system. I had to manually reconcile these signatures with the expected usage across the codebase to restore build stability. * feat(mcp): add RAG tools (query, ingest, collections) Add vector database tools to the MCP server for RAG operations: - rag_query: Search for relevant documentation using semantic similarity - rag_ingest: Ingest files or directories into the vector database - rag_collections: List available collections Uses existing internal/cmd/rag exports (QueryDocs, IngestDirectory, IngestFile) and pkg/rag for Qdrant client access. Default collection is "hostuk-docs" with topK=5 for queries. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(mcp): add metrics tools (record, query) Add MCP tools for recording and querying AI/security metrics events. The metrics_record tool writes events to daily JSONL files, and the metrics_query tool provides aggregated statistics by type, repo, and agent. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add 'core mcp serve' command Add CLI command to start the MCP server for AI tool integration. - Create internal/cmd/mcpcmd package with serve subcommand - Support --workspace flag for directory restriction - Handle SIGINT/SIGTERM for clean shutdown - Register in full.go build variant Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ws): add WebSocket hub package for real-time streaming Add pkg/ws package implementing a hub pattern for WebSocket connections: - Hub manages client connections, broadcasts, and channel subscriptions - Client struct represents connected WebSocket clients - Message types: process_output, process_status, event, error, ping/pong - Channel-based subscription system (subscribe/unsubscribe) - SendProcessOutput and SendProcessStatus for process streaming integration - Full test coverage including concurrency tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(mcp): add process management and WebSocket MCP tools Add MCP tools for process management: - process_start: Start a new external process - process_stop: Gracefully stop a running process - process_kill: Force kill a process - process_list: List all managed processes - process_output: Get captured process output - process_input: Send input to process stdin Add MCP tools for WebSocket: - ws_start: Start WebSocket server for real-time streaming - ws_info: Get hub statistics (clients, channels) Update Service struct with optional process.Service and ws.Hub fields, new WithProcessService and WithWSHub options, getter methods, and Shutdown method for cleanup. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(webview): add browser automation package via Chrome DevTools Protocol Add pkg/webview package for browser automation: - webview.go: Main interface with Connect, Navigate, Click, Type, QuerySelector, Screenshot, Evaluate - cdp.go: Chrome DevTools Protocol WebSocket client implementation - actions.go: DOM action types (Click, Type, Hover, Scroll, etc.) and ActionSequence builder - console.go: Console message capture and filtering with ConsoleWatcher and ExceptionWatcher - angular.go: Angular-specific helpers for router navigation, component access, and Zone.js stability Add MCP tools for webview: - webview_connect/disconnect: Connection management - webview_navigate: Page navigation - webview_click/type/query/wait: DOM interaction - webview_console: Console output capture - webview_eval: JavaScript execution - webview_screenshot: Screenshot capture Add documentation: - docs/mcp/angular-testing.md: Guide for Angular application testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: document new packages and BugSETI application - Update CLAUDE.md with documentation for: - pkg/ws (WebSocket hub for real-time streaming) - pkg/webview (Browser automation via CDP) - pkg/mcp (MCP server tools: process, ws, webview) - BugSETI application overview - Add comprehensive README for BugSETI with: - Installation and configuration guide - Usage workflow documentation - Architecture overview - Contributing guidelines Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(bugseti): add BugSETI system tray app with auto-update BugSETI - Distributed Bug Fixing like SETI@home but for code Features: - System tray app with Wails v3 - GitHub issue fetching with label filters - Issue queue with priority management - AI context seeding via seed-agent-developer skill - Automated PR submission flow - Stats tracking and leaderboard - Cross-platform notifications - Self-updating with stable/beta/nightly channels Includes: - cmd/bugseti: Main application with Angular frontend - internal/bugseti: Core services (fetcher, queue, seeder, submit, config, stats, notify) - internal/bugseti/updater: Auto-update system (checker, downloader, installer) - .github/workflows/bugseti-release.yml: CI/CD for all platforms Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: resolve import cycle and code duplication - Remove pkg/log import from pkg/io/local to break import cycle (pkg/log/rotation.go imports pkg/io, creating circular dependency) - Use stderr logging for security events in sandbox escape detection - Remove unused sync/atomic import from core.go - Fix duplicate LogSecurity function declarations in cli/log.go - Update workspace/service.go Crypt() call to match interface Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: update tests for new function signatures and format code - Update core_test.go: Config(), Display() now panic instead of returning error - Update runtime_pkg_test.go: sr.Config() now panics instead of returning error - Update MustServiceFor tests to use assert.Panics - Format BugSETI, MCP tools, and webview packages with gofmt Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Snider <631881+Snider@users.noreply.github.com> Co-authored-by: Claude <developers@lethean.io> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
309 lines
10 KiB
YAML
309 lines
10 KiB
YAML
# BugSETI Release Workflow
|
|
# Builds for all platforms and creates GitHub releases
|
|
name: "BugSETI Release"
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'bugseti-v*.*.*' # Stable: bugseti-v1.0.0
|
|
- 'bugseti-v*.*.*-beta.*' # Beta: bugseti-v1.0.0-beta.1
|
|
- 'bugseti-nightly-*' # Nightly: bugseti-nightly-20260205
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
env:
|
|
APP_NAME: bugseti
|
|
WAILS_VERSION: "3"
|
|
|
|
jobs:
|
|
# Determine release channel from tag
|
|
prepare:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.version.outputs.version }}
|
|
channel: ${{ steps.version.outputs.channel }}
|
|
prerelease: ${{ steps.version.outputs.prerelease }}
|
|
steps:
|
|
- name: Determine version and channel
|
|
id: version
|
|
env:
|
|
TAG: ${{ github.ref_name }}
|
|
run: |
|
|
if [[ "$TAG" == bugseti-nightly-* ]]; then
|
|
VERSION="${TAG#bugseti-}"
|
|
CHANNEL="nightly"
|
|
PRERELEASE="true"
|
|
elif [[ "$TAG" == *-beta.* ]]; then
|
|
VERSION="${TAG#bugseti-v}"
|
|
CHANNEL="beta"
|
|
PRERELEASE="true"
|
|
else
|
|
VERSION="${TAG#bugseti-v}"
|
|
CHANNEL="stable"
|
|
PRERELEASE="false"
|
|
fi
|
|
|
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
echo "channel=${CHANNEL}" >> "$GITHUB_OUTPUT"
|
|
echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT"
|
|
|
|
echo "Tag: $TAG"
|
|
echo "Version: $VERSION"
|
|
echo "Channel: $CHANNEL"
|
|
echo "Prerelease: $PRERELEASE"
|
|
|
|
build:
|
|
needs: prepare
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# macOS ARM64 (Apple Silicon)
|
|
- os: macos-latest
|
|
goos: darwin
|
|
goarch: arm64
|
|
ext: ""
|
|
archive: tar.gz
|
|
# macOS AMD64 (Intel)
|
|
- os: macos-13
|
|
goos: darwin
|
|
goarch: amd64
|
|
ext: ""
|
|
archive: tar.gz
|
|
# Linux AMD64
|
|
- os: ubuntu-latest
|
|
goos: linux
|
|
goarch: amd64
|
|
ext: ""
|
|
archive: tar.gz
|
|
# Linux ARM64
|
|
- os: ubuntu-24.04-arm
|
|
goos: linux
|
|
goarch: arm64
|
|
ext: ""
|
|
archive: tar.gz
|
|
# Windows AMD64
|
|
- os: windows-latest
|
|
goos: windows
|
|
goarch: amd64
|
|
ext: ".exe"
|
|
archive: zip
|
|
|
|
runs-on: ${{ matrix.os }}
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
CHANNEL: ${{ needs.prepare.outputs.channel }}
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: cmd/bugseti
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Setup Go
|
|
uses: host-uk/build/actions/setup/go@v4.0.0
|
|
with:
|
|
go-version: "1.25"
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "20"
|
|
|
|
- name: Install Wails CLI
|
|
run: go install github.com/wailsapp/wails/v3/cmd/wails3@latest
|
|
|
|
- name: Install frontend dependencies
|
|
working-directory: cmd/bugseti/frontend
|
|
run: npm ci
|
|
|
|
- name: Generate bindings
|
|
run: wails3 generate bindings -f '-tags production' -clean=false -ts -i
|
|
|
|
- name: Build frontend
|
|
working-directory: cmd/bugseti/frontend
|
|
run: npm run build
|
|
|
|
- name: Install Linux dependencies
|
|
if: matrix.goos == 'linux'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev
|
|
|
|
- name: Build BugSETI
|
|
shell: bash
|
|
env:
|
|
EXT: ${{ matrix.ext }}
|
|
ARCHIVE: ${{ matrix.archive }}
|
|
COMMIT_SHA: ${{ github.sha }}
|
|
run: |
|
|
BINARY="${APP_NAME}${EXT}"
|
|
ARCHIVE_PREFIX="${APP_NAME}-${GOOS}-${GOARCH}"
|
|
|
|
BUILD_FLAGS="-tags production -trimpath -buildvcs=false"
|
|
|
|
# Version injection via ldflags
|
|
LDFLAGS="-s -w"
|
|
LDFLAGS="${LDFLAGS} -X github.com/host-uk/core/internal/bugseti.Version=${VERSION}"
|
|
LDFLAGS="${LDFLAGS} -X github.com/host-uk/core/internal/bugseti.Channel=${CHANNEL}"
|
|
LDFLAGS="${LDFLAGS} -X github.com/host-uk/core/internal/bugseti.Commit=${COMMIT_SHA}"
|
|
LDFLAGS="${LDFLAGS} -X github.com/host-uk/core/internal/bugseti.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
|
|
if [ "$GOOS" = "windows" ]; then
|
|
export CGO_ENABLED=0
|
|
LDFLAGS="${LDFLAGS} -H windowsgui"
|
|
|
|
# Generate Windows syso resource
|
|
cd build
|
|
wails3 generate syso -arch ${GOARCH} -icon windows/icon.ico -manifest windows/wails.exe.manifest -info windows/info.json -out ../wails_windows_${GOARCH}.syso 2>/dev/null || true
|
|
cd ..
|
|
elif [ "$GOOS" = "darwin" ]; then
|
|
export CGO_ENABLED=1
|
|
export CGO_CFLAGS="-mmacosx-version-min=10.15"
|
|
export CGO_LDFLAGS="-mmacosx-version-min=10.15"
|
|
export MACOSX_DEPLOYMENT_TARGET="10.15"
|
|
else
|
|
export CGO_ENABLED=1
|
|
fi
|
|
|
|
mkdir -p bin
|
|
go build ${BUILD_FLAGS} -ldflags="${LDFLAGS}" -o "./bin/${BINARY}"
|
|
|
|
# Clean up syso files
|
|
rm -f *.syso
|
|
|
|
# Package based on platform
|
|
if [ "$GOOS" = "darwin" ]; then
|
|
# Create .app bundle
|
|
mkdir -p "./bin/BugSETI.app/Contents/"{MacOS,Resources}
|
|
cp build/darwin/icons.icns "./bin/BugSETI.app/Contents/Resources/" 2>/dev/null || true
|
|
cp "./bin/${BINARY}" "./bin/BugSETI.app/Contents/MacOS/"
|
|
cp build/darwin/Info.plist "./bin/BugSETI.app/Contents/"
|
|
codesign --force --deep --sign - "./bin/BugSETI.app" 2>/dev/null || true
|
|
tar czf "./bin/${ARCHIVE_PREFIX}.tar.gz" -C ./bin "BugSETI.app"
|
|
elif [ "$GOOS" = "windows" ]; then
|
|
cd ./bin && zip "${ARCHIVE_PREFIX}.zip" "${BINARY}" && cd ..
|
|
else
|
|
tar czf "./bin/${ARCHIVE_PREFIX}.tar.gz" -C ./bin "${BINARY}"
|
|
fi
|
|
|
|
# Rename raw binary for individual download
|
|
mv "./bin/${BINARY}" "./bin/${ARCHIVE_PREFIX}${EXT}"
|
|
|
|
# Generate checksum
|
|
cd ./bin
|
|
sha256sum "${ARCHIVE_PREFIX}.${ARCHIVE}" > "${ARCHIVE_PREFIX}.${ARCHIVE}.sha256"
|
|
sha256sum "${ARCHIVE_PREFIX}${EXT}" > "${ARCHIVE_PREFIX}${EXT}.sha256"
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bugseti-${{ matrix.goos }}-${{ matrix.goarch }}
|
|
path: |
|
|
cmd/bugseti/bin/bugseti-*
|
|
retention-days: 7
|
|
|
|
release:
|
|
needs: [prepare, build]
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
TAG_NAME: ${{ github.ref_name }}
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
CHANNEL: ${{ needs.prepare.outputs.channel }}
|
|
PRERELEASE: ${{ needs.prepare.outputs.prerelease }}
|
|
REPO: ${{ github.repository }}
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
path: dist
|
|
merge-multiple: true
|
|
|
|
- name: List release files
|
|
run: |
|
|
echo "=== Release files ==="
|
|
ls -la dist/
|
|
echo "=== Checksums ==="
|
|
cat dist/*.sha256
|
|
|
|
- name: Create release
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# Determine release title
|
|
if [ "$CHANNEL" = "nightly" ]; then
|
|
TITLE="BugSETI Nightly (${VERSION})"
|
|
elif [ "$CHANNEL" = "beta" ]; then
|
|
TITLE="BugSETI v${VERSION} (Beta)"
|
|
else
|
|
TITLE="BugSETI v${VERSION}"
|
|
fi
|
|
|
|
# Create release notes
|
|
cat > release-notes.md << EOF
|
|
## BugSETI ${VERSION}
|
|
|
|
**Channel:** ${CHANNEL}
|
|
|
|
### Downloads
|
|
|
|
| Platform | Architecture | Binary | Archive |
|
|
|----------|-------------|--------|---------|
|
|
| macOS | ARM64 (Apple Silicon) | [bugseti-darwin-arm64](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-darwin-arm64) | [tar.gz](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-darwin-arm64.tar.gz) |
|
|
| macOS | AMD64 (Intel) | [bugseti-darwin-amd64](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-darwin-amd64) | [tar.gz](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-darwin-amd64.tar.gz) |
|
|
| Linux | AMD64 | [bugseti-linux-amd64](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-linux-amd64) | [tar.gz](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-linux-amd64.tar.gz) |
|
|
| Linux | ARM64 | [bugseti-linux-arm64](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-linux-arm64) | [tar.gz](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-linux-arm64.tar.gz) |
|
|
| Windows | AMD64 | [bugseti-windows-amd64.exe](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-windows-amd64.exe) | [zip](https://github.com/${REPO}/releases/download/${TAG_NAME}/bugseti-windows-amd64.zip) |
|
|
|
|
### Checksums (SHA256)
|
|
|
|
\`\`\`
|
|
$(cat dist/*.sha256)
|
|
\`\`\`
|
|
|
|
---
|
|
*BugSETI - Distributed Bug Fixing, like SETI@home but for code*
|
|
EOF
|
|
|
|
# Build release command
|
|
RELEASE_ARGS=(
|
|
--title "$TITLE"
|
|
--notes-file release-notes.md
|
|
)
|
|
|
|
if [ "$PRERELEASE" = "true" ]; then
|
|
RELEASE_ARGS+=(--prerelease)
|
|
fi
|
|
|
|
# Create the release
|
|
gh release create "$TAG_NAME" \
|
|
"${RELEASE_ARGS[@]}" \
|
|
dist/*
|
|
|
|
# Scheduled nightly builds
|
|
nightly:
|
|
if: github.event_name == 'schedule'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Create nightly tag
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
DATE=$(date -u +%Y%m%d)
|
|
TAG="bugseti-nightly-${DATE}"
|
|
|
|
# Delete existing nightly tag for today if it exists
|
|
gh release delete "$TAG" --yes 2>/dev/null || true
|
|
git push origin ":refs/tags/$TAG" 2>/dev/null || true
|
|
|
|
# Create new tag
|
|
git tag "$TAG"
|
|
git push origin "$TAG"
|