Copilot commented on code in PR #16259:
URL: https://github.com/apache/grails-core/pull/16259#discussion_r3883928402


##########
grails-forge/grails-forge-web-netty/build.gradle:
##########
@@ -121,5 +122,23 @@ tasks.named('dockerBuild') {
     images = [findProperty('dockerImageName') ?: 'grailsforge']
 }
 
+tasks.register('awsElasticBeanstalk', Zip) {
+    dependsOn('shadowJar')
+    archiveFileName.set('grails-forge-web-netty-aws.zip')
+    destinationDirectory.set(layout.buildDirectory.dir('distributions'))
+    reproducibleFileOrder = true
+    preserveFileTimestamps = false
+    from({ tasks.named('shadowJar').get().archiveFile.get() }) {
+        rename { 'app.jar' }
+    }
+    from(layout.projectDirectory.dir('aws')) {
+        includeEmptyDirs = false
+    }
+}
+
+tasks.named('assemble') {
+    dependsOn(awsElasticBeanstalk)
+}

Review Comment:
   `assemble` is wired to `dependsOn(awsElasticBeanstalk)` using the task name 
as a script property. In this repo we typically depend on `TaskProvider`s (e.g. 
`tasks.named(...)`) to avoid eager task realization and keep configuration 
avoidance consistent.



##########
grails-forge/infrastructure/README.md:
##########
@@ -0,0 +1,96 @@
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Grails Forge AWS Infrastructure
+
+Deploy `shared.yaml` first and then one `environment.yaml` stack for each 
slot. The shared stack owns the artifact bucket, public ALB, Elastic Beanstalk 
application, IAM roles, and security groups. Each slot stack owns exactly one 
Elastic Beanstalk environment and one unique HTTPS listener-rule priority.
+
+The current target is `us-east-1` in the default VPC. Discover its ID and 
public default subnets before deploying. Supply at least two subnet IDs from 
different Availability Zones to `PublicSubnets` and `InstanceSubnets`.
+
+```bash
+VPC_ID=$(aws ec2 describe-vpcs \
+  --region us-east-1 \
+  --filters Name=is-default,Values=true \
+  --query 'Vpcs[0].VpcId' \
+  --output text)
+
+aws ec2 describe-subnets \
+  --region us-east-1 \
+  --filters Name=vpc-id,Values="$VPC_ID" Name=default-for-az,Values=true \
+  --query 'Subnets[].SubnetId' \
+  --output text
+```
+
+Use a concrete Corretto 25 Elastic Beanstalk platform ARN. Grails 7 and Grails 
8 both run on Java 25, so this avoids older Corretto platform deprecations. Use 
`Architecture=arm64` and `InstanceType=t4g.small` when the selected platform 
advertises arm64. Otherwise, use `Architecture=x86_64` and 
`InstanceType=t3.small` with a matching x86_64 platform ARN.

Review Comment:
   This sentence states that “Grails 7 and Grails 8 both run on Java 25”, but 
the repository baseline is `javaVersion=21` and the Forge build comments refer 
to a Java 21 compile baseline. Please reword this to avoid implying a Java 25 
requirement (while still recommending Corretto 25 if that’s the operational 
choice).



##########
.github/workflows/release.yml:
##########
@@ -24,7 +24,7 @@ env:
   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   GRAILS_PUBLISH_RELEASE: 'true'
   JAVA_DISTRIBUTION: liberica
-  JAVA_VERSION: 21.0.7 # this must be a specific version for reproducible 
builds, keep it synced with .sdkmanrc and verification container
+  JAVA_VERSION: 21.0.12 # this must be a specific version for reproducible 
builds, keep it synced with .sdkmanrc and verification container
   JAVA_VERSION_MICRONAUT: 25.0.3 # the Grails-Micronaut "island" 
(grails-micronaut, grails-micronaut-bom) is built against Micronaut 5 which 
targets JVM 25 bytecode. Keep this synced with the secondary JDK installed in 
etc/bin/Dockerfile and the JDK_25_HOME branch in etc/bin/verify-reproducible.sh.

Review Comment:
   `JAVA_VERSION` was bumped to `21.0.12` here, but other reproducibility pins 
still reference `21.0.7` (e.g. `.sdkmanrc`, `etc/bin/Dockerfile`, and 
`release-publish-docs.yml`). This breaks the “keep it synced” guarantee and can 
cause inconsistent CI vs local verification.



##########
RELEASE.md:
##########
@@ -603,7 +612,7 @@ the following workflows:
 2. `codestyle.yml` - Runs checkstyle on our build to ensure code style 
requirements are met against any submitted code.
 3. `forge-*.yml` - Workflows to build & publish our public App Generation 
website.
 4. `gradle.yml` - Our main CI workflow & snapshot publishing.
-5. `groovy-joint-workflow.yml` - A workflow that runs with the latest snapshot 
of Groovy to ensure we are forward
+5. `groovy-snapshot-canary.yml` - A workflow that runs with the latest 
snapshot of Groovy to ensure we are forward

Review Comment:
   `RELEASE.md` references a workflow file (`groovy-snapshot-canary.yml`) that 
does not exist in this repo (the current Groovy workflow is 
`.github/workflows/groovy-joint-workflow.yml`). This makes the release runbook 
misleading unless the workflow rename/addition is part of the PR.



##########
grails-forge/docs/aws-elastic-beanstalk.md:
##########
@@ -0,0 +1,208 @@
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# AWS Elastic Beanstalk Deployment Runbook
+
+This runbook describes operating the five Forge API slots on AWS Elastic 
Beanstalk. Public DNS for `latest.grails.org`, `snapshot.grails.org`, 
`next.grails.org`, `prev.grails.org`, and `prev-snapshot.grails.org` points at 
the shared ALB. The UI remains at `https://start.grails.org`.
+
+## Architecture
+
+Five Forge API slots run in separate Elastic Beanstalk environments. One 
shared application load balancer (ALB) terminates TLS and routes each stable 
hostname by host header. The Forge UI remains at `https://start.grails.org` and 
is not part of this migration.
+
+The shared CloudFormation stack creates the ALB and listeners, Elastic 
Beanstalk application, artifact bucket, IAM roles, and security groups. Each 
environment stack creates exactly one Elastic Beanstalk environment. Elastic 
Beanstalk owns the environment's target group and shared-listener host rule. 
Neither template creates an `AWS::ElasticBeanstalk::ApplicationVersion` or sets 
an environment `VersionLabel`; the deployment workflow creates application 
versions and updates environments after the stacks exist.
+
+`dns.yaml` is optional and reserved for a future move of authoritative DNS to 
Route 53. Current cutover is manual in Cloudflare.
+
+## Prerequisites and Defaults
+
+Use `us-east-1` for this migration and the default VPC. DNS is currently 
authoritative in Cloudflare. Use an ACM wildcard or SAN certificate that covers 
all five slot hostnames and is issued in `us-east-1`, the ALB region.
+
+The operator creating or updating infrastructure needs administrator-level 
credentials appropriate for CloudFormation, IAM, EC2, ACM, Elastic Beanstalk, 
and S3. This is separate from the restricted GitHub deployment role: routine 
workflow deployments do not create infrastructure stacks.
+
+Discover the default VPC and public default subnets in different Availability 
Zones before creating the stacks:
+
+```bash
+aws ec2 describe-vpcs \
+  --region us-east-1 \
+  --filters Name=is-default,Values=true \
+  --query 'Vpcs[0].VpcId' \
+  --output text
+
+aws ec2 describe-subnets \
+  --region us-east-1 \
+  --filters Name=vpc-id,Values=<DEFAULT_VPC_ID> 
Name=default-for-az,Values=true \
+  --query 'Subnets[?MapPublicIpOnLaunch==`true`].[SubnetId,AvailabilityZone]' \
+  --output table
+```
+
+Create or identify a GitHub Actions OIDC provider and record its ARN. Set the 
repository variable `AWS_FORGE_DEPLOY_ROLE_ARN` to the shared stack's 
`DeployRoleArn`. It is an OIDC role ARN, not an AWS access-key secret.
+
+Do not store a GitHub OAuth app client ID or secret. The start.grails.org UI 
removed Push to GitHub, and the unused server-side create/OAuth integration is 
not part of this deployment. Keep `GITHUB_REDIRECT_URL` as the browser redirect 
to the Forge UI.
+
+Grails 7 and Grails 8 both run on Java 25, so select a concrete Corretto 25 
Elastic Beanstalk `PlatformArn`. Prefer an `arm64` platform with `t4g.small` 
only when that platform supports `arm64`; otherwise select an `x86_64` platform 
with `t3.small`.

Review Comment:
   This runbook claims Grails 7/8 “run on Java 25”, which conflicts with the 
repo’s Java 21 baseline and the Forge build’s own Java 21 compilation comments. 
Please rephrase this as a runtime platform recommendation instead of a 
requirement.



-- 
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]

Reply via email to