Files
ForgeFlow/docs/SETUP_GUIDE.md
T
2026-07-24 20:29:23 +02:00

13 KiB

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:

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:

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:

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:

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:

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:

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:

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:

<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:

examples/gitea-actions/deploy.yml
examples/gitea-actions/rollback.yml

to the target repository as:

.gitea/workflows/deploy.yml
.gitea/workflows/rollback.yml

Review the runner label in both files:

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:

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:

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:

/srv/YOUR-APP
/srv/YOUR-APP/compose.yml

2. Install the target configuration

Copy the template:

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:

sudo nano /etc/forgeflow/targets.conf

Each active line has seven pipe-separated fields:

repository|environment|app_dir|branch|compose_file|healthcheck_url|status_file

Example:

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:

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

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:

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:

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:

examples/server/nginx-forgeflow-status.conf

Example URL:

https://YOUR-APP-HOST/.well-known/forgeflow

Expected response:

{
  "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:

Invoke-WebRequest "https://YOUR-APP-HOST/.well-known/forgeflow"
Invoke-WebRequest "https://YOUR-APP-HOST/health"

See 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:

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 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.