diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..8cbaa24 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,40 @@ +# Deploys the reDeploy marketing site (apps/website, Vite static build) to GitHub +# Pages on every push to main. Uses the Actions-based Pages deployment (not classic +# branch-deploy) because the artifact is a build output, not a checked-in folder. +# Custom domain: redeploy.thesolidchain.com (configured in the repo's Pages settings; +# apps/website/public/CNAME travels with the artifact for good measure). +name: pages + +on: + push: + branches: [main] + paths: + - "apps/website/**" + - ".github/workflows/pages.yml" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - run: pnpm --filter @redeploy/website build + - uses: actions/configure-pages@v5 + - uses: actions/upload-pages-artifact@v3 + with: + path: apps/website/dist + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8bc5b89 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Roberto Cano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 96d8688..32dfc5a 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,121 @@ -# reDeploy +# reDeploy `^^` -reDeploy is a **deployment system built on top of Hardhat Ignition**. It lets you declaratively define -contract deployments (constructor args, inter-contract links, ordering), deploy them **idempotently and -resumably** (a contract already deployed is never re-deployed), apply **resumable post-deployment -configuration**, **verify** both source and on-chain configuration, and **read** existing deployment state from -external systems. A **visual studio** (drag-and-drop) authors the connection/config graph and inspects live -deployments. reDeploy reuses Hardhat Ignition's module engine, journal, and resume semantics wherever possible -rather than reinventing them. +> **Declarative, idempotent, verifiable smart-contract deployments** — built on +> [Hardhat Ignition](https://hardhat.org/ignition). One spec. One graph. One truth. +> +> **Website:** [redeploy.thesolidchain.com](https://redeploy.thesolidchain.com) · a product of **The Solid Chain** -Built for smart-contract teams deploying multi-contract systems across chains who need reproducible, resumable, -verifiable deployments and a visual way to wire and inspect them. +reDeploy lets you declaratively define contract deployments (constructor args, inter-contract links, +ordering), deploy them **idempotently and resumably** — a contract already deployed is never re-deployed, and +an interrupted run picks up exactly where it stopped — apply **resumable post-deployment configuration**, +**verify** both source and on-chain configuration, and **read** deployment state back through a typed API. +A **visual studio** (drag-and-drop) authors the connection/config graph and inspects live deployments. +reDeploy reuses Hardhat Ignition's module engine, journal, and resume semantics wherever possible rather than +reinventing them. + +Built for smart-contract teams deploying multi-contract systems across chains who need reproducible, +resumable, verifiable deployments — and a visual way to wire and inspect them. + +## Highlights + +- **Declarative spec** — contracts, args, `ref`s between them, and explicit ordering in one JSON document. + Args can be literals, per-network **params**, safe **expressions** (`keccak256`, CREATE2 addresses, + arithmetic), async **resolvers**, or values **read live** from already-deployed contracts. +- **Idempotent & resumable** — the Ignition journal is the source of truth. Re-running a deploy skips what's + on-chain, creates only what's missing, and resumes interrupted runs. Safe to run in CI. +- **Post-deploy configuration** — roles, wiring, setters declared as steps (`set` / `grantRole` / `wire`), + applied like migrations: journaled, resumable, re-runnable. +- **Two-layer verification** — source on Etherscan & Sourcify, plus on-chain assertion that the *live + configuration* still matches the declared spec. Drift is a diff, not an incident. +- **Multi-network** — one spec, many networks: per-network parameters, per-network journals, network + selection end-to-end from studio to server. +- **Visual studio** — drag-and-drop authoring over the same engine: simulate the plan, deploy for real, + inspect any live deployment. Emits the same spec files you'd write by hand. + +## Quick start + +```sh +git clone https://github.com/robercano/reDeploy && cd reDeploy +pnpm install +cp .env.example .env # fill in what you need; never commit .env + +# terminal 1 — a local chain +anvil + +# terminal 2 — the deploy server +pnpm --filter @redeploy/deploy-server dev + +# terminal 3 — the studio (proxies /api to the deploy server) +pnpm --filter @redeploy/studio dev # → http://localhost:5173 +``` + +Prefer the terminal? The `redeploy` CLI wraps the same libraries: + +```sh +redeploy simulate --spec protocol.spec.json # plan only, nothing on-chain +redeploy deploy --spec protocol.spec.json # idempotent, resumable +redeploy apply-config --spec protocol.spec.json # post-deploy steps +redeploy verify --source --config # both verification layers +redeploy status # read the journal back +``` + +Full local walkthrough (Anvil, `.env`, SSE endpoints, real deploy): +**[`docs/RUNBOOK-anvil-deploy.md`](docs/RUNBOOK-anvil-deploy.md)**. ## Packages & apps -- **`packages/core`** — `@redeploy/core`: deployment engine over Ignition — declarative spec, dependency - resolution/ordering, idempotent journal-based resume, plan-only simulate. -- **`packages/config`** — `@redeploy/config`: post-deployment configuration — declarative steps, resumable - partial configuration, config-state idempotency. -- **`packages/verify`** — `@redeploy/verify`: source/bytecode verification (Etherscan/Sourcify) + on-chain - assertion that live configuration matches the declared spec. -- **`packages/reader`** — `@redeploy/reader`: read-only library exposing deployment + config state via a typed - API to external systems. -- **`apps/studio`** — `@redeploy/studio`: visual tool (React + React Flow) for drag-and-drop authoring of - connections/config (emits spec files) and a deployment inspector. -- **`apps/deploy-server`** — `@redeploy/deploy-server`: HTTP server (node:http, no framework) exposing - deployment **simulate** (plan-only) and **real deploy** over `@redeploy/core` (+ `@redeploy/reader`), - consumed by the studio. -- **`contracts/`** — Foundry project: sample interconnected Solidity contracts used as deployment fixtures. + +| Module | Package | What it does | +| --- | --- | --- | +| `packages/core` | `@redeploy/core` | Deployment engine over Ignition — declarative spec, dependency resolution/ordering, idempotent journal-based resume, plan-only simulate. | +| `packages/config` | `@redeploy/config` | Post-deployment configuration — declarative steps, resumable partial configuration, args read live from deployed contracts. | +| `packages/verify` | `@redeploy/verify` | Source/bytecode verification (Etherscan/Sourcify) + on-chain assertion that live configuration matches the declared spec. | +| `packages/reader` | `@redeploy/reader` | Read-only typed API over deployment + config state — snapshots and per-network address-book export for external systems. | +| `apps/cli` | `@redeploy/cli` | The `redeploy` command — deploy/simulate/apply-config/verify/status/snapshot over the libraries. | +| `apps/studio` | `@redeploy/studio` | Visual tool (React + React Flow) for drag-and-drop authoring of connections/config (emits spec files) and a deployment inspector. | +| `apps/deploy-server` | `@redeploy/deploy-server` | Minimal `node:http` server exposing simulate (plan-only), real deploy, deployment state, and network discovery to the studio and other clients. | +| `apps/website` | `@redeploy/website` | The public one-page site served at redeploy.thesolidchain.com. | +| `contracts/` | — | Foundry project: sample interconnected Solidity contracts used as deployment fixtures. | ## Deploy server -`apps/deploy-server` is a minimal `node:http` server (no framework) that exposes deployment simulation and -execution as an HTTP API for the studio (and any other client). It listens on `127.0.0.1:8787` by default -(override with the `PORT` / `HOST` env vars; `HOST` stays loopback unless explicitly overridden). It loads a -repo-root `.env` on startup — real `process.env` values always take precedence over the file. -Endpoints: +`apps/deploy-server` is a minimal `node:http` server (no framework) listening on `127.0.0.1:8787` by default +(`PORT` / `HOST` env overrides; `HOST` stays loopback unless explicitly overridden). It loads a repo-root +`.env` on startup — real `process.env` values take precedence. + - **`GET /health`** → `{ "status": "ok" }`. -- **`GET /api/deployment`** → read-only JSON `DeploymentView` (`{ contracts, configSteps, warnings }`), built - from the on-disk Ignition journal. Returns the empty view (`{contracts:[],configSteps:[],warnings:[]}`) for a - never-deployed directory, or `500 { "error": "Failed to read deployment state" }` on other read failures. The - deployment directory is resolved **strictly from server env** — never from client input — as a deliberate - security boundary against path traversal. -- **`POST /api/simulate`** — plan-only, no chain writes. Body is a `DeploymentSpec` JSON document. Response is - `Content-Type: text/event-stream` (SSE): zero or more `event: step` frames (one per planned step, each - augmented with `address: null`), followed by a terminal `event: done` frame — `{success:true}` on success, or - `{success:false, errors:[...]}` on failure. -- **`POST /api/deploy`** — a **real** deploy that broadcasts transactions on-chain. Body is a `DeploymentSpec` - JSON document. Response is SSE: an `event: progress` frame (`{phase:"deploying"}`), then a terminal - `event: done` frame — `{success:true, deployment: DeploymentView | null, warning?}` on success, or - `{success:false, errors:[{code?, message}]}` on failure. - -Environment variables read by the deploy path (values are never echoed in responses or logs): -- `RPC_URL` — JSON-RPC endpoint. Defaults to `http://127.0.0.1:8545` (Anvil's default). -- `FOUNDRY_OUT` — Foundry artifacts directory. Defaults to `/contracts/out`. -- `DEPLOYER_PRIVATE_KEY` — required for real deploys (`POST /api/deploy`); accepted with or without a `0x` - prefix. Missing → a terminal `done{success:false}` SSE error, not a crash. -- `DEPLOYMENT_DIR` — where the Ignition journal is persisted. Defaults to an OS-temp directory - (`redeploy-deployments/default`). Successful real deploys also persist a snapshot under - `/snapshots/.json`. +- **`GET /api/deployment`** → read-only `DeploymentView` (`{ contracts, configSteps, warnings }`) built from + the on-disk Ignition journal. The deployment directory is resolved **strictly from server env** — never from + client input — as a deliberate boundary against path traversal. +- **`GET /api/networks`** → the configured network registry for multi-network deploys. +- **`POST /api/simulate`** → plan-only, no chain writes. SSE stream: `step` frames, then a terminal `done`. +- **`POST /api/deploy`** → a **real** deploy that broadcasts on-chain. SSE stream: `progress`, then a + terminal `done` with the resulting `DeploymentView`. Secrets are never echoed in responses or logs. + +Environment variables for the deploy path: `RPC_URL` (defaults to Anvil's `http://127.0.0.1:8545`), +`FOUNDRY_OUT` (defaults to `contracts/out`), `DEPLOYER_PRIVATE_KEY` (required for real deploys — use a +throwaway key locally, a keystore/hardware wallet for anything real), `DEPLOYMENT_DIR` (journal + snapshot +location). See [`.env.example`](.env.example). ## Studio deploy flow -The studio (`apps/studio`, Vite dev server on `:5173`) proxies `/api` requests to the deploy-server at -`http://127.0.0.1:8787` (override via `VITE_DEPLOY_SERVER_URL`). **Both dev servers must be running** for the -studio's deploy flow to work. - -Toolbar actions: -- **`Deploy (simulate)`** — POSTs the current spec to `/api/simulate` for a plan-only preview (shows - `Simulating…` while in flight). No chain writes. -- **`Plan`** — a local, synchronous dry-run diff (create/skip/change) against the last known deployment state; - no network call. -- **`Deploy (real)`** — opens a confirmation modal (red/danger styling, since it's irreversible) and, once - confirmed, POSTs to `/api/deploy` to broadcast on-chain (shows `Deploying…` while in flight). - -The read-only **Inspector** renders the resulting `DeploymentView` as a React Flow canvas: each contract node -shows its Deploy ID, contract name, deployed address (blue monospace) or "(not deployed)", and constructor -args; a right-side panel lists config steps with completed/pending badges; a context badge reads -"Real deployment (broadcast on-chain)" or "Simulated plan (dry run)" depending on the source of the view. - -For the full step-by-step local walkthrough against Anvil (start Anvil, configure `.env`, run both dev -servers, deploy, and curl the SSE endpoints directly), see -**[`docs/RUNBOOK-anvil-deploy.md`](docs/RUNBOOK-anvil-deploy.md)**. -## Contributor tooling (orchestrator harness) -This repo is developed using an orchestrated multi-agent Claude Code setup (a lead orchestrator that scopes -work to worktree-isolated implementers, gated by adversarial reviewers). If you're contributing to reDeploy (or -adapting its `.claude/` harness for another project), see: +The studio (`:5173`) proxies `/api` to the deploy server (`:8787`, override `VITE_DEPLOY_SERVER_URL`); both +dev servers must run for the deploy flow. Toolbar: **Deploy (simulate)** for a plan-only preview, +**Plan** for a local create/skip/change diff, **Deploy (real)** for a confirmed on-chain broadcast — results +render in the read-only Inspector (React Flow canvas with addresses, args, and config-step status). + +## Contributing & the orchestrator harness + +This repo is developed with an orchestrated multi-agent Claude Code setup — a lead orchestrator scoping work +to worktree-isolated implementers, gated by adversarial reviewers and CI. If you're contributing (or adapting +the `.claude/` harness for your own project): + - **[`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md)** — harness setup, step by step. - **[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)** — the orchestrator/implementer/reviewer mental model. - **[`docs/USAGE.md`](docs/USAGE.md)** — how to drive the orchestrator day to day. + +Gates for every module (build · lint · typecheck · test · coverage ≥ 80%) run locally via +`.claude/scripts/gate.sh` and in CI on every PR. + +## License + +[MIT](LICENSE) © 2026 Roberto Cano · The Solid Chain diff --git a/apps/cli/package.json b/apps/cli/package.json index 1e8bc90..2e2923c 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,9 +1,10 @@ { "name": "@redeploy/cli", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", - "description": "Thin command-line entry point for reDeploy: deploy/simulate (core), apply-config (config), verify (verify), status/snapshot (reader). Wraps existing library APIs — no reimplemented business logic.", + "description": "Thin command-line entry point for reDeploy: deploy/simulate (core), apply-config (config), verify (verify), status/snapshot (reader). Wraps existing library APIs \u2014 no reimplemented business logic.", "bin": { "redeploy": "dist/index.js" }, diff --git a/apps/deploy-server/package.json b/apps/deploy-server/package.json index cb60de0..a4750e9 100644 --- a/apps/deploy-server/package.json +++ b/apps/deploy-server/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/deploy-server", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "HTTP deploy server: exposes deployment simulation and execution as an API. Built on node:http, no framework deps.", diff --git a/apps/studio/package.json b/apps/studio/package.json index 3631ae5..f6c592f 100644 --- a/apps/studio/package.json +++ b/apps/studio/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/studio", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Visual tool: drag-and-drop authoring of contract connections and configuration (emits spec files) plus a deployment inspector. React + React Flow.", diff --git a/apps/website/package.json b/apps/website/package.json index 97e9d2f..0e862ac 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/website", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Public marketing site for reDeploy: sells its benefits and showcases Studio features. Static Vite build, no backend.", diff --git a/apps/website/public/CNAME b/apps/website/public/CNAME new file mode 100644 index 0000000..caa6af5 --- /dev/null +++ b/apps/website/public/CNAME @@ -0,0 +1 @@ +redeploy.thesolidchain.com diff --git a/package.json b/package.json index 73e41d2..210e223 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "redeploy", "version": "0.0.0", + "license": "MIT", "private": true, "description": "Hardhat Ignition-based deployment system: declarative deploy/config, idempotent resume, verification, reader library, and a visual authoring/inspection studio.", "type": "module", @@ -23,6 +24,8 @@ "solhint": "^5.2.0" }, "pnpm": { - "onlyBuiltDependencies": ["esbuild"] + "onlyBuiltDependencies": [ + "esbuild" + ] } } diff --git a/packages/config/package.json b/packages/config/package.json index 3138710..d567bd5 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/config", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Post-deployment configuration: declarative config steps, resumable partial configuration, config-state idempotency.", diff --git a/packages/core/package.json b/packages/core/package.json index 2f93814..5bced31 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/core", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Deployment engine on top of Hardhat Ignition: declarative deployment spec, dependency resolution and ordering, idempotent journal-based resume.", diff --git a/packages/reader/package.json b/packages/reader/package.json index b335a4f..4750c06 100644 --- a/packages/reader/package.json +++ b/packages/reader/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/reader", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Read-only library to load deployment and configuration state and expose a typed API to external systems.", diff --git a/packages/verify/package.json b/packages/verify/package.json index 656ec75..8b06cc5 100644 --- a/packages/verify/package.json +++ b/packages/verify/package.json @@ -1,6 +1,7 @@ { "name": "@redeploy/verify", "version": "0.0.0", + "license": "MIT", "private": true, "type": "module", "description": "Verification: source/bytecode verification (Etherscan/Sourcify) and on-chain assertion that live configuration matches the declared spec.",