From 2837a872a0a685e4893a9e99bc1dd4ec1c3eaf31 Mon Sep 17 00:00:00 2001 From: AJ Emerich Date: Mon, 2 Feb 2026 18:07:22 +0100 Subject: [PATCH] docs(git): update descriptions --- .../plugin/git/AbstractCloningTask.java | 5 +- .../io/kestra/plugin/git/AbstractGitTask.java | 52 +++++++++----- .../kestra/plugin/git/AbstractKestraTask.java | 2 +- .../kestra/plugin/git/AbstractPushTask.java | 16 ++--- .../kestra/plugin/git/AbstractSyncTask.java | 8 ++- src/main/java/io/kestra/plugin/git/Clone.java | 25 ++++--- .../io/kestra/plugin/git/NamespaceSync.java | 67 +++++++++++------- src/main/java/io/kestra/plugin/git/Push.java | 32 ++++----- .../io/kestra/plugin/git/PushDashboards.java | 16 +++-- .../kestra/plugin/git/PushExecutionFiles.java | 28 ++++---- .../java/io/kestra/plugin/git/PushFlows.java | 48 ++++--------- .../kestra/plugin/git/PushNamespaceFiles.java | 39 ++++------- src/main/java/io/kestra/plugin/git/Sync.java | 17 +++-- .../io/kestra/plugin/git/SyncDashboards.java | 24 +++---- .../java/io/kestra/plugin/git/SyncFlow.java | 25 +++++-- .../java/io/kestra/plugin/git/SyncFlows.java | 59 +++++----------- .../kestra/plugin/git/SyncNamespaceFiles.java | 32 ++++----- .../java/io/kestra/plugin/git/TenantSync.java | 68 +++++++++++-------- 18 files changed, 281 insertions(+), 282 deletions(-) diff --git a/src/main/java/io/kestra/plugin/git/AbstractCloningTask.java b/src/main/java/io/kestra/plugin/git/AbstractCloningTask.java index 21618ca0..17b5621d 100644 --- a/src/main/java/io/kestra/plugin/git/AbstractCloningTask.java +++ b/src/main/java/io/kestra/plugin/git/AbstractCloningTask.java @@ -19,7 +19,8 @@ @Getter public abstract class AbstractCloningTask extends AbstractGitTask { @Schema( - title = "Whether to clone submodules" + title = "Clone submodules", + description = "Default false; enable to fetch and initialize nested submodules." ) protected Property cloneSubmodules; @@ -85,4 +86,4 @@ protected void checkoutBranch(Git git, String branch, Logger logger) throws Exce logger.info("Checked out branch {}", branch); } } -} \ No newline at end of file +} diff --git a/src/main/java/io/kestra/plugin/git/AbstractGitTask.java b/src/main/java/io/kestra/plugin/git/AbstractGitTask.java index f252204e..6f5cb18f 100644 --- a/src/main/java/io/kestra/plugin/git/AbstractGitTask.java +++ b/src/main/java/io/kestra/plugin/git/AbstractGitTask.java @@ -56,52 +56,68 @@ public abstract class AbstractGitTask extends Task { private static final AtomicReference SSL_CONFIGURED_KEY = new AtomicReference<>(null); private static final Object SSL_CONFIG_LOCK = new Object(); - @Schema(title = "The URI to clone from") + @Schema( + title = "Repository URL", + description = "HTTP(S) or SSH URI used for clone and push operations." + ) protected Property url; - @Schema(title = "The username or organization") + @Schema( + title = "Username or organization", + description = "Used for HTTP basic authentication and as a fallback commit author." + ) protected Property username; - @Schema(title = "The password or Personal Access Token (PAT) – when you authenticate the task with a PAT, any flows or files pushed to Git from Kestra will be pushed from the user associated with that PAT. This way, you don't need to configure the commit author (the `authorName` and `authorEmail` properties).") + @Schema( + title = "Password or personal access token", + description = "Supplies HTTP credentials. When a PAT is used, pushes are recorded under that PAT’s user without needing `authorName` and `authorEmail`." + ) protected Property password; @Schema( - title = "PEM-format private key content that is paired with a public key registered on Git", - description = "To generate an ECDSA PEM format key from OpenSSH, use the following command: `ssh-keygen -t ecdsa -b 256 -m PEM`. " + - "You can then set this property with your private key content and put your public key on Git." + title = "PEM private key", + description = "PEM-formatted private key matching a public key registered on the Git server. Generate with `ssh-keygen -t ecdsa -b 256 -m PEM`." ) protected Property privateKey; - @Schema(title = "The passphrase for the `privateKey`") + @Schema(title = "Passphrase for `privateKey`") protected Property passphrase; @Schema( - title = "Optional path to a PEM-encoded CA certificate to trust (in addition to the JVM default truststore)", - description = "Equivalent to `git config http.sslCAInfo `. Use this for self-signed/internal CAs." + title = "Extra trusted CA PEM path", + description = "Optional PEM-encoded CA bundle added to the JVM truststore; equivalent to `git config http.sslCAInfo ` for self-signed or internal CAs." ) protected Property trustedCaPemPath; - @Schema(title = "Specify whether to disable proxy.") + @Schema( + title = "Disable proxy for HTTP", + description = "When true, forces direct connections instead of using the JVM proxy settings." + ) protected Property noProxy; - @Schema(title = "The initial Git branch") + @Schema(title = "Initial Git branch") public abstract Property getBranch(); - @Schema(title = "Connect timeout in milliseconds for HTTP connections.") + @Schema( + title = "HTTP connect timeout (ms)", + description = "Default 10000 ms." + ) @Builder.Default protected Property connectTimeout = Property.ofValue(10000); - @Schema(title = "Read timeout in milliseconds for HTTP connections.") + @Schema( + title = "HTTP read timeout (ms)", + description = "Default 60000 ms." + ) @Builder.Default protected Property readTimeout = Property.ofValue(60000); @Schema( - title = "Git configuration to apply to the repository", + title = "Git configuration overrides", description = """ - Map of Git config keys and values, applied after clone - few examples: - - 'core.fileMode': false -> ignore file permission changes - - 'core.autocrlf': false -> prevent line ending conversion + Map of git config keys and values applied after clone, e.g.: + - core.fileMode: false (ignore permission flips) + - core.autocrlf: false (preserve line endings) """ ) protected Property> gitConfig; diff --git a/src/main/java/io/kestra/plugin/git/AbstractKestraTask.java b/src/main/java/io/kestra/plugin/git/AbstractKestraTask.java index 406b5e6b..89a0d911 100644 --- a/src/main/java/io/kestra/plugin/git/AbstractKestraTask.java +++ b/src/main/java/io/kestra/plugin/git/AbstractKestraTask.java @@ -23,7 +23,7 @@ public abstract class AbstractKestraTask extends AbstractGitTask { @Schema(title = "Kestra API URL. If null, uses 'kestra.url' from [configuration](https://kestra.io/docs/configuration#kestra-url). If that is also null, defaults to 'http://localhost:8080'.") private Property kestraUrl; - @Schema(title = "Authentication information.") + @Schema(title = "Authentication information") @NotNull private Auth auth; diff --git a/src/main/java/io/kestra/plugin/git/AbstractPushTask.java b/src/main/java/io/kestra/plugin/git/AbstractPushTask.java index e287960b..9d255c44 100644 --- a/src/main/java/io/kestra/plugin/git/AbstractPushTask.java +++ b/src/main/java/io/kestra/plugin/git/AbstractPushTask.java @@ -65,27 +65,27 @@ public abstract class AbstractPushTask extend protected Property commitMessage; @Schema( - title = "If `true`, the task will only output modifications without pushing any file to Git yet. If `false` (default), all listed files will be pushed to Git immediately." + title = "Dry run only", + description = "When true, writes a diff file without pushing. Default false pushes immediately." ) @Builder.Default private Property dryRun = Property.ofValue(false); @Schema( - title = "The commit author email", - description = "If null, no author will be set on this commit." + title = "Commit author email", + description = "If null, no author is set." ) private Property authorEmail; @Schema( - title = "The commit author name", - description = "If null, the username will be used instead.", - defaultValue = "`username`" + title = "Commit author name", + description = "Defaults to `username` when empty." ) private Property authorName; @Schema( - title = "Whether to delete flows/files from Git that are no longer present in Kestra", - description = "If `true` (default), files present in Git but not in Kestra will be deleted from the Git repository." + title = "Delete removed resources", + description = "If true (default), removes Git files that no longer exist in Kestra." ) @Builder.Default private Property delete = Property.ofValue(true); diff --git a/src/main/java/io/kestra/plugin/git/AbstractSyncTask.java b/src/main/java/io/kestra/plugin/git/AbstractSyncTask.java index 6f51241e..d53624e4 100644 --- a/src/main/java/io/kestra/plugin/git/AbstractSyncTask.java +++ b/src/main/java/io/kestra/plugin/git/AbstractSyncTask.java @@ -42,13 +42,15 @@ public abstract class AbstractSyncTask extends AbstractCloningTask implements RunnableTask { @Schema( - title = "If `true`, the task will only output modifications without performing any modification to Kestra. If `false` (default), all listed modifications will be applied." + title = "Dry run only", + description = "When true, writes a diff without applying changes to Kestra." ) @Builder.Default private Property dryRun = Property.ofValue(false); @Schema( - title = "If `true` (default), the task will fail if the specified directory doesn't exist. If `false`, missing directories will be skipped." + title = "Fail if git directory missing", + description = "Default true. If false, skips when the rendered `gitDirectory` path does not exist." ) @Builder.Default private Property failOnMissingDirectory = Property.ofValue(true); @@ -264,4 +266,4 @@ public enum SyncState { UPDATED, UNCHANGED } -} \ No newline at end of file +} diff --git a/src/main/java/io/kestra/plugin/git/Clone.java b/src/main/java/io/kestra/plugin/git/Clone.java index 609941a3..f2ff6c1b 100644 --- a/src/main/java/io/kestra/plugin/git/Clone.java +++ b/src/main/java/io/kestra/plugin/git/Clone.java @@ -21,7 +21,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Clone a Git repository." + title = "Clone a Git repository", + description = "Clones a repository over HTTP(S) or SSH, optionally checking out a branch, tag, or commit. Defaults to a shallow clone (depth 1) unless a tag or commit is requested; set `cloneSubmodules` to fetch submodules." ) @Plugin( examples = { @@ -122,28 +123,34 @@ ) public class Clone extends AbstractCloningTask implements RunnableTask { @Schema( - title = "The optional directory associated with the clone operation", - description = "If the directory isn't set, the current directory will be used." + title = "Target directory", + description = "Subdirectory under the working directory where the repo is cloned; defaults to the working directory root." ) private Property directory; @Schema( - title = "The branch to checkout – ignored if \"commit\" is provided." + title = "Branch to checkout", + description = "Used only when no commit or tag is specified." ) private Property branch; @Schema( - title = "Creates a shallow clone with a history truncated to the specified number of commits.\nIgnored when `commit` is provided to guarantee the commit is available.") + title = "Shallow clone depth", + description = "Defaults to 1. Ignored when `commit` or `tag` is set to ensure history is available." + ) @Builder.Default private Property depth = Property.ofValue(1); @Schema( - title = "Commit SHA1 to checkout (detached HEAD) – works also with a shortened SHA1.", - description = "If set, the repository is cloned and the specified commit is checked out. This takes precedence over `branch` and disables shallow cloning to ensure the commit is present." + title = "Commit SHA to checkout", + description = "Detached HEAD checkout; short SHA allowed. Overrides `branch` and disables shallow clone." ) private Property commit; - @Schema(title = "Tag to checkout – ignored if `commit` is provided.") + @Schema( + title = "Tag to checkout", + description = "Ignored when `commit` is set; performs a full fetch to reach the tag." + ) private Property tag; @Override @@ -220,7 +227,7 @@ public Property getUrl() { @Getter public static class Output implements io.kestra.core.models.tasks.Output { @Schema( - title = "The path where the repository is cloned" + title = "Path where the repository is cloned" ) private final String directory; } diff --git a/src/main/java/io/kestra/plugin/git/NamespaceSync.java b/src/main/java/io/kestra/plugin/git/NamespaceSync.java index 214e63d8..f7ec60cf 100644 --- a/src/main/java/io/kestra/plugin/git/NamespaceSync.java +++ b/src/main/java/io/kestra/plugin/git/NamespaceSync.java @@ -55,8 +55,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Unidirectional namespace sync between Kestra and Git.", - description = "Create/update is driven by 'sourceOfTruth'; delete/keep/fail is driven by 'whenMissingInSource'." + title = "Sync a namespace with Git", + description = "Syncs flows and Namespace Files for a single namespace between Git and Kestra. Direction is controlled by `sourceOfTruth`; deletions follow `whenMissingInSource` and respect `protectedNamespaces`. Supports dry-run diff output and optional subdirectory via `gitDirectory`." ) @Plugin( priority = Plugin.Priority.SECONDARY, @@ -116,58 +116,73 @@ public enum WhenMissingInSource {DELETE, KEEP, FAIL} public enum OnInvalidSyntax {SKIP, WARN, FAIL} @Schema( - title = "The branch to read from / write to (required).", - description = "Branch prefixed with `origin/` or `refs/heads/` are not supported." + title = "Branch to sync", + description = "Required branch name (no `origin/` or `refs/heads/` prefixes); must exist on the remote." ) @NotNull private Property branch; @Schema( - title = "Subdirectory inside the repo used to store Kestra code and files; if empty, repo root is used.", - description = """ - This is the base folder in your Git repository where Kestra will look for code and files. - If you don't set it, the repo root will be used. Inside that folder, Kestra always expects - a structure like /flows, /files, etc. - - | gitDirectory | namespace | Expected Git path | - | ------------ | --------------- | -----------------------------------------| - | (not set) | company | company/flows/my-flow.yaml | - | monorepo | system | monorepo/system/flows/my-flow.yaml | - | projectA | company.team | projectA/company.team/flows/my-flow.yaml |""" + title = "Git base directory", + description = "Optional subfolder in the repo; default is repo root. Within it, files are expected under `/flows` and `/files`." ) private Property gitDirectory; - @Schema(title = "Target namespace to sync (required).") + @Schema( + title = "Namespace to sync", + description = "Required; syncs only this namespace (no child namespaces)." + ) @NotNull private Property namespace; - @Schema(title = "Select the source of truth.") + @Schema( + title = "Source of truth", + description = "KESTRA (default) pushes Kestra state to Git; GIT applies Git state into Kestra." + ) @Builder.Default private Property sourceOfTruth = Property.ofValue(SourceOfTruth.KESTRA); - @Schema(title = "Behavior when an object is missing from the selected source of truth.") + @Schema( + title = "Handling when missing in source", + description = "Default DELETE. Options: DELETE removes from target, KEEP leaves untouched, FAIL stops the run. Protected namespaces override deletions." + ) @Builder.Default private Property whenMissingInSource = Property.ofValue(WhenMissingInSource.DELETE); - @Schema(title = "Namespaces protected from deletion regardless of policies.") + @Schema( + title = "Protected namespaces", + description = "List that cannot be deleted even when policy is DELETE; defaults to `system`." + ) @Builder.Default private Property> protectedNamespaces = Property.ofValue(List.of("system")); - @Schema(title = "If true, only compute the plan and output a diff without applying changes.") + @Schema( + title = "Dry run only", + description = "When true, produces a diff file without applying changes or pushing." + ) @Builder.Default private Property dryRun = Property.ofValue(false); - @Schema(title = "Behavior when encountering invalid syntax while syncing.") + @Schema( + title = "On invalid syntax", + description = "Default FAIL. Options: SKIP, WARN, FAIL." + ) @Builder.Default private Property onInvalidSyntax = Property.ofValue(OnInvalidSyntax.FAIL); - @Schema(title = "Git commit message when pushing back to Git.") + @Schema( + title = "Git commit message", + description = "Used when committing back to Git; defaults to \"Namespace sync from Kestra\"." + ) private Property commitMessage; - @Schema(title = "The commit author email.") + @Schema(title = "Commit author email") private Property authorEmail; - @Schema(title = "The commit author name (defaults to username if null).") + @Schema( + title = "Commit author name", + description = "Defaults to `username` when not set." + ) private Property authorName; // Directory names (namespace-first structure: //.yaml) @@ -720,11 +735,11 @@ public static class Output implements io.kestra.core.models.tasks.Output { @Schema(title = "A file containing all changes applied (or not in case of dry run) to/from Git.") private URI diff; - @Schema(title = "ID of the commit pushed (if any).") + @Schema(title = "ID of the commit pushed (if any)") @Nullable private String commitId; - @Schema(title = "URL to the commit (if any).") + @Schema(title = "URL to the commit (if any)") @Nullable private String commitURL; } diff --git a/src/main/java/io/kestra/plugin/git/Push.java b/src/main/java/io/kestra/plugin/git/Push.java index 333130d1..daec5e99 100644 --- a/src/main/java/io/kestra/plugin/git/Push.java +++ b/src/main/java/io/kestra/plugin/git/Push.java @@ -49,11 +49,8 @@ @Deprecated(since = "1.0.0", forRemoval = true) @Schema( deprecated = true, - title = "Commit and push files to a Git repository.", - description = """ - Replaced by [PushFlows](https://kestra.io/plugins/plugin-git/tasks/io.kestra.plugin.git.pushflows) and [PushNamespaceFiles](https://kestra.io/plugins/plugin-git/tasks/io.kestra.plugin.git.pushnamespacefiles) for flow and namespace files push scenario. You can add `inputFiles` to be committed and pushed. Furthermore, you can use this task in combination with the `Clone` task so that you can first clone the repository, then add or modify files and push to Git afterwards. " + - "Check the examples below as well as the [Version Control with Git](https://kestra.io/docs/developer-guide/git) documentation for more information. Git does not guarantee the order of push operations to a remote repository, which can lead to potential conflicts when multiple users or flows attempt to push changes simultaneously. - To minimize the risk of data loss and merge conflicts, it is strongly recommended to use sequential workflows or push changes to separate branches.""" + title = "Deprecated: push mixed files to Git", + description = "Use PushFlows for flows and PushNamespaceFiles for namespace files. Keeps committing working-directory changes (including `inputFiles`) and pushes to Git; branch is created if missing. Prefer serialized pushes to avoid conflicts." ) @Plugin( examples = { @@ -128,14 +125,14 @@ ) public class Push extends AbstractCloningTask implements RunnableTask, NamespaceFilesInterface, InputFilesInterface { @Schema( - title = "The optional directory associated with the push operation", - description = "If the directory isn't set, the current directory will be used." + title = "Target directory", + description = "Working-directory subfolder containing the Git repo; defaults to the working directory root." ) private Property directory; @Schema( - title = "The branch to which files should be committed and pushed", - description = "If the branch doesn't exist yet, it will be created." + title = "Branch to push", + description = "Created if absent." ) @NotNull private Property branch; @@ -158,8 +155,8 @@ public class Push extends AbstractCloningTask implements RunnableTask> addFilesPattern = Property.ofValue(List.of(".")); @@ -350,7 +347,7 @@ private PersonIdent author(RunContext runContext) throws IllegalVariableEvaluati @Getter public static class Output implements io.kestra.core.models.tasks.Output { @Schema( - title = "ID of the commit pushed." + title = "ID of the commit pushed" ) @Nullable private final String commitId; @@ -363,21 +360,22 @@ public static class Output implements io.kestra.core.models.tasks.Output { @Jacksonized public static class FlowFiles { @Schema( - title = "Whether to push flows as YAML files to Git" + title = "Push flows from the current namespace" ) @Builder.Default @JsonInclude(JsonInclude.Include.NON_NULL) private Property enabled = Property.ofValue(true); @Schema( - title = "Whether flows from child namespaces should be included" + title = "Include child namespaces" ) @Builder.Default @JsonInclude(JsonInclude.Include.NON_NULL) private Property childNamespaces = Property.ofValue(true); @Schema( - title = "To which directory flows should be pushed (relative to `directory`)" + title = "Flow destination directory", + description = "Relative to `directory`; defaults to `_flows`." ) @Builder.Default private Property gitDirectory = Property.ofValue("_flows"); @@ -386,10 +384,10 @@ public static class FlowFiles { @Builder @Getter public static class Author { - @Schema(title = "The commit author name, if null the username will be used instead") + @Schema(title = "Commit author name (defaults to username)") private Property name; - @Schema(title = "The commit author email, if null no author will be set on this commit") + @Schema(title = "Commit author email (optional)") private Property email; } } diff --git a/src/main/java/io/kestra/plugin/git/PushDashboards.java b/src/main/java/io/kestra/plugin/git/PushDashboards.java index 60bf8ed9..37c5d4b9 100644 --- a/src/main/java/io/kestra/plugin/git/PushDashboards.java +++ b/src/main/java/io/kestra/plugin/git/PushDashboards.java @@ -37,7 +37,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Commit and push your saved dashboards to a Git repository." + title = "Push dashboards to Git", + description = "Commits saved dashboards to Git under `gitDirectory` (default `_dashboards`), filtered by glob patterns. Creates the branch if missing; supports dry-run diff generation." ) @Plugin( examples = { @@ -71,16 +72,23 @@ } ) public class PushDashboards extends AbstractPushTask { - @Schema(title = "The branch to which dashboards should be committed and pushed") + @Schema( + title = "Branch to push dashboards", + description = "Defaults to `main`; created if it does not exist." + ) @Builder.Default private Property branch = Property.ofValue("main"); - @Schema(title = "Directory to which dashboards should be pushed") + @Schema( + title = "Dashboard destination directory", + description = "Relative path inside the repository; defaults to `_dashboards`." + ) @Builder.Default private Property gitDirectory = Property.ofValue("_dashboards"); @Schema( - title = "List of glob patterns or a single one that declares which dashboards should be included in the Git commit", + title = "Dashboards to include", + description = "Glob pattern(s) matching dashboard IDs; defaults to all (`**`).", oneOf = {String.class, String[].class}, defaultValue = "**" ) diff --git a/src/main/java/io/kestra/plugin/git/PushExecutionFiles.java b/src/main/java/io/kestra/plugin/git/PushExecutionFiles.java index ede0ce6e..17cf141a 100644 --- a/src/main/java/io/kestra/plugin/git/PushExecutionFiles.java +++ b/src/main/java/io/kestra/plugin/git/PushExecutionFiles.java @@ -30,8 +30,8 @@ @NoArgsConstructor @Getter @Schema( - title = "Commit and push execution output files to a Git repository.", - description = "This task pushes one or more files produced by a task execution directly to Git." + title = "Push execution files to Git", + description = "Stages execution output files from the working directory or storage and pushes them to Git under `gitDirectory` (default `_outputs`). Branch is created if missing; use `dryRun` to only generate the diff." ) @Plugin( examples = { @@ -96,36 +96,36 @@ with open("report.txt", "w") as f: ) public class PushExecutionFiles extends AbstractPushTask { @Schema( - title = "The branch to which files should be committed and pushed", - description = "If the branch doesn’t exist yet, it will be created." + title = "Branch to push files", + description = "Defaults to `main`; created if absent." ) @Builder.Default private Property branch = Property.ofValue("main"); @Schema( - title = "Directory in the Git repository where files should be pushed", - description = "Defaults to `_outputs`." + title = "Destination directory", + description = "Relative path inside the repository; defaults to `_outputs`." ) @Builder.Default private Property gitDirectory = Property.ofValue("_outputs"); @Schema( - title = "Glob pattern(s) to select execution output files from the working directory", - description = "If provided, will match files relative to the execution working directory." + title = "Glob pattern(s) for execution files", + description = "Matches files relative to the execution working directory." ) private Object files; @Schema( - title = "A map of key-value pairs where the key is the filename and the value is the URI of the file to upload.", - description = "This should be a map of URIs, with the key being the filename that will be upload and the value is the URI." + - "This property is intended to be used with the output files of other tasks. Many Kestra tasks, incl. all Downloads tasks, " + - "output a map of files so that you can directly pass the output property to this task e.g., " + - "[outputFiles in the S3 Downloads task](https://kestra.io/plugins/plugin-aws/tasks/s3/io.kestra.plugin.aws.s3.downloads#outputfiles) " + - "or the [files in the Archive Decompress task](https://kestra.io/plugins/plugin-compress/tasks/io.kestra.plugin.compress.archivedecompress#files).", + title = "Explicit file map", + description = "Map of destination filename to source file URI (string or JSON map). Useful for wiring outputFiles from other tasks.", anyOf = {Map.class, String.class} ) private Object filesMap; + @Schema( + title = "Fail when no files are found", + description = "If true, raises an error when nothing matches `files` or `filesMap`; default false logs a warning and skips." + ) @Builder.Default private Property errorOnMissing = Property.ofValue(false); diff --git a/src/main/java/io/kestra/plugin/git/PushFlows.java b/src/main/java/io/kestra/plugin/git/PushFlows.java index 4fde7244..2ea02267 100644 --- a/src/main/java/io/kestra/plugin/git/PushFlows.java +++ b/src/main/java/io/kestra/plugin/git/PushFlows.java @@ -33,11 +33,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Commit and push your saved flows to a Git repository.", - description = """ - Using this task, you can push one or more flows from a given namespace (and optionally also child namespaces) to Git. - Check the examples below to see how you can push all flows or only specific ones. - To learn more, check the [Version Control with Git](https://kestra.io/docs/developer-guide/git) guide.""" + title = "Push flows to Git", + description = "Exports saved flows from `sourceNamespace` (optionally child namespaces) into `gitDirectory` (default `_flows`) and pushes to Git. Can rewrite namespaces to `targetNamespace`; branch is created if missing and dry-run writes only the diff." ) @Plugin( examples = { @@ -111,42 +108,35 @@ Using this task, you can push one or more flows from a given namespace (and opti ) public class PushFlows extends AbstractPushTask { @Schema( - title = "The branch to which files should be committed and pushed", - description = "If the branch doesn't exist yet, it will be created." + title = "Branch to push flows", + description = "Defaults to `main`; created if absent." ) @Builder.Default private Property branch = Property.ofValue("main"); @Schema( - title = "Directory to which flows should be pushed", - description = """ - If not set, flows will be pushed to a Git directory named _flows and will optionally also include subdirectories named after the child namespaces. - If you prefer, you can specify an arbitrary path, e.g., kestra/flows, allowing you to push flows to that specific Git directory. - If the `includeChildNamespaces` property is set to true, this task will also push all flows from child namespaces into their corresponding nested directories, e.g., flows from the child namespace called prod.marketing will be added to the marketing folder within the _flows folder. - Note that the targetNamespace (here prod) is specified in the flow code; therefore, kestra will not create the prod directory within _flows. You can use the PushFlows task to push flows from the sourceNamespace, and use SyncFlows to then sync PR-approved flows to the targetNamespace, including all child namespaces.""" + title = "Flow destination directory", + description = "Relative path inside the repo; defaults to `_flows`. Child namespaces are nested under this path when `includeChildNamespaces` is true." ) @Builder.Default private Property gitDirectory = Property.ofValue("_flows"); @Schema( - title = "The source namespace from which flows should be synced to the `gitDirectory`" + title = "Source namespace", + description = "Namespace to export flows from; defaults to the current flow namespace." ) @Builder.Default private Property sourceNamespace = new Property<>("{{ flow.namespace }}"); @Schema( - title = "The target namespace, intended as the production namespace", - description = "If set, the `sourceNamespace` will be overwritten to the `targetNamespace` in the flow source code to prepare your branch for merging into the production namespace." + title = "Target namespace override", + description = "If set, rewrites the `namespace` field in exported flows to this value." ) private Property targetNamespace; @Schema( - title = "List of glob patterns or a single one that declare which flows should be included in the Git commit", - description = """ - By default, all flows from the specified sourceNamespace will be pushed (and optionally adjusted to match the targetNamespace before pushing to Git). - If you want to push only the current flow, you can use the "{{flow.id}}" expression or specify the flow ID explicitly, e.g. myflow. - Given that this is a list of glob patterns, you can include as many flows as you wish, provided that the user is authorized to access that namespace. - Note that each glob pattern try to match the file name OR the relative path starting from `gitDirectory`""", + title = "Flows to include", + description = "Glob pattern(s) against flow IDs; defaults to all (`**`).", oneOf = {String.class, String[].class}, defaultValue = "**" ) @@ -154,18 +144,8 @@ By default, all flows from the specified sourceNamespace will be pushed (and opt private Object flows; @Schema( - title = "Whether you want to push flows from child namespaces as well", - description = """ - By default, it’s `false`, so the task will push only flows from the explicitly declared namespace without pushing flows from child namespaces. If set to `true`, flows from child namespaces will be pushed to child directories in Git. See the example below for a practical explanation: - - | Source namespace in the flow code | Git directory path | Synced to target namespace | - | --------------------------------- | ------------------------------ | ----------------------------- | - | namespace: dev | _flows/flow1.yml | namespace: prod | - | namespace: dev | _flows/flow2.yml | namespace: prod | - | namespace: dev.marketing | _flows/marketing/flow3.yml | namespace: prod.marketing | - | namespace: dev.marketing | _flows/marketing/flow4.yml | namespace: prod.marketing | - | namespace: dev.marketing.crm | _flows/marketing/crm/flow5.yml | namespace: prod.marketing.crm | - | namespace: dev.marketing.crm | _flows/marketing/crm/flow6.yml | namespace: prod.marketing.crm |""" + title = "Include child namespaces", + description = "When true, exports flows from child namespaces into nested directories under `gitDirectory`." ) @Builder.Default private Property includeChildNamespaces = Property.ofValue(false); diff --git a/src/main/java/io/kestra/plugin/git/PushNamespaceFiles.java b/src/main/java/io/kestra/plugin/git/PushNamespaceFiles.java index 9eb8f749..11cdb777 100644 --- a/src/main/java/io/kestra/plugin/git/PushNamespaceFiles.java +++ b/src/main/java/io/kestra/plugin/git/PushNamespaceFiles.java @@ -31,11 +31,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Commit and push Namespace Files created from Kestra’s UI to Git.", - description = """ - Using this task, you can push one or more Namespace Files from a given kestra namespace to Git. Note that in contrast to `PushFlows`, this task requires pushing code for each namespace separately. You can use the `ForEach` task as shown below to loop over multiple namespaces. Check the [Version Control with Git](https://kestra.io/docs/developer-guide/git) guide for more examples. - Git does not guarantee the order of push operations to a remote repository, which can lead to potential conflicts when multiple users or flows attempt to push changes simultaneously. - To minimize the risk of data loss and merge conflicts, it is strongly recommended to use sequential workflows or push changes to separate branches.""" + title = "Push Namespace Files to Git", + description = "Exports Namespace Files from a single Kestra namespace into `gitDirectory` (default `_files`) and pushes to Git. Branch is created if missing; use `files` globs to narrow the selection and `dryRun` to emit a diff only. Push sequentially to avoid merge conflicts." ) @Plugin( examples = { @@ -106,41 +103,29 @@ ) public class PushNamespaceFiles extends AbstractPushTask { @Schema( - title = "The branch to which Namespace Files should be committed and pushed", - description = "If the branch doesn’t exist yet, it will be created. If not set, the task will push the files to the `kestra` branch." + title = "Branch to push Namespace Files", + description = "Defaults to `main`; created if absent." ) @Builder.Default private Property branch = Property.ofValue("main"); @Schema( - title = "The namespace from which files should be pushed to the `gitDirectory`" + title = "Source namespace", + description = "Namespace whose files are exported; defaults to the current flow namespace." ) @Builder.Default private Property namespace = new Property<>("{{ flow.namespace }}"); @Schema( - title = "Directory to which Namespace Files should be pushed.", - description = """ - If not set, files will be pushed to a Git directory `named _files`. See the table below for an example mapping of Namespace Files to Git paths: - - | Namespace File Path | Git directory path | - | --------------------- | ---------------------------- | - | scripts/app.py | _files/scripts/app.py | - | scripts/etl.py | _files/scripts/etl.py | - | queries/orders.sql | _files/queries/orders.sql | - | queries/customers.sql | _files/queries/customers.sql | - | requirements.txt | _files/requirements.txt |""" + title = "Destination directory", + description = "Relative path inside the repo; defaults to `_files`. Paths under the namespace are preserved beneath this directory." ) @Builder.Default private Property gitDirectory = Property.ofValue("_files"); @Schema( - title = "Which Namespace Files should be included in the commit", - description = """ - By default, Kestra will push all Namespace Files from the specified namespace. - If you want to push only a specific file or directory (e.g., myfile.py), you can set it explicitly using files: myfile.py. - Given that this is a glob pattern string (or a list of glob patterns), you can include as many files as you wish, provided that the user is authorized to access that namespace. - Note that each glob pattern try to match the file name OR the relative path starting from `gitDirectory`""", + title = "Namespace Files to include", + description = "Glob pattern(s); defaults to all (`**`). Matches paths relative to the namespace root.", defaultValue = "**" ) @@ -157,8 +142,8 @@ public Property getCommitMessage() { } @Schema( - title = "Fail the task if no files are matched", - description = "If true, the task will fail explicitly when no files are matched by the provided 'files' property." + title = "Fail when no files are matched", + description = "If true, throws when the glob finds no files; otherwise logs and skips." ) @Builder.Default private Property errorOnMissing = Property.ofValue(false); diff --git a/src/main/java/io/kestra/plugin/git/Sync.java b/src/main/java/io/kestra/plugin/git/Sync.java index 1a3abc80..538504ec 100644 --- a/src/main/java/io/kestra/plugin/git/Sync.java +++ b/src/main/java/io/kestra/plugin/git/Sync.java @@ -46,12 +46,8 @@ @Deprecated(since = "1.0.0", forRemoval = true) @Schema( deprecated = true, - title = "Synchronizes the code for Namespace Files and flows based on the current state in Git.", - description = "Replaced by [SyncFlows](https://kestra.io/plugins/plugin-git/tasks/io.kestra.plugin.git.syncflows) and [SyncNamespaceFiles](https://kestra.io/plugins/plugin-git/tasks/io.kestra.plugin.git.syncnamespacefiles). Files located in `gitDirectory` will be synced with namespace files under `namespaceFilesDirectory` folder. " + - "Any file not present in the `gitDirectory` but present in `namespaceFilesDirectory` will be deleted from namespace files to ensure that Git remains a single source of truth for your workflow and application code. " + - "If you don't want some files from Git to be synced, you can add them to a `.kestraignore` file at the root of your `gitDirectory` folder — that file works the same way as `.gitignore`. \n\n" + - "If there is a `_flows` folder under the `gitDirectory` folder, any file within it will be parsed and imported as a flow under the namespace declared in the task. It's important to keep in mind that all flows **must be located within the same directory without any nested directories**. If you want to deploy all flows to kestra from Git using the Git Sync pattern, you have to place all your flows in the `_flows` directory. Adding namespace folders will result in an error and that's expected. Flows are not equivalent to Namespace Files — while Namespace Files can be stored in arbitrarily nested folders stored in Internal Storage, Flows are just metadata. Flows are sent to Kestra's API and stored in the database backend. This is why they follow a different deployment pattern and cannot be stored in nested folders in Git. \n\n" + - "Another important aspect is that the namespace defined in the flow code **might get overwritten (!)** if the namespace defined within Git doesn't match the namespace or a child namespace defined in the Git Sync task. All Git deployments, both the Git Sync and Kestra's CI/CD integrations, operate on a namespace level to ensure namespace-level governance of permissions, secrets, and to allow separation of resources. If you leverage multiple namespaces in a monorepo, you can create multiple flows, each using the Git Sync task to sync specific Git directories to the desired namespaces." + title = "Deprecated: sync flows and Namespace Files", + description = "Superseded by SyncFlows and SyncNamespaceFiles. Syncs `_flows` (flows) plus other files from `gitDirectory` into a namespace, deleting extras unless excluded via `.kestraignore`. Flow files must live directly under `_flows` (no nesting)." ) @Plugin( examples = { @@ -87,19 +83,22 @@ public class Sync extends AbstractCloningTask implements RunnableTask gitDirectory; @Schema( - title = "Namespace files directory to which files from Git should be synced – it defaults to the root directory of the namespace." + title = "Target namespace files directory", + description = "Optional subpath under the namespace; defaults to namespace root." ) private Property namespaceFilesDirectory; private Property branch; @Schema( - title = "If true, the task will only display modifications without syncing any files yet. If false (default), all namespace files and flows will be overwritten based on the state in Git." + title = "Dry run only", + description = "When true, logs planned additions/updates/deletions without applying." ) private Property dryRun; diff --git a/src/main/java/io/kestra/plugin/git/SyncDashboards.java b/src/main/java/io/kestra/plugin/git/SyncDashboards.java index a10bd112..6ffb4e8a 100644 --- a/src/main/java/io/kestra/plugin/git/SyncDashboards.java +++ b/src/main/java/io/kestra/plugin/git/SyncDashboards.java @@ -30,12 +30,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Sync dashboards from Git to Kestra.", - description = """ - This task syncs dashboards from a given Git branch to Kestra. - If the `delete` property is set to true, any dashboard available in Kestra but not present in the `gitDirectory` will be deleted, maintaining Git as the single source of truth for your dashboards. - Check the [Version Control with Git](https://kestra.io/docs/version-control-cicd/git) documentation for more details. - """ + title = "Sync dashboards from Git", + description = "Imports dashboards from a Git branch. Can delete dashboards missing in Git, respects `.kestraignore`, and supports dry-run diff output." ) @Plugin( examples = { @@ -73,19 +69,22 @@ public class SyncDashboards extends AbstractSyncTask branch = Property.ofValue("main"); @Schema( - title = "Directory from which dashboards should be synced." + title = "Git directory for dashboards", + description = "Relative path containing dashboard YAML; defaults to `_dashboards`." ) @Builder.Default private Property gitDirectory = Property.ofValue("_dashboards"); @Schema( - title = "Whether you want to delete dashboards present in kestra but not present in Git." + title = "Delete dashboards missing in Git", + description = "Default false to avoid destructive syncs." ) @Builder.Default private Property delete = Property.ofValue(false); @@ -193,11 +192,8 @@ protected Output output(URI diffFileStorageUri) { @Getter public static class Output extends AbstractSyncTask.Output { @Schema( - title = "A file containing all changes applied (or not in case of dry run) from Git.", - description = """ - The output format is a ION file with one row per synced flow, each row containing the information whether the flow would be added, deleted, or overwritten in Kestra by the state of what's in Git. - - A row looks as follows: `{gitPath:"flows/flow1.yml",syncState:"ADDED",flowId:"flow1",namespace:"prod",revision:1}`""" + title = "Diff of synced dashboards", + description = "ION file listing per-dashboard sync actions (added, deleted, updated, unchanged)." ) private URI dashboards; diff --git a/src/main/java/io/kestra/plugin/git/SyncFlow.java b/src/main/java/io/kestra/plugin/git/SyncFlow.java index 5ad3d629..6dab4bac 100644 --- a/src/main/java/io/kestra/plugin/git/SyncFlow.java +++ b/src/main/java/io/kestra/plugin/git/SyncFlow.java @@ -28,7 +28,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Sync a single flow from a Git repository to a Kestra namespace." + title = "Sync a single flow from Git", + description = "Imports one flow YAML from a Git branch into a target namespace. Flow namespace is rewritten to `targetNamespace`. Supports dry-run to validate without saving." ) @Plugin( examples = { @@ -56,7 +57,10 @@ public class SyncFlow extends AbstractGitTask implements RunnableTask branch = Property.ofValue("main"); @@ -65,15 +69,24 @@ public Property getBranch() { return this.branch; } - @Schema(title = "The target namespace where the flow will be synced") + @Schema( + title = "Target namespace", + description = "Replaces any namespace declared in the flow file." + ) @NotNull private Property targetNamespace; - @Schema(title = "The full path to the flow YAML file within the Git repository") + @Schema( + title = "Flow file path", + description = "Relative path to the flow YAML inside the repository." + ) @NotNull private Property flowPath; - @Schema(title = "If true, the task will only log the action without actually syncing the flow.") + @Schema( + title = "Dry run only", + description = "When true, validates and logs without importing." + ) @Builder.Default private Property dryRun = Property.ofValue(Boolean.FALSE); @@ -128,4 +141,4 @@ public static class Output implements io.kestra.core.models.tasks.Output { @Schema(title = "The new revision number of the flow") private final Integer revision; } -} \ No newline at end of file +} diff --git a/src/main/java/io/kestra/plugin/git/SyncFlows.java b/src/main/java/io/kestra/plugin/git/SyncFlows.java index f5e21e0f..bfa8fc44 100644 --- a/src/main/java/io/kestra/plugin/git/SyncFlows.java +++ b/src/main/java/io/kestra/plugin/git/SyncFlows.java @@ -33,9 +33,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Sync flows from Git to Kestra.", - description = """ - This task syncs flows from a given Git branch to a Kestra `namespace`. If the `delete` property is set to true, any flow available in Kestra but not present in the `gitDirectory` will be deleted, maintaining Git as the single source of truth for your flows. Check the [Version Control with Git](https://kestra.io/docs/version-control-cicd/git) documentation for more details.""" + title = "Sync flows from Git", + description = "Imports flows from a Git branch into `targetNamespace`, optionally traversing child namespaces. Can rewrite namespaces to `targetNamespace`, delete missing flows when `delete` is true, and emit a diff on dry-run." ) @Plugin( examples = { @@ -109,66 +108,43 @@ public class SyncFlows extends AbstractSyncTask { public static final Pattern NAMESPACE_FINDER_PATTERN = Pattern.compile("(?m)^namespace: (.*)$"); @Schema( - title = "The branch from which flows will be synced to Kestra" + title = "Branch to sync", + description = "Defaults to `main`." ) @Builder.Default private Property branch = Property.ofValue("main"); @Schema( - title = "The target namespace to which flows from the `gitDirectory` should be synced", - description = """ - If the top-level namespace specified in the flow source code is different than the `targetNamespace`, it will be overwritten by this target namespace. This facilitates moving between environments and projects. If `includeChildNamespaces` property is set to true, the top-level namespace in the source code will also be overwritten by the `targetNamespace` in children namespaces. - - For example, if the `targetNamespace` is set to `prod` and `includeChildNamespaces` property is set to `true`, then: - - `namespace: dev` in flow source code will be overwritten by `namespace: prod`, - - `namespace: dev.marketing.crm` will be overwritten by `namespace: prod.marketing.crm`. - - See the table below for a practical explanation: - - | Source namespace in the flow code | Git directory path | Synced to target namespace | - | --------------------------------- | ------------------------------ | ----------------------------- | - | namespace: dev | _flows/flow1.yml | namespace: prod | - | namespace: dev | _flows/flow2.yml | namespace: prod | - | namespace: dev.marketing | _flows/marketing/flow3.yml | namespace: prod.marketing | - | namespace: dev.marketing | _flows/marketing/flow4.yml | namespace: prod.marketing | - | namespace: dev.marketing.crm | _flows/marketing/crm/flow5.yml | namespace: prod.marketing.crm | - | namespace: dev.marketing.crm | _flows/marketing/crm/flow6.yml | namespace: prod.marketing.crm | - """ + title = "Target namespace", + description = "Flows are rewritten to this namespace (and nested namespaces when applicable)." ) @NotNull private Property targetNamespace; @Schema( - title = "Directory from which flows should be synced", - description = """ - If not set, this task assumes your branch has a Git directory named `_flows` (equivalent to the default `gitDirectory` of the [PushFlows](https://kestra.io/docs/how-to-guides/pushflows) task). - - If `includeChildNamespaces` property is set to `true`, this task will push all flows from nested subdirectories into their corresponding child namespaces, e.g. if `targetNamespace` is set to `prod`, then: - - - flows from the `_flows` directory will be synced to the `prod` namespace, - - flows from the `_flows/marketing` subdirectory in Git will be synced to the `prod.marketing` namespace, - - flows from the `_flows/marketing/crm` subdirectory will be synced to the `prod.marketing.crm` namespace.""" + title = "Git directory for flows", + description = "Relative path containing flow YAML; defaults to `_flows`. Subdirectories map to child namespaces when `includeChildNamespaces` is true." ) @Builder.Default private Property gitDirectory = Property.ofValue("_flows"); @Schema( - title = "Whether you want to sync flows from child namespaces as well", - description = "It’s `false` by default so that we sync only flows from the explicitly declared `gitDirectory` without traversing child directories. If set to `true`, flows from subdirectories in Git will be synced to child namespace in Kestra using the dot notation `.` for each subdirectory in the folder structure." + title = "Include child namespaces", + description = "Default false. When true, subdirectories under `gitDirectory` are synced to corresponding child namespaces." ) @Builder.Default private Property includeChildNamespaces = Property.ofValue(false); @Schema( - title = "Whether you want to delete flows present in Kestra but not present in Git", - description = "It’s `false` by default to avoid destructive behavior. Use this property with caution because when set to `true` and `includeChildNamespaces` is also set to `true`, this task will delete all flows from the `targetNamespace` and all its child namespaces that are not present in Git rather than only overwriting the changes." + title = "Delete flows missing in Git", + description = "Default false to avoid destructive syncs. When true (and especially with `includeChildNamespaces`), removes flows not present in Git." ) @Builder.Default private Property delete = Property.ofValue(false); @Schema( - title = "Ignore flows when they have validation failure", - description = "Due to breaking changes, some flows may not be valid anymore by the time of the synchronisation. To avoid synchronizing flows that are no longer valid, set this property to true." + title = "Ignore invalid flows", + description = "If true, skips flows that fail validation instead of failing the task." ) @Builder.Default private Property ignoreInvalidFlows = Property.ofValue(false); @@ -352,11 +328,8 @@ protected Output output(URI diffFileStorageUri) { @Getter public static class Output extends AbstractSyncTask.Output { @Schema( - title = "A file containing all changes applied (or not in case of dry run) from Git", - description = """ - The output format is a ION file with one row per synced flow, each row containing the information whether the flow would be added, deleted, or overwritten in Kestra by the state of what's in Git. - - A row looks as follows: `{gitPath:"flows/flow1.yml",syncState:"ADDED",flowId:"flow1",namespace:"prod",revision:1}`""" + title = "Diff of synced flows", + description = "ION file listing per-flow sync actions (added, deleted, overwritten, updated)." ) private URI flows; diff --git a/src/main/java/io/kestra/plugin/git/SyncNamespaceFiles.java b/src/main/java/io/kestra/plugin/git/SyncNamespaceFiles.java index ab1f6e09..2878d834 100644 --- a/src/main/java/io/kestra/plugin/git/SyncNamespaceFiles.java +++ b/src/main/java/io/kestra/plugin/git/SyncNamespaceFiles.java @@ -26,16 +26,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Sync Namespace Files from Git to Kestra.", - description = """ - This task syncs Namespace Files from a given Git branch to a Kestra namespace. - - If the `delete` property is set to true, any Namespace Files available in Kestra but not present in the `gitDirectory` will be deleted. This allows you to maintain Git as the single source of truth for your Namespace Files. Check the Version Control with Git documentation for more details. - - - Using this task, you can push one or more Namespace Files from a given Kestra namespace to Git. Check the [Version Control with Git](https://kestra.io/docs/version-control-cicd) documentation for more details. - - If you don't want some files from Git to be synced, you can add them to a `.kestraignore` file at the root of your `gitDirectory` folder — that file works the same way as `.gitignore`.""" + title = "Sync Namespace Files from Git", + description = "Imports Namespace Files from a Git branch into a Kestra namespace. Can delete files missing in Git, honors `.kestraignore`, and supports dry-run diff output." ) @Plugin( examples = { @@ -106,27 +98,29 @@ ) public class SyncNamespaceFiles extends AbstractSyncTask { @Schema( - title = "The branch from which Namespace files will be synced to Kestra – defaults to `main`." + title = "Branch to sync", + description = "Defaults to `main`." ) @Builder.Default private Property branch = Property.ofValue("main"); @Schema( - title = "The namespace from which files should be synced from the `gitDirectory` to Kestra" + title = "Target namespace", + description = "Namespace receiving the files; defaults to the current flow namespace." ) @Builder.Default private Property namespace = new Property<>("{{ flow.namespace }}"); @Schema( - title = "Directory from which Namespace files should be synced", - description = "If not set, this task assumes your branch includes a directory named `_files`" + title = "Git directory for Namespace Files", + description = "Relative path containing files; defaults to `_files`." ) @Builder.Default private Property gitDirectory = Property.ofValue("_files"); @Schema( - title = "Whether you want to delete Namespace files present in Kestra but not present in Git", - description = "It’s `false` by default to avoid destructive behavior. Use with caution because when set to `true`, this task will delete all Namespace files which are not present in Git." + title = "Delete files missing in Git", + description = "Default false. When true, removes Namespace Files absent from Git." ) @Builder.Default private Property delete = Property.ofValue(false); @@ -222,10 +216,8 @@ protected Output output(URI diffFileStorageUri) { @Getter public static class Output extends AbstractSyncTask.Output { @Schema( - title = "A file containing all changes applied (or not in case of dry run) from Git", - description = """ - The output format is a ION file with one row per file, each row containing the number of added, deleted, and changed lines. - A row looks as follows: `{changes:"3",file:"path/to/my/script.py",deletions:"-5",additions:"+10"}`""" + title = "Diff of synced Namespace Files", + description = "ION file listing per-file sync actions (added, deleted, overwritten)." ) private URI files; diff --git a/src/main/java/io/kestra/plugin/git/TenantSync.java b/src/main/java/io/kestra/plugin/git/TenantSync.java index e29a9fcd..f67e2dd5 100644 --- a/src/main/java/io/kestra/plugin/git/TenantSync.java +++ b/src/main/java/io/kestra/plugin/git/TenantSync.java @@ -43,8 +43,8 @@ @Getter @NoArgsConstructor @Schema( - title = "Unidirectional tenant sync between Kestra and Git.", - description = "Synchronizes ALL namespaces, flows, files, and dashboards between Kestra and Git." + title = "Sync an entire tenant with Git", + description = "Synchronizes all namespaces, flows, Namespace Files, and dashboards for one tenant. Direction is set by `sourceOfTruth`; deletions follow `whenMissingInSource` with `protectedNamespaces` safeguards. Supports dry-run diff output and optional subdirectory via `gitDirectory`." ) @Plugin( priority = Plugin.Priority.SECONDARY, @@ -105,58 +105,72 @@ public enum WhenMissingInSource {DELETE, KEEP, FAIL} public enum OnInvalidSyntax {SKIP, WARN, FAIL} @Schema( - title = "The branch to read from / write to (required).", - description = "Branch prefixed with `origin/` or `refs/heads/` are not supported." + title = "Branch to sync", + description = "Required branch name (no `origin/` or `refs/heads/` prefixes); must exist on the remote." ) @NotNull private Property branch; @Schema( - title = "Subdirectory inside the repo used to store Kestra code and files; if empty, repo root is used.", - description = """ - This is the base folder in your Git repository where Kestra will look for code and files. - If you don't set it, the repo root will be used. Inside that folder, Kestra always expects - a structure like /flows, /files, etc. - - | gitDirectory | namespace | Expected Git path | - | ------------ | --------------- | -----------------------------------------| - | (not set) | company | company/flows/my-flow.yaml | - | monorepo | system | monorepo/system/flows/my-flow.yaml | - | projectA | company.team | projectA/company.team/flows/my-flow.yaml | - """ + title = "Git base directory", + description = "Optional subfolder in the repo; default is repo root. Within it, namespaces are under `/flows` and `/files`, dashboards under `_global/dashboards`." ) private Property gitDirectory; - @Schema(title = "Select the source of truth.") + @Schema( + title = "Source of truth", + description = "KESTRA (default) pushes Kestra state to Git; GIT applies Git state into Kestra." + ) @Builder.Default private Property sourceOfTruth = Property.ofValue(SourceOfTruth.KESTRA); - @Schema(title = "Behavior when an object is missing from the selected source of truth.") + @Schema( + title = "Handling when missing in source", + description = "Default DELETE. Options: DELETE removes from target, KEEP leaves untouched, FAIL stops the run. Protected namespaces override deletions." + ) @Builder.Default private Property whenMissingInSource = Property.ofValue(WhenMissingInSource.DELETE); - @Schema(title = "Namespaces protected from deletion regardless of policies.") + @Schema( + title = "Protected namespaces", + description = "List that cannot be deleted even when policy is DELETE; defaults to `system`." + ) @Builder.Default private Property> protectedNamespaces = Property.ofValue(List.of("system")); - @Schema(title = "If true, only compute the plan and output a diff without applying changes.") + @Schema( + title = "Dry run only", + description = "When true, produces a diff file without applying changes or pushing." + ) @Builder.Default private Property dryRun = Property.ofValue(false); - @Schema(title = "Behavior when encountering invalid syntax while syncing.") + @Schema( + title = "On invalid syntax", + description = "Default FAIL. Options: SKIP, WARN, FAIL." + ) @Builder.Default private Property onInvalidSyntax = Property.ofValue(OnInvalidSyntax.FAIL); - @Schema(title = "Git commit message when pushing back to Git.") + @Schema( + title = "Git commit message", + description = "Used when committing back to Git; defaults to \"Tenant sync from Kestra\"." + ) private Property commitMessage; - @Schema(title = "The commit author email.") + @Schema(title = "Commit author email") private Property authorEmail; - @Schema(title = "The commit author name (defaults to username if null).") + @Schema( + title = "Commit author name", + description = "Defaults to `username` when not set." + ) private Property authorName; - @Schema(title = "Whether to clone submodules") + @Schema( + title = "Clone submodules", + description = "Default false; enable to fetch nested submodules." + ) protected Property cloneSubmodules; // Directory names @@ -965,11 +979,11 @@ public static class Output implements io.kestra.core.models.tasks.Output { @Schema(title = "A file containing all changes applied (or not in case of dry run) to/from Git.") private URI diff; - @Schema(title = "ID of the commit pushed (if any).") + @Schema(title = "ID of the commit pushed (if any)") @Nullable private String commitId; - @Schema(title = "URL to the commit (if any).") + @Schema(title = "URL to the commit (if any)") @Nullable private String commitURL; }