jamesfredley commented on code in PR #16229:
URL: https://github.com/apache/grails-core/pull/16229#discussion_r4408368561


##########
.github/workflows/release-promote-jars.yml:
##########
@@ -0,0 +1,83 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Apache Polaris, a TLP, promotes a closed staging repository after its vote:
+# 
https://github.com/apache/polaris/blob/7866ce5c009d64e4c1454b47bca3df9873c6c0b2/.github/workflows/release-4-publish-release.yml
+# Grails already uses the same NEXUS_STAGE_DEPLOYER_* secrets in
+# release-drop-staging.yml. This workflow never writes dist.apache.org/release:
+# https://infra.apache.org/github-actions-policy.html
+name: "Release - Promote Nexus Staging"
+on:
+  workflow_dispatch:
+    inputs:
+      version:
+        description: 'Release version without the v prefix (e.g. 8.0.0-M1)'
+        required: true
+        type: string
+      staging_description:
+        description: 'Nexus staging repository description (defaults to 
<repository>:<version>)'
+        required: false
+        type: string
+        default: ''
+      repository:
+        description: 'Repository name used only for the default staging 
description'
+        required: false
+        type: string
+        default: grails-core
+permissions:
+  contents: read
+jobs:
+  promote:
+    name: "Promote Nexus staging repository"
+    environment: release
+    # Keep the release environment restricted to trusted refs.
+    runs-on: ubuntu-24.04
+    steps:
+      - name: "📥 Checkout the workflow ref"
+        uses: actions/[email protected]
+        with:
+          persist-credentials: false
+      - name: "📝 Establish staging description"
+        env:
+          VERSION: ${{ inputs.version }}
+          STAGING_DESCRIPTION_INPUT: ${{ inputs.staging_description }}
+          REPOSITORY: ${{ inputs.repository }}
+        run: |
+          set -euo pipefail
+          if [ -z "${VERSION}" ]; then
+            echo "::error::Version must not be empty."
+            exit 1
+          fi
+          if [ -n "${STAGING_DESCRIPTION_INPUT}" ]; then
+            echo "STAGING_DESCRIPTION=${STAGING_DESCRIPTION_INPUT}" >> 
"$GITHUB_ENV"
+          else
+            echo "STAGING_DESCRIPTION=${REPOSITORY}:${VERSION}" >> 
"$GITHUB_ENV"
+          fi
+      - name: "🚀 Promote Nexus staging repository"
+        env:
+          NEXUS_USER: ${{ secrets.NEXUS_STAGE_DEPLOYER_USER }}

Review Comment:
   @C:\Users\james\AppData\Local\Temp\reply-atr-promote.txt



##########
.github/workflows/release-promote-jars.yml:
##########
@@ -0,0 +1,83 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Apache Polaris, a TLP, promotes a closed staging repository after its vote:
+# 
https://github.com/apache/polaris/blob/7866ce5c009d64e4c1454b47bca3df9873c6c0b2/.github/workflows/release-4-publish-release.yml
+# Grails already uses the same NEXUS_STAGE_DEPLOYER_* secrets in
+# release-drop-staging.yml. This workflow never writes dist.apache.org/release:
+# https://infra.apache.org/github-actions-policy.html
+name: "Release - Promote Nexus Staging"
+on:
+  workflow_dispatch:
+    inputs:
+      version:
+        description: 'Release version without the v prefix (e.g. 8.0.0-M1)'
+        required: true
+        type: string
+      staging_description:
+        description: 'Nexus staging repository description (defaults to 
<repository>:<version>)'
+        required: false
+        type: string
+        default: ''
+      repository:
+        description: 'Repository name used only for the default staging 
description'
+        required: false
+        type: string
+        default: grails-core
+permissions:
+  contents: read
+jobs:
+  promote:
+    name: "Promote Nexus staging repository"
+    environment: release
+    # Keep the release environment restricted to trusted refs.
+    runs-on: ubuntu-24.04
+    steps:
+      - name: "📥 Checkout the workflow ref"
+        uses: actions/[email protected]
+        with:
+          persist-credentials: false
+      - name: "📝 Establish staging description"
+        env:
+          VERSION: ${{ inputs.version }}
+          STAGING_DESCRIPTION_INPUT: ${{ inputs.staging_description }}
+          REPOSITORY: ${{ inputs.repository }}
+        run: |
+          set -euo pipefail
+          if [ -z "${VERSION}" ]; then
+            echo "::error::Version must not be empty."
+            exit 1
+          fi
+          if [ -n "${STAGING_DESCRIPTION_INPUT}" ]; then
+            echo "STAGING_DESCRIPTION=${STAGING_DESCRIPTION_INPUT}" >> 
"$GITHUB_ENV"
+          else
+            echo "STAGING_DESCRIPTION=${REPOSITORY}:${VERSION}" >> 
"$GITHUB_ENV"
+          fi
+      - name: "🚀 Promote Nexus staging repository"
+        env:
+          NEXUS_USER: ${{ secrets.NEXUS_STAGE_DEPLOYER_USER }}

Review Comment:
   @C:\Users\james\AppData\Local\Temp\reply-atr-promote.txt



##########
RELEASE.md:
##########
@@ -433,6 +439,83 @@ Announcements should come from your apache email address 
(see https://infra.apac
 expected format. The announcement should be sent to `[email protected]`, 
`[email protected]`, `[email protected]`, &
 `[email protected]`. See the `close` job for a generated email.
 
+### What GitHub Actions may automate
+
+The following boundaries preserve PMC authority and use only opt-in, protected 
workflows. Apache's release policy permits
+automated release infrastructure to sign artifacts, while the vote remains a 
community email process.
+
+| Activity | GitHub Actions boundary and evidence |
+| --- | --- |
+| ATR compose, resolve, one announce, and distribution record | Opt-in 
workflows call [ASF Tooling actions](https://github.com/apache/tooling-actions) 
against [ATR Beta](https://releases.apache.org/docs/). Official examples: 
[compose](https://github.com/apache/tooling-asf-example/blob/main/.github/workflows/build-and-rsync-to-atr.yaml),
 
[resolve](https://github.com/apache/tooling-asf-example/blob/main/.github/workflows/resolve-vote-on-atr.yaml),
 
[announce](https://github.com/apache/tooling-asf-example/blob/main/.github/workflows/announce-release-on-atr.yaml),
 and 
[record](https://github.com/apache/tooling-asf-example/blob/main/.github/workflows/record-distribution-on-atr.yaml).
 |
+| Signing in GitHub Actions | [Apache release 
policy](https://www.apache.org/legal/release-policy.html) requires release 
artifacts to be signed by the Release Manager or automated release 
infrastructure. ATR [Trusted 
Publishing](https://releases.apache.org/docs/trusted-publishing) accepts those 
signatures when the committee is eligible for CI builds. |
+| Publish the voted distributions to `dist/release` | Beta ATR commits the 
approved artifacts to `svn:dist:release` itself. The workflow calls ATR. It 
does not write SVN. See [Promoting to 
release](https://releases.apache.org/docs/promoting-to-release). |
+| Documentation and website content | [GitHub Actions 
policy](https://infra.apache.org/github-actions-policy.html) permits work on 
website content and other non-released data. Grails already deploys 
documentation from GitHub Actions. |
+| Promote closed Nexus staging after a passed vote | `Release - Promote Nexus 
Staging` is `workflow_dispatch` plus the protected `release` environment. It 
follows the [Apache Polaris TLP promotion 
workflow](https://github.com/apache/polaris/blob/7866ce5c009d64e4c1454b47bca3df9873c6c0b2/.github/workflows/release-4-publish-release.yml)
 and uses the existing `NEXUS_STAGE_DEPLOYER_USER` / `NEXUS_STAGE_DEPLOYER_PW` 
secrets used to drop staging. |
+| Skip `dist/dev` only when using ATR | ATR candidates may skip the 
traditional staging location as described in [Staging and 
voting](https://releases.apache.org/docs/staging-and-voting). The `dist/dev` 
plus Nexus path remains Grails' official default until the PMC opts in to ATR. |
+
+The following must remain manual:
+
+| Activity | Why it remains manual |
+| --- | --- |
+| Start the binding PMC vote and hold it for at least 72 hours | [Apache 
release policy](https://www.apache.org/legal/release-policy.html) says release 
votes SHOULD remain open for at least 72 hours. ATR can send and tally the vote 
email, but `apache/tooling-actions` has no action that starts a vote. |
+| Move `dist/dev` distributions when ATR is not used | [GitHub Actions 
policy](https://infra.apache.org/github-actions-policy.html) prohibits 
automated services from pushing official release data without prior 
Infrastructure authorization. The default Grails path still uses 
`releaseDistributions.sh` as the release manager. |
+| Rebuild and compare artifacts on trusted hardware | Trusted Publishing 
requires an independent rebuild outside GitHub Actions before publication. 
Grails already documents that comparison in this file. |
+| Report the release to ASF Reporter | [ASF Reporter 
addrelease](https://reporter.apache.org/addrelease.html) has no documented 
public API. |
+| Send lists beyond the one ATR announcement | ATR rejects a second 
announcement for the same release. Send `[email protected]`, 
`[email protected]`, and `[email protected]` manually after the 
single ATR announce. |
+| Forge, SDKMAN!, the static website, and the blog | ATR records external 
distributions. It does not publish those Grails channels. |
+
+ATR Beta on `releases.apache.org` publishes finished releases directly to 
`svn:dist:release`. The PMC email that announces Beta to `pmcs@` is still 
tracked by 
[tooling-trusted-releases#1520](https://github.com/apache/tooling-trusted-releases/issues/1520).
 That open issue does not keep the platform on Alpha.
+
+## Apache Trusted Releases (ATR)
+
+[ASF Tooling](https://tooling.apache.org/) runs [Apache Trusted 
Releases](https://releases.apache.org/) to automate compose, vote, and finish. 
ATR is **Beta**. The existing `dist/dev` to `dist/release` and Nexus staging 
path remains the official Grails process until the PMC opts in. See the [ATR 
documentation](https://releases.apache.org/docs/) and 
[apache/tooling-actions](https://github.com/apache/tooling-actions).
+
+The workflows pin `apache/tooling-actions` to 
`dcba9f4ed2956f7a30113c3067e766eeda37d891` (`main` on 2026-10-08). [Trusted 
Publishing](https://releases.apache.org/docs/trusted-publishing) says these 
actions are not tagged and must be referenced by a full commit hash, not 
`@main`. Other `apache/*` actions stay on a branch. 
`validateRepositoryConventions` requires that commit hash for 
`apache/tooling-actions/*` and still rejects a commit hash for every other 
`apache/*` action.
+
+| Manual step today | Tooling action | Grails workflow |
+| --- | --- | --- |
+| Upload source, binary, wrapper, and docs zips | `upload-to-atr` | `Release - 
ATR Upload (experimental)`, or `atr_upload` in `release.yml` when 
`ATR_ENABLED=true` |
+| Send the `[VOTE]` email | none (start the vote in the [ATR 
UI](https://releases.apache.org/) or with `atr vote start`) | — |
+| Send the `[RESULT][VOTE]` email | `release-on-atr` with `resolve: true` | 
`Release - ATR Resolve Vote (experimental)` |
+| Publish the voted zips to `dist/release` | ATR, when automatic publication 
was selected at vote start, or the Publish button | not a GitHub Actions SVN 
write |
+| Promote Nexus staging to Maven Central | none | `Release - Promote Nexus 
Staging`, then `Release - ATR Record Distribution (experimental)` with 
`platform=MAVEN` |
+| Send the `[ANNOUNCE]` email | `release-on-atr` with `announce: true` | 
`Release - ATR Announce (experimental)` once, to `[email protected]` |
+| ASF Reporter, Forge, SDKMAN!, website, blog | none | unchanged |
+
+### Opt-in setup
+
+1. Log in at https://releases.apache.org/ with ASF credentials and confirm the 
Grails project. Discuss on 
[[email protected]](https://lists.apache.org/[email protected])
 / [#apache-trusted-releases](https://the-asf.slack.com/archives/C049WADAAQG).
+2. Set the project download path suffix to `core/{{VERSION}}`. Grails 
publishes under `dist/release/grails/core/<version>/`, not in the committee 
root next to `KEYS`.
+3. Configure [Trusted 
Publishing](https://releases.apache.org/docs/trusted-publishing) for repository 
`grails-core`:
+
+    * Compose: `.github/workflows/release.yml` and 
`.github/workflows/release-atr-upload.yml`
+    * Vote: `.github/workflows/release-atr-resolve.yml`
+    * Finish: `.github/workflows/release-atr-announce.yml` and 
`.github/workflows/release-atr-record.yml`
+
+4. The committee page must show CI builds enabled. That requires a signing key 
whose primary UID contains `Automated Release Signing` and whose email is 
`[email protected]`. The release workflow imports `GRAILS_GPG_KEY` and 
signs with `GPG_KEY_ID`. Confirm that selected key matches this UID before the 
workflows will be accepted. If it does not, ask Infrastructure for a key that 
does. Voters still compare an independent rebuild on trusted hardware with the 
uploaded artifacts.

Review Comment:
   @C:\Users\james\AppData\Local\Temp\reply-atr-key.txt



##########
RELEASE.md:
##########
@@ -325,29 +326,34 @@ Confirm the Grails PMC votes passed with a +1 from at 
least 3 PMC members. The `
 
 ### Release the Staged Jar files
 
-The `release` job in the `Release` workflow has a step entitled `🚀 Release JAR 
files - MANUAL`. You can release the jar
-files by one of 2 ways:
+After the PMC vote has passed and the protected `release` environment is 
approved, prefer the opt-in
+`Release - Promote Nexus Staging` workflow. Run it from Actions with the 
version without `v`; leave
+`staging_description` empty to use `grails-core:<version>`. This is manually 
dispatched after the vote, following the
+[Apache Polaris TLP 
precedent](https://github.com/apache/polaris/blob/7866ce5c009d64e4c1454b47bca3df9873c6c0b2/.github/workflows/release-4-publish-release.yml).
 
-1. On https://repository.apache.org/#stagingRepositories, the staged artifacts 
must be released by opening the `grails-core` staging repository and
-   clicking the `Release` button. It took almost 2 hours for the initial ASF 
release to publish these jars to Maven
-   Central.
-2. Alternatively, the `release` job in the `Release` workflow will output an 
example command line to release the staging
-   repository via the scripts checked into grails-core. Execute the script & 
set the placeholder values to release the
-   jar files.
+The following remain fallbacks:
+
+1. On https://repository.apache.org/#stagingRepositories, release the staged 
artifacts by opening the `grails-core` staging repository and
+    clicking the `Release` button. It took almost 2 hours for the initial ASF 
release to publish these jars to Maven
+    Central.
+2. Run `.github/scripts/releaseJarFiles.sh grails-core:<version> <ASF_USER>`. 
The script prompts for a password unless
+    `NEXUS_PASS` is already set, which is how the protected workflow supplies 
its secret.
 
 ### Move the distributions from `dev` to `release`
 
-On dist.apache.org, the staged source distribution, binary distributions & 
documentation distribution must be moved from 
`https://dist.apache.org/repos/dist/dev/grails/` to 
`https://dist.apache.org/repos/dist/release/grails/`. Per ASF
-infrastructure, this must be performed manually, and we are not allowed to 
automate it via a gated approval workflow.
-Either move them via your SVN client or use the checked in script to perform 
these actions as your user.
+If this candidate was staged on ATR, skip this `dist/dev` move. Beta ATR 
commits the voted artifacts directly to `svn:dist:release` when the release is 
published. Set the Grails project's download path suffix to `core/{{VERSION}}` 
so the tree is `dist/release/grails/core/<version>/`, which is where the 
source, binary, wrapper, and documentation distributions belong. Do not run 
`releaseDistributions.sh` for an ATR candidate, and do not move anything out of 
`dist/atr`. See [Apache Trusted Releases (ATR)](#apache-trusted-releases-atr).

Review Comment:
   @C:\Users\james\AppData\Local\Temp\reply-atr-svn.txt



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