This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 7.0.x-prune-branches in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit b56d014b879d97213ec5c0e692d9d26e079d33d4 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Sun Mar 8 20:41:07 2026 -0500 temporary scripts for branch maintenance --- DeleteBranches.groovy | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ ProtectBranches.groovy | 99 +++++++++++++++++++++++++++ build.gradle | 18 ++++- 3 files changed, 296 insertions(+), 1 deletion(-) diff --git a/DeleteBranches.groovy b/DeleteBranches.groovy new file mode 100644 index 0000000000..c7cdc742ae --- /dev/null +++ b/DeleteBranches.groovy @@ -0,0 +1,180 @@ +import groovy.json.JsonBuilder + +// --- Configuration --- +def githubToken = "YOUR_PERSONAL_ACCESS_TOKEN" +def repoOwner = "apache" +def repoName = "grails-core" +def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}" + +def tableData = """ +| origin/GRAILS-6737-Groovy-1.7.5 | 2010-09-17 | CLOSED | +| origin/GRAILS-6278 | 2010-09-17 | CLOSED | +| origin/GRAILS-5087 | 2012-12-07 | CLOSED | +| origin/GRAILS-9997 | 2013-07-30 | CLOSED | +| origin/GRAILS-10533 | 2013-10-14 | CLOSED | +| origin/GRAILS-10512 | 2013-10-14 | CLOSED | +| origin/GRAILS-10613 | 2013-10-15 | CLOSED | +| origin/GRAILS-10660 | 2013-10-29 | CLOSED | +| origin/GRAILS-10631 | 2013-11-05 | CLOSED | +| origin/GRAILS-10728 | 2013-11-06 | CLOSED | +| origin/GRAILS-10448 | 2013-11-06 | CLOSED | +| origin/GRAILS-10780 | 2013-11-19 | CLOSED | +| origin/GRAILS-10813 | 2013-11-21 | CLOSED | +| origin/GRAILS-10838 | 2013-11-25 | CLOSED | +| origin/GRAILS-10826 | 2013-11-26 | CLOSED | +| origin/GRAILS-10835 | 2013-11-27 | CLOSED | +| origin/GRAILS-10853 | 2013-12-02 | CLOSED | +| origin/GRAILS-10868 | 2013-12-03 | CLOSED | +| origin/GRAILS-10871 | 2013-12-03 | CLOSED | +| origin/GRAILS-9664 | 2013-12-04 | CLOSED | +| origin/GRAILS-10882 | 2013-12-09 | CLOSED | +| origin/GRAILS-10852 | 2013-12-13 | CLOSED | +| origin/GRAILS-10910 | 2013-12-13 | CLOSED | +| origin/GRAILS-10908 | 2013-12-14 | CLOSED | +| origin/GRAILS-10683b | 2013-12-23 | CLOSED | +| origin/GRAILS-10897 | 2014-01-08 | CLOSED | +| origin/GRAILS-8426 | 2014-01-10 | CLOSED | +| origin/GRAILS-10973 | 2014-01-13 | CLOSED | +| origin/GRAILS-11003 | 2014-01-22 | CLOSED | +| origin/GRAILS-11011 | 2014-01-22 | CLOSED | +| origin/GRAILS-11075 | 2014-02-04 | CLOSED | +| origin/GRAILS-11093 | 2014-02-06 | CLOSED | +| origin/GRAILS-11104 | 2014-02-11 | CLOSED | +| origin/GRAILS-10683 | 2014-02-13 | CLOSED | +| origin/GRAILS-11145 | 2014-02-26 | CLOSED | +| origin/GRAILS-11197 | 2014-03-10 | CLOSED | +| origin/GRAILS-9686 | 2014-03-14 | CLOSED | +| origin/GRAILS-10031 | 2014-03-17 | CLOSED | +| origin/GRAILS-11222 | 2014-03-18 | CLOSED | +| origin/GRAILS-11238 | 2014-03-19 | CLOSED | +| origin/GRAILS-11242 | 2014-03-24 | CLOSED | +| origin/GRAILS-11204 | 2014-05-01 | CLOSED | +| origin/GRAILS-6766 | 2014-05-01 | CLOSED | +| origin/GRAILS-9996 | 2014-05-08 | CLOSED | +| origin/GRAILS-10905 | 2014-05-08 | CLOSED | +| origin/GRAILS-11448 | 2014-05-27 | CLOSED | +| origin/GRAILS-11453 | 2014-05-28 | CLOSED | +| origin/GRAILS-11462 | 2014-06-02 | CLOSED | +| origin/GRAILS-11129 | 2014-06-10 | CLOSED | +| origin/GRAILS-11505 | 2014-06-13 | CLOSED | +| origin/GRAILS-11505B | 2014-06-17 | CLOSED | +| origin/GRAILS-11505C | 2014-06-17 | CLOSED | +| origin/GRAILS-11585 | 2014-07-16 | CLOSED | +| origin/GRAILS-11576 | 2014-07-25 | CLOSED | +| origin/GRAILS-11625 | 2014-08-04 | CLOSED | +| origin/GRAILS-11543 | 2014-08-14 | CLOSED | +| origin/GRAILS-11666 | 2014-08-18 | CLOSED | +| origin/GRAILS-11661 | 2014-08-18 | CLOSED | +| origin/GRAILS-11686 | 2014-08-26 | CLOSED | +| origin/GRAILS-11680 | 2014-10-21 | CLOSED | +| origin/GRAILS-11791 | 2014-10-23 | CLOSED | +| origin/GRAILS-11748 | 2014-10-23 | CLOSED | +| origin/GRAILS-11806 | 2014-10-30 | CLOSED | +| origin/GRAILS-11638 | 2014-10-30 | CLOSED | +| origin/GRAILS-11976 | 2015-02-09 | CLOSED | +| origin/GRAILS-11973 | 2015-02-09 | CLOSED | +| origin/GRAILS-11958 | 2015-02-09 | CLOSED | +| origin/GRAILS-12112 | 2015-03-25 | CLOSED | +| origin/issue_9183 | 2015-08-13 | CLOSED | +| origin/issue10188 | 2016-10-27 | CLOSED | +| origin/issue10282 | 2016-11-19 | CLOSED | +| origin/GRAILS-10300-10315 | 2016-12-09 | CLOSED | +| origin/issue10423 | 2017-01-24 | CLOSED | +| origin/GRAILS-10392 | 2017-02-09 | CLOSED | +| origin/issue10502 | 2017-02-27 | CLOSED | +| origin/issue10600 | 2017-04-22 | CLOSED | +| origin/issue-10844 | 2018-02-26 | CLOSED | +| origin/issue-10844_take2 | 2020-11-05 | CLOSED | +| origin/feature/scaffolding-5.1.0 | 2024-09-11 | CLOSED | +| origin/renovate/major-jansi.version | 2024-10-24 | CLOSED | +| origin/renovate/major-javahamcrest-monorepo | 2024-10-24 | CLOSED | +| origin/add-grails-events-transform | 2024-12-23 | CLOSED | +| origin/renovate/alpine-3.x | 2024-12-27 | CLOSED | +| origin/renovate/actions-upload-artifact-4.x | 2025-02-21 | CLOSED | +| origin/renovate/com.gradle.develocity-3.x | 2025-02-25 | CLOSED | +| origin/renovate/io.micronaut.serde-micronaut-serde-jackson-2.x | 2025-03-03 | CLOSED | +| origin/renovate/io.micronaut-micronaut-http-client-4.x | 2025-03-13 | CLOSED | +| origin/issue-14804 | 2025-06-11 | CLOSED | +| origin/retry-build-step | 2025-06-18 | CLOSED | +| origin/renovate/micronautversion | 2025-07-12 | CLOSED | +| origin/addition-micronaut-feature-test | 2025-08-06 | CLOSED | +| origin/update-rest-transform-dependency | 2025-08-07 | CLOSED | +| origin/JavaExec-argsFile | 2025-09-22 | CLOSED | +| origin/java-25-support-test | 2025-09-24 | CLOSED | +| origin/fix-starter-published-dependencies | 2025-10-04 | CLOSED | +| origin/fix/null-constructor-arg-groovy4 | 2026-03-03 | CLOSED | +| origin/issue_8974 | 2015-03-23 | MERGE | +| origin/issue_610 | 2015-04-06 | MERGE | +| origin/issue-11211 | 2019-01-03 | MERGE | +| origin/patch-decouple-gradle | 2024-07-24 | MERGE | +| origin/web-profile-jar-artifact | 2025-10-08 | MERGE | +| origin/jrebelFeatureFix | 2025-10-29 | MERGE | +| origin/chore/gsp_and_gson_dependencies_and_apply | 2025-11-12 | MERGE | +| origin/fix/issue_15228-respond-errors | 2025-11-18 | MERGE | +| origin/banner-versions | 2025-11-19 | MERGE | +| origin/remove-webjars-locator-core-dep | 2025-11-26 | MERGE | +| origin/merge-back-7.0.5 | 2026-01-12 | MERGE | +| origin/invokeDynamicDisable | 2026-01-17 | MERGE | +| origin/deps/update-java-gradle-groovy-versions | 2026-01-27 | MERGE | +| origin/task/add-agents-md-15145 | 2026-01-30 | MERGE | +| origin/matrei-patch-1 | 2026-02-12 | MERGE | +| origin/fix/flaky-geb-tests | 2026-02-19 | MERGE | +| origin/refactor/centralize-groovydoc-plugin | 2026-02-19 | MERGE | +| origin/test/query-connection-routing | 2026-02-21 | MERGE | +| origin/micronaut-fixes-2 | 2026-02-21 | MERGE | +| origin/forgeReloadingChanges | 2026-02-23 | MERGE | +| origin/database-cleanup-feature | 2026-02-25 | MERGE | +| origin/fix-detachedcriteria-join-get-hibernate7 | 2026-02-25 | MERGE | +| origin/fix-detachedcriteria-join-get | 2026-02-25 | MERGE | +| origin/fix/where-query-bugs | 2026-02-26 | MERGE | +| origin/fix/async-promise-spec-read-timeout | 2026-03-03 | MERGE | +| origin/fix/groovy-joint-ci-stability | 2026-03-03 | MERGE | +""" + +tableData.eachLine { line -> + if (!line.contains("|") || line.contains("---") || line.contains("Branch")) return null + + def parts = line.split("\\|").collect { it.trim() } + if (parts.size() < 4) return null + + def branch = parts[1].replace("origin/", "") + def type = parts[3] + + if (type == "MERGE" || type == "CLOSED") { + deleteBranch(baseApiUrl, githubToken, branch) + } else { + println "SKIPPING [${type}]: ${branch}" + } + return null +} + +/** + * Removes the branch from the remote. + */ +def deleteBranch(baseUrl, token, branch) { + println "DELETING: ${branch}" + def url = new URL("${baseUrl}/git/refs/heads/${branch}") + sendRequest(url, token, "DELETE", null) +} + +def sendRequest(url, token, method, body) { + try { + def conn = url.openConnection() as HttpURLConnection + conn.requestMethod = method + conn.setRequestProperty("Authorization", "token ${token}") + conn.setRequestProperty("Accept", "application/vnd.github.v3+json") + if (body) { + conn.doOutput = true + conn.setRequestProperty("Content-Type", "application/json") + conn.outputStream.withWriter { it << body } + } + + if (conn.responseCode in [200, 201, 204]) { + println "SUCCESS: ${conn.responseCode}" + } else { + println "FAILED: ${conn.responseCode} - ${conn.errorStream?.text}" + } + } catch (Exception e) { + println "ERROR: ${e.message}" + } +} diff --git a/ProtectBranches.groovy b/ProtectBranches.groovy new file mode 100644 index 0000000000..97a6707d20 --- /dev/null +++ b/ProtectBranches.groovy @@ -0,0 +1,99 @@ +import groovy.json.JsonBuilder + +// --- Configuration --- +def githubToken = "YOUR_PERSONAL_ACCESS_TOKEN" +def repoOwner = "apache" +def repoName = "grails-core" +def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}" + +def tableData = """ +| origin/1.1.x | 2009-11-26 | RELEASE | +| origin/1.3.0.RC2 | 2010-04-23 | RELEASE | +| origin/1.2.x | 2010-10-11 | RELEASE | +| origin/1.3.x | 2012-06-01 | RELEASE | +| origin/2.0.x | 2013-05-30 | RELEASE | +| origin/2.1.x | 2013-09-21 | RELEASE | +| origin/2.2.x | 2014-07-27 | RELEASE | +| origin/2.3.x | 2015-06-17 | RELEASE | +| origin/2.4.x | 2015-09-08 | RELEASE | +| origin/3.0.x | 2016-07-27 | RELEASE | +| origin/3.1.x | 2017-05-09 | RELEASE | +| origin/3.1.x-issue-9058 | 2017-05-23 | RELEASE | +| origin/3.2.x | 2019-10-10 | RELEASE | +| origin/master | 2021-11-24 | RELEASE | +| origin/4.0.x | 2022-06-03 | RELEASE | +| origin/5.1.x | 2022-10-13 | RELEASE | +| origin/5.0.x | 2022-11-25 | RELEASE | +| origin/5.2.x | 2023-02-13 | RELEASE | +| origin/2.5.x | 2023-12-17 | RELEASE | +| origin/3.3.x | 2024-01-09 | RELEASE | +| origin/4.1.x | 2024-01-26 | RELEASE | +| origin/5.3.x | 2024-01-26 | RELEASE | +| origin/6.1.x | 2024-02-27 | RELEASE | +| origin/6.0.x | 2024-04-09 | RELEASE | +| origin/5.4.x | 2024-09-11 | RELEASE | +| origin/6.2.x | 2025-01-03 | RELEASE | +| origin/gh-pages | 2025-01-07 | RELEASE | +| origin/7.1.x | 2026-02-27 | RELEASE | +| origin/8.0.x | 2026-02-28 | RELEASE | +| origin/7.0.x | 2026-03-04 | RELEASE | +| origin/main | 2026-03-04 | RELEASE | +""" + +tableData.eachLine { line -> + if (!line.contains("|") || line.contains("---") || line.contains("Branch")) return null + + def parts = line.split("\\|").collect { it.trim() } + if (parts.size() < 4) return null + + def branch = parts[1].replace("origin/", "") + def type = parts[3] + + if (type == "RELEASE") { + protectBranch(baseApiUrl, githubToken, branch) + } else { + println "SKIPPING [${type}]: ${branch}" + } + return null +} + +/** + * Sets the branch to 'Read Only' and prevents deletion + * unless the 'enforce_admins' rule is manually toggled. + */ +def protectBranch(baseUrl, token, branch) { + println "PROTECTING: ${branch}" + def url = new URL("${baseUrl}/branches/${branch}/protection") + def body = new JsonBuilder([ + enforce_admins: true, + required_status_checks: null, + required_pull_request_reviews: null, + restrictions: null, + allow_force_pushes: false, + allow_deletions: false + ]).toString() + + sendRequest(url, token, "PUT", body) +} + +def sendRequest(url, token, method, body) { + try { + def conn = url.openConnection() as HttpURLConnection + conn.requestMethod = method + conn.setRequestProperty("Authorization", "token ${token}") + conn.setRequestProperty("Accept", "application/vnd.github.v3+json") + if (body) { + conn.doOutput = true + conn.setRequestProperty("Content-Type", "application/json") + conn.outputStream.withWriter { it << body } + } + + if (conn.responseCode in [200, 201, 204]) { + println "SUCCESS: ${conn.responseCode}" + } else { + println "FAILED: ${conn.responseCode} - ${conn.errorStream?.text}" + } + } catch (Exception e) { + println "ERROR: ${e.message}" + } +} diff --git a/build.gradle b/build.gradle index ae6246d0e9..2e4d4f0b2c 100644 --- a/build.gradle +++ b/build.gradle @@ -88,4 +88,20 @@ apply { // logger.lifecycle("\t- ${dep}") // } // } -//} \ No newline at end of file +//} + +tasks.register('deleteBranches') { + group = 'Maintenance' + description = 'Executes the DeleteBranches.groovy script to clean up remote branches.' + doLast { + new GroovyShell().evaluate(file('DeleteBranches.groovy')) + } +} + +tasks.register('protectBranches') { + group = 'Maintenance' + description = 'Executes the ProtectBranches.groovy script to set protection on release branches.' + doLast { + new GroovyShell().evaluate(file('ProtectBranches.groovy')) + } +} \ No newline at end of file
