Skip to content

0.11.0

Choose a tag to compare

@github-actions github-actions released this 15 Jul 23:27

Added

  • deploy confirms before a solution's first import to a target: the first time a solution is imported to an environment that doesn't have it yet, deploy asks for confirmation — worded per managed/unmanaged mode, since Flowline can't switch a target's mode back once set. Doesn't fire for dev (already rejected by the DTAP gate) or when the solution already exists in the target (the existing, non-bypassable managed/unmanaged mismatch guard covers that case). Breaking for CI: a pipeline doing a first-time deploy of a solution to a target now exits 17 unless it already passes --force first-import (or --force all) — add it to existing non-interactive first-deploy scripts.
  • deploy publishes the packed solution zip to CI natively: on Azure Pipelines, the zip is attached as a build artifact automatically, named <SolutionName>-<Version> so the version is visible in the Artifacts tab without changing the underlying zip's own filename; on GitHub Actions, its resolved path is written to the step output artifact-path-<SolutionName> for the workflow's own actions/upload-artifact step to reference. No new flag, fires regardless of the subsequent import's outcome, and a failure to emit either signal is a warning, never a deploy-blocking error.
  • [CustomApi(UniqueName = "...")]: override a Custom API's unique name with the complete Dataverse name, publisher prefix included — lets a class migrated from another registration tool (spkl, Daxif) adopt an already-live Custom API in place when Flowline's derived name wouldn't match it. The prefix is validated against the live solution's publisher prefix and push fails with a clear error on mismatch; two Custom APIs resolving to the same final unique name — derived or explicit — now fail the push instead of silently colliding.
  • // flowline:onchange annotation: bind a web resource function to a specific field's OnChange event, the same way // flowline:onload/onsave bind to the form's OnLoad/OnSave. Scoped per attribute — two annotations targeting different fields on the same form register and update independently instead of clobbering each other. push's dry-run/verbose change report and the rename-aware diagnostics introduced for onload/onsave in 0.10.0 both cover onchange as well.
  • Tab and IFRAME form events: form-event annotations now also bind to a Tab's TabStateChange event and an IFRAME's OnReadyStateComplete event, scoped by tab name or control id the same way onchange is scoped by attribute. IFRAME control ids match prefix-insensitively, so an annotation can use either the bare suffix a maker actually types or the Maker Portal's fully-prefixed IFRAME_... control name.
  • [bulkEdit] and [order:N] annotation modifiers: append to any flowline:onload/onsave/onchange annotation. [bulkEdit] (onload only) toggles the form library's "Enable for bulk edit form" setting. [order:N] sets explicit cross-file handler ordering, overriding the default annotation-encounter order — push fails if two annotations for the same event/scope claim the same order value. Dataverse's 50-handler-per-event cap is now enforced before any write.
  • Push plugin assemblies packaged as a NuGet package (PluginPackage): when the Plugins project's build produces a .nupkg (e.g. pac plugin init's default project shape), push auto-detects it and registers a Dataverse PluginPackage instead of a classic assembly — supports multiple plugin-bearing DLLs in one package, each synced independently. Change detection hashes the whole package, so an unchanged package skips the content write and only syncs each assembly's own drifted steps/Custom APIs. Standalone --pluginFile now also accepts a .nupkg path. New .flowline key PluginPackageMode (Auto default / Nupkg / Dll) controls the behavior: Auto uses a package when the build produced one, else falls back to the classic assembly; Nupkg requires a package and fails loudly if the build didn't produce one; Dll forces the classic path even when a package exists — the only option for on-premises environments, since Dependent Assemblies packages are cloud-only. Orphan cleanup redirects a package-owned assembly's deletion to its parent package (Dataverse rejects a direct delete on a package-owned assembly) and deletes any Custom API still bound to it first. push fails clearly if the build output contains more than one .nupkg (a stale package left over from a previous version bump) and self-heals a .nupkg that's older than the assembly it was built from (NuGet's incremental Pack step can skip regenerating it) by forcing one full rebuild.
  • Flowline ships as a Claude Code / Codex agent plugin: adds flowline and flowline-migration skills plus marketplace catalogs for both ecosystems, so an agent knows how to drive Flowline commands and how to migrate an existing spkl/Daxif/PACX/ALM Accelerator project before a Flowline project even exists. See the README for install instructions.

Changed

  • Form event handler merge preserves a foreign handler's position: an out-of-the-box or ISV-authored handler already registered on an event now keeps its original position in the form's handler list instead of always being pushed after Flowline's own handlers — it keeps running exactly where it always ran relative to Flowline-managed handlers.
  • deploy no longer accepts --managed (breaking change, no deprecation window): managed/unmanaged mode was already a single project-wide setting read from .flowline, decided at clone/sync time — deploy --managed only ever mutated .flowline via a confirm prompt, it was never a genuine per-run override. Configure managed/unmanaged exclusively via clone --managed/sync --managed. config is also dropped from deploy's valid --force specifiers, since it has no remaining config-write hazard.
  • deploy's artifact-reuse cache now reports its outcome on every run, not just on a hit: a fresh pack used to print nothing, so a cache miss was indistinguishable from a broken feature. Every non---path deploy now prints the real outcome, naming the reason on a miss (no cached build yet, source changed, unresolvable commit, --no-cache, managed-flag mismatch, or a missing artifact file). Projects with Test and/or UAT configured also get a longer "build once, reused across every stage" explanation; on CI the line still reports the real outcome (a self-hosted or persisted-workspace runner can genuinely hit) with a note appended pointing at --path for reusing one build across ephemeral per-stage jobs. Cache mechanics are unchanged — this is messaging-only.

Fixed

Security