Skip to content

temporary scripts for branch maintenance#15488

Open
borinquenkid wants to merge 11 commits into7.0.xfrom
7.0.x-prune-branches
Open

temporary scripts for branch maintenance#15488
borinquenkid wants to merge 11 commits into7.0.xfrom
7.0.x-prune-branches

Conversation

@borinquenkid
Copy link
Member

Two tasks one to protect the release branches and another to delete stale branches

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Gradle-invokable maintenance automation for GitHub branch hygiene in apache/grails-core (protect release branches, delete stale branches) via two Groovy scripts executed from the root build.gradle.

Changes:

  • Registers two new Gradle maintenance tasks: deleteBranches and protectBranches.
  • Introduces ProtectBranches.groovy to apply GitHub branch protection to a curated list of release branches.
  • Introduces DeleteBranches.groovy to delete a curated list of merged/closed branches via the GitHub API.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 8 comments.

File Description
build.gradle Adds Gradle tasks that execute the maintenance Groovy scripts via GroovyShell.
ProtectBranches.groovy New script that calls GitHub’s branch protection API for listed branches.
DeleteBranches.groovy New script that calls GitHub’s refs API to delete listed branches.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

borinquenkid and others added 7 commits March 8, 2026 20:51
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

borinquenkid and others added 3 commits March 8, 2026 21:03
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

conn.readTimeout = 30_000
conn.requestMethod = method
conn.setRequestProperty("Authorization", "token ${token}")
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub’s REST API requires a valid User-Agent header on requests; HttpURLConnection won’t add one automatically. Add a User-Agent request property to avoid 403/invalid request failures.

Suggested change
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
conn.setRequestProperty("User-Agent", "DeleteBranchesScript/1.0")

Copilot uses AI. Check for mistakes.
Comment on lines +119 to +120
allow_force_pushes : false,
allow_deletions : false
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allow_force_pushes / allow_deletions are sent as booleans, but GitHub’s branch protection API expects these to be objects (e.g., { enabled: false }) or omitted. With the current JSON shape, the PUT is likely to be rejected and protection won’t be applied.

Suggested change
allow_force_pushes : false,
allow_deletions : false
allow_force_pushes : [enabled: false],
allow_deletions : [enabled: false]

Copilot uses AI. Check for mistakes.
Comment on lines +101 to +102
* Sets the branch to 'Read Only' and prevents deletion
* unless the 'enforce_admins' rule is manually toggled.
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment states protection is “Read Only” and that deletion depends on toggling enforce_admins, but enforce_admins only controls whether admins are subject to the protection rules. Please update the comment to accurately describe the protections being applied (e.g., review requirements, status checks, force-push/deletion settings).

Suggested change
* Sets the branch to 'Read Only' and prevents deletion
* unless the 'enforce_admins' rule is manually toggled.
* Applies branch protection that requires status checks and at least one
* approving review, applies to admins, and disallows force pushes and deletions.

Copilot uses AI. Check for mistakes.
conn.readTimeout = 30_000
conn.requestMethod = method
conn.setRequestProperty("Authorization", "token ${token}")
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub’s REST API requires a valid User-Agent header on requests; HttpURLConnection will not add one automatically. Add a User-Agent request property (and keep it consistent with other outbound HTTP usage in the repo) to avoid 403/invalid request failures.

Suggested change
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
conn.setRequestProperty("Accept", "application/vnd.github.v3+json")
conn.setRequestProperty("User-Agent", "apache-grails-core-protect-branches-script")

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +69
| origin/8.0.x | 2026-02-28 | RELEASE |
| origin/8.0.x-hibernate7 | 2026-03-01 | RELEASE |
| origin/7.0.x | 2026-03-04 | RELEASE |
| origin | 2026-03-04 | RELEASE |
| origin/8.0.x-hibernate7-dev | 2026-03-05 | RELEASE |
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The embedded table includes an origin entry. After replace('origin/', ''), that becomes branch name origin, which is unlikely to exist and will make the script fail for that row. Consider filtering out non-branch rows (e.g., origin, origin/HEAD -> ...) before calling the API.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +26
def githubToken = System.getenv('GITHUB_TOKEN') ?: System.getProperty('github.token')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"

if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable or the -Dgithub.token system property."
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The githubToken resolution here allows reading the GitHub PAT from System.getProperty('github.token') and explicitly suggests passing it via -Dgithub.token on the command line. On shared build agents or multi-user systems, command-line JVM system properties may be observable via process listings or logs, which can expose the token and let other users perform unauthorized operations on this repository. To avoid this exposure, rely on environment variables or a dedicated secret mechanism for the token and remove the system property option and its mention in the error message.

Suggested change
def githubToken = System.getenv('GITHUB_TOKEN') ?: System.getProperty('github.token')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"
if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable or the -Dgithub.token system property."
def githubToken = System.getenv('GITHUB_TOKEN')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"
if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable."

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +29
def githubToken = System.getenv('GITHUB_TOKEN') ?: System.getProperty('github.token')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"

if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable or the -Dgithub.token system property."
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The githubToken resolution here allows reading the GitHub PAT from System.getProperty('github.token') and encourages use of -Dgithub.token on the command line. On shared build agents or multi-user systems, JVM system properties set via command-line arguments can be exposed via process listings or logs, leaking the token and allowing other users to gain unauthorized access to this repository. To reduce this risk, load the token only from secure channels such as environment variables or a secret store and remove the system property path and related documentation.

Suggested change
def githubToken = System.getenv('GITHUB_TOKEN') ?: System.getProperty('github.token')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"
if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable or the -Dgithub.token system property."
def githubToken = System.getenv('GITHUB_TOKEN')
def repoOwner = "apache"
def repoName = "grails-core"
def baseApiUrl = "https://api.github.com/repos/${repoOwner}/${repoName}"
if (!githubToken || githubToken == "YOUR_PERSONAL_ACCESS_TOKEN") {
throw new IllegalStateException(
"GitHub token is required. Set the GITHUB_TOKEN environment variable."

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants