refactor: hexagonal architecture, DDD domain layer, CD service rename, CI tests#90
Open
ronenhamias wants to merge 10 commits into
Open
refactor: hexagonal architecture, DDD domain layer, CD service rename, CI tests#90ronenhamias wants to merge 10 commits into
ronenhamias wants to merge 10 commits into
Conversation
- Remove unused imports, smee() function, and empty event handler from index.js - Remove 6 unused static methods from utils.js (isPullRequest, time, mapToChecks, format, getPrgress, toPrgress) - Remove unused labels() and content() methods from github-service.js - Remove unused sendResponse() from http-gateway.js - Simplify toDeployRequest() in environments.js by removing empty release branches - Remove no-op env() wrapper from statuses/templates.js - Remove broken build/watch scripts and unused deps (lodash, body-parser, smee-client, babel stack) from package.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When LOCAL_DEV=true in .env: - robokit.js skips Vault k8s login and starts the Probot server directly using credentials already present in .env - environments.js skips the WebSocket connection to the env service and returns a mock observable that emits RUNNING -> SUCCEEDED events so the full GitHub check-run flow can be exercised locally Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… LOCAL_DEV mode - Replace God-class http-gateway with focused domain modules: coordinator, context, check-run, deployment, environment - Remove all pull_request and feature-branch deploy label code - Add LOCAL_DEV mode: skips Vault auth and env-service, uses mock deploy - Add e2e test suite (test/e2e.test.js) and fakewebhook.ps1 for manual testing - Fix bugs: duration calculation (getSeconds), vault-api constructor, connectFailed promise - Remove new Promise antipatterns; flatten all async flows to async/await - Remove unused statuses (waiting, running), config fields, and dead env vars - Add ROBOKIT_RELEASE_CHECK constant; single-expression shouldTrigger - Simplify cache and templates (remove unnecessary classes) - Write comprehensive README with setup, config reference, and trigger docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename environment service → CdServiceClient (cd-service/) to reflect what it actually does: continuous deployment - Extract domain layer: PipelineStatus, DeploymentPolicy, DeploymentContext - Extract application layer: DeploymentOrchestrator, deploymentLock - Extract adapters: CheckRunAdapter, DeploymentAdapter, OctokitRegistry - Add structured JSON logging via pino (replaces console.log with tags) - Add /health endpoint for Kubernetes liveness probes - Add per-repo deployment concurrency lock (prevents double-deploy on rapid pushes to same branch) - Fix CANCELLED/CANCELED typo in status mapping (dead code in marker()) - Fix WebSocket double-connect race condition in CdServiceClient - Remove GitHub API preview headers (ant-man, flash — now stable) - Validate required env vars at boot, exit with clear error if missing - Remove mystery trigger-deploy file - Remove rxjs-compat, use rxjs Subject directly - Move templates to src/templates/, fix "Continues" → "Continuous" typo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PipelineStatus: all env→GitHub mappings, marker symbols, isTerminal, unknown-status fallbacks, and a guard against the CANCELED/CANCELLED typo - DeploymentContext: field assignment, Object.freeze, withCheckRunName, withNamespace, chaining - DeploymentPolicy: CI trigger (deployable/non-deployable branch, release bypass, wrong conclusion), release trigger, own-check-run guard, user action evaluation (deploy_now, cancel, null/unknown) - deploymentLock: concurrent key isolation, skips duplicate, releases on completion and on error, isLocked reflects live state - Delete dead test/index.test.js (referenced deleted index.js) - Add /health check to e2e suite Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
npm test must pass before the image is built or the deploy trigger fires. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Superseded by the e2e test suite (test/e2e.test.js) which sends signed webhooks programmatically via npm run test:e2e. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
trigger-deploy removed — manual deploy triggers replaced by the Re-Deploy button on the Robokit CD check run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace old app/ flat layout with new src/ hexagonal tree - Remove deleted fakewebhook.ps1 section - Clean up .env example (remove removed E2E-only variables) - Add GET /health endpoint documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Complete architectural overhaul of Robokit from a flat, monolithic layout into a hexagonal (ports & adapters) architecture with a clean domain-driven design layer. Alongside the structural refactor, the "environment service" concept is consistently renamed to Continuous Deployment (CD) service throughout the codebase.
What changed
Architecture — Hexagonal / DDD
The entire
app/directory is replaced bysrc/with strict layering:Deleted (dead / replaced):
app/cache.js,app/config.js,app/environments.js,app/github-service.js,app/http-gateway.js,app/utils.js,app/vault-api.js,app/statuses/templates.js,index.js,robokit.jsDomain layer (
src/domain/)PipelineStatus.jsCANCELLEDvsCANCELEDtypo bug.DeploymentContext.jsObject.freeze). All deploy state in one place;withCheckRunName()/withNamespace()return new instances.DeploymentPolicy.jsevaluate(checkRun)decides trigger type;evaluateUserAction(action)maps GitHub button clicks. Zero I/O.Application layer (
src/application/)DeploymentOrchestrator.jscoordinator.js. Drives the full deploy pipeline: build immutable context → acquire lock → create check run → stream CD service → update GitHub on every status change → finalize. Uses localstateobject instead of mutable shared object.deploymentLock.jsowner/repo:branchconcurrency guard. A second deploy for the same key while one is in-flight is skipped with a warning rather than running in parallel.Adapters (
src/adapters/)cd-service/CdServiceClient.jsenvironments.js. Fixed WebSocket double-connect race with#connectingprivate field (reuses in-flight promise). Usesrxjsdirectly (Subject) — removesrxjs-compat.cd-service/CdServiceMock.jsLOCAL_DEV=true. Emits RUNNING×2 then SUCCEEDED; no real WS needed.github/CheckRunAdapter.jscheck-run.js. UsesPipelineStatus— fixes the CANCELLED conclusion bug. Removed obsoleteant-man-preview/flash-previewheaders.github/DeploymentAdapter.jsdeployment.js. Same cleanup.github/OctokitRegistry.jscache.js. Typed register/get with warn-on-miss.vault/VaultAdapter.jsvault-api.js.Infrastructure
src/config.js— validates all required env vars at boot (APP_ID,PRIVATE_KEY,WEBHOOK_SECRET), exits with a clear message on missing values. Groups all config in one object.src/logger.js— pino structured logger; child loggers carrydeployId,repo,branch,shacorrelation fields across the entire pipeline.src/server.js— selects real vs mock CD service based onLOCAL_DEV. AddsGET /healthendpoint ({ status, uptime, cdService }).src/templates/renderer.js— safe string interpolation (only substitutesstring | numbervalues). Fixed "Continues Delivery" → "Continuous Delivery" typo in templates.package.json— addedpino, removedrxjs-compat. Updated scripts:start→ Probot,robokit→ direct node for IntelliJ.Dockerfile— updatedCOPYpaths for newsrc/layout.Tests
test/unit/domain/PipelineStatus.test.js— 20 tests covering all status mappings, markers,isTerminal, unknown fallbacks, and the CANCELED/CANCELLED typo guard.test/unit/domain/DeploymentContext.test.js— 6 tests: field assignment, immutability,withCheckRunName,withNamespace, chaining.test/unit/domain/DeploymentPolicy.test.js— 14 tests: allevaluate()branches and allevaluateUserAction()cases.test/unit/application/deploymentLock.test.js— 6 tests: basic run, skip duplicate, release after completion, release after error, key isolation,isLockedstate.test/e2e.test.js— addedGET /healthtest; cleaned up stale commented-out tests.CI
.github/workflows/publish-docker.yml— added atestjob that runsnpm testbefore the Docker build. Thebuildjob now hasneeds: test, so a failing test blocks the image publish..envcleanupRemoved unused variables (
GITHUB_INSTALLATION_ID,GITHUB_OWNER,GITHUB_REPO,GITHUB_SHA). Regrouped remaining variables into four labelled sections:Server,GitHub App,Continuous Deployment Service,Vault.Test plan
npm testpasses (all unit tests green)testjob runs beforebuildon push todevelopLOCAL_DEV=true npm run robokitstarts without errors;/healthreturns{ status: 'ok' }check_runwebhook (smee.io) triggers the mock CD pipeline and completes the GitHub check rundeploy.skipped.already-in-progressand returns without error