close
Skip to content

fix(ci): run wrapper verification after publishForge to avoid first-bump 404#15602

Merged
jamesfredley merged 5 commits into
7.0.xfrom
fix/wrapper-verify-after-forge-publish
Apr 25, 2026
Merged

fix(ci): run wrapper verification after publishForge to avoid first-bump 404#15602
jamesfredley merged 5 commits into
7.0.xfrom
fix/wrapper-verify-after-forge-publish

Conversation

@jamesfredley

Copy link
Copy Markdown
Contributor

Description

Fixes the Verify grails-wrapper failure that broke the publish run on 7.1.x at https://github.com/apache/grails-core/actions/runs/24911783419/job/72960758147 with:

Unable to execute Grails Wrapper: Could not find the Grails Repo in any repository:
https://repo1.maven.org/maven2/org/apache/grails/grails-cli,
https://repository.apache.org/content/groups/public/org/apache/grails/grails-cli

Root cause

This repository contains three independent sub-projects that publish separately:

Sub-project CI job Publishes
grails-core (root) publish grails-shell-cli, grails-wrapper, ~70 modules
grails-gradle/ publishGradle Gradle plugins
grails-forge/ publishForge grails-cli (combined shadow jar), grails-forge-cli

The Verify grails-wrapper step ran grailsw --version, and grailsw always downloads org.apache.grails:grails-cli (GrailsWrapperHome.CLI_COMBINED_PROJECT_NAME = "grails-cli"). That artifact is produced by publishForge, but publishForge needs: [ buildForge, publishGradle, publish ], so it runs after the verify step that depends on it.

Until now the smoke test happened to pass because Nexus already had a grails-cli/<projectVersion> snapshot from a previous publishForge run. PR #15598 then pinned verify to projectVersion via PREFERRED_GRAILS_VERSION, which exposed the underlying chicken-and-egg: the very first publish run after any post-release version bump finds no grails-cli/<new-version>-SNAPSHOT and 404s.

Confirmed against https://repository.apache.org/content/groups/public/org/apache/grails/grails-cli/:

  • 7.0.11-SNAPSHOT/ exists (stale, dated 20260404 - prior publishForge run before the verify ran on 20260424).
  • 7.1.0-SNAPSHOT/ and 7.1.0/ exist.
  • 7.1.1-SNAPSHOT/ does not exist - the version was bumped post-release on 7.1.x and publishForge has not run since. Hence the 404 on 7.1.x.

7.0.x will hit the same failure the next time it bumps to 7.0.12-SNAPSHOT, so this fix targets 7.0.x for forward-merge into 7.1.x and 8.0.x.

Fix

Move the wrapper smoke test out of publish and into a new verifyWrapper job that needs: [ publish, publishForge ]. By the time it runs, both the wrapper itself (from publish) and grails-cli/<projectVersion> (from publishForge) are in Nexus.

Wiring:

  • publish builds the wrapper distZip and uploads it as a new intermediate artifact apache-grails-wrapper-distribution-zip (renamed to wrapper.zip for a stable filename).
  • verifyWrapper downloads that zip, runs grailsw --version (which now succeeds because grails-cli/<projectVersion> exists), and uploads the extracted contents under the existing user-facing artifact name apache-grails-wrapper-SNAPSHOT-bin. The artifact name visible on the workflow summary page is unchanged.
  • docs is intentionally left as needs: [ publish ] to preserve current parallelism with publishForge/verifyWrapper. Wrapper verification failures should surface as a CI failure, not gate documentation publishing.

The PREFERRED_GRAILS_VERSION pin from PR #15598 is preserved, since pinning to the branch's snapshot is still desirable - we just no longer require that snapshot to have been pre-published.

Job graph (after this PR)

buildGradle ─┐
             └─► publishGradle ─┐
                                ├─► publish ─┬─► publishForge ─► verifyWrapper
build* ─────────────────────────┤            └─► docs
functional* ────────────────────┤
hibernate5Functional* ──────────┤
mongodbFunctional* ─────────────┘
buildForge ────────────────────────────────► publishForge

(* gated by [skip tests].)

Contributor Checklist

Issue and Scope

  • This PR addresses a CI regression in the publish pipeline that surfaced after PR fix(wrapper): honor PREFERRED_GRAILS_VERSION and repair publish CI #15598 was merged. No issue ticket since the failure is internal to the publish job; happy to file one if preferred.
  • This PR addresses the complete scope of the failure - the smoke test now runs at the only point in the graph where both required artifacts are guaranteed present.
  • This PR contains a single, focused change (workflow restructure only).
  • This PR targets 7.0.x because the bug is structural and forward-merges cleanly into 7.1.x and 8.0.x. The publish/publishForge/docs section of gradle.yml is identical across all three branches.

Code Quality

  • No production code changes; only .github/workflows/gradle.yml.
  • YAML parses (python -c 'import yaml; yaml.safe_load(open(... ))').
  • Job dependency graph verified: verifyWrapper.needs == ['publish', 'publishForge'], docs.needs == ['publish'], publishForge.needs == ['buildForge', 'publishGradle', 'publish'].
  • No reformatting outside the changed region.

Licensing and Attribution

  • No new source files added; existing license headers preserved.

Documentation

  • No user-facing changes - this is a CI-only fix. The user-facing artifact name on the workflow summary page (apache-grails-wrapper-SNAPSHOT-bin) is unchanged.

The next post-bump run on each release branch will exercise the new ordering. If verification fails for an unrelated reason in the future, the failure will now be reported on its own job rather than masked inside publish.

…ump 404

The `Verify grails-wrapper` step ran `grailsw --version` against the just-built wrapper, which downloads `org.apache.grails:grails-cli` from Apache Nexus. `grails-cli` is published by `publishForge` (in the grails-forge sub-project), but the verify step lived in the `publish` job which runs before `publishForge`. The smoke test only worked because Nexus already had a stale `grails-cli` snapshot for the same projectVersion from a previous run. The first publish run after a post-release version bump (e.g. 7.0.x bumping to 7.0.12-SNAPSHOT, or 7.1.x's recent bump to 7.1.1-SNAPSHOT) would always 404.

Move the verification into a new `verifyWrapper` job that depends on both `publish` and `publishForge`, so by the time it runs `grails-cli` for this branch's exact projectVersion is guaranteed to be in Nexus. The `publish` job now uploads the wrapper distribution zip as an intermediate artifact (`apache-grails-wrapper-distribution-zip`) and `verifyWrapper` produces the user-facing `apache-grails-wrapper-SNAPSHOT-bin` artifact unchanged.

Assisted-by: claude-code:claude-opus-4
Copilot AI review requested due to automatic review settings April 25, 2026 01:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a CI publish pipeline ordering issue where the grails-wrapper smoke test (grailsw --version) could run before grails-cli (published by publishForge) exists for a freshly bumped SNAPSHOT version, causing 404 failures.

Changes:

  • Removes wrapper verification from the publish job and introduces a dedicated verifyWrapper job.
  • Uploads the wrapper distribution zip as an intermediate artifact from publish, then downloads/verifies it in verifyWrapper after publishForge completes.
  • Keeps the user-facing artifact name (apache-grails-wrapper-SNAPSHOT-bin) by re-uploading extracted wrapper contents from verifyWrapper.

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

Comment thread .github/workflows/gradle.yml
@bito-code-review

Copy link
Copy Markdown

To prevent the 'Output Agent IP' step from failing the entire verifyWrapper job due to network issues, add 'continue-on-error: true' to make it non-blocking.

.github/workflows/gradle.yml

- name: "Output Agent IP" # in the event RAO blocks this agent, this can be used to debug it
        run: curl -s https://api.ipify.org
        continue-on-error: true

Comment thread .github/workflows/gradle.yml Outdated
Comment thread .github/workflows/gradle.yml Outdated
Comment thread .github/workflows/gradle.yml Outdated
Comment thread .github/workflows/gradle.yml Outdated
Resolve conflict in .github/workflows/gradle.yml: keep this branch's verifyWrapper job restructure while picking up dependabot's actions/upload-artifact v7.0.0 -> v7.0.1 bump for the new upload steps.

Assisted-by: claude-code:claude-opus-4
Per review feedback: drop the 'smoke test downloads grails-cli from Nexus' framing and the historical 'Previously the verify step lived inside publish' narrative. The job's purpose is to verify the wrapper works end-to-end; ordering after publishForge is the means, not the end.

Assisted-by: claude-code:claude-opus-4
Restore the publish job's wrapper build step to its byte-identical pre-PR form (just \./gradlew :grails-wrapper:distZip\) and upload the gradle-produced apache-grails-wrapper-<version>.zip directly via path glob, instead of renaming it to wrapper.zip first. The verify run script is also restored to its pre-PR form, with only \mkdir -p build\ added since the new job doesn't run gradle to create that directory.

Net effect: the intermediate artifact 'apache-grails-wrapper-distribution-zip' now contains the version-stamped filename produced by gradle, matching the convention already in use elsewhere in this workflow (e.g. the docs job). The user-facing apache-grails-wrapper-SNAPSHOT-bin artifact is unaffected.

Assisted-by: claude-code:claude-opus-4
…per-SNAPSHOT-bin directly

Per review feedback, eliminate the secondary apache-grails-wrapper-distribution-zip artifact. The publish job now uploads the extracted wrapper directory under its existing user-facing name (apache-grails-wrapper-SNAPSHOT-bin), and verifyWrapper downloads that single artifact and runs grailsw --version directly against it.

The publish job's Create Grails Wrapper Distribution Zip step absorbs the cp/unzip/mv ceremony that used to live in the inline verify step; only the grailsw --version invocation moves to the new verifyWrapper job. The user-facing artifact name and contents are identical to the pre-PR state.

Assisted-by: claude-code:claude-opus-4
@jamesfredley jamesfredley requested a review from jdaugherty April 25, 2026 14:38
@jamesfredley jamesfredley merged commit ef9d8cf into 7.0.x Apr 25, 2026
29 checks passed
@jamesfredley jamesfredley deleted the fix/wrapper-verify-after-forge-publish branch April 25, 2026 14:51
@jamesfredley

Copy link
Copy Markdown
Contributor Author

Monitorig https://github.com/apache/grails-core/actions/runs/24933507519 and then will merge up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants