Skip to content

Skip porter-state for modifies: false custom actions#3582

Draft
kichristensen wants to merge 4 commits intogetporter:mainfrom
kichristensen:issue3579
Draft

Skip porter-state for modifies: false custom actions#3582
kichristensen wants to merge 4 commits intogetporter:mainfrom
kichristensen:issue3579

Conversation

@kichristensen
Copy link
Copy Markdown
Contributor

What does this change

Custom actions declared with modifies: false (e.g. dry-run) would silently overwrite the installation's porter-state whenever they produced outputs. This happened because Finalize() called packStateBag() unconditionally, regardless of the action's modifies flag.

This change guards packStateBag() in Finalize(): if the action is found in the bundle's custom actions map and has Modifies: false, state packing is skipped. For built-in actions (install, upgrade, uninstall) and modifies: true actions the existing behavior is preserved.

Run records and user-defined outputs for modifies: false actions continue to be persisted — this is correct per the Porter docs, which state that outputs are recorded when they explicitly apply to an action via applyTo.

What issue does it fix

Closes #3579

Notes for the reviewer

  • No changes to ShouldRecord() — its hasOutput OR-term is intentional. The Porter docs confirm that outputs are recorded when they explicitly apply to an action via applyTo. State isolation is a separate concern enforced in Finalize().
  • The guard mirrors the existing pattern in ShouldRecord(): if action, err := bundle.GetAction(action); err == nil — an error means a built-in action, which defaults to the safe path (pack state).

Checklist

  • Did you write tests?
  • Did you write documentation?
  • Did you change porter.yaml or a storage document record? Update the corresponding schema file.
  • If this is your first pull request, please add your name to the bottom of our Contributors list. Thank you for making Porter better! 🙇‍♀️

@kichristensen kichristensen changed the title fix: skip porter-state for modifies:false actions Skip porter-state for modifies: false custom actions Apr 5, 2026
When a custom action has modifies: false, Finalize() now skips
packStateBag(), preventing porter-state from being written back
to the installation. Run records and user-defined outputs are
still persisted as expected.

Fixes getporter#3579

Signed-off-by: Kim Christensen <kimworking@gmail.com>
Add test case for stateful, modifies:false action with an applyTo
output to document that recording runs/outputs is correct behavior
per Porter docs. State isolation is enforced in Finalize(), not
ShouldRecord().

Signed-off-by: Kim Christensen <kimworking@gmail.com>
Add test bundle and TestInvoke_ModifiesFalse_DoesNotPersistState to
assert that invoking a modifies:false action leaves porter-state
unchanged, while still recording the run and saving user outputs.

Signed-off-by: Kim Christensen <kimworking@gmail.com>
The previous fix skipped packStateBag() inside the invocation
image, but the CNAB driver requires all outputs with no default
to be present — so it failed with "required output porter-state
is missing and has no default".

Move the guard to SaveOperationResult on the host side: when the
action has modifies:false, skip persisting internal outputs
(porter-state) to the installation's output record while still
allowing packStateBag() to write the file for the driver.

Signed-off-by: Kim Christensen <kimworking@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom actions with modifies: false persist porter-state back to installation

1 participant