This commit is contained in:
NuklearRabbit
2026-07-24 20:29:23 +02:00
commit 66060348da
107 changed files with 14771 additions and 0 deletions
+485
View File
@@ -0,0 +1,485 @@
# ForgeFlow setup and first-test guide
This is the canonical guide for turning the source release into a locally
configured desktop application and testing one complete path:
```text
local change -> commit -> push -> exact-SHA deployment -> healthcheck -> rollback
```
You never need to provide your Gitea token, SSH key or server credentials to a
developer. Enter them only on the computer or server where they belong.
---
## Part 1 — Prepare the Windows desktop
### 1. Extract the release
Extract the complete ForgeFlow ZIP to a normal local directory, for example:
```text
C:\Tools\ForgeFlow
```
Avoid running it directly from inside the ZIP or from a temporary email folder.
### 2. Install the prerequisites
Required:
- Node.js 22 or newer;
- npm, normally installed with Node.js;
- Git for Windows available on `PATH`;
- a normal signed-in Windows desktop session so Electron can use OS credential
encryption.
Optional manual check:
```powershell
node --version
npm --version
git --version
git config --global user.name
git config --global user.email
```
Configure the Git identity when either value is empty:
```powershell
git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL"
```
### 3. Run the local setup command
Open PowerShell in the extracted folder and run:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
.\setup-windows.ps1
```
This command:
1. checks Node.js, npm and Git;
2. installs the declared project dependency versions;
3. runs source validation and all automated tests;
4. starts the Electron desktop application.
No Gitea or server credential is requested by the PowerShell script.
---
## Part 2 — Complete the ForgeFlow desktop wizard
The first launch uses five explicit steps.
### Step 1. Readiness
Select **Run readiness check**. ForgeFlow verifies:
- Git CLI availability;
- Git author identity;
- writable application storage;
- writable diagnostic storage;
- availability of operating-system credential encryption.
Warnings are informative. Red required checks block completion until resolved.
A safe setup diagnostic ZIP can already be exported at this stage.
### Step 2. Gitea
Create a Gitea access token (personal access token) in your own Gitea account. The exact scope labels
can vary by Gitea version. Give it only the minimum rights needed for:
- reading the repositories you want to show in ForgeFlow;
- reading repository contents and branches;
- reading Actions runs and jobs;
- dispatching the fixed deployment and rollback workflows.
Do not put this token in a Markdown file, `.env`, workflow or chat message.
Enter locally in ForgeFlow:
```text
Instance URL: https://YOUR-GITEA-HOST
Access token: PASTE LOCALLY IN THE PASSWORD FIELD
```
Select **Validate & continue**. ForgeFlow confirms the user identity and
repository access. When OS encryption is available, the token is stored with
Electron `safeStorage`; otherwise it remains session-only and must be entered
again after restarting.
### Step 3. Folders
Choose one or more project roots that contain local repositories, for
example:
```text
C:\Development
D:\Projects
```
Do not select the entire system disk. A focused project root produces faster
and clearer discovery.
The first configured root is also the default clone destination. When cloning
`owner/repository`, ForgeFlow automatically creates:
```text
<first-project-root>\repository
```
The normal **Clone from Gitea** action does not open a folder picker. Use
**Choose another location** only when a repository belongs under a different
parent directory. ForgeFlow still creates the repository-named subfolder.
### Step 4. Discovery
ForgeFlow scans Git metadata and matches each local `origin` to a Gitea
repository. Generated dependency directories are skipped.
### Step 5. Ready
Enter ForgeFlow. Repositories that could not be matched can still be linked or
cloned from their repository screen. A clone is automatically linked and
monitored after Git completes.
---
## Part 3 — Prepare one repository for deployment
Start with a non-critical staging application when possible.
### 1. Verify the local repository
The repository should have:
- a configured `origin` pointing to the same Gitea repository;
- a normal branch such as `main`;
- no unresolved conflicts;
- an upstream branch after the first push.
### 2. Add the fixed Gitea Actions workflows
Copy:
```text
examples/gitea-actions/deploy.yml
examples/gitea-actions/rollback.yml
```
to the target repository as:
```text
.gitea/workflows/deploy.yml
.gitea/workflows/rollback.yml
```
Review the runner label in both files:
```yaml
runs-on: forgeflow-production
```
Replace it with the exact label of the trusted runner that can reach the target
server environment. Commit and push these workflow files before running the
deployment preflight.
The workflows accept only controlled inputs:
```text
environment
commit_sha or target_sha
request_id
```
ForgeFlow creates the `request_id` automatically so desktop diagnostics,
Actions output and server status can be correlated without exposing a secret.
---
## Part 4 — Prepare the server and trusted runner
The example implementation targets a dedicated Git checkout deployed with
Docker Compose. Adapt the allowlisted target values, not the security model.
### 1. Confirm the server prerequisites
On the target server, verify:
```bash
git --version
docker --version
docker compose version
curl --version
flock --version
```
The application checkout must already exist and have a working `origin` that the
server can fetch without interactive prompts.
Example:
```text
/srv/YOUR-APP
/srv/YOUR-APP/compose.yml
```
### 2. Install the target configuration
Copy the template:
```bash
sudo install -d -o root -g root -m 0755 /etc/forgeflow
sudo install -o root -g root -m 0640 \
examples/server/forgeflow-targets.conf \
/etc/forgeflow/targets.conf
```
Edit it as root:
```bash
sudo nano /etc/forgeflow/targets.conf
```
Each active line has seven pipe-separated fields:
```text
repository|environment|app_dir|branch|compose_file|healthcheck_url|status_file
```
Example:
```text
jens/my-app|staging|/srv/my-app-staging|main|/srv/my-app-staging/compose.yml|http://127.0.0.1:18080/health|/var/lib/forgeflow-status/my-app-staging.json
```
Rules:
- repository must exactly match `owner/repository` in Gitea;
- environment must exactly match the ForgeFlow profile value;
- all filesystem paths must be absolute;
- status files must stay under `/var/lib/forgeflow-status/`;
- the configuration must remain root-owned and not group/other writable.
Validate permissions:
```bash
sudo stat -c '%U %G %a %n' /etc/forgeflow/targets.conf
```
Expected owner is `root`; a mode such as `640` is appropriate.
### 3. Install the allowlisted deployment entry point
```bash
sudo install -o root -g root -m 0755 \
examples/server/forgeflow-deploy \
/usr/local/bin/forgeflow-deploy
```
The script:
- accepts only a valid repository, environment, full SHA and request ID;
- resolves the repository/environment through the root-owned target file;
- rejects unsafe paths and branches;
- prevents concurrent deployments with `flock`;
- fetches the allowed branch;
- proves that the requested SHA is an ancestor of the remote branch;
- resets only the dedicated deployment checkout;
- runs the fixed Docker Compose redeploy;
- performs repeated healthchecks;
- writes live, previous and requested SHAs atomically;
- records the correlation request ID and last exit code.
### 4. Restrict runner elevation
Copy and edit the sudoers example:
```bash
sudo install -o root -g root -m 0440 \
examples/server/forgeflow-runner.sudoers \
/etc/sudoers.d/forgeflow-runner
sudo visudo -cf /etc/sudoers.d/forgeflow-runner
```
Replace `act_runner` with the actual trusted runner account. Do not grant that
account unrestricted passwordless `sudo`, shell access or wildcard commands.
### 5. Register and start the Gitea runner
Register a dedicated trusted runner according to your Gitea instance and runner
version. Attach the exact label referenced by the workflow, for example:
```text
forgeflow-production
```
Only repositories you control should be able to schedule jobs on a runner with
production access.
---
## Part 5 — Publish server version status
The server script writes one non-secret JSON status document per environment.
Serve it over HTTPS independently of the application process so it can still
report a failed release.
Copy and adapt:
```text
examples/server/nginx-forgeflow-status.conf
```
Example URL:
```text
https://YOUR-APP-HOST/.well-known/forgeflow
```
Expected response:
```json
{
"repository": "jens/my-app",
"environment": "staging",
"request_id": "00000000-0000-0000-0000-000000000000",
"commit_sha": "0123456789abcdef0123456789abcdef01234567",
"previous_sha": "89abcdef0123456789abcdef0123456789abcdef",
"requested_sha": "0123456789abcdef0123456789abcdef01234567",
"deployed_at": "2026-07-24T12:00:00Z",
"health": "healthy",
"last_exit_code": 0
}
```
Test from the ForgeFlow desktop computer:
```powershell
Invoke-WebRequest "https://YOUR-APP-HOST/.well-known/forgeflow"
Invoke-WebRequest "https://YOUR-APP-HOST/health"
```
See [`STATUS_ENDPOINT.md`](STATUS_ENDPOINT.md) for the accepted contract.
---
## Part 6 — Create the deployment profile in ForgeFlow
Open the linked repository and add an environment.
Fill in:
```text
Profile name: Staging
Environment input: staging
Allowed branch: main
Deploy workflow: deploy.yml
Rollback workflow: rollback.yml
Status URL: https://YOUR-APP-HOST/.well-known/forgeflow
Healthcheck URL: https://YOUR-APP-HOST/health
Confirmation: enabled
```
Save the profile.
---
## Part 7 — Run Deployment preflight
Select **Preflight** on the environment card. ForgeFlow must verify:
1. local repository link;
2. valid Git working tree;
3. allowed current branch;
4. clean working tree;
5. published upstream;
6. zero commits ahead and zero behind;
7. exact local SHA exists on the allowed remote branch;
8. local deploy workflow exists;
9. remote deploy workflow exists on Gitea;
10. Gitea Actions API is readable;
11. a configured server status endpoint;
12. current status-endpoint reachability;
13. application healthcheck result when configured.
The status URL is mandatory because ForgeFlow uses it after the workflow to prove
that the server applied the exact SHA for the exact request ID. An unreachable
status document can be a warning before the very first deployment because the
server script may create it, but the operation cannot finish successfully until
the endpoint returns the requested SHA and request ID. Required failures block
the Continue button and the deployment backend repeats its own Git/SHA checks at
dispatch time.
---
## Part 8 — First safe end-to-end test
Use a staging profile first.
1. Make a harmless visible change.
2. Review the diff in ForgeFlow.
3. Enter a commit message.
4. Select **Commit & push**.
5. Confirm that Local and Gitea show the same SHA.
6. Select **Deploy SHA -> Staging**.
7. Review and continue through Deployment preflight.
8. Confirm the exact SHA.
9. Follow workflow, job and healthcheck progress.
10. Confirm that the server status endpoint reports the same full SHA.
11. Create a second harmless commit and deploy it.
12. Use **Rollback** to restore the recorded previous SHA.
Also test deliberately:
- an uncommitted local change;
- a local commit that was not pushed;
- the wrong branch;
- a missing workflow file;
- a stopped runner;
- a failed healthcheck;
- a second deployment while the lock is held.
ForgeFlow should block unsafe local states and clearly retain failed operation
metadata for diagnostics.
---
## Part 9 — Export a diagnostic bundle without sharing credentials
Open **Diagnostics**.
1. Run **System preflight**.
2. Select **Strict privacy** when sharing externally.
3. Select **Create diagnostic ZIP**.
4. Inspect the ZIP before sending it.
The bundle deliberately contains no encrypted token field and omits raw runner
logs. Before writing the ZIP, ForgeFlow runs a safety audit for known runtime
secrets, private-key markers and unredacted URL credentials. If that audit
fails, no bundle is written.
See [`DIAGNOSTICS.md`](DIAGNOSTICS.md) for the exact contents and limitations.
---
## Part 8 — Configure an Unraid server
Open **Settings → SSH / Unraid servers**. Enter the host, SSH port, username and
`/mnt/user/appdata` as the base path. Prefer a private key. Save, then run
**Test & trust** to record the server host-key fingerprint.
For an existing project, enter its current server folder name. ForgeFlow
inspects the root Git repository, tracked modifications, Compose files and
nested repositories before it permits deployment.
For a new project, use the repository name as server folder. Select the
repository Compose file or enable basic generated Compose and enter host and
container ports.
See `docs/SSH_UNRAID_DEPLOYMENT.md`.