Add dispatchable Plugin Portal publish workflow to main#232
Conversation
Isolates Portal publication so a re-run never re-triggers the Maven Central step. Adds workflow_dispatch with required ref/version inputs so the v1.0.0 tag can be published retroactively. Root cause fixed: the missing GPG signing env (ORG_GRADLE_PROJECT_signingInMemoryKey*) is now present alongside Portal creds, resolving the signatory error on marker publications.
Review Summary by QodoAdd dispatchable Plugin Portal publish workflow to main
WalkthroughsDescription• Add dedicated Gradle Plugin Portal publish workflow with manual dispatch support • Enable retroactive v1.0.0 plugin publication via workflow_dispatch inputs • Include GPG signing environment variables for plugin marker publication • Support both tag-triggered and manual ref-based workflow execution Diagramflowchart LR
A["Tag Push or<br/>Manual Dispatch"] -->|"ref + version inputs"| B["Checkout Git Ref"]
B --> C["Setup Build Environment"]
C --> D["Determine Version"]
D -->|"Strip v prefix or<br/>use input version"| E["Publish to Portal"]
E -->|"GPG + Portal Creds"| F["Plugin Published"]
File Changes1. .github/workflows/publish-plugin-portal.yml
|
Code Review by Qodo
1. Ref/version mismatch publish
|
There was a problem hiding this comment.
Pull request overview
Adds a dedicated GitHub Actions workflow on main to publish the Gradle plugin to the Gradle Plugin Portal via tag push or manual workflow_dispatch, enabling (re-)publishing an already-cut release tag (e.g. v1.0.0) without modifying main.
Changes:
- Introduces
.github/workflows/publish-plugin-portal.ymlwithworkflow_dispatchinputs (ref,version) to publish a specific tag. - Adds logic to derive
VERSION_NAMEfrom either the dispatch input or the tag name. - Runs
:featured-gradle-plugin:publishPluginswith Portal + GPG signing secrets configured.
| push: | ||
| tags: | ||
| - "v[0-9]+.[0-9]+.[0-9]+" | ||
| - "v[0-9]+.[0-9]+.[0-9]+-*" |
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: false |
There was a problem hiding this comment.
2 issues found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/publish-plugin-portal.yml">
<violation number="1" location=".github/workflows/publish-plugin-portal.yml:22">
P2: The concurrency group uses `github.ref`, which for `workflow_dispatch` events resolves to the branch ref (e.g. `refs/heads/main`) rather than the tag being published. This means all manual dispatch runs will share the same concurrency group and serialize against each other, even when publishing different tags. Consider incorporating `inputs.ref` into the group key for dispatch runs, e.g.:
```yaml
group: ${{ github.workflow }}-${{ inputs.ref || github.ref }}
```</violation>
<violation number="2" location=".github/workflows/publish-plugin-portal.yml:37">
P1: `workflow_dispatch` accepts `ref` and `version` independently without enforcing they match, so a manual run can publish a release version from non-tag code.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| # On tag push: check out the triggering tag. | ||
| # On workflow_dispatch: check out the explicit ref input so develop-HEAD | ||
| # (1.1.0-SNAPSHOT) is never published in place of the release tag. | ||
| ref: ${{ inputs.ref || github.ref }} |
There was a problem hiding this comment.
P1: workflow_dispatch accepts ref and version independently without enforcing they match, so a manual run can publish a release version from non-tag code.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/publish-plugin-portal.yml, line 37:
<comment>`workflow_dispatch` accepts `ref` and `version` independently without enforcing they match, so a manual run can publish a release version from non-tag code.</comment>
<file context>
@@ -0,0 +1,66 @@
+ # On tag push: check out the triggering tag.
+ # On workflow_dispatch: check out the explicit ref input so develop-HEAD
+ # (1.1.0-SNAPSHOT) is never published in place of the release tag.
+ ref: ${{ inputs.ref || github.ref }}
+
+ - uses: ./.github/actions/setup-build-env
</file context>
| contents: read | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} |
There was a problem hiding this comment.
P2: The concurrency group uses github.ref, which for workflow_dispatch events resolves to the branch ref (e.g. refs/heads/main) rather than the tag being published. This means all manual dispatch runs will share the same concurrency group and serialize against each other, even when publishing different tags. Consider incorporating inputs.ref into the group key for dispatch runs, e.g.:
group: ${{ github.workflow }}-${{ inputs.ref || github.ref }}Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/publish-plugin-portal.yml, line 22:
<comment>The concurrency group uses `github.ref`, which for `workflow_dispatch` events resolves to the branch ref (e.g. `refs/heads/main`) rather than the tag being published. This means all manual dispatch runs will share the same concurrency group and serialize against each other, even when publishing different tags. Consider incorporating `inputs.ref` into the group key for dispatch runs, e.g.:
```yaml
group: ${{ github.workflow }}-${{ inputs.ref || github.ref }}
```</comment>
<file context>
@@ -0,0 +1,66 @@
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
</file context>
| group: ${{ github.workflow }}-${{ github.ref }} | |
| group: ${{ github.workflow }}-${{ inputs.ref || github.ref }} |
| ref: ${{ inputs.ref || github.ref }} | ||
|
|
||
| - uses: ./.github/actions/setup-build-env | ||
|
|
||
| - name: Determine version | ||
| id: version | ||
| env: | ||
| INPUT_VERSION: ${{ inputs.version }} | ||
| run: | | ||
| if [[ -n "${INPUT_VERSION}" ]]; then | ||
| # Manual dispatch: use the explicitly supplied version. | ||
| VERSION="${INPUT_VERSION}" | ||
| else | ||
| # Tag push: strip the leading "v" from the tag (e.g. v1.0.0 -> 1.0.0). | ||
| VERSION="${GITHUB_REF_NAME#v}" | ||
| fi |
There was a problem hiding this comment.
1. Ref/version mismatch publish 🐞 Bug ≡ Correctness
On workflow_dispatch, the workflow checks out inputs.ref but publishes using the separately supplied inputs.version without verifying they correspond, so it can publish the wrong code under the wrong version to the Gradle Plugin Portal. This contradicts the repo’s documented release convention that tag name and VERSION_NAME must match (minus the leading v).
Agent Prompt
### Issue description
`workflow_dispatch` accepts `ref` and `version` as independent required inputs, but the workflow does not validate that the checked-out ref corresponds to the version being published. This can lead to publishing code from one tag/commit under a different version number.
### Issue Context
The repository’s release process documentation states that the tag name must match `VERSION_NAME` in `gradle.properties` (with the `v` prefix stripped). The workflow currently relies on operator correctness but provides no guardrails.
### Fix Focus Areas
- .github/workflows/publish-plugin-portal.yml[9-16]
- .github/workflows/publish-plugin-portal.yml[37-66]
### Suggested fix
Add a validation step for `workflow_dispatch` runs before publishing. For example:
- Ensure `inputs.ref` is a tag-like value (e.g., starts with `v`).
- Compute `TAG_VERSION="${REF#v}"` and fail if `inputs.version != TAG_VERSION`.
- Optionally, make `version` optional and derive it from `ref` by default to eliminate mismatch risk.
Example (bash):
```bash
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
REF="${{ inputs.ref }}"
TAG_VERSION="${REF#v}"
if [[ "${REF}" == "${TAG_VERSION}" ]]; then
echo "ref must start with 'v' (e.g. v1.0.0)"; exit 1
fi
if [[ "${{ inputs.version }}" != "${TAG_VERSION}" ]]; then
echo "version input (${{ inputs.version }}) must match ref ($TAG_VERSION)"; exit 1
fi
fi
```
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Adds
.github/workflows/publish-plugin-portal.ymltomainso thatworkflow_dispatchbecomes available (GitHub only exposes manual dispatch for workflows present on the default branch).This unblocks publishing the already-cut v1.0.0 plugin to the Gradle Plugin Portal via:
The workflow checks out the supplied
ref(thev1.0.0tag), so it publishes the exact tagged plugin code as 1.0.0 —main's version state is not modified by this PR (single new file, no other changes).Scope note:
main's existingpublish.ymlstill contains the broken inline Portal step; it is harmless until the next tag push and is fixed ondevelopby #228. That fix reachesmainthrough the normal release back-merge — it is intentionally not pulled in here to keep this PR a single-file, version-neutral change. Companion PR fordevelop: #231.🤖 Generated with Claude Code