feat: harden server pull deployments and git hygiene
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# ForgeFlow 0.10.0
|
||||
|
||||
ForgeFlow 0.10.0 makes existing Unraid workloads substantially easier and safer to adopt, verify and deploy.
|
||||
|
||||
## Deployment discovery and verification
|
||||
|
||||
- Automatic discovery links unique running server workloads to their matching Gitea repositories while excluding unrelated infrastructure and stale release folders.
|
||||
- Deployment cards preserve the last verified live commit and compare it with the current Gitea branch, even when a container was updated outside ForgeFlow.
|
||||
- Existing Compose project names, files, services, remote folders and DockerMan metadata are adopted from server truth instead of guessed or overwritten.
|
||||
|
||||
## Safe Server pull
|
||||
|
||||
- Server pull is now the recommended deployment route and fetches the exact requested commit from Gitea.
|
||||
- Each repository receives its own repository-scoped read-only deploy key; ForgeFlow never installs the desktop Gitea token on Unraid.
|
||||
- Gitea SSH host fingerprints are pinned and checked before trust is changed and before every pull.
|
||||
- Fetch, archive, checksum, Compose validation, activation and rollback remain exact-commit and transactional.
|
||||
- Direct copy remains available when server-side Git access is undesirable, and monitoring-only links cannot deploy accidentally.
|
||||
|
||||
## Git hygiene
|
||||
|
||||
- Git Validator now also checks `.gitattributes`, `.editorconfig`, dependency lockfiles and a Gitea Actions workflow.
|
||||
- Safe repairs create reviewable files without committing or pushing them automatically.
|
||||
- Existing identity, upstream, synchronization, branch-protection, documentation, secret-path and oversized-file checks remain available in one scored view.
|
||||
|
||||
## Interface and reliability
|
||||
|
||||
- The deployment workspace now emphasizes repository, container, environment and live-versus-Gitea evidence, with a focused animated project illustration and clearer server inventory.
|
||||
- Large unrelated server inventories are summarized instead of producing dozens of indistinguishable cards.
|
||||
- Connection validation consistently opens the same encrypted Electron profile as the installed app.
|
||||
- Obsolete ForgeFlow artifacts are removed from `dist` after every successful packaged build.
|
||||
|
||||
No container was restarted or replaced during automatic discovery. Deployments still require a successful preflight and an explicit user action.
|
||||
@@ -0,0 +1,10 @@
|
||||
# ForgeFlow 0.9.2
|
||||
|
||||
## Emergency deployment and discovery repair
|
||||
|
||||
- Existing deployment profiles without an explicit mode migrate to **Push bundle**, never Server-side Git.
|
||||
- Push bundle deploys the clean, committed local HEAD directly over SSH/SFTP and never requires a Gitea key, upstream, remote sync, or Git on Unraid.
|
||||
- Desktop-to-Unraid authentication can use the server password; a failed key opens a password recovery flow instead of blocking deployment.
|
||||
- Server inventory scans `docker ps -a`, complete Docker inspect data, Compose projects, and every DockerMan user template, including stopped and template-only workloads.
|
||||
- Inventory connection failures are shown as failures rather than misleading zero counts.
|
||||
- Existing Compose and DockerMan workloads can be linked manually without restarting or modifying them.
|
||||
@@ -0,0 +1,25 @@
|
||||
# ForgeFlow 0.9.3
|
||||
|
||||
This release removes server-side repository authentication from every SSH/Unraid deployment path and makes server Compose files the primary discovery source.
|
||||
|
||||
## Direct deployment only
|
||||
|
||||
- Every existing SSH/Unraid deployment profile is migrated to **Direct copy**, except profiles explicitly marked **Monitor only**.
|
||||
- Deployment and rollback archive the exact committed local HEAD, upload it over the already configured desktop-to-Unraid connection and run Docker Compose on Unraid.
|
||||
- Preflight contains no Unraid-to-repository access probe, no remote `git ls-remote`, no repository-key validation and no Git requirement on Unraid.
|
||||
- Password authentication for the desktop-to-Unraid connection remains supported and is independent of repository access.
|
||||
|
||||
## Compose-file inventory and automatic linking
|
||||
|
||||
- Server Inventory scans Compose YAML files such as `compose.yml`, `compose.yaml`, `docker-compose.yml`, `docker-compose.yaml`, overrides and stack YAML files below the configured appdata roots.
|
||||
- YAML discovery still runs when Docker inspection fails or Docker is unavailable, so a container-query problem no longer produces a false empty inventory.
|
||||
- ForgeFlow reads the Compose project name, file set, service names and image names from the server.
|
||||
- A unique high-confidence repository match based on both Compose folder and project identity is linked automatically.
|
||||
- Remaining strong matches use a one-click link action with server folder, Compose project, Compose files, services, container identity and preservation paths already filled in.
|
||||
- Runtime containers, stopped containers and DockerMan templates are merged with the YAML definition when available. `/mnt/user/appdata`, `/mnt/cache/appdata` and disk-backed appdata paths are treated as the same logical deployment location.
|
||||
|
||||
## Reliability
|
||||
|
||||
- The inventory shell script is safe under `set -euo pipefail`; Docker or Compose command failures are captured as warnings instead of aborting the scan.
|
||||
- Large runtime, cache, log and database folders are pruned while searching for Compose files.
|
||||
- A failed inventory operation remains visible as an error and is never presented as zero workloads.
|
||||
@@ -0,0 +1,7 @@
|
||||
# ForgeFlow 0.9.4
|
||||
|
||||
ForgeFlow now treats the real Compose files discovered on Unraid as the only activation source for adopted workloads. A generated labels fragment is no longer merged into an imported project, so stale service hints such as `geointel` cannot create a phantom service without an image or build context.
|
||||
|
||||
Direct copy redeployments always use `--force-recreate`. The runtime service list comes from `docker compose config --services`, not from manually stored service names. Before activation ForgeFlow records the existing container ID for every service; after activation it verifies that each service is running, not unhealthy, and uses a different container ID.
|
||||
|
||||
ForgeFlow also rejects the deployment when Compose starts a duplicate workload while leaving the previous container running. The new SHA is written only after these checks pass. Existing DockerMan templates and the real Compose files remain untouched.
|
||||
@@ -0,0 +1,11 @@
|
||||
# ForgeFlow 0.9.5
|
||||
|
||||
ForgeFlow 0.9.5 makes Direct copy deployments fail closed and adds an in-app repair for Unraid write permissions.
|
||||
|
||||
Before a bundle is created or uploaded, ForgeFlow probes the linked project folder, `.forgeflow` upload/state folders and every active Compose file using the configured SSH identity. A failed check names the exact path, user, owner, group and mode. Deployment stops before file transfer and before any Docker or Compose command changes the runtime. The same write-access check runs again immediately before upload to prevent a stale preflight result.
|
||||
|
||||
Every SSH / Unraid deployment card now includes **Check / fix write access**. The same action appears beside a blocking preflight result. It normalizes the linked source tree and ForgeFlow state folders to safe shared access, uses the Unraid `users` group where available and preserves existing executable bits. Configured runtime locations such as `.env`, `appdata`, `data`, `config`, `logs`, mounted data paths and common generated dependency folders are excluded. It never runs Docker, stops a container, removes a container or uses `chmod 777`. The action also runs when the SSH account is root so manual SMB/file-copy access can be repaired, not only ForgeFlow's own write access.
|
||||
|
||||
Direct copy now validates candidate Compose configuration and builds candidate images before replacing live source files. It never implicitly executes `docker compose down`, `--remove-orphans` or `--force-recreate`. Existing container IDs, image IDs and source files are captured first. When activation fails, ForgeFlow restores the prior source, retags the previous images, attempts to restore the previous runtime and retains the backup evidence. A release is only promoted after the exact linked Compose services are running and verified.
|
||||
|
||||
This release does not claim live validation against a specific private Unraid server. The automated suite validates generated Bash syntax, permission-report parsing, scoped repair commands, no server-to-Gitea authentication, no destructive Compose flags and transactional deployment ordering.
|
||||
@@ -1,97 +1,73 @@
|
||||
# SSH / Unraid deployment
|
||||
|
||||
ForgeFlow can inventory existing Unraid workloads and deploy an exact Git commit through one of three explicit modes.
|
||||
ForgeFlow uses one deployment flow for Unraid: it copies the exact committed local project from the desktop to the server and activates the Compose definition found for that deployment.
|
||||
|
||||
## Deployment modes
|
||||
|
||||
### Push bundle — default
|
||||
### Direct copy — default
|
||||
|
||||
ForgeFlow creates an archive from the exact local commit and uploads it through the trusted desktop-to-Unraid SSH connection. The Unraid server needs Docker, Docker Compose, `tar` and a SHA-256 checksum tool. It does **not** need Git access or a Gitea key.
|
||||
|
||||
### Server-side Git — optional
|
||||
|
||||
Unraid fetches the exact commit from Gitea. This mode additionally requires Git, a trusted Gitea host key and a non-interactive Unraid-to-Gitea identity with repository access.
|
||||
ForgeFlow creates an archive from the exact local commit and uploads it through the configured desktop-to-Unraid connection. Unraid needs Docker, Docker Compose, `tar` and a SHA-256 checksum tool. Unraid does not clone, fetch or authenticate to a repository.
|
||||
|
||||
### Monitor only
|
||||
|
||||
ForgeFlow inventories and tracks the workload but refuses deploy and rollback operations until another mode is selected.
|
||||
ForgeFlow inventories and tracks the workload but refuses deploy and rollback operations until **Direct copy** is selected.
|
||||
|
||||
## Security model
|
||||
All older SSH/Unraid profiles are migrated to Direct copy unless they were explicitly Monitor only.
|
||||
|
||||
- Credentials are entered only in the local ForgeFlow desktop application.
|
||||
- Ed25519 private keys are preferred.
|
||||
- Passwords and key passphrases use Electron safe storage.
|
||||
- The first trusted connection records the SSH host-key fingerprint; later changes fail closed.
|
||||
- ForgeFlow validates the selected private key before saving the server configuration.
|
||||
- Desktop-to-Unraid authentication, Docker access, Compose availability and optional Unraid-to-Gitea access are reported as separate checks.
|
||||
- Remote inventory collects selected labels, mounts, ports and runtime state; it does not collect container environment values.
|
||||
- The renderer cannot submit arbitrary shell commands. Remote scripts are assembled from validated profile fields and transported as base64-encoded Bash input.
|
||||
- Incomplete SSH output is rejected rather than interpreted.
|
||||
## Server Inventory and automatic linking
|
||||
|
||||
## Server Inventory and manual linking
|
||||
Server Inventory reads the server itself instead of relying on ForgeFlow history. The default scan root is `/mnt/user/appdata`, together with the configured server base path and the cache-backed appdata path when present. It combines:
|
||||
|
||||
**Server Inventory** includes running and stopped containers, Compose projects, DockerMan installations and standalone containers even when `/mnt/user/appdata/<app>` is not a Git checkout.
|
||||
- running and stopped containers from `docker ps -a` and Docker Inspect;
|
||||
- active and stopped Compose projects;
|
||||
- DockerMan templates;
|
||||
- Compose YAML files below the configured appdata roots, including standard override files.
|
||||
|
||||
An exact repository remote or trusted provenance label may be linked automatically. Similar names remain suggestions. For an uncertain workload, use **Link workload** and choose:
|
||||
YAML discovery continues even when Docker inspection fails. For each Compose definition ForgeFlow reads the working directory, project name, file set, services and images. It then compares those values with the linked local repositories.
|
||||
|
||||
1. the repository;
|
||||
2. Push bundle, Server-side Git or Monitor only;
|
||||
3. the folder below the configured server base path.
|
||||
|
||||
The resulting profile preserves the detected Compose project name, Compose files, service set, container metadata and stable workload selector. Linking itself does not recreate a container or rewrite a DockerMan template.
|
||||
A unique high-confidence match based on both the Compose folder and project identity is linked automatically. Other strong matches show a one-click **Link to repository** action. The server folder, Compose project, Compose files, service list, visible container identity, ports and preservation paths are already filled in; linking does not recreate the container.
|
||||
|
||||
## Compose identity
|
||||
|
||||
An adopted installation keeps the identity reported by Docker:
|
||||
An adopted installation retains the identity detected on the server:
|
||||
|
||||
```text
|
||||
Visible container: omniroute
|
||||
Server folder: OmniRoute
|
||||
Compose project: omniroute-production
|
||||
Compose files: compose.yml, compose.unraid.yml
|
||||
Compose services: api, worker
|
||||
Visible container: geointel
|
||||
Server folder: GeoIntel
|
||||
Compose project: geointel
|
||||
Compose files: compose.yml, compose.override.yml
|
||||
Compose services: web, worker
|
||||
```
|
||||
|
||||
ForgeFlow adds `.forgeflow/compose.metadata.yml` as the final Compose overlay. For adopted workloads this overlay adds labels only; it does not replace the existing image or `container_name`.
|
||||
ForgeFlow adds `.forgeflow/compose.metadata.yml` as the final Compose overlay. For adopted workloads this overlay adds safe labels only; it does not replace the existing image, volumes, ports, networks or `container_name`.
|
||||
|
||||
`--force-recreate` and `--remove-orphans` are disabled by default and can be enabled explicitly per profile. Multiple Compose files and services are retained and validated.
|
||||
`--force-recreate` and `--remove-orphans` remain disabled by default. Existing DockerMan templates are not rewritten.
|
||||
|
||||
## DockerMan safety
|
||||
## Direct-copy sequence
|
||||
|
||||
Existing DockerMan templates under `/boot/config/plugins/dockerMan/templates-user` are never rewritten for adopted workloads. ForgeFlow manages a persistent DockerMan template only when all of the following are true:
|
||||
1. Verify the selected local branch, clean working tree and exact committed HEAD.
|
||||
2. Test the desktop-to-Unraid connection, Docker, Compose, `tar`, checksum tooling and deployment storage.
|
||||
3. Create the release locally with `git archive`.
|
||||
4. Upload a temporary `.part` file through SFTP.
|
||||
5. Verify SHA-256 and reject unsafe archive paths or symbolic links.
|
||||
6. Preserve `.forgeflow`, `.git` and configured runtime paths such as `.env`, `data`, `config`, `logs` and application-specific folders.
|
||||
7. Update only files covered by the managed release manifests; unrelated server files remain untouched.
|
||||
8. Validate the detected merged Compose configuration.
|
||||
9. Activate the retained Compose project and verify every selected service is running and not unhealthy.
|
||||
10. Promote the active SHA and manifests only after activation succeeds.
|
||||
11. Run the optional desktop health check and persist runtime state.
|
||||
|
||||
- the profile uses ForgeFlow-generated Compose;
|
||||
- **Manage DockerMan template** is enabled;
|
||||
- the workload was not adopted from the server.
|
||||
If activation fails, ForgeFlow restores the previous managed files and Compose metadata and leaves the previous active SHA authoritative.
|
||||
|
||||
Metadata repair for an adopted application therefore updates the Compose metadata labels only and leaves the original Unraid template intact.
|
||||
## Authentication model
|
||||
|
||||
## Push bundle sequence
|
||||
|
||||
1. Verify the clean local working tree, selected branch, upstream state and exact commit.
|
||||
2. Verify the exact commit exists on the configured remote branch.
|
||||
3. Test desktop-to-Unraid SSH, Docker, Compose, `tar`, checksum tooling and deployment storage.
|
||||
4. Create the release with `git archive` from the exact commit.
|
||||
5. Upload a temporary `.part` file through SFTP.
|
||||
6. Verify the SHA-256 digest and reject unsafe paths or symbolic links.
|
||||
7. Store a retained release manifest and back up files that ForgeFlow is about to manage.
|
||||
8. Preserve `.forgeflow`, `.git` and configured runtime paths such as `.env`, `data`, `config`, `logs` and application-specific folders.
|
||||
9. Update only files in the old or new ForgeFlow managed-file manifests; unrelated server files remain untouched.
|
||||
10. Validate the merged Compose configuration.
|
||||
11. Start the configured Compose project and verify every selected service has a running container and is not unhealthy.
|
||||
12. Promote `current-sha`, status and managed-file manifests atomically.
|
||||
13. Run the optional desktop healthcheck and persist runtime state.
|
||||
|
||||
If activation fails, ForgeFlow restores the backed-up files and previous Compose metadata, restarts the previous Compose state where possible and leaves the previous active SHA untouched.
|
||||
|
||||
## Server-side Git sequence
|
||||
|
||||
Server-side Git retains the exact-SHA flow for installations that deliberately keep a checkout on Unraid. Preflight runs `git ls-remote` from Unraid, rejects tracked server edits, verifies the configured origin and checks that the selected SHA belongs to the allowed remote branch. The active SHA is written only after Compose validation and service verification.
|
||||
|
||||
## Interrupted operations and locks
|
||||
|
||||
A push deployment creates `.forgeflow/deploy.lock` with a request ID, timestamp and shell PID. A lock older than two hours is removed only when its recorded process no longer exists. Startup and **Reconcile** compare the requested SHA with server state and container health; unresolved operations eventually become failed rather than remaining active indefinitely.
|
||||
- The only remote authentication used for Direct copy is the configured desktop-to-Unraid connection.
|
||||
- That connection may use an Unraid password or a private key.
|
||||
- Passwords and private-key passphrases use Electron safe storage.
|
||||
- The first trusted connection records the SSH host-key fingerprint; later changes fail closed.
|
||||
- Remote inventory collects selected labels, mounts, ports and runtime state; it does not collect container environment values.
|
||||
- The renderer cannot submit arbitrary shell commands; remote scripts are assembled from validated profile fields.
|
||||
|
||||
## Rollback
|
||||
|
||||
Rollback is accepted only for the exact `previousSha` recorded for the profile. Push bundle mode recreates that commit archive locally and uses the same checksum, backup, Compose validation and atomic promotion flow. Server-side Git mode verifies and checks out the exact previous commit through its Git workflow.
|
||||
Rollback is allowed only to the exact `previousSha` recorded for the profile. ForgeFlow recreates that commit archive locally and uses the same upload, checksum, backup, Compose validation and atomic promotion flow.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 326 KiB |
Reference in New Issue
Block a user