Harden rundeck-plugin-versions skill after two real misses - #22
Conversation
Three fixes, all found by revisiting this skill after the ua-runner ansible-plugin gap: 1. mapping.tsv: ua-runner now tracks a real ansiblePluginVersion, pyWinrmPluginVersion, opensshNodeExecutionVersion, sshjPluginVersion property (Forrest's call - track a real property rather than rely on runner-agent/build.gradle's submodule-read mechanism as the source of truth). Retired the VIA-SUBMODULE token from the data (kept supported in the scripts in case a future case needs it). 2. Fixed a real bug in both check-versions.sh and bump-versions-pr.sh: prop_ver()'s grep|head|sed pipeline exits 1 when a property genuinely isn't present yet, and under this script's set -euo pipefail, that silently killed the whole script (no error, just stopped) instead of reporting 'not found' like every other missing-property case. Found for real running check-versions.sh --plugin ansible-plugin right after adding it to ua-runner's mapping.tsv column, before the PR adding the actual property had merged. 3. Added scripts/audit-consumption.sh (Workflow D): read-only sweep that greps every '-' cell's repo for a real dependency reference to that plugin, in both compact and verbose Gradle syntax. Verified it catches both kinds of gap found this week (a plain compact-syntax grep alone would have missed rundeck-ec2-nodes-plugin's verbose-syntax dependency, same as the first time this was tried by hand) by deliberately reverting mapping.tsv to the old wrong state and confirming it flags exactly those rows, then restoring the correct file.
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate issues affect missing-property reporting and audit reliability.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Hardens the rundeck-plugin-versions skill with explicit ua-runner mappings, safer missing-property handling, and dependency-consumption auditing.
Changes:
- Replaces submodule markers with explicit ua-runner properties.
- Prevents missing properties from aborting version scripts.
- Adds Workflow D and
audit-consumption.sh.
File summaries
| File | Summary | Review findings |
|---|---|---|
skills/rundeck-plugin-versions/SKILL.md |
Documents the updated mappings and audit workflow. | None. |
skills/rundeck-plugin-versions/scripts/check-versions.sh |
Handles absent properties without crashing. | Missing properties can be treated as unconsumed, leaving rows OK (moderate, 2 votes). |
skills/rundeck-plugin-versions/scripts/bump-versions-pr.sh |
Applies missing-property handling. | Absent properties may be reported as up to date without warning (moderate, 1 vote). |
skills/rundeck-plugin-versions/scripts/audit-consumption.sh |
Adds repository-wide dependency auditing. | Missing/non-Git repositories fail without diagnostics (moderate, 3 votes); searches the current checkout instead of origin/main (moderate, 1 vote); masks git grep failures (moderate, 1 vote); and restricts searches to limited file patterns (moderate, 1 vote). |
skills/rundeck-plugin-versions/reference.md |
Updates mapping guidance and consumption notes. | None. |
skills/rundeck-plugin-versions/mapping.tsv |
Tracks explicit ua-runner properties. | None. |
Review details
Suppressed comments (6)
skills/rundeck-plugin-versions/scripts/audit-consumption.sh:64
- This searches the currently checked-out working tree, unlike the version scripts' documented
origin/mainsnapshots. Workflow D does not requiremain, so running it from a feature branch can miss a dependency that exists onorigin/mainand report a false clean result; inspect a fixedorigin/maintree or explicitly requiremain.
git -C "$repo_dir" grep -lE \
"org\.rundeck[.a-zA-Z]*:${plugin}[:'\"]|name:[[:space:]]*['\"]${plugin}['\"]" \
-- '*.gradle' '*.gradle.kts' 2>/dev/null | grep -v '^rundeck/' || true
skills/rundeck-plugin-versions/scripts/audit-consumption.sh:63
- The compact-coordinate branch only matches
org.rundeck..., but the canonical repository guidance says current plugin artifacts usecom.rundeck.plugins(PLUGINS_OVERVIEW.md:14,CLAUDE.md:69). Acom.rundeck.plugins:<plugin>:...dependency in a-row will be missed and can produce a false clean audit; match both coordinate groups.
"org\.rundeck[.a-zA-Z]*:${plugin}[:'\"]|name:[[:space:]]*['\"]${plugin}['\"]" \
skills/rundeck-plugin-versions/scripts/audit-consumption.sh:64
- The trailing
|| truemasks everygit grepfailure, not only its expected exit 1 for no matches. A broken or inaccessible checkout can therefore become an empty hit list and the script can printNo gaps foundwithout inspecting the repository; preserve the no-match case but report or propagate exit statuses greater than 1.
-- '*.gradle' '*.gradle.kts' 2>/dev/null | grep -v '^rundeck/' || true
skills/rundeck-plugin-versions/scripts/audit-consumption.sh:64
- Workflow D says this searches the repo's whole tracked tree, but these pathspecs restrict
git grepto*.gradleand*.gradle.kts. A valid dependency declaration in another tracked Gradle/Groovy script is therefore invisible and can produce a falseNo gaps found; either search-- .or narrow the documented guarantee.
git -C "$repo_dir" grep -lE \
"org\.rundeck[.a-zA-Z]*:${plugin}[:'\"]|name:[[:space:]]*['\"]${plugin}['\"]" \
-- '*.gradle' '*.gradle.kts' 2>/dev/null | grep -v '^rundeck/' || true
skills/rundeck-plugin-versions/scripts/audit-consumption.sh:68
- The new workflow/documentation says every
-cell is audited, but this loop only branches onpro_propandua_prop;core_propis never checked and the script has no--rundeckpath. A mistaken Core-mapping would still pass unnoticed. Add Core scanning or explicitly scope Workflow D to the two non-Core columns.
while IFS=$'\t' read -r plugin core_prop pro_prop ua_prop; do
skills/rundeck-plugin-versions/scripts/bump-versions-pr.sh:52
- The same empty result is silently skipped at
curhandling, so when a mapped ua-runner property has not landed yet this script can printup to date, no PR neededwithout telling the operator that the property is absent. Since this change makes those mappings explicit, the transitional missing-property state should be warned about rather than reported as current.
grep -E "^[[:space:]]*${prop}[[:space:]]*=" "$f" 2>/dev/null | head -1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//' || true
- Files reviewed: 6/6 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # produce noise) for either Gradle dependency syntax referencing a plugin. | ||
| find_reference() { | ||
| local repo_dir="$1" plugin="$2" | ||
| [ -d "$repo_dir/.git" ] || return 1 |
| # found" (found for real 2026-09-17: checking ansible-plugin against | ||
| # ua-runner's origin/main, which didn't have the property yet, aborted | ||
| # the script with zero output and no error message). | ||
| grep -E "^[[:space:]]*${prop}[[:space:]]*=" "$f" 2>/dev/null | head -1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//' || true |
What
Three fixes to the
rundeck-plugin-versionsskill, all found by revisiting it after Forrest caught that ua-runner also needed the ansible-plugin bump.mapping.tsv: ua-runner now tracks a real
ansiblePluginVersion,pyWinrmPluginVersion,opensshNodeExecutionVersion,sshjPluginVersionproperty (per Forrest's explicit call - track a real property in ua-runner's owngradle.properties, rather than rely onrunner-agent/build.gradle's submodule-read mechanism as the source of truth). Retires theVIA-SUBMODULEtoken from the actual data; the scripts still support it in case a future plugin genuinely needs it.Real bug fixed in both
check-versions.shandbump-versions-pr.sh:prop_ver()'sgrep|head|sedpipeline exits 1 when a property genuinely isn't present yet (a normal case - e.g. added tomapping.tsvbut the PR adding the property hasn't merged). Under this script'sset -euo pipefail, that silently killed the whole script - no error message, it just stopped - instead of reporting "not found" like every other missing case. Found runningcheck-versions.sh --plugin ansible-pluginright after adding it to ua-runner's column, before rundeckpro/ua-runner#222 had merged.New
scripts/audit-consumption.sh(Workflow D): read-only sweep that checks every-cell inmapping.tsvagainst a real grep of the corresponding repo's whole tracked tree, in both compact ("group:artifact:version") and verbose (group: '...', name: '...') Gradle dependency syntax. Verified it catches both kinds of gap found this week by deliberately revertingmapping.tsvto the old wrong state and confirming it flags exactly those rows (includingrundeck-ec2-nodes-plugin's verbose-syntax dependency, which a compact-only grep would miss - the exact mistake made the first time this kind of sweep was tried by hand), then restoring the correct file.Why
This is the second time in a week a real consumption gap slipped through unnoticed until something else went wrong.
audit-consumption.shturns "grep one plugin by hand after a report seems off" into a standing, repeatable check (Workflow D in SKILL.md).