{"id":25299211,"url":"https://github.com/frankfarrell/blast-radius","last_synced_at":"2026-05-01T13:31:28.802Z","repository":{"id":88518660,"uuid":"152737229","full_name":"frankfarrell/blast-radius","owner":"frankfarrell","description":"Gradle plugin for multi module projects that decides which modules have changed","archived":false,"fork":false,"pushed_at":"2018-12-12T16:58:59.000Z","size":29,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T22:44:51.815Z","etag":null,"topics":["continuous-deployment","gradle","gradle-plugin","java"],"latest_commit_sha":null,"homepage":"","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/frankfarrell.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}},"created_at":"2018-10-12T10:53:25.000Z","updated_at":"2024-03-18T08:17:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"9c1587e5-390c-4fc2-b822-c75cb080ae3b","html_url":"https://github.com/frankfarrell/blast-radius","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/frankfarrell/blast-radius","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankfarrell%2Fblast-radius","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankfarrell%2Fblast-radius/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankfarrell%2Fblast-radius/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankfarrell%2Fblast-radius/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frankfarrell","download_url":"https://codeload.github.com/frankfarrell/blast-radius/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankfarrell%2Fblast-radius/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32499681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"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":["continuous-deployment","gradle","gradle-plugin","java"],"created_at":"2025-02-13T04:54:00.909Z","updated_at":"2026-05-01T13:31:28.792Z","avatar_url":"https://github.com/frankfarrell.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![Gradle Badge](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/com/github/frankfarrell/blastradius/com.github.frankfarrell.blastradius.gradle.plugin/maven-metadata.xml.svg)](https://plugins.gradle.org/plugin/com.github.frankfarrell.blastradius)\n\n# Blast Radius\n\nBlast radius is a gradle plugin that detects which, if any, modules of a gradle project have \nchanged in a deploy-worthy way since the last commit, build or tag. \n\nSo, for example, if you have the following project structure, \n```\nroot\n    - moduleA\n    - moduleB\n    - moduleC : depends on moduleB\n```\nA change to the src directory of moduleB will return true for moduleB and moduleC, and false for moduleA and root (`:` by convention). \nIf we change a README in moduleA, since that is not deploy-worthy, it returns false for all modules, including root. \n\n## Why? \n\nIf you are doing continuous deployment, but you do not have all your deployable modules in different repos\nwith different deployment pipelines, you can use this plugin to limit the blast radius of your deployment. Deploying often is good, but not if there is no change. \n\nBut, even in a single module project you can use this plugin to limit deployments on changes such as to unit tests, documentation etc. \n\nNote that the plugin isn't too clever, so it will interpret new whitespace in application code as deploy-worthy. \n\n## How does it work? \n\nIt builds a set of regular expressions from patterns you provided in the configuration and thne does a git diff, matching against files that have changed. \n\n## Using it\n\nConfiguring it: \n```groovy\n\nimport com.github.frankfarrell.blastradius.BlastRadiusPlugin\n\nbuildscript {   \n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath(\"com.github.frankfarrell:blast-radius:+\")\n    }\n}\n\napply plugin: BlastRadiusPlugin\n```\n\nYou have two options. Standalone or multi module\n\n### Standalone\n\n```groovy\ntask checkIfAnythingHasChangedTask(type: com.github.frankfarrell.blastradius.ModuleChangedTask){\n    filePatterns = [\"/[^.]*.gradle\", \"/src/main/.*\"]\n}\n\ntask migrateLambda(type: AWSLambdaMigrateFunctionTask, dependsOn: [build, checkIfAnythingHasChangedTask]) {\n    functionName = \"my-first-lambda\"\n    functionDescription = \"Too agile for servers\"\n    role = \"arn:aws:iam::${awsAccountId}:role/some-role\"\n    zipFile = jar.archivePath\n    handler = \"com.github.frankfarrell.test.MainHandler\"\n    memorySize = 512\n    runtime = com.amazonaws.services.lambda.model.Runtime.Java8\n\n    doFirst{\n        if(!checkIfAnythingHasChangedTask.toDeploy){\n            println(\"Won't deploy\")\n            throw new StopExecutionException(\"Won't deploy, no changes\")\n        }\n        else {\n            println(\"Will deploy\")\n        }\n    }\n\n\n}\n```\n\nAs you can see ModuleChangedTask has an output variable `toDeploy` which can be used as a boolean in other modules. \n\n### Multi-module\n\n```groovy\ntask changedModulesTask(type: com.github.frankfarrell.blastradius.ProjectModulesChangedTask){\n    filePatterns = [\"/[^.]*.gradle\", \"/src/main/.*\", \"/deploy/.*\"]\n    fileLocation = \"${changeFile}\"\n    moduleFilePatterns = [\n            \":\": defaultFilePatterns + [\"/pipeline/.*\", \"/buildSrc/[^.]*.gradle\", \"/buildSrc/src/main/.*\"],\n            \":terraform\" : [\"/[^.]*.gradle\", \"/[^.]*.sh\", \"/[^.]*.tf\", \"/[^.]*.tfvars\"],\n            \":kubernetes-module\" : defaultFilePatterns + [\"/helm/.*\"],\n            \":docker-type-module\" : [\"/[^.]*[.]gradle\", \"/.*Dockerfile\", \"/deploy/.*\" ],\n         ]\n}\n```\n1. filePatterns =\u003e Default set of file patterms. Note that these are regular expressions, not unix glob patterns\n2. fileLocation =\u003e the module will write the results to a file in this location, the file has this format\n    ```csv\n    :,false\n    :terraform,true\n    :kubernetes-module,false\n    :docker-type-module,true\n    ``` \n3. moduleFilePatterns =\u003e You can overide the defaults for specific patterns. Examples above are for terraform, kubernetes helm and dockerfiles. \n\n### DiffStrategy\nEither version of the task takes a parameter `diffStrategy` that determines how the diff is done. \nIf it fails to find the value, the task returns true for everything (better to dpeloy to much than not to have deployed at all)\n1. JENKINS_LAST_COMMIT =\u003e Uses the previous git commit from the jenkins build. Watch out for running the same build with different parameters! \n2. PREVIOUS_TAG =\u003e If you build with tag 0.1.2, this will do a diff with tag 0.1.1. If you build with HEAD it will compare HEAD with the top commit. Tags must use semantic versioning\n3. PREVIOUS_COMMIT =\u003e Just compares with the previous commit.\n4. SPECIFIC_COMMIT =\u003e Compare to an explicit commit hash passed in the `previousCommit` attribute. `previousCommit` is mandatory\n\n### Using it from a pipeline\n\nAssuming you have the task configured as above\n\n```groovy\n\npipeline {\n   \n    environment {\n        CHANGE_FILE = \"changeFile\"\n    }\n\n    stage(\"Changed Modules\"){\n        steps{\n            sh \"./gradlew changedModuleTask -PchangeFile=${env.CHANGE_FILE}\"\n    \n            script {\n                changedFiles = readFile(\"${env.CHANGE_FILE}\")\n                        .split(\"\\n\")\n                        .collectEntries{\n                            [(it.split(\",\")[0]): new Boolean(it.split(\",\")[1])]\n                        }\n            }\n        }\n    }\n    \n    //changedFiles is now a map from module name(always with leading :, where a solo : is the root module) that can be used in following steps\n    \n    stage(\"Some other stage\"){\n         \n        when {\n            expression {\n                return changedFiles[\":some-module\"] //You may want an elvis operator if there is a chance the module won't be present in the map\n            }\n        }\n        steps{\n            //Do stuff\n        }\n    }\n    \n}\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrankfarrell%2Fblast-radius","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrankfarrell%2Fblast-radius","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrankfarrell%2Fblast-radius/lists"}