Thin main jar + manual Maven Central publish workflow#27
Conversation
maven-shade-plugin replaced the main artifact with the uber jar, so the published com.testingbot:TestingBotTunnel Maven artifact bundled Jetty, Apache HTTP, commons-cli, etc. Consumers (e.g. the Jenkins TestingBot plugin) then got those bundled classes shadowing their own copies on a flat classpath, breaking modern APIs and the test harness. Attach the shaded uber jar under the 'shaded' classifier instead of replacing the main artifact: - Maven Central gets a thin main jar whose POM declares the real dependencies (transitive, correctly versioned). - Docker, the CLI release asset, and the package-time smoke test use the runnable '-shaded' jar. - The GitHub release asset keeps the familiar runnable TestingBotTunnel-<version>.jar name. Verified locally: main jar has 0 bundled Jetty classes (451 KB); shaded jar runs 'java -jar ... --version'.
Lets us publish the current POM version to Central on demand (e.g. 4.8, already released on GitHub/Docker) without re-tagging or re-running the GitHub release + Docker jobs. Deploy-only, mirrors release.yml's Central/GPG setup. Run it from a branch that produces the thin jar.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe build now publishes a thin main JAR alongside a shaded ChangesMaven artifact flow
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Maven
participant Docker
participant GitHubReleases
participant MavenCentral
Maven->>Maven: Attach shaded JAR and run smoke test
Maven->>Docker: Provide shaded JAR
Docker->>Docker: Rename artifact to testingbot-tunnel.jar
Maven->>GitHubReleases: Copy shaded JAR to release-assets
GitHubReleases->>GitHubReleases: Upload release asset
Maven->>MavenCentral: Deploy signed artifacts
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/maven-publish.yml:
- Around line 10-15: Add workflow-level token permissions in the Maven publish
workflow by declaring contents read access alongside the top-level on
configuration. Keep the publish job behavior unchanged while ensuring the
workflow token has no write permissions.
- Around line 10-15: Add workflow-level concurrency to the Maven publish
workflow, using a stable group for all runs and configuring new manual runs to
wait for an existing publish rather than deploying concurrently. Keep the
existing publish job and workflow_dispatch trigger unchanged.
- Around line 18-22: Update the “Checkout code” and “Set up JDK 11” steps to
reference immutable, verified commit SHAs for actions/checkout and
actions/setup-java instead of the mutable `@v4` tags, while preserving their
existing action versions and configuration.
- Around line 3-11: Restrict the workflow_dispatch entry for the Maven publish
workflow to an approved protected release tag or branch, and validate that the
checked-out ref and POM version match the expected release before deployment.
Add the validation before the Maven publish step and fail the workflow on any
mismatch, while preserving the existing manual publishing behavior for valid
release refs.
- Around line 18-19: Update the actions/checkout step in the Maven publish
workflow to set persist-credentials to false, ensuring the checkout does not
retain the GitHub token in local Git configuration before mvn deploy runs.
- Around line 34-38: Remove the inline -Dgpg.passphrase argument from the Maven
deploy command. Keep GPG_PASSPHRASE in the existing env configuration so
actions/setup-java continues supplying the passphrase through the environment.
In @.github/workflows/release.yml:
- Around line 55-56: Update the “Upload JAR to GitHub Releases” workflow step to
use the current major version of softprops/action-gh-release and pin it to the
corresponding full commit SHA instead of the mutable `@v1` tag.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 25e17f30-3379-40a3-8438-398fdc53b9db
📒 Files selected for processing (4)
.github/workflows/maven-publish.yml.github/workflows/release.ymlDockerfilepom.xml
| # Manually publish the current POM version to Maven Central, without creating a | ||
| # GitHub release or Docker image (use this to publish a version that was already | ||
| # tagged/released on GitHub, e.g. 4.8). Select the branch to run from in the | ||
| # "Run workflow" dropdown — it publishes whatever version the checked-out POM has. | ||
| # | ||
| # NOTE: Maven Central versions are immutable. Only run this from a branch whose | ||
| # build produces the thin main jar (i.e. after the thin-jar change is merged). | ||
| on: | ||
| workflow_dispatch: |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/maven-publish.yml"
echo "=== file outline ==="
ast-grep outline "$file" --view expanded || true
echo
echo "=== numbered file excerpt ==="
cat -n "$file"
echo
echo "=== search for workflow env/permissions/checkout/setup-java/deploy ==="
rg -n "workflow_dispatch|permissions:|environment:|actions/checkout|setup-java|mvn|deploy|gpg|MAVEN_CENTRAL|maven" "$file"Repository: testingbot/Testingbot-Tunnel
Length of output: 2438
Gate this publish job to a protected release ref. The workflow accepts any selected branch and runs it with Maven Central and GPG secrets, so a bad or compromised ref can publish the wrong immutable version or alter the publish steps. Enforce a protected tag/branch and reject POM/version mismatches before deploy.
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 10-11: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/maven-publish.yml around lines 3 - 11, Restrict the
workflow_dispatch entry for the Maven publish workflow to an approved protected
release tag or branch, and validate that the checked-out ref and POM version
match the expected release before deployment. Add the validation before the
Maven publish step and fail the workflow on any mismatch, while preserving the
existing manual publishing behavior for valid release refs.
Source: MCP tools
…rrency, GPG env maven-publish.yml: - Add contents:read permissions and a maven-central-publish concurrency group (queue, never race) - Pin actions/checkout + actions/setup-java to commit SHAs; set persist-credentials: false - Drop the inline -Dgpg.passphrase (passphrase already supplied via the GPG_PASSPHRASE env by setup-java) release.yml: - Pin softprops/action-gh-release to v3 commit SHA (was mutable @v1) Skipped: restricting workflow_dispatch to a protected release tag + ref/version validation. The workflow is intentionally a maintainer-only manual publish (workflow_dispatch needs repo write and secrets) that must be runnable from master or a feature branch (e.g. to publish 4.8 thin from this branch); tying it to a protected tag defeats that, and Central's immutability already blocks overwriting an existing version.
Problem
maven-shade-pluginwas configured to replace the main build artifact with the shaded uber jar, so the publishedcom.testingbot:TestingBotTunnelMaven artifact was a fat jar bundling Jetty (~1000 classes), Apache HTTP, commons-cli, Jackson, logback, etc.Maven consumers (notably the Jenkins TestingBot plugin) then received those bundled classes on a flat classpath, where they shadow the consumer's own copies. Concretely this:
Requestis a class vs an interface), blocking allJenkinsRule/JCasC tests, andDefaultParser/Option.builderthrewNoSuchFieldErrorat runtime).You can't exclude classes bundled inside a jar, so consumers had no way to fix this.
Change
Attach the shaded uber jar under a
shadedclassifier instead of replacing the main artifact:-shadedjar, so nothing changes for CLI users.TestingBotTunnel-<version>.jardownload name (the release workflow renames the shaded jar).No dependency versions changed; this is purely how the artifact is packaged/published.
Verification
Local
mvn -DskipTests package(JDK 11):TestingBotTunnel-4.8.jar— 0 bundled Jetty classes, 451 KB (thin).TestingBotTunnel-4.8-shaded.jar— 7.3 MB, runnable:java -jar target/TestingBotTunnel-4.8-shaded.jar --version→Version: testingbot-tunnel.jar 4.8.The existing release workflow (tag →
mvn clean deployvia the Central Portal plugin) publishes the thin main jar + sources + javadoc + theshadedclassifier, all GPG-signed.Also: manual "Publish to Maven Central" workflow
Adds
.github/workflows/maven-publish.yml(workflow_dispatch) that deploys the current POM version to Central on demand — deploy only, no GitHub release or Docker. This is how to get 4.8 onto Maven Central (it's already released on GitHub/Docker but never published to Central), without re-tagging.masterafter merge), so4.8is published thin and stays thin.Summary by CodeRabbit