{"id":31482305,"url":"https://github.com/snowflake-labs/snowflake-flow-diff","last_synced_at":"2025-10-02T07:47:28.912Z","repository":{"id":277385972,"uuid":"924680756","full_name":"Snowflake-Labs/snowflake-flow-diff","owner":"Snowflake-Labs","description":"GitHub Action for Comparing Differences in Apache NiFi Flow Definitions","archived":false,"fork":false,"pushed_at":"2025-09-22T15:19:43.000Z","size":157,"stargazers_count":10,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-22T17:26:44.001Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Snowflake-Labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-30T13:09:47.000Z","updated_at":"2025-09-22T15:17:22.000Z","dependencies_parsed_at":"2025-02-13T17:43:32.658Z","dependency_job_id":"1644a7cb-5e7a-418e-aba7-874223086e90","html_url":"https://github.com/Snowflake-Labs/snowflake-flow-diff","commit_stats":null,"previous_names":["snowflake-labs/snowflake-flow-diff"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/Snowflake-Labs/snowflake-flow-diff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsnowflake-flow-diff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsnowflake-flow-diff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsnowflake-flow-diff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsnowflake-flow-diff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Snowflake-Labs","download_url":"https://codeload.github.com/Snowflake-Labs/snowflake-flow-diff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsnowflake-flow-diff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277974415,"owners_count":25908396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-02T02:00:08.890Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-02T07:47:27.548Z","updated_at":"2025-10-02T07:47:28.907Z","avatar_url":"https://github.com/Snowflake-Labs.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ![https://www.snowflake.com/](https://www.snowflake.com/wp-content/uploads/2023/02/Snowflake-Logo-e1682724848599.png) Snowflake Flow Diff for Apache NiFi\n\nThis action is brought to you by [Snowflake](https://www.snowflake.com/), don't hesitate to visit our website and reach out to us if you have questions about this action.\n\n## Usage\n\nWhen using the GitHub Flow Registry Client in NiFi to version control your flows, add the below file `.github/workflows/flowdiff.yml` to the repository into which flow definitions are versioned.\n\nWhenever a pull request is opened, reopened or when a new commit is pushed to an existing pull request, this workflow will be triggered and will compare the modified flow(s) in the pull request and will\nautomatically comment the pull request with a human readable description of the changes included in the pull request.\n\n```yaml\nname: Snowflake Flow Diff on Pull Requests\non:\n  pull_request:\n    types: [opened, reopened, synchronize]\n\njobs:\n  execute_flow_diff:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    name: Executing Flow Diff\n    steps:\n      # checking out the code of the pull request (merge commit - if the PR is mergeable)\n      - name: Checkout PR code\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.pull_request.head.ref }}\n          fetch-depth: 0\n          path: submitted-changes\n\n      # getting the path of the flow definition(s) that changed\n      - name: Get changed files\n        id: files\n        run: |\n          cd submitted-changes\n\n          # 1. grab every changed connector JSON\n          files=$(git diff --name-only $(git merge-base HEAD origin/${{ github.event.pull_request.base.ref }}) HEAD | grep '\\.json$')\n\n          # 2. make it a comma-separated list (no trailing comma)\n          bare=$(echo \"$files\" | tr '\\n' ',' | sed 's/,$//')\n\n          # 3. prefix for original-code (flowA)\n          flowA=$(echo \"$bare\" | sed 's|[^,]\\+|original-code/\u0026|g')\n\n          # 4. prefix for submitted-changes (flowB)\n          flowB=$(echo \"$bare\" | sed 's|[^,]\\+|submitted-changes/\u0026|g')\n\n          # 5. export both as outputs\n          echo \"flowA=$flowA\" \u003e\u003e $GITHUB_OUTPUT\n          echo \"flowB=$flowB\" \u003e\u003e $GITHUB_OUTPUT\n\n      # checking out the code without the change of the PR\n      - name: Checkout original code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n          path: original-code\n      - run: cd original-code \u0026\u0026 git checkout HEAD^\n\n      # Running the diff\n      - name: Snowflake Flow Diff\n        uses: snowflake-labs/snowflake-flow-diff@v0\n        id: flowdiff\n        with:\n          flowA: ${{ steps.files.outputs.flowA }}\n          flowB: ${{ steps.files.outputs.flowB }}\n```\n\nNote - you may want to change `grep  '\\.json$'` with a more specific pattern to match your specific requirements.\n\n## Checkstyle\n\nOptionally, it is possible to enable a checkstyle check on the new version of the flow. If some violations against NiFi best practices are found, a message will be added to the comment published on the pull request.\n\nTo enable checkstyle:\n\n```yaml\n      # Running the diff\n      - name: Snowflake Flow Diff\n        uses: snowflake-labs/snowflake-flow-diff@v0\n        id: flowdiff\n        with:\n          flowA: ${{ steps.files.outputs.flowA }}\n          flowB: ${{ steps.files.outputs.flowB }}\n          checkstyle: true\n          # optional: path to YAML configuration of the rules\n          checkstyle-rules: submitted-changes/.github/checkstyle/checkstyle-rules.yaml\n```\n\nThe YAML file can be used to include or exclude specific rules and to configure rule parameters. For example:\n\n```yaml\ninclude:\n  - concurrentTasks\nrules:\n  concurrentTasks:\n    parameters:\n      limit: 2\n    overrides:\n      \".*sql-connector\":\n        limit: 4\n    exclude:\n      - \"Ignore.*\"\n```\n\nAt the root level, if `include` is specified, only those rules will be executed. If `exclude` is specified AND `include` is not specified, all rules except the ones specified will be executed. For each rule, it is possible to specify default values for parameters (when supported by the rule, see below), to override parameters for specific flows using a regular expression against the flow name, and to exclude flows using a regular expression.\n\nAvailable rules:\n- `concurrentTasks` to check the number of concurrent tasks and define an upper limit (parameter: `limit`, default value is 2)\n- `snapshotMetadata` to check that the flow snapshot metadata is present in the file\n- `emptyParameter` to check that no parameter is set to an empty string\n- `defaultParameters` to check parameters with a default value (parameter: `defaultParameters`, comma-separated list of parameter names having an expected default value)\n- `unusedParameter` to check if all specified parameters are used in the flow\n- `noSelfLoop` to check if there are self-loop connections in the flow\n- `enforcePrioritizer` to check if all connections in the flow are set with the configured list of prioritizers (parameter: `prioritizers`, comma-separated list of expected prioritizers, example: `org.apache.nifi.prioritizer.FirstInFirstOutPrioritizer`)\n- `backpressureThreshold` to ensure each connection keeps both data size and object count backpressure thresholds greater than zero\n\n## Example\n\nThe GitHub Action will automatically publish a comment on the pull request with a comprehensive description of the changes between the flows of the two branches.\nHere is an example of what the comment could look like:\n\n```markdown\n### Executing Snowflake Flow Diff for flow: `MyExample`\n\n#### Checkstyle Violations\n\u003e [!CAUTION]\n\u003e - Processor named `UpdateAttribute` is configured with 4 concurrent tasks\n\n#### Flow Changes\n- The destination of a connection has changed from `UpdateAttribute` to `InvokeHTTP`\n- A self-loop connection `[success]` has been added on `UpdateAttribute`\n- A connection `[success]` from `My Generate FlowFile Processor` to `UpdateAttribute` has been added\n- A Processor of type `GenerateFlowFile` named `GenerateFlowFile` has been renamed from `GenerateFlowFile` to `My Generate FlowFile Processor`\n- In Processor of type `GenerateFlowFile` named `GenerateFlowFile`, the Scheduling Strategy changed from `TIMER_DRIVEN` to `CRON_DRIVEN`\n- A Parameter Context named `Test Parameter Context` has been added\n- The Parameter Context `Test Parameter Context` with parameters `{addedParam=newValue}` has been added to the process group `TestingFlowDiff`\n- A Processor of type `UpdateAttribute` named `UpdateAttribute` has been removed\n- In Processor of type `GenerateFlowFile` named `GenerateFlowFile`, the Run Schedule changed from `1 min` to `* * * * * ?`\n- A Parameter Context named `Another one to delete` has been added\n- A Processor of type `UpdateAttribute` named `UpdateAttribute` has been added with the configuration [`ALL` nodes, `4` concurrent tasks, `0ms` run duration, `WARN` bulletin level, `TIMER_DRIVEN` (`0 sec`), `30 sec` penalty duration, `1 sec` yield duration] and the below properties:\n  - `Store State` = `Do not store state`\n  - `canonical-value-lookup-cache-size` = `100`\n\n#### Bundle Changes\n- The bundle `org.apache.nifi:nifi-standard-nar` has been changed from version `2.1.0` to version `2.2.0`\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowflake-labs%2Fsnowflake-flow-diff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowflake-labs%2Fsnowflake-flow-diff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowflake-labs%2Fsnowflake-flow-diff/lists"}