{"id":29863470,"url":"https://github.com/drevops/environment-detector","last_synced_at":"2026-03-11T04:31:58.402Z","repository":{"id":288534590,"uuid":"956927235","full_name":"drevops/environment-detector","owner":"drevops","description":"🔬 Zero-config environment type detection","archived":false,"fork":false,"pushed_at":"2026-02-27T00:42:37.000Z","size":200,"stargazers_count":2,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-27T02:13:00.036Z","etag":null,"topics":["acquia","ci","ddev","environment","lagoon","pantheon","php","platform","skpr","tugboat"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drevops.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"drevops","patreon":"drevops"}},"created_at":"2025-03-29T06:18:04.000Z","updated_at":"2026-02-26T20:55:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"36a641a0-50fe-4db3-bee4-3e631ad89d40","html_url":"https://github.com/drevops/environment-detector","commit_stats":null,"previous_names":["drevops/environment-detector"],"tags_count":5,"template":false,"template_full_name":"AlexSkrypnyk/scaffold","purl":"pkg:github/drevops/environment-detector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fenvironment-detector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fenvironment-detector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fenvironment-detector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fenvironment-detector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drevops","download_url":"https://codeload.github.com/drevops/environment-detector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fenvironment-detector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30370798,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acquia","ci","ddev","environment","lagoon","pantheon","php","platform","skpr","tugboat"],"created_at":"2025-07-30T07:13:24.653Z","updated_at":"2026-03-11T04:31:58.390Z","avatar_url":"https://github.com/drevops.png","language":"PHP","funding_links":["https://github.com/sponsors/drevops","https://patreon.com/drevops"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"\" rel=\"noopener\"\u003e\n  \u003cimg width=100px height=100px src=\"logo.png\" alt=\"Environment Detector\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eZero-config environment type detection\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![GitHub Issues](https://img.shields.io/github/issues/drevops/environment-detector.svg)](https://github.com/drevops/environment-detector/issues)\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/drevops/environment-detector.svg)](https://github.com/drevops/environment-detector/pulls)\n[![Test PHP](https://github.com/drevops/environment-detector/actions/workflows/test-php.yml/badge.svg)](https://github.com/drevops/environment-detector/actions/workflows/test-php.yml)\n[![codecov](https://codecov.io/gh/drevops/environment-detector/graph/badge.svg?token=Q2S80GFSF6)](https://codecov.io/gh/drevops/environment-detector)\n![GitHub release (latest by date)](https://img.shields.io/github/v/release/drevops/environment-detector)\n![LICENSE](https://img.shields.io/github/license/drevops/environment-detector)\n![Renovate](https://img.shields.io/badge/renovate-enabled-green?logo=renovatebot)\n\n\u003c/div\u003e\n\n---\n\n## Features\n\n- Detects environment type: `local`, `ci`, `dev`, `preview`, `stage`, `prod`, or user-defined\n- Supports many popular providers out-of-the-box: [Acquia](src/Providers/Acquia.php), [CircleCI](src/Providers/CircleCi.php), [DDEV](src/Providers/Ddev.php), [Docker](src/Providers/Docker.php), [GitHub Actions](src/Providers/GitHubActions.php), [GitLab CI](src/Providers/GitLabCi.php), [Lagoon](src/Providers/Lagoon.php), [Lando](src/Providers/Lando.php), [Pantheon](src/Providers/Pantheon.php), [Platform.sh](src/Providers/PlatformSh.php), [Skpr](src/Providers/Skpr.php), [Tugboat](src/Providers/Tugboat.php)\n- Detects custom contexts: [Drupal](src/Contexts/Drupal.php) (more to come)\n- Simple API for checking current environment\n- Extendable via custom providers and contexts\n- Override and fallback support for precise control\n- Optimised for performance with static caching\n\n## Installation\n\n```bash\ncomposer require drevops/environment-detector\n```\n\n## Quick Start\n\n```php\nuse DrevOps\\EnvironmentDetector\\Environment;\n\nEnvironment::init();\nif (getenv('ENVIRONMENT_TYPE') === Environment::LOCAL) {\n  // Apply local settings.\n}\n```\n\nAlternatively, use the convenience methods:\n\n```php\nuse DrevOps\\EnvironmentDetector\\Environment;\n\n// No need to init() - a first call to is*() will auto-initialize.\nif (Environment::isLocal()) {\n  // Apply local settings.\n}\n\nif (Environment::isProd()) {\n  // Apply production settings.\n}\n```\n\n## How It Works\n\n1. **Provider detection:** Each provider checks for environment-specific variables\n   or files to identify itself.\n2. **Type mapping:** Once identified, the provider maps its internal state to a\n   type like `dev`, `prod`, or a custom type.\n3. **Context detection**: Optionally applies provider- or framework-specific\n   changes (e.g., modify Drupal `$settings` global variable to add `$settings['environment']` value).\n\nThe resolved type is stored in the `ENVIRONMENT_TYPE` env var. If already set,\nthis value takes precedence over the provider detection. The `contextualize`\nstill applies context changes even if the type is pre-set via environment\nvariable.\n\n## Advanced Usage\n\n### Advanced initialization with customization\n\n```php\nEnvironment::init(\n  contextualize: TRUE,                            // Whether to apply the context automatically\n  fallback: Environment::DEVELOPMENT,             // The fallback environment type\n  override: function($provider, $type) {          // The override callback to change the environment type\n    if ($type === Environment::DEVELOPMENT \u0026\u0026 $provider-\u003eid() === 'tugboat') {\n      return 'qa';\n    }\n    return $type;\n  },\n  providers: [new MyCustomProvider()],            // Additional provider instances\n  contexts: [new MyCustomContext()],              // Additional context instances\n);\n```\n\n### Fallback Type\n\nIf an environment type is not detected, a fallback `Environment::DEVELOPMENT` will be\nreturned by default. This is to ensure that, in case of misconfiguration, the application\ndoes not apply local settings in production or production settings in local - 'development'\ntype is the safest default.\n\nYou can set a different fallback type during initialization:\n\n```php\nEnvironment::init(fallback: Environment::PRODUCTION);\n```\n\n## Providers\n\nOnly one provider can be active. If multiple match, or none match, an exception\nis thrown. Register custom providers using `init(providers:[MyCustomProvider::class])`.\n\nSupported built-ins:\n\n- [Acquia](src/Providers/Acquia.php)\n- [CircleCI](src/Providers/CircleCi.php)\n- [DDEV](src/Providers/Ddev.php)\n- [Docker](src/Providers/Docker.php)\n- [GitHub Actions](src/Providers/GitHubActions.php)\n- [GitLab CI](src/Providers/GitLabCi.php)\n- [Lagoon](src/Providers/Lagoon.php)\n- [Lando](src/Providers/Lando.php)\n- [Pantheon](src/Providers/Pantheon.php)\n- [Platform.sh](src/Providers/PlatformSh.php)\n- [Skpr](src/Providers/Skpr.php)\n- [Tugboat](src/Providers/Tugboat.php)\n\n### Accessing Provider Data\n\n```php\n// Initialize first to detect the active provider\nEnvironment::init();\n\n$provider = Environment::getActiveProvider();\nif ($provider \u0026\u0026 $provider-\u003eid() === 'acquia') {\n  // Acquia-specific logic\n  $data = $provider-\u003edata();\n  if (isset($data['AH_SITE_GROUP'])) {\n    // Use Acquia-specific environment data\n  }\n}\n```\n\n### Adding a Custom Provider\n\n```php\nuse DrevOps\\EnvironmentDetector\\Providers\\ProviderInterface;\nuse DrevOps\\EnvironmentDetector\\Environment;\n\nclass CustomHosting implements ProviderInterface {\n  public function active(): bool {\n    return isset($_SERVER['CUSTOM_ENV']);\n  }\n\n  public function data(): array {\n    return ['CUSTOM_ENV' =\u003e $_SERVER['CUSTOM_ENV'] ?? null];\n  }\n\n  public function type(): ?string {\n    return match ($_SERVER['CUSTOM_ENV_TYPE'] ?? null) {\n      'dev' =\u003e Environment::DEVELOPMENT,\n      'qa' =\u003e 'qa',\n      'live' =\u003e Environment::PRODUCTION,\n      default =\u003e null,\n    };\n  }\n\n  public function id(): string {\n    return 'customhosting';\n  }\n\n  public function label(): string {\n    return 'Custom Hosting';\n  }\n\n  public function contextualize(\\DrevOps\\EnvironmentDetector\\Contexts\\ContextInterface $context): void {\n    // Optional: Apply provider-specific context changes\n  }\n}\n\n// Register the custom provider during initialization\nEnvironment::init(providers: [new CustomHosting()]);\n```\n\n### Contexts\n\nContexts apply environment-specific changes to frameworks or applications. A context may\nprovide generic changes that are applied to the application. A provider may also provide\nprovider-specific context changes.\n\nFor example, a **Drupal** context applies changes to the global `$settings` array, while a\n**Lagoon** provider's `contextualize()` method adds Lagoon-specific changes to the `$settings` array.\n\nThe goal is to have enough context changes to cover the most common use cases, but also\nto allow adding custom contexts to cover specific use cases within the application.\n\n#### Adding a custom context\n\n```php\nuse DrevOps\\EnvironmentDetector\\Contexts\\ContextInterface;\n\nclass CustomContext implements ContextInterface {\n  public function active(): bool {\n    return class_exists('MyFramework');\n  }\n\n  public function contextualize(): void {\n    // Apply generic context changes\n    global $configuration;\n    $configuration['custom_value'] = $_SERVER['custom_value'] ?? 'default';\n  }\n\n  public function id(): string {\n    return 'myframework';\n  }\n\n  public function label(): string {\n    return 'My Framework';\n  }\n}\n\n// Register the custom context during initialization\nEnvironment::init(contexts: [new CustomContext()]);\n```\n\n## Maintenance\n\n```bash\ncomposer install\ncomposer lint\ncomposer test\n```\n\n---\n\n*This repository was created using the *[*Scaffold*](https://getscaffold.dev/)*\nproject template.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrevops%2Fenvironment-detector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrevops%2Fenvironment-detector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrevops%2Fenvironment-detector/lists"}