From 0a7df87f22572d177324c43f2e0df8e6e306738c Mon Sep 17 00:00:00 2001 From: Eduardo Ribeiro Date: Mon, 11 May 2026 22:17:00 -0400 Subject: [PATCH 1/4] fix: pass 'column' argument to CreateAction mutateDataUsing According to the documentation, the CreateAction should receive the 'column' identifier inside the $arguments array in the mutateDataUsing method. This fix ensures the column argument is properly passed down to the action, allowing developers to know which column triggered the creation. --- src/BoardResourcePage.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/BoardResourcePage.php b/src/BoardResourcePage.php index 313801742..7a12389bf 100644 --- a/src/BoardResourcePage.php +++ b/src/BoardResourcePage.php @@ -9,6 +9,7 @@ use Filament\Actions\Exceptions\ActionNotResolvableException; use Filament\Forms\Contracts\HasForms; use Filament\Resources\Pages\Page; +use Filament\Tables\Contracts\HasTable; use Livewire\Attributes\Url; use Relaticle\Flowforge\Concerns\BaseBoard; use Relaticle\Flowforge\Concerns\InteractsWithBoard; @@ -86,7 +87,7 @@ protected function resolveActions(array $actions, bool $isMounting = true): arra $resolvedAction = $this->resolveBoardAction($action, $resolvedActions); } elseif (filled($action['context']['schemaComponent'] ?? null)) { $resolvedAction = $this->resolveSchemaComponentAction($action, $resolvedActions); - } elseif (filled($action['context']['table'] ?? null)) { + } elseif ($this instanceof HasTable && filled($action['context']['table'] ?? null)) { $resolvedAction = $this->resolveTableAction($action, $resolvedActions); } else { $resolvedAction = $this->resolveAction($action, $resolvedActions); @@ -96,15 +97,21 @@ protected function resolveActions(array $actions, bool $isMounting = true): arra continue; } + if (filled($action['arguments'] ?? [])) { + $resolvedAction->mergeArguments($action['arguments']); + } + $resolvedAction->nestingIndex($actionNestingIndex); $resolvedAction->boot(); $resolvedActions[] = $resolvedAction; - $this->cacheSchema( - "mountedActionSchema{$actionNestingIndex}", - $this->getMountedActionSchema($actionNestingIndex, $resolvedAction), - ); + if ($isMounting) { + $this->cacheSchema( + "mountedActionSchema{$actionNestingIndex}", + $this->getMountedActionSchema($actionNestingIndex, $resolvedAction), + ); + } } return $resolvedActions; From 7e75af1239bae981fb0d17a8c0b0b9f52be01eb1 Mon Sep 17 00:00:00 2001 From: Manuk Date: Tue, 12 May 2026 12:46:39 +0400 Subject: [PATCH 2/4] test: cover column argument propagation on BoardResourcePage column actions Reproduces issue #124: a CreateAction registered via columnActions() on a BoardResourcePage previously dropped the wire:click `column` argument, so mutateDataUsing() callbacks received an empty arguments array. The fix in 0a7df87f now mirrors upstream InteractsWithActions::resolveActions() and propagates arguments via mergeArguments(). Adds: - TestResource + TestBoardResourcePage fixtures - SchemasServiceProvider registration in TestCase (needed for assertSchemaExists macro) - Pest test using Filament's TestAction macro to call the column action with column=in_progress and assert the created Task lands in the right column --- .../BoardResourcePageColumnActionTest.php | 20 ++++++++ tests/Fixtures/TestBoardResourcePage.php | 48 +++++++++++++++++++ tests/Fixtures/TestPanelProvider.php | 3 ++ tests/Fixtures/TestResource.php | 23 +++++++++ tests/TestCase.php | 2 + 5 files changed, 96 insertions(+) create mode 100644 tests/Feature/BoardResourcePageColumnActionTest.php create mode 100644 tests/Fixtures/TestBoardResourcePage.php create mode 100644 tests/Fixtures/TestResource.php diff --git a/tests/Feature/BoardResourcePageColumnActionTest.php b/tests/Feature/BoardResourcePageColumnActionTest.php new file mode 100644 index 000000000..d6ea782d9 --- /dev/null +++ b/tests/Feature/BoardResourcePageColumnActionTest.php @@ -0,0 +1,20 @@ +callAction( + TestAction::make('createTask')->arguments(['column' => 'in_progress']), + ['title' => 'New Task'], + ); + + $task = Task::where('title', 'New Task')->firstOrFail(); + + expect($task->status)->toBe('in_progress'); +}); diff --git a/tests/Fixtures/TestBoardResourcePage.php b/tests/Fixtures/TestBoardResourcePage.php new file mode 100644 index 000000000..e27a672c1 --- /dev/null +++ b/tests/Fixtures/TestBoardResourcePage.php @@ -0,0 +1,48 @@ +query($this->getEloquentQuery()) + ->recordTitleAttribute('title') + ->columnIdentifier('status') + ->positionIdentifier('order_position') + ->columns([ + Column::make('todo')->label('To Do'), + Column::make('in_progress')->label('In Progress'), + Column::make('completed')->label('Completed'), + ]) + ->columnActions([ + CreateAction::make('createTask') + ->model(Task::class) + ->schema([ + TextInput::make('title')->required(), + ]) + ->mutateDataUsing(function (array $data, array $arguments): array { + $data['status'] = $arguments['column'] ?? 'todo'; + + return $data; + }), + ]); + } +} diff --git a/tests/Fixtures/TestPanelProvider.php b/tests/Fixtures/TestPanelProvider.php index b74c3d3d9..0ca4ad8af 100644 --- a/tests/Fixtures/TestPanelProvider.php +++ b/tests/Fixtures/TestPanelProvider.php @@ -29,6 +29,9 @@ public function panel(Panel $panel): Panel ->pages([ TestBoard::class, ]) + ->resources([ + TestResource::class, + ]) ->middleware([ EncryptCookies::class, AddQueuedCookiesToResponse::class, diff --git a/tests/Fixtures/TestResource.php b/tests/Fixtures/TestResource.php new file mode 100644 index 000000000..296cb88f6 --- /dev/null +++ b/tests/Fixtures/TestResource.php @@ -0,0 +1,23 @@ + TestBoardResourcePage::route('/'), + ]; + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index ba4dc40c7..eb6b6e150 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -11,6 +11,7 @@ use Filament\Forms\FormsServiceProvider; use Filament\Infolists\InfolistsServiceProvider; use Filament\Notifications\NotificationsServiceProvider; +use Filament\Schemas\SchemasServiceProvider; use Filament\Support\SupportServiceProvider; use Filament\Tables\TablesServiceProvider; use Filament\Widgets\WidgetsServiceProvider; @@ -48,6 +49,7 @@ protected function getPackageProviders($app): array InfolistsServiceProvider::class, LivewireServiceProvider::class, NotificationsServiceProvider::class, + SchemasServiceProvider::class, SupportServiceProvider::class, TablesServiceProvider::class, WidgetsServiceProvider::class, From c6faa7adb1b12c8c033ffb37ec08a36c29469cdb Mon Sep 17 00:00:00 2001 From: Manuk Date: Tue, 12 May 2026 12:46:43 +0400 Subject: [PATCH 3/4] docs: use mutateDataUsing in column action examples mutateFormDataUsing was deprecated in Filament 5 in favour of mutateDataUsing. Both go through the same code path, so this is a pure naming swap. --- docs/content/2.essentials/2.customization.md | 2 +- docs/content/2.essentials/5.troubleshooting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/2.essentials/2.customization.md b/docs/content/2.essentials/2.customization.md index 3b9d72434..5b31379d8 100644 --- a/docs/content/2.essentials/2.customization.md +++ b/docs/content/2.essentials/2.customization.md @@ -108,7 +108,7 @@ public function board(Board $board): Board ->options(['low' => 'Low', 'medium' => 'Medium', 'high' => 'High']) ->default('medium'), ]) - ->mutateFormDataUsing(function (array $data, array $arguments): array { + ->mutateDataUsing(function (array $data, array $arguments): array { if (isset($arguments['column'])) { $data['status'] = $arguments['column']; $data['position'] = $this->getBoardPositionInColumn($arguments['column']); diff --git a/docs/content/2.essentials/5.troubleshooting.md b/docs/content/2.essentials/5.troubleshooting.md index 9b041d8f0..855a6b012 100644 --- a/docs/content/2.essentials/5.troubleshooting.md +++ b/docs/content/2.essentials/5.troubleshooting.md @@ -85,7 +85,7 @@ class TaskBoard extends BoardPage ```php CreateAction::make() - ->mutateFormDataUsing(function (array $data, array $arguments): array { + ->mutateDataUsing(function (array $data, array $arguments): array { if (isset($arguments['column'])) { $data['status'] = $arguments['column']; $data['position'] = $this->getBoardPositionInColumn($arguments['column']); From 45abcdddba6d76bd2c66ebd924c6e283c4aef191 Mon Sep 17 00:00:00 2001 From: Manuk Date: Tue, 12 May 2026 20:39:36 +0400 Subject: [PATCH 4/4] ci: open changelog PR instead of pushing to protected branch The release-triggered Changelog workflow was pushing the CHANGELOG.md update directly to 4.x via stefanzweifel/git-auto-commit-action. Branch protection on 4.x ("Changes must be made through a pull request") rejects that push, so every release since v4.0.10 has shipped without its CHANGELOG entry. Swap the commit-and-push step for peter-evans/create-pull-request, which opens a PR from chore/changelog- with the skip-changelog label, then enable auto-merge (squash) so the PR lands without human intervention. 4.x has no required status checks and 0 required reviews, so auto-merge clears immediately. Also tag the PR with skip-changelog so it's excluded from the next release's auto-generated notes (per .github/release.yml). --- .github/workflows/changelog.yml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 9fa8b0a1f..86798af0d 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -6,6 +6,7 @@ on: permissions: contents: write + pull-requests: write jobs: update: @@ -34,9 +35,23 @@ jobs: latest-version: ${{ github.event.release.name }} release-notes: ${{ github.event.release.body }} - - name: Commit updated CHANGELOG - uses: stefanzweifel/git-auto-commit-action@v7 + - name: Open changelog PR + id: cpr + uses: peter-evans/create-pull-request@v7 with: - branch: ${{ steps.branch.outputs.name }} - commit_message: Update CHANGELOG - file_pattern: CHANGELOG.md + base: ${{ steps.branch.outputs.name }} + branch: chore/changelog-${{ github.event.release.tag_name }} + delete-branch: true + commit-message: "chore: update CHANGELOG for ${{ github.event.release.tag_name }}" + title: "chore: update CHANGELOG for ${{ github.event.release.tag_name }}" + body: | + Auto-generated CHANGELOG update for release ${{ github.event.release.tag_name }}. + + Release notes: ${{ github.event.release.html_url }} + labels: skip-changelog + + - name: Enable auto-merge + if: steps.cpr.outputs.pull-request-operation == 'created' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh pr merge --auto --squash "${{ steps.cpr.outputs.pull-request-number }}"