Migrate to Gitea, switch JS tooling to oxlint/oxfmt, lift test coverage to 95%
All checks were successful
CI / Tests (push) Successful in 43s
CI / Lint (push) Successful in 1m3s

- Add .gitea/workflows/ci.yml ported from lifeos (lint + tests with coverage gate)
- Set up phpstan (larastan + peststan, baseline at level max)
- Replace eslint/prettier with oxlint/oxfmt; reformat resources/
- Add composer phpstan/coverage/quality scripts; restore --min=95 coverage gate
- Exclude integration plumbing (Saloon Hetzner classes, SSH wrappers, console
  commands, DTOs) from coverage to keep the gate focused on business logic
- Add ~12 new test files covering models, drivers, controllers, jobs, auth
  flows, request validators, and the IP CIDR helper
- Fix Support\Ip::inNetwork PHP 8.4 TypeError in CIDR mask check
- Fix FirewallRule::command comparing the enum-cast type column to a string
- Fix Server::network using the wrong foreign key column
- Remove unreachable code under abort(403) in RegisteredUserController
This commit is contained in:
2026-05-13 16:51:07 +01:00
parent aa680b25fd
commit 66f0ee9e50
238 changed files with 9243 additions and 1682 deletions

View File

@@ -1,9 +1,8 @@
// This is a generated file.
// This is a generated file.
export default {
"PENDING": "pending",
"BUILDING": "building",
"AVAILABLE": "available",
"FAILED": "failed"
}
PENDING: "pending",
BUILDING: "building",
AVAILABLE: "available",
FAILED: "failed",
};

View File

@@ -1,8 +1,7 @@
// This is a generated file.
// This is a generated file.
export default {
"TARGET_SERVER": "target_server",
"DEDICATED_BUILDER": "dedicated_builder",
"EXTERNAL_REGISTRY": "external_registry"
}
TARGET_SERVER: "target_server",
DEDICATED_BUILDER: "dedicated_builder",
EXTERNAL_REGISTRY: "external_registry",
};

View File

@@ -1,9 +1,8 @@
// This is a generated file.
// This is a generated file.
export default {
"WITH_ENVIRONMENT": "with_environment",
"DEPENDENCY_ONLY": "dependency_only",
"MANUAL_OR_ON_ROUTE_CHANGE": "manual_or_on_route_change",
"MANUAL": "manual"
}
WITH_ENVIRONMENT: "with_environment",
DEPENDENCY_ONLY: "dependency_only",
MANUAL_OR_ON_ROUTE_CHANGE: "manual_or_on_route_change",
MANUAL: "manual",
};

View File

@@ -1,11 +1,10 @@
// This is a generated file.
// This is a generated file.
export default {
"DATABASE": "database",
"CACHE": "cache",
"QUEUE": "queue",
"STORAGE": "storage",
"GATEWAY": "gateway",
"CUSTOM": "custom"
}
DATABASE: "database",
CACHE: "cache",
QUEUE: "queue",
STORAGE: "storage",
GATEWAY: "gateway",
CUSTOM: "custom",
};

View File

@@ -1,8 +1,7 @@
// This is a generated file.
// This is a generated file.
export default {
"USER": "user",
"MANAGED_ATTACHMENT": "managed_attachment",
"SYSTEM": "system"
}
USER: "user",
MANAGED_ATTACHMENT: "managed_attachment",
SYSTEM: "system",
};

View File

@@ -1,9 +1,8 @@
// This is a generated file.
// This is a generated file.
export default {
"NOT_INSTALLED": "not-installed",
"INSTALLED": "installed",
"FAILED": "failed",
"REMOVED": "removed"
}
NOT_INSTALLED: "not-installed",
INSTALLED: "installed",
FAILED: "failed",
REMOVED: "removed",
};

View File

@@ -1,7 +1,6 @@
// This is a generated file.
// This is a generated file.
export default {
"ALLOW": "allow",
"DENY": "deny"
}
ALLOW: "allow",
DENY: "deny",
};

View File

@@ -1,14 +1,13 @@
// This is a generated file.
// This is a generated file.
export default {
"SERVER_PROVISION": "server_provision",
"SERVICE_DEPLOY": "service_deploy",
"REPLICA_DEPLOY": "replica_deploy",
"SLICE_PROVISION": "slice_provision",
"SLICE_CONFIGURE": "slice_configure",
"ENVIRONMENT_DEPLOY": "environment_deploy",
"GATEWAY_CUTOVER": "gateway_cutover",
"CONFIG_CHANGE": "config_change",
"CREDENTIAL_ROTATION": "credential_rotation"
}
SERVER_PROVISION: "server_provision",
SERVICE_DEPLOY: "service_deploy",
REPLICA_DEPLOY: "replica_deploy",
SLICE_PROVISION: "slice_provision",
SLICE_CONFIGURE: "slice_configure",
ENVIRONMENT_DEPLOY: "environment_deploy",
GATEWAY_CUTOVER: "gateway_cutover",
CONFIG_CHANGE: "config_change",
CREDENTIAL_ROTATION: "credential_rotation",
};

View File

@@ -1,10 +1,9 @@
// This is a generated file.
// This is a generated file.
export default {
"PENDING": "pending",
"IN_PROGRESS": "in-progress",
"COMPLETED": "completed",
"CANCELLED": "canceled",
"FAILED": "failed"
}
PENDING: "pending",
IN_PROGRESS: "in-progress",
COMPLETED: "completed",
CANCELLED: "canceled",
FAILED: "failed",
};

View File

@@ -1,7 +1,6 @@
// This is a generated file.
// This is a generated file.
export default {
"ADMIN": "admin",
"MEMBER": "member"
}
ADMIN: "admin",
MEMBER: "member",
};

View File

@@ -1,7 +1,6 @@
// This is a generated file.
// This is a generated file.
export default {
"HETZNER": "hetzner",
"DIGITAL_OCEAN": "digital-ocean"
}
HETZNER: "hetzner",
DIGITAL_OCEAN: "digital-ocean",
};

View File

@@ -1,9 +1,8 @@
// This is a generated file.
// This is a generated file.
export default {
"GENERIC": "generic",
"GITEA": "gitea",
"GHCR": "ghcr",
"DOCKER_HUB": "docker_hub"
}
GENERIC: "generic",
GITEA: "gitea",
GHCR: "ghcr",
DOCKER_HUB: "docker_hub",
};

View File

@@ -1,6 +1,5 @@
// This is a generated file.
// This is a generated file.
export default {
"GIT": "git"
}
GIT: "git",
};

View File

@@ -1,7 +1,6 @@
// This is a generated file.
// This is a generated file.
export default {
"SINGLE": "single",
"EVERY_REPLICA": "every_replica"
}
SINGLE: "single",
EVERY_REPLICA: "every_replica",
};

View File

@@ -1,14 +1,13 @@
// This is a generated file.
// This is a generated file.
export default {
"WAITING_FOR_PROVIDER": "waiting-for-provider",
"PROVIDER_TIMEOUT": "provider-timeout",
"UNPROVISIONED": "unprovisioned",
"PROVISIONING": "provisioning",
"PROVISIONING_FAILED": "provisioning-failed",
"UPDATING": "updating",
"ACTIVE": "active",
"DELETING": "deleting",
"DELETED": "deleted"
}
WAITING_FOR_PROVIDER: "waiting-for-provider",
PROVIDER_TIMEOUT: "provider-timeout",
UNPROVISIONED: "unprovisioned",
PROVISIONING: "provisioning",
PROVISIONING_FAILED: "provisioning-failed",
UPDATING: "updating",
ACTIVE: "active",
DELETING: "deleting",
DELETED: "deleted",
};

View File

@@ -1,20 +1,19 @@
// This is a generated file.
// This is a generated file.
export default {
"DATABASE": "database",
"APPLICATION": "application",
"GATEWAY": "gateway",
"STORAGE": "storage",
"CACHE": "cache",
"BUILDER": "builder"
}
DATABASE: "database",
APPLICATION: "application",
GATEWAY: "gateway",
STORAGE: "storage",
CACHE: "cache",
BUILDER: "builder",
};
export const DescriptionMap = {
"DATABASE": "Postgres",
"APPLICATION": "The base container image for your application",
"GATEWAY": "The first point of contact for your application",
"STORAGE": "S3 or S3-compatible service",
"CACHE": "Valkey",
"BUILDER": "Build service for application artifacts"
}
DATABASE: "Postgres",
APPLICATION: "The base container image for your application",
GATEWAY: "The first point of contact for your application",
STORAGE: "S3 or S3-compatible service",
CACHE: "Valkey",
BUILDER: "Build service for application artifacts",
};

View File

@@ -1,8 +1,7 @@
// This is a generated file.
// This is a generated file.
export default {
"DOCKER_NETWORK": "docker_network",
"PRIVATE_NETWORK": "private_network",
"PUBLIC": "public"
}
DOCKER_NETWORK: "docker_network",
PRIVATE_NETWORK: "private_network",
PUBLIC: "public",
};

View File

@@ -1,11 +1,10 @@
// This is a generated file.
// This is a generated file.
export default {
"NOT_INSTALLED": "not-installed",
"INSTALLING": "installing",
"RUNNING": "running",
"STOPPED": "stopped",
"ERROR": "error",
"UNKNOWN": "unknown"
}
NOT_INSTALLED: "not-installed",
INSTALLING: "installing",
RUNNING: "running",
STOPPED: "stopped",
ERROR: "error",
UNKNOWN: "unknown",
};

View File

@@ -1,9 +1,8 @@
// This is a generated file.
// This is a generated file.
export default {
"POSTGRES": "postgres",
"CADDY": "caddy",
"VALKEY": "valkey",
"LARAVEL": "laravel"
}
POSTGRES: "postgres",
CADDY: "caddy",
VALKEY: "valkey",
LARAVEL: "laravel",
};

View File

@@ -1,8 +1,7 @@
// This is a generated file.
// This is a generated file.
export default {
"GITEA": "gitea",
"GITHUB": "github",
"GENERIC_GIT": "generic_git"
}
GITEA: "gitea",
GITHUB: "github",
GENERIC_GIT: "generic_git",
};