Copilot commented on code in PR #16306:
URL: https://github.com/apache/grails-core/pull/16306#discussion_r3920097483
##########
.github/workflows/gradle.yml:
##########
@@ -1144,12 +1144,6 @@ jobs:
if: github.repository_owner == 'apache' && github.event_name == 'push'
needs: [ publish ]
runs-on: ubuntu-24.04
- # Documentation publishing targets a shared resource (the
apache/grails-website repo).
- # Share the static group used by the release documentation publish
(release.yml) so only
- # one documentation publish can run at a time across every branch; the
rest queue.
- concurrency:
- group: grails-docs-publish
- cancel-in-progress: false
steps:
Review Comment:
The CI docs publishing job no longer serializes publishes across branches.
Since publishing updates a shared external repository/site, simultaneous runs
from different branches can conflict.
##########
.github/workflows/release.yml:
##########
@@ -633,20 +633,14 @@ jobs:
run: |
echo "::group::Manual Grails Forge deployment"
echo "Deploy Forge via
https://github.com/apache/grails-core/actions/workflows/forge-deploy-aws.yml"
- echo "Use workflow from the maintenance branch. Choose slot latest,
snapshot, next, prev, or prev-snapshot."
+ echo "Use workflow from the maintenance branch. Choose slot latest,
snapshot, next, next-snapshot, prev, prev-snapshot, or older."
echo "Do not run this workflow from a historical git tag."
echo "::endgroup::"
docs:
environment: docs
name: "VOTE SUCCEEDED - Publish Documentation"
needs: [ publish, source, upload, release ]
runs-on: ubuntu-24.04
Review Comment:
The docs publishing job no longer has a cross-branch concurrency group, so
multiple releases/branches can publish documentation to the shared
apache/grails-website target at the same time and race/overwrite each other.
##########
grails-doc/build.gradle:
##########
@@ -118,13 +130,32 @@ combinedGroovydoc.configure { Groovydoc gdoc ->
gdoc.source(project.files(allSourceDirs))
gdoc.ext.groovydocSourceDirs = allSourceDirs
- gdoc.classpath = files(sources.collect { SourceSet it ->
it.compileClasspath.filter(File.&isDirectory) }.flatten().unique())
+ // The full compile classpath, not just the sibling projects' class
directories: Groovydoc
+ // needs to load the external types referenced by the sources, otherwise
it links them to
+ // a page it never generated instead of to the external javadocs
configured above.
+ gdoc.classpath = files(sources.collect { SourceSet it ->
it.compileClasspath })
gdoc.destinationDir =
project.layout.buildDirectory.dir('combined-api/api').get().asFile
gdoc.inputs.files(gdoc.source).withPropertyName("groovyDocSrc").withPathSensitivity(PathSensitivity.RELATIVE)
gdoc.outputs.dir(gdoc.destinationDir)
}
+tasks.register('auditGroovydocLinks', AuditGroovydocLinksTask) {
+ apiDocsDir = project.layout.dir(combinedGroovydoc.map { it.destinationDir
})
+ // A 'links' mapping only applies to types Groovydoc managed to resolve,
so a package whose
+ // classes it cannot load has to be listed here. Keeping the list to what
genuinely cannot
+ // be linked leaves every other unresolvable type a build failure.
+ unmappedPackages = [
+ // Gradle's API cannot go on the Groovydoc classpath: it bundles
an older Groovy
+ // and the Ant groovydoc task then fails to initialise.
+ 'org.gradle.',
+ // The publish plugin is maintained in its own repository, with no
javadoc site to
+ // link to. The rest of org.apache.grails.gradle.* lives in the
grails-gradle
+ // included build and is documented in this aggregate, so it stays
audited.
+ 'org.apache.grails.gradle.publish.'
+ ]
+}
Review Comment:
The new auditGroovydocLinks task is registered but not wired into the docs
build, so it won't run during normal documentation generation (and running it
standalone may execute before aggregateGroovydoc has produced the API docs).
##########
grails-doc/src/en/guide/theWebLayer/urlmappings/restfulMappings.adoc:
##########
@@ -82,6 +82,78 @@ delete "/books/$id"(controller:"book", action:"delete")
Notice how the HTTP method name is prefixed prior to each URL mapping
definition.
+==== Mapping every controller as a resource
+
+
+If every controller in an application follows the RESTful resource
conventions, the mappings can be
+applied to all of them at once by capturing the controller in the URL and
passing `*` as the
+`resources` argument:
+
+[source,groovy]
+----
+"/$controller"(resources: '*')
+----
+
+This generates the same mappings as a named `resources` mapping, but resolves
the controller from the
+request instead of from the mapping, so the number of mappings does not grow
with the number of
+controllers:
+
+[format="csv", options="header"]
+|===
+
+HTTP Method,URI,Grails Action
+GET,/${controller},index
+GET,/${controller}/create,create
+POST,/${controller},save
+GET,/${controller}/${id},show
+GET,/${controller}/${id}/edit,edit
+PUT,/${controller}/${id},update
+PATCH,/${controller}/${id},patch
+DELETE,/${controller}/${id},delete
+|===
+
+Because the controller and action are captured from the URL, they are subject
to the same validation
+as any other wildcard mapping, described in
link:theWebLayer.html#embeddedVariables[Embedded Variables]:
+a URI whose captured values do not correspond to a registered controller and
action does not match.
+
+The `includes` and `excludes` parameters apply as they do for a named
resource. An application that
+serves only JSON, for example, has no use for the two actions that render HTML
forms:
+
+[source,groovy]
+----
+"/$controller"(resources: '*', excludes: ['create', 'edit'])
+----
+
+The mapping can also be placed inside a `group`:
+
+[source,groovy]
+----
+group "/api/v1", {
+ "/$controller"(resources: '*')
+}
+----
+
+A namespace can be captured from the URL in the same way, which maps every
namespaced controller
+without naming the namespaces:
+
+[source,groovy]
+----
+"/$namespace/$controller"(resources: '*')
+----
+
+[format="csv", options="header"]
+|===
+
+HTTP Method,URI,Grails Action
+GET,/${namespace}/${controller},index
+GET,/${namespace}/${controller}/${id},show
+|===
+
+NOTE: The URL must capture the controller, and child resources cannot be
nested within a wildcard
+`resources` mapping, because the controller is not known until a request is
matched. Both are
+rejected when the mappings are evaluated.
Review Comment:
This NOTE says only child resources cannot be nested, but the implementation
rejects any nested mappings (the presence of a closure) for wildcard
`resources: '*'`. The doc should match the behavior to avoid misleading users.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]