Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/scripts/update-contributors.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env groovy
@Grab('org.apache.groovy:groovy-yaml')
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.yaml.YamlBuilder
import groovy.yaml.YamlSlurper

def token = System.getenv('GITHUB_TOKEN')
def repo = System.getenv('GITHUB_REPOSITORY')

if (!token) {
println "GITHUB_TOKEN not set — skipping contributor update"
System.exit(0)
}

def requestProps = [
Authorization : "token ${token}",
'User-Agent' : 'update-contributors-action',
Accept : 'application/vnd.github+json',
]

// 1. Fetch all contributors via REST (sorted by contributions desc, bots excluded)
def contributors = []
def page = 1
while (true) {
def url = "https://api.github.com/repos/${repo}/contributors?per_page=100&page=${page}"
def batch = new JsonSlurper().parseText(url.toURL().getText(requestProperties: requestProps)) as List
if (!batch) break
contributors.addAll(batch)
page++
}

def humans = contributors.findAll { it.type != 'Bot' }
if (!humans) {
println "No human contributors found — skipping update"
System.exit(0)
}

def nodeIds = humans*.node_id
def loginByNode = humans.collectEntries { [it.node_id, it.login] }

// 2. Fetch display names via GraphQL
def gqlQuery = 'query($ids:[ID!]!){nodes(ids:$ids){...on User{id name login}}}'
def gqlBody = JsonOutput.toJson([query: gqlQuery, variables: [ids: nodeIds]])

def conn = 'https://api.github.com/graphql'.toURL().openConnection() as HttpURLConnection
conn.doOutput = true
conn.requestMethod = 'POST'
conn.setRequestProperty('Authorization', "token ${token}")
conn.setRequestProperty('Content-Type', 'application/json')
conn.setRequestProperty('User-Agent', 'update-contributors-action')
conn.outputStream.withWriter { it << gqlBody }

def gqlNodes = new JsonSlurper().parseText(conn.inputStream.text).data.nodes
def nameByNode = gqlNodes.findAll().collectEntries { [(it.id): (it.name ?: it.login)] } as Map<String, String>

// 3. Build ordered map: login → display name (preserving contribution order)
def ordered = humans.collectEntries { c ->
def login = loginByNode[c.node_id]
[login, nameByNode[c.node_id] ?: login]
} as LinkedHashMap<String, String>

// 4. Update the contributors section in project.yml
def projectYmlFile = new File('project.yml')
def projectYml = new YamlSlurper().parse(projectYmlFile) as Map

projectYml.contributors = ordered

def yaml = new YamlBuilder()
yaml(projectYml)
projectYmlFile.text = yaml.toString()

println "Updated ${ordered.size()} contributors in project.yml"
88 changes: 88 additions & 0 deletions .github/scripts/update-versions.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env groovy
@Grab('org.apache.groovy:groovy-yaml')
import groovy.json.JsonSlurper
import groovy.yaml.YamlBuilder
import groovy.yaml.YamlSlurper

def token = System.getenv('GITHUB_TOKEN')
def repo = System.getenv('GITHUB_REPOSITORY')

if (!token) {
println "GITHUB_TOKEN not set — skipping version update"
System.exit(0)
}

def requestProps = [
Authorization: "token ${token}",
'User-Agent' : 'update-versions-action',
Accept : 'application/vnd.github+json',
]

def projectYmlFile = new File('project.yml')
def projectYml = new YamlSlurper().parse(projectYmlFile) as Map
def ignore = (projectYml.versions?.ignore ?: []) as List<String>

def entries = new JsonSlurper().parseText(
"https://api.github.com/repos/${repo}/contents/?ref=gh-pages"
.toURL().getText(requestProperties: requestProps)
) as List

def semver = ~/^\d+\.\d+\.(\d+|x)(-.*)?$/
def parseVer = { String v ->
def m = v =~ /^(\d+)\.(\d+)\.(x|\d+)(?:-(.+))?$/
if (!m) return [0, 0, -2, '']
[m[0][1] as int, m[0][2] as int, m[0][3] == 'x' ? -1 : m[0][3] as int, m[0][4] ?: '']
}

def sorted = entries
.findAll { it.type == 'dir' && (it.name as String) ==~ semver }
.collect { it.name as String }
.findAll { v -> !ignore.contains(v) }
.toSorted { a, b ->
def av = parseVer(a)
def bv = parseVer(b)
bv[0] <=> av[0] ?: bv[1] <=> av[1] ?: bv[2] <=> av[2] ?:
(!av[3] && bv[3] ? -1 : av[3] && !bv[3] ? 1 : bv[3] <=> av[3])
}

if (!sorted) {
println "No versioned directories found on gh-pages — skipping update"
System.exit(0)
}

// ignore is preserved; only current and previous are updated
projectYml.versions.current = sorted.first()
projectYml.versions.previous = sorted

def yaml = new YamlBuilder()
yaml(projectYml)
projectYmlFile.text = yaml.toString()

println "Versions updated: current=${projectYml.versions.current}, total=${sorted.size()}"

// Generate ghpages.html so the workflow can push it directly to gh-pages
def tmplFile = new File('docs/src/docs/index.tmpl')
if (tmplFile.exists()) {
def githubOrg = projectYml.github.org as String
def githubProject = projectYml.github.project as String
def optionsHtml = sorted
.collect { v -> "<option value=\"${v}\">${v}</option>" }
.join('\n ')

def tokens = [
LATEST_VERSION : projectYml.versions.current,
OTHER_VERSIONS_OPTIONS: optionsHtml,
GITHUB_REPO_URL : "https://github.com/${githubOrg}/${githubProject}",
GITHUB_ORG_URL : "https://github.com/${githubOrg}",
PROJECT_TITLE : projectYml.project.title as String,
PROJECT_DESCRIPTION : projectYml.project.description as String,
PROJECT_ORG : projectYml.project.org as String,
REPO_SLUG : githubProject,
]

def html = new groovy.text.SimpleTemplateEngine().createTemplate(tmplFile.text).make(tokens).toString()
def outFile = new File('build/ghpages.html')
outFile.parentFile.mkdirs()
outFile.text = html
println "Generated build/ghpages.html"
}
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,10 @@ jobs:
env:
GRADLE_PUBLISH_RELEASE: 'false'
SOURCE_FOLDER: build/docs
update-index:
if: github.repository_owner == 'gpc' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
needs: publish
uses: ./.github/workflows/update-versions.yml
permissions:
contents: write
secrets: inherit
11 changes: 10 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,19 @@ jobs:
GRADLE_PUBLISH_RELEASE: 'true'
SOURCE_FOLDER: build/docs
VERSION: ${{ env.VERSION }}
update-index:
name: "Update Version Index"
needs: [ docs ]
uses: ./.github/workflows/update-versions.yml
with:
branch: ${{ github.event.release.target_commitish }}
permissions:
contents: write
secrets: inherit
close:
name: "To Next Version"
environment: close # this step will be delayed until approved
needs: [ publish, docs, release ]
needs: [ publish, docs, release, update-index ]
runs-on: ubuntu-24.04
permissions:
contents: write # required for gradle.properties revert
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/update-contributors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Update Contributors

on:
push:
branches:
- '[0-9]+.[0-9]+.x'
- main
workflow_dispatch:

permissions:
contents: write

env:
JAVA_DISTRIBUTION: 'liberica'

jobs:
update-contributors:
runs-on: ubuntu-24.04
steps:
- name: "📥 Checkout repository"
uses: actions/checkout@v6

- name: "Export .sdkmanrc properties"
uses: apache/grails-github-actions/export-gradle-properties@asf
with:
file: ".sdkmanrc"
prefix: "SDKMANRC_"

- name: "Determine Java Version"
run: echo "SDKMANRC_java=${{ env.SDKMANRC_java }}" | sed 's/-.*//' >> $GITHUB_ENV

- name: "☕️ Setup JDK"
uses: actions/setup-java@v5
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.SDKMANRC_java }}

- name: "🦊 Install Groovy ${{ env.SDKMANRC_groovy }}"
run: |
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install groovy ${{ env.SDKMANRC_groovy }} < /dev/null
echo "$HOME/.sdkman/candidates/groovy/current/bin" >> $GITHUB_PATH

- name: "👥 Update contributors in project.yml"
env:
GITHUB_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: groovy .github/scripts/update-contributors.groovy

- name: "📝 Commit if changed"
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if ! git diff --quiet project.yml; then
git add project.yml
git commit -m "chore: update contributors [skip ci]"
git push
else
echo "No contributor changes to commit"
fi
83 changes: 83 additions & 0 deletions .github/workflows/update-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Update GitHub Index Page

on:
workflow_call:
inputs:
branch:
description: 'Branch to checkout and commit project.yml on'
type: string
default: ''
workflow_dispatch:

permissions:
contents: write

env:
JAVA_DISTRIBUTION: 'liberica'

jobs:
update-versions:
runs-on: ubuntu-24.04
steps:
- name: "📥 Checkout repository"
uses: actions/checkout@v6
with:
ref: ${{ inputs.branch || github.ref_name }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- name: "Export .sdkmanrc properties"
uses: apache/grails-github-actions/export-gradle-properties@asf
with:
file: ".sdkmanrc"
prefix: "SDKMANRC_"

- name: "Determine Java Version"
run: echo "SDKMANRC_java=${{ env.SDKMANRC_java }}" | sed 's/-.*//' >> $GITHUB_ENV

- name: "☕️ Setup JDK"
uses: actions/setup-java@v5
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.SDKMANRC_java }}

- name: "🦊 Install Groovy ${{ env.SDKMANRC_groovy }}"
run: |
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install groovy ${{ env.SDKMANRC_groovy }} < /dev/null
echo "$HOME/.sdkman/candidates/groovy/current/bin" >> $GITHUB_PATH

- name: "🔢 Update versions in project.yml and generate ghpages.html"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: groovy .github/scripts/update-versions.groovy

- name: "📝 Commit project.yml if changed"
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if ! git diff --quiet project.yml; then
git add project.yml
git commit -m "chore: update versions [skip ci]"
git push
else
echo "No version changes to commit"
fi

- name: "🚀 Push updated index to gh-pages"
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
cp build/ghpages.html /tmp/ghpages.html
git fetch origin gh-pages
git checkout gh-pages
cp /tmp/ghpages.html ghpages.html
if ! git diff --quiet ghpages.html; then
git add ghpages.html
git commit -m "chore: update version index [skip ci]"
git push origin gh-pages
else
echo "No index changes to push to gh-pages"
fi
19 changes: 3 additions & 16 deletions build-logic/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,15 @@ plugins {
id 'groovy-gradle-plugin'
}

file('../gradle.properties').withInputStream { is ->
extensions.extraProperties.set(
'gradleProperties',
new Properties().tap { load(is) }
)
}

allprojects { project ->
gradleProperties.stringPropertyNames().each { key ->
project.extensions.extraProperties.set(
key,
gradleProperties.getProperty(key)
)
}
}
def gradleProperties = new Properties()
file('../gradle.properties').withInputStream { gradleProperties.load(it) }

dependencies {
implementation platform("org.apache.grails:grails-bom:${gradleProperties.grailsVersion}")
implementation 'org.apache.groovy:groovy-yaml'
implementation 'cloud.wondrify:asset-pipeline-gradle'
implementation "com.adarshr:gradle-test-logger-plugin:${gradleProperties.testLoggerVersion}"
implementation 'org.apache.grails:grails-gradle-plugins'
implementation 'org.apache.grails.gradle:grails-publish'
implementation "org.asciidoctor.jvm.convert:org.asciidoctor.jvm.convert.gradle.plugin:${gradleProperties.asciidoctorVersion}"
}

Loading
Loading