feat: Trigger Lagoon Deployments for App Instances#56
Conversation
cef3c95 to
579e6f6
Compare
cfba370 to
5d83b74
Compare
9a578d4 to
33fd4c6
Compare
- chore: trigger deploy via api instead of lagoon cli - chore: find by uuid - chore: only cache token for 2min
0c16e85 to
0edf925
Compare
There was a problem hiding this comment.
Pull request overview
Adds Lagoon deployment/command triggering capabilities for Polydock App Instances from both Artisan commands and the Filament Admin UI, leveraging the freedomtech-hosting/ft-lagoon-php GraphQL client and SSH-based token retrieval.
Changes:
- Introduces new Lagoon-related Artisan commands for bulk/single-instance deploy triggers and for running allowed commands across instances (with optional concurrency).
- Adds a Filament “Trigger Deploy” header action (with last deployment lookup) on the App Instance view page.
- Updates Lagoon/Amazee AI related dependencies and enhances Lagoon token initialization diagnostics.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Feature/Filament/CreatePolydockAppInstanceTest.php | Import ordering tweak. |
| tests/Feature/Console/Commands/RunLagoonCommandOnAppInstancesTest.php | Adds feature tests for the new command execution workflow. |
| config/polydock.php | Changes Amazee AI backend provider debug default. |
| composer.json | Bumps Lagoon/Polydock-related package versions. |
| composer.lock | Locks updated dependency graph (incl. new packages). |
| app/Services/LagoonClientService.php | Centralizes Lagoon client config + SSH token retrieval + GraphQL initialization. |
| app/PolydockServiceProviders/PolydockServiceProviderFTLagoon.php | Improves token caching/error diagnostics; throws on missing token. |
| app/PolydockEngine/Engine.php | Adjusts required-variable validation and backfills Lagoon runtime defaults on legacy instances. |
| app/Filament/Admin/Resources/UserRemoteRegistrationResource.php | Removes unused import. |
| app/Filament/Admin/Resources/PolydockAppInstanceResource/Pages/ViewPolydockAppInstance.php | Adds “Trigger Deploy” action + last deployment display via Lagoon API. |
| app/Console/Commands/TriggerLagoonDeployOnAppInstances.php | New bulk deploy-trigger command (API-based, optional concurrency). |
| app/Console/Commands/TriggerLagoonDeployOnAppInstance.php | New single-instance deploy-trigger command (API-based). |
| app/Console/Commands/RunLagoonCommandOnAppInstances.php | New bulk command-runner via Lagoon API with allowlist + optional concurrency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| file_put_contents(base_path('tests/fixtures/lagoon-private-key'), 'dummy-key'); | ||
|
|
||
| $this->app->instance('polydock.lagoon.token_fetcher', fn () => 'fake-token'); | ||
|
|
||
| $mock = \Mockery::mock(Client::class); | ||
| $mock->shouldReceive('setLagoonToken')->with('fake-token')->once(); | ||
| $mock->shouldReceive('initGraphqlClient')->once(); |
There was a problem hiding this comment.
LagoonClientService::getLagoonToken() invokes the bound polydock.lagoon.token_fetcher callable with the $config array, but the test binds a zero-arg closure. This will throw an ArgumentCountError when the command runs. Bind a callable that accepts the config parameter (e.g., fn (array $config) => 'fake-token') or change the service to support zero-arg fetchers.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
app/Filament/Admin/Resources/PolydockAppInstanceResource/Pages/ViewPolydockAppInstance.php
Outdated
Show resolved
Hide resolved
app/Filament/Admin/Resources/PolydockAppInstanceResource/Pages/ViewPolydockAppInstance.php
Outdated
Show resolved
Hide resolved
| $phpBinary = PHP_BINARY; | ||
| $artisan = base_path('artisan'); | ||
| $commandBase = [ | ||
| $phpBinary, | ||
| $artisan, | ||
| 'polydock:instances:run-lagoon-command', | ||
| $appUuid, | ||
| '--force', | ||
| ]; | ||
|
|
||
| if ($envOverride) { | ||
| $commandBase[] = "--environment={$envOverride}"; | ||
| } | ||
| if ($variablesOnly) { | ||
| $commandBase[] = '--variables-only'; | ||
| } | ||
|
|
||
| $pool = Process::pool(function (Pool $pool) use ($instances, $commandBase) { | ||
| foreach ($instances as $instance) { | ||
| $command = array_merge($commandBase, ["--instance-id={$instance->id}"]); | ||
| $pool->as($instance->id)->command($command); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Concurrent mode builds a child-process command for polydock:instances:run-lagoon-command but omits the required command_name argument and points at the wrong command entirely for deployments. As written, the spawned processes will fail to start (and no deploy will be triggered). Consider adding an --instance-id worker mode to this command and have the pool call polydock:instances:trigger-deploy (or call polydock:app-instance:trigger-deploy per instance) with the correct args/options instead of run-lagoon-command.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…/ViewPolydockAppInstance.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…not Artisan CLI wrapper) (#97) * refactor: use LagoonClientService directly in Trigger Deploy admin action
* fix: update token_fetcher closures in tests to accept array config parameter
* feat: Trigger Lagoon Deployments for App Instances (#56) * chore: artisan add trigger lagoon deploy and run lagoon commands on app instances * chore: add a button to trigger a deploy from app instance * Use upstream lib Ssh code * chore: add support for buildVariables * chore: only cache token for 2min * chore: tweak label Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: fix deploy cmd Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: cleanup test ssh Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: run pint * feat: add api token management, app class discovery, and enhanced store/app configuration (#68) feat: add Lagoon Script Configuration section with lifecycle scripts for app management feat: enhance registration response with additional Lagoon project details fix: update response keys in RegisterController for consistency with underscore naming convention fix error for missing lagoon-auto-idle variables, including tests feat: add Lagoon runtime settings to Polydock Store App configuration and infolist feat: implement API token management and access control with middleware fix: handle null appInstance in user remote registration URL generation chore: add amazeeio/polydock-app-amazeeclaw dependency to composer.json chore: update dependencies in composer.json and composer.lock to latest versions chore: move internal package dependencies to ^0.1 chore: refresh composer lock for v0.1.1 package releases chore: update polydock-app-amazeeclaw requirement and lockfile so Polydoc consumes the new store-level app-specific configuration field behavior. chore: update polydock-engine to consume the latest amazeeclaw release and refresh composer.lock via Dockerized composer to keep dependency resolution reproducible. fix: update route for instance registration and add authentication middleware fix: changed the route for showing instance registration from '/instances/{uuid}' to '/register/{uuid}' and added a TODO comment regarding future CRUD endpoint implementation. fix: wrong helpertext for autoIdle - only allow 0/1 (off/on) chore: artisan add trigger lagoon deploy and run lagoon commands on app instances chore: add a button to trigger a deploy from app instance chore: use upstream lib Ssh code chore: add support for buildVariables chore: update error handling for trigger deploy chore: trigger deploy via api instead of lagoon cli chore: only cache token for 2min chore: enable debug with env var options chore: fix concurrent calling chore: create and cleanup ssh keys in tests chore: implement getSearchResultsUsing to prevent memory-heavy query chore: lookup uuid for instance --------- Co-authored-by: Michael Schmid <michael.schmid@amazee.io> * chore: Adds wildcards to allow removing multiple emails at once (#31) * Adds wildcards * chore: update app/Console/Commands/RemoveAppInstancesByEmail.php --------- Co-authored-by: Blaize Kaye <blaize.kaye@amazee.io> Co-authored-by: Dan Lemon <daniel.lemon@amazee.io> * chore: add scramble docs / openapi endpoint (#91) * chore: add endpoints for moad - chore: switch to scramble - chore: force openapi output to be `api/openapi.json` endpoint * chore: check for running instance Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: bump deps * Bump league/commonmark from 2.8.0 to 2.8.1 (#92) Bumps [league/commonmark](https://github.com/thephpleague/commonmark) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/thephpleague/commonmark/releases) - [Changelog](https://github.com/thephpleague/commonmark/blob/2.8/CHANGELOG.md) - [Commits](thephpleague/commonmark@2.8.0...2.8.1) --- updated-dependencies: - dependency-name: league/commonmark dependency-version: 2.8.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump rollup from 4.53.5 to 4.59.0 (#89) Bumps [rollup](https://github.com/rollup/rollup) from 4.53.5 to 4.59.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](rollup/rollup@v4.53.5...v4.59.0) --- updated-dependencies: - dependency-name: rollup dependency-version: 4.59.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump minimatch and editorconfig (#90) Bumps [minimatch](https://github.com/isaacs/minimatch) and [editorconfig](https://github.com/editorconfig/editorconfig-core-js). These dependencies needed to be updated together. Updates `minimatch` from 9.0.1 to 9.0.7 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](isaacs/minimatch@v9.0.1...v9.0.7) Updates `editorconfig` from 1.0.4 to 1.0.7 - [Release notes](https://github.com/editorconfig/editorconfig-core-js/releases) - [Changelog](https://github.com/editorconfig/editorconfig-core-js/blob/main/CHANGELOG.md) - [Commits](editorconfig/editorconfig-core-js@v1.0.4...v1.0.7) --- updated-dependencies: - dependency-name: minimatch dependency-version: 9.0.7 dependency-type: indirect - dependency-name: editorconfig dependency-version: 1.0.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: fix import of DB facade Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Add feature tests for TriggerLagoonDeployOnAppInstances command (#101) * Initial plan * feat: add TriggerLagoonDeployOnAppInstancesTest feature tests Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> * Pre-fetch Lagoon token once in coordinator to avoid per-worker SSH bursts (#100) * Initial plan * Pre-fetch Lagoon token once in coordinator; pass to concurrent workers via env var Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> * chore: trigger deploy Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: enhance validation Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Enforce Sanctum token abilities on authenticated API routes (#102) * Initial plan * feat: apply instances.read/write ability middleware to API routes Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> * chore: fix tests * fix: use isolated temp directory for SSH key in skipped-metadata test (#103) * Initial plan * fix: use temp directory for key file in test_it_skips_instances_missing_metadata Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Michael Schmid <michael.schmid@amazee.io> Co-authored-by: Blaize Kaye <blaize.kaye@gmail.com> Co-authored-by: Blaize Kaye <blaize.kaye@amazee.io> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: dan2k3k4 <158704+dan2k3k4@users.noreply.github.com>
Introduces the ability to trigger Lagoon deployments for Polydock App Instances directly from the Polydock Engine.
Adds two new Artisan commands for bulk or single-instance deployments and integrates a "Trigger Deploy" action into the Filament Admin UI.
Key Changes
polydock:instances:run-lagoon-command:FreedomtechHosting\FtLagoonPhp\Client).--forceis used).polydock:instances:trigger-deploy:lagoon deploy -p [project] -e [branch]for running instances.ViewPolydockAppInstance:PolydockAppInstance: AddedgetName()andsetName()convenience methods.tests/Feature/Console/Commands/RunLagoonCommandOnAppInstancesTest.phpcovering:How to Test
CLI (API-based):
CLI (Lagoon CLI-based):
php artisan polydock:instances:trigger-deploy {app_uuid}Admin UI: