96 Commits

Author SHA1 Message Date
Andras Bacsai 1bac524008 test: replace assert.Error with require.Error across test files
Follows same pattern as da3479c. require.Error halts test immediately
on failure, preventing nil dereference in subsequent assert.Contains calls.
2026-05-02 20:21:31 +02:00
Andras Bacsai da3479c65a test: replace assert.NoError with require.NoError across test files
Aligns remaining test files with the pattern established in 6e80c95.
Using require halts the test immediately on fatal errors instead of
continuing with invalid state.
2026-05-02 18:59:38 +02:00
Andras Bacsai a896d5f991 chore(lint): add revive config and fix exhaustive switch defaults
Add revive var-naming rule with skipPackageNameChecks to suppress
package-name lint violations. Add explicit default cases to switch
statements in wireguard/intent.go for exhaustiveness. Upgrade
assert.NoError to require.NoError in firewall tests to halt on error.
2026-05-02 18:14:04 +02:00
Andras Bacsai c6445f9c80 docs(init): update llms-full.txt for intent-scoped subcommands
Reflect bootstrap/extend/upgrade split (replacing apply) and new
--intent flag on plan. Fix trailing-whitespace alignment in intent
tests.
2026-05-02 18:08:31 +02:00
Andras Bacsai d3b6ebffd9 refactor(init): replace apply with intent-scoped bootstrap/extend/upgrade
Split the monolithic `apply` subcommand into three purpose-built commands:
- `bootstrap`: first-time mesh install, keeps interactive alpha gate
- `extend`: adds new hosts to an existing mesh, peer-refresh only on existing hosts
- `upgrade`: bumps agent binaries across fleet, leaves mesh config untouched

Intent filtering lives in `internal/wireguard/intent.go` (ValidateIntent +
filterByIntent). Suppressed actions surface on plan.Skipped so operators see
what would have fired and why.

Also renames broker → scheduler (service + tests) to match its actual role.
2026-04-30 19:57:50 +02:00
Andras Bacsai 483fa075f7 refactor(broker): replace Redis with HTTP-over-UDS transport
Drop Redis as a broker dependency. Broker now exposes an HTTP listener
on a Unix domain socket at /run/coolify/broker.sock instead of reading
from Redis streams.

- Remove RedisInstallCommand and redis.go entirely
- Remove ActionInstallRedis from plan and apply phases
- Drop redisURL param from BrokerServiceUnit; add BrokerUnixSocketPath
  constant; systemd unit gains RuntimeDirectory=coolify (creates socket dir)
- e2e smoke tests switch from redis-cli XADD/LPOP to curl --unix-socket
  against /v1/build/dispatch, /v1/build/result/:id, /v1/build/:id/cancel
2026-04-22 21:10:44 +02:00
Andras Bacsai eb854da7c8 feat(init): per-host builder enrollment via --builder-hosts
Replace the cluster-wide --enable-builder bool with a per-host subset
controlled by --builder-hosts=<ip>,<ip>. Semantics:
  * --builder-hosts empty + --enable-builder=true: every host in
    --servers gets the builder capability (previous behavior)
  * --builder-hosts non-empty: only listed hosts get the capability;
    --enable-builder is ignored
  * --builder-hosts entries not in --servers are dropped

DesiredMesh.BuilderHostSet() + HasBuilderCap(host) compute the final
set and are used by:
  * phase 3 (install-builder): only on builder-capable hosts
  * phase 5 (JWT caps + coold BuilderConfig): per-host caps claim,
    COOLD_BUILDER_* env only when enabled
  * plan.go (ActionInstallBuilder): planned only for enrolled hosts

Adds 6 unit tests for BuilderHostSet covering empty/all/subset cases
and regenerates llms-full.txt for the new flag.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 11:44:52 +02:00
Andras Bacsai 286917cd95 feat(init): pass mgmt + container pools to coold as builder deny nets
When --enable-builder is set, populate BuilderConfig.DenyNets with
the mesh management pool (default 100.64.0.0/16) and the container
pool (default 10.210.0.0/16). coold emits these as
COOLD_BUILDER_DENY_NETS, which the builder adapter expands into
systemd IPAddressDeny entries for every build subprocess.

This keeps the policy in sync with the operator's actual --wg-mgmt-pool
and --container-pool choices without hard-coding RFC1918 defaults.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 10:56:35 +02:00
Andras Bacsai 93e3e626e3 feat(init): collapse builder into coold capability, drop phase 6
Mirrors the coold-side refactor that merges builder traffic onto coold's
gRPC stream. The provisioner no longer installs a separate builder
systemd unit, mints a builder JWT, or exposes a second broker listener:

- --install-builder → --enable-builder (capability toggle, not a daemon
  install). --builder-version removed; the builder binary tracks the
  coold release.
- Phase 6 (builder service + builder JWT) deleted. Phase 5 now mints
  the host JWT with a `caps` claim ("coold" always; "builder" when
  enabled) and rewrites the coold unit with COOLD_BUILDER_* env.
- Phase 3 picks up a single extra step when EnableBuilder is true:
  install buildah/git and drop the builder binary at
  /usr/local/bin/builder (short-lived subprocess, no unit file).
- internal/services: BrokerServiceUnit drops the builder bind arg;
  CooldServiceUnit gains an optional *BuilderConfig; builder.go keeps
  only install + workdir constants; jwt.go has a single MintHostJWT.
- e2e-mesh.sh adds steps 9+10 — push build:cmd through Redis and
  assert the resulting image, then dispatch and cancel a slow build
  and assert the scope is killed with stage=cancel.
- llms-full.txt regenerated to reflect the flag rename.

Breaking: pairs with the coold commit that deletes :6444 and
builder.proto. Deploy in lockstep.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 09:58:24 +02:00
Andras Bacsai c9b6df3171 refactor(firewall): rename FirewallFlags→Flags, drop error from discoverNamespacesOnHosts
Rename `FirewallFlags` to `Flags` and `bindFirewallFlags` to `bindFlags`
within the firewall package — the `Firewall` prefix is redundant inside
the `firewall` package.

Drop the unused error return from `discoverNamespacesOnHosts`; the
function accumulates per-host errors into `ServerResult` slices and has
no package-level error path, so the third return value was always nil.

Also switches test assertions from `assert.Error/NoError` to
`require.Error/NoError` where the test cannot continue meaningfully on
failure, and adds broker service tests.
2026-04-21 22:01:58 +02:00
Andras Bacsai 346320504c style: align struct literals and promote deps to direct
Promote golang-jwt/jwt/v5, mattn/go-isatty, golang.org/x/crypto, and
golang.org/x/term from indirect to direct dependencies in go.mod.

Fix data races in firewall test fakes by guarding calls slice with sync.Mutex.

Reformat struct literals and map literals across cmd, internal/wireguard,
and internal/firewall for consistent column alignment.
2026-04-21 21:24:21 +02:00
Andras Bacsai 8341802c88 fix(init): wire central host through phase 5 too
Phase 5 was filtering central out via hostsExcluding(), leaving the
coold instance on the central VM without broker env vars and without a
host-jwt. That breaks single-server deploys (only one host, which is
also central) and leaves central's own coold as a standalone API-only
process in fleet mode.

Run phase 5 on desired.Hosts directly so central also receives a JWT
and gets COOLD_BROKER_URL/COOLD_HOST_JWT_PATH injected. Drop
hostsExcluding() since it has no other callers.

Verified end-to-end on a single-server bed: `coolify init apply
--servers X --central X` now produces a working broker <-> coold dispatch
path on the same box.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 19:30:32 +02:00
Andras Bacsai 298bd28cd1 feat(init): add --central flag for broker + Redis setup on a host
Adds phases 4 + 5 to `coolify init apply` for bootstrapping the v5 central
transport plane without Laravel:

- Phase 4 (central-only): apt-install Redis, download coolify-broker from
  GitHub releases, generate an EC P-256 JWT keypair under /etc/coolify/, and
  enable coolify-broker.service bound to the wg0 mgmt IP:6443.
- Phase 5 (per non-central host): read jwt.priv from central, mint a 1-year
  ES256 JWT (sub = host wg0 IP), write it to /etc/coolify/host-jwt, rewrite
  coold.service with COOLD_BROKER_URL + COOLD_HOST_JWT_PATH, restart coold.

New service generators under internal/services:
- broker.go — unit, install command, JWT keypair setup
- redis.go  — apt install + enable
- jwt.go    — golang-jwt/jwt/v5 ES256 minting

coold.go gains CooldServiceUnitWithBroker + BrokerConfig so the unit can
carry broker env vars on non-central hosts. DesiredMesh gains CentralHost +
BrokerVersion; empty CentralHost skips phases 4+5 (existing behavior).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 17:35:47 +02:00
Andras Bacsai 0380aac05b fix(firewall): key bridge dispatch on ip saddr/daddr, not iifname
Bridge interface names (e.g. "coolify-default-mesh") exceed Linux
IFNAMSIZ=16, so iifname/oifname matching silently fails at the kernel
level. Switch renderBridgeScaffold to accept []*net.IPNet and emit
`ip saddr`/`ip daddr` set rules instead.

Also fix nft chain-declaration order: coolify_intra must be declared
before the forward chain's jump rules reference it, as nft validates
jump targets at add-rule time.

Add `mkdir -p /etc/coolify` before bridge scaffold write so `cat >.tmp`
doesn't ENOENT on fresh hosts where coold hasn't run yet.
2026-04-21 13:27:43 +02:00
Andras Bacsai 0980f1e363 test(wireguard): add nft bridge scaffold tests and golden fixture
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 12:49:26 +02:00
Andras Bacsai 3a500014b2 feat(init): add nft/bridge-table probes and nft precondition check
Probe 10a/10b detect nft binary availability and the coolify_bridge nft
table on each host. DefaultDenyActive is now gated on BridgeTableExists
so a host with only the iptables chain (no bridge table) triggers
reinstall. BuildPlan validates NftAvailable per host before computing
actions, surfacing a clear error instead of a silent nft shell failure.
Update --skip-default-deny help text to reflect the full scope of the
default-deny scaffold (cross-host and intra-host).
2026-04-21 12:42:52 +02:00
Andras Bacsai 6dc6e0770a fix(firewall): fix nft idempotency, move table delete, use constants, pre-alloc slice
- Pre-delete forward + coolify_intra chains before nft -f to prevent
  "chain already exists" error on second apply (Fix 1)
- Move nft delete table before blanket iptables ACCEPT in mode-A to
  close the window where bridge traffic could be dropped (Fix 2)
- Replace hardcoded nft path/table strings with BridgeTableName,
  BridgeScaffoldPath, BridgeAllowRulesPath constants (Fix 3)
- Pre-allocate ifNames slice with make([]string, 0, len(sorted)) (Fix 4)
2026-04-21 12:40:50 +02:00
Andras Bacsai f70d779d0b feat(firewall): add nft bridge-family scaffold for intra-namespace default-deny
- Add BridgeTableName, BridgeAllowRulesPath, BridgeScaffoldPath consts
- Add namespaces []string param to FirewallServiceUnit and InstallFirewallCommand
- Emit nft bridge table/chain scaffold in default-deny mode; tear it down in permissive mode
- Write /etc/coolify/bridge-fw.nft atomically on apply (delete it in permissive mode)
- Add BridgeTableExists and NftAvailable fields to ServerState
- Order coold after coolify-mesh-fw.service so the bridge scaffold is in place before coold starts
2026-04-21 12:37:09 +02:00
Andras Bacsai 901097e541 feat(init): replace binary upload with GitHub release download
Switch coold/corrosion installation from uploading local binaries via
SSH to downloading from GitHub releases on each remote host.

- Remove --coold-binary / --corrosion-binary flags and elfcheck
- Add --coold-version / --corrosion-version flags (default: nightly)
- Add CooldInstallCommand / CorrosionInstallCommand with arch detection
- nightly tag always re-downloads; pinned tags skip if already installed
- Drop FileSha256 pre-flight checks (no longer needed)
- Add tests for version substitution and arch detection in install cmds
2026-04-21 12:05:51 +02:00
Andras Bacsai ef8e740476 feat(mesh): add multi-namespace support to WireGuard overlay
Introduce per-namespace Podman bridges (`coolify-<ns>-mesh`) and
subnet allocation so a single mesh cluster can carry multiple isolated
container networks carved from a shared `--container-pool`.

- Add `cmd/common/meshnet.go`: shared `MeshNetFlags`, `PodmanNetworkFor`,
  `ValidateNamespace`, and flag-binding helpers used by both `init` and
  `firewall` sub-commands.
- Replace flat `PodmanNetworkName` field on `FirewallFlags` with
  `Namespace` + `AllNamespaces`; `--all-namespaces` fans out discovery
  across every `io.coolify.managed=true` bridge on each host.
- Thread `Namespace` into `AllowRule`, `ComputeID`, and coold REST
  payloads so rules are scoped per namespace.
- Extend WireGuard planner (`internal/wireguard/plan.go`,
  `subnet.go`) to allocate one deterministically-ordered subnet per
  host per namespace; `AllowedIPs` now lists every peer's namespace
  subnets, keeping `wg0.conf` stable across re-runs.
- Pass `COOLD_NAMESPACES=<ns>:<network>:<gw>,...` env to coold so it
  can bind DNS and track rules per namespace.
- Add `scripts/e2e-mesh.sh` for end-to-end multi-namespace smoke test.
- Update CLAUDE.md architecture docs to reflect namespace layout.
2026-04-21 09:15:49 +02:00
Andras Bacsai 95250d32a0 feat(firewall): add --wg-interface flag and thread iface through coold client
Add WGInterface field to FirewallFlags with --wg-interface flag (default
from DefaultWGInterface). Thread iface parameter through CooldApply,
CooldRevoke, CooldList, and CooldListAll so the WireGuard interface name
is configurable instead of hardcoded to wg0.

Also replace hardcoded "coolify-mesh" strings with PodmanNetworkName
where applicable.
2026-04-20 21:14:36 +02:00
Andras Bacsai e5e33b46ae refactor(firewall): replace SSH/iptables with coold REST client
Drop direct iptables manipulation over SSH. Firewall allow/revoke/list
now POST/DELETE/GET against coold's REST API via SSH-bounced curl.

- Add internal/firewall/coold_client.go with CooldApply, CooldRevoke,
  CooldList and per-host bearer-token resolution (reads
  /etc/coolify/api-token over SSH when no override given)
- Delete apply.go, list.go, persist.go — coold owns kernel rules,
  persistence (allow.rules snapshot), and the systemd unit
- Add --coold-port (default 8443) and --coold-token persistent flags
- Update CLAUDE.md and CONTROL_PLANE.md to reflect coold-owned surface
  and outbound WSS/gRPC dial architecture
2026-04-20 17:35:27 +02:00
Andras Bacsai 84fec60a60 feat(firewall): add cross-host container allow-rule command
Add `coolify firewall` command tree (alpha) for managing iptables
COOLIFY-ALLOW rules across SSH-reachable servers in the coolify-mesh
Podman network.

New subcommands:
- containers: discover running containers across all servers
- list: show installed allow rules
- allow: add src→dst:port allow rule
- revoke: remove an allow rule

Extract shared SSH-mesh flags (--servers, --ssh-key, --ssh-user,
--ssh-port, --concurrency, --ssh-timeout) into cmd/common.SSHMeshFlags
so both `init` and `firewall` reuse the same flag set. Trim duplicated
flag definitions from cmd/init/flags.go accordingly.

Internal packages added:
- internal/firewall/rule.go: AllowRule model + iptables rule rendering
- internal/firewall/discover.go: fan-out container discovery via podman ps
- internal/firewall/list.go: fan-out rule listing via iptables-save
- internal/firewall/apply.go: apply/revoke rules over SSH
- internal/firewall/persist.go: rule persistence helpers
- internal/models/firewall.go: ContainerRow / AllowRuleRow display models

Full unit-test coverage added for all new packages.
2026-04-20 13:53:36 +02:00
Andras Bacsai 0df8f401e1 Merge remote-tracking branch 'origin/v4.x' into coolify-init-wireguard-mesh 2026-04-20 13:36:31 +02:00
github-actions[bot] 594e274b6b chore: bump version to v1.6.2 2026-04-20 10:54:34 +00:00
Andras Bacsai 4d9b21a662 feat(application): add preview deployment delete command
Add `application previews delete` subcommand to delete PR preview
deployments. Includes service method, CLI command with confirmation
prompt and --force flag, and full test coverage.
2026-04-19 14:55:42 +02:00
Andras Bacsai 6f1b38cf84 feat(dns): bind coold DNS to bridge gateway, disable aardvark-dns
Add --disable-dns to podman network create so netavark never starts
aardvark-dns on the bridge gateway IP:53 — coold owns that socket for
cluster-wide service discovery (CONTROL_PLANE.md §5).

- CooldServiceUnit takes bridgeGatewayIP param; injects
  COOLD_BRIDGE_GATEWAY_IP and COOLD_DNS_ZONE env vars into systemd unit
- podmanNetRecreateCmd drops and recreates network to fix pre-alpha
  drift where dns_enabled=true; phase2 detects via PodmanDNSEnabled
- Add namespace column to service_endpoints schema (reserved for
  per-app isolation / multi-tenant scoping)
- Pass containerAssignments to phase3Server
- Document port 53 conflict handling layers in CONTROL_PLANE.md
2026-04-17 16:24:57 +02:00
Andras Bacsai 1e67e5e3f5 feat(corrosion): detect schema drift and auto-reset DB on schema change
Replace boolean `healthy` column with `state` (liveness) and `health`
(readiness) columns in the CR-SQLite schema.

Add sha256-based schema drift detection: Probe reads the remote schema
file hash into CorrosionSchemaSha256; BuildPlan triggers
ActionWriteCorrosionSchema when hash mismatches; phase3Server stops
corrosion and wipes the DB before writing the new schema so CR-SQLite
can re-bootstrap cleanly.

Fix systemd activation: use `enable` + `restart` instead of
`enable --now` so already-active services pick up new config without a
separate reload step.
2026-04-17 15:07:26 +02:00
Andras Bacsai 67e53195bb feat(init): add corrosion + coold install support
Add --install-coold flag to `coolify init` that uploads and installs the
corrosion (gossip/CRSQLite) and coold (host agent) binaries on each node.

- New internal/services package: pure config generators for corrosion
  TOML, CoolifySchemaSQL, and coold systemd unit; ELF64/aarch64 validator
- wireguard.DesiredMesh gains InstallCoold, binary paths/shas, and port fields
- apply/plan wire pre-flight checks: ELF arch validation + SHA-256 hashing
  before any SSH connection is opened
- SSH client gains helpers used by the wireguard apply layer
2026-04-17 13:56:36 +02:00
Andras Bacsai f4d8049867 docs(control-plane): introduce coold as per-host agent boundary
Document coold as the security/audit layer between Coolify control
plane and the podman socket. Add architecture diagram showing the
communication flow. Update all references from direct podman socket
access to coold REST API over wg0.

Also add comment to enablePodmanSocketCmd clarifying the socket stays
Unix-only and is never exposed on TCP.
2026-04-16 15:31:50 +02:00
Andras Bacsai 1dfbc8cb7b feat(init): add WireGuard mesh bootstrap command
Add `coolify init plan` and `coolify init apply` commands for
bootstrapping a WireGuard full-mesh overlay between servers.

- SSH fanout to reconstruct current WireGuard state per host
- Plan engine diffs desired vs actual mesh (peers, IPs, firewall)
- Apply executes plan idempotently over SSH with concurrency control
- Podman install + coolify-mesh bridge network setup
- iptables firewall rules with optional default-deny container policy
- Subnet allocators for mgmt pool (100.64.0.0/16) and container pool (10.210.0.0/16)
- CONTROL_PLANE.md spec for v5 control plane responsibilities
2026-04-16 15:25:44 +02:00
github-actions[bot] ab951a561c chore: bump version to v1.6.1 2026-04-16 10:01:33 +00:00
github-actions[bot] b0eb8dbd15 chore: bump version to v1.6.0 2026-03-30 13:06:16 +00:00
Andras Bacsai c292ba8b42 test(deployment): use assert.NoError in deploy service test
Replace `require.NoError` with `assert.NoError` when reading request body in `deployment_test` to keep assertion style consistent in this test block.
2026-03-30 14:10:34 +02:00
Andras Bacsai 28d54b0df9 feat(deployment): support preview deploy fields via request payload
Add shared deploy flags (`--force`, `--pull-request-id`, `--docker-tag`) to
`deploy uuid|name|batch`, and validate `--docker-tag` against minimum
Coolify version `4.0.0-beta.471`.

Refactor deployment triggering to send a structured `DeployRequest` via
`POST /deploy` instead of GET query parameters, enabling optional payload
fields for preview/tagged deployments.

Update deployment service tests to assert POST method and JSON body, and
document the new flags and example usage in the README.
2026-03-30 13:50:52 +02:00
Andras Bacsai ce0e8fe9cd fix(version): write update notice to stderr to preserve JSON stdout
Redirect the version update message from stdout to stderr so command JSON output stays machine-readable.

Expand checker tests with shared stdout/stderr capture helpers and assertions to verify:
- update notices are emitted on stderr only
- stdout remains clean during checks and errors
- JSON output to stdout is unaffected when an update is available
2026-03-30 13:35:01 +02:00
Andras Bacsai cad379eefb test(service): use assert.True/False helpers for boolean assertions
Replace assert.Equal with more specific boolean assertion helpers
(assert.True and assert.False) for improved readability and
idiomatic Go testing practices.
2026-03-23 14:40:55 +01:00
Andras Bacsai 53ab7b315c feat(storage): require minimum API version 4.0.0-beta.470
Add version check validation across all storage CRUD operations in application,
database, and service commands. This ensures the API client meets the minimum
version requirement before executing storage operations.

Also includes:
- Documentation updates for dockerfile-target-build parameter in llms.txt
- Field alignment formatting fixes in ApplicationCreateRequest structs
2026-03-23 14:38:19 +01:00
Andras Bacsai 8a7d2c20af Merge remote-tracking branch 'origin/v4.x' into coolify-cli-storage-endpoints 2026-03-23 14:32:49 +01:00
Andras Bacsai f67411de2c feat(storage): add CRUD operations for persistent and file storages
Add comprehensive storage management system for applications, databases, and services:

- Implement storage subcommands (list, create, update, delete) with full API integration
- Add support for both persistent volumes and file-based storage management
- Create Storage model with comprehensive validation for type-specific operations
- Implement ApplicationService, DatabaseService, and ServiceService storage methods
- Add extensive unit tests covering CRUD operations and edge cases
- Integrate storage subcommand into application, database, and service CLI commands
- Add dockerfile-target-build flag support to application creation and update commands

Storage operations support:
- Persistent volumes: create with optional host paths, update mount paths and names
- File storages: create/update with content or file system paths, support directories
- Common features: mount path management, read-only detection, preview suffix toggling
2026-03-23 14:27:21 +01:00
Andras Bacsai 0872e48283 feat(models): add ApplicationSettings and expand Application with extended configuration
- Add ApplicationSettings struct for application-level feature flags
- Expand Application model with git, build, health check, and resource limit fields
- Add comprehensive unit tests for Application marshaling/unmarshaling
- Add application.json fixture for testing
2026-03-23 11:03:01 +01:00
Andras Bacsai cdc5a1e732 Merge pull request #50 from YaRissi/fix/app-env-sync
fix: app env bulk
2026-03-23 10:28:15 +01:00
Andras Bacsai 6bd783dc8a Merge remote-tracking branch 'origin/v4.x' into v4.x 2026-03-23 10:21:46 +01:00
Andras Bacsai 2ac1d0f869 chore: bump version to v1.5.0 2026-03-23 10:21:28 +01:00
Andras Bacsai 801c2e0b3c Merge pull request #55 from baer95/tablewriter
refactor: improve table output format
2026-03-20 18:14:18 +01:00
Andras Bacsai ea4bec7492 refactor(output): reorganize table formatter and improve test robustness
- Move empty slice check before table writer creation for early exit
- Fix error message typo: "ascii w" → "table"
- Enhance boolean test to dynamically locate data rows instead of hardcoded indices
2026-03-20 18:14:04 +01:00
Andras Bacsai 7e59cd76c3 feat(env): add database environment variable management
Add complete environment variable management for databases with full CRUD
operations, including a new sync command to load variables from .env files.
Support comment field across application, service, and database entities.

- Implement database env service layer with create, read, update, delete, list
- Add sync command for bulk loading and updating from .env files
- Add --comment flag to application and service env commands
- Include comprehensive test coverage for database service operations
- Update to Go 1.24.13
2026-03-20 17:31:42 +01:00
Andras Bacsai 81b9e9cdd0 test(application): fix linter warnings in BulkUpdateEnvs tests
Address unused function parameters and unhandled error return values.
2026-03-19 22:26:15 +01:00
Andras Bacsai fe01e8f9b8 test(application): verify BulkUpdateEnvs request serialization and error handling
- Add request body assertions to validate correct serialization in BulkUpdateEnvs test
- Add new test case for API error handling (500 response)
2026-03-19 22:08:26 +01:00
Andras Bacsai daa2a4cdcb Merge remote-tracking branch 'origin/v4.x' into fix/app-env-sync 2026-03-19 22:06:32 +01:00