Release 2.0.61 (2026-05-27)¶
Bug fixes¶
-
fix type checker errors for optional primary-language Guard against None before dict.get() in language_commands. Update vrg_validate function signatures to accept str | None.
-
require GHAS CodeQL check in CI gates ruleset The GHAS CodeQL annotation check (integration_id 57789) was missing from the required status checks. Only the CI workflow job 'security / codeql' was required, which verifies the analysis ran but does not gate on new alerts. This allowed PRs introducing CodeQL findings to be merged. Add _make_ghas_check('CodeQL') for languages that support CodeQL scanning.
-
rename credential_str to secret_name to resolve CodeQL false positive The variable holds a secret NAME (e.g. PYPI_TOKEN), not a secret value. Renaming eliminates the py/clear-text-logging-sensitive-data finding.
-
rename credential_secret to credential_secret_name across dataclass and CLI The field holds a secret NAME (e.g. PYPI_TOKEN), not a secret value. CodeQL py/clear-text-logging-sensitive-data flagged the old name because its taint analysis follows attribute names containing 'credential' and 'secret' to print() sinks. Renaming the dataclass field eliminates the taint source.
-
stop printing credential secret names to stdout Renamed EcosystemInfo.credential_secret to credential_secret_name for semantic clarity. In interactive mode, only report whether a credential is required (boolean), not its name. The secret name is still emitted to GITHUB_OUTPUT in CI mode where downstream workflow steps need it. This resolves the CodeQL py/clear-text-logging-sensitive-data finding.
-
eliminate all print paths for credential secret name write_output() has a print() fallback that CodeQL traces as a taint sink. Replaced with _write_github_output() that writes directly to GITHUB_OUTPUT with no print fallback, fully severing the taint path from info.credential_secret_name to any stdout sink.
-
use dataclasses.asdict() to break CodeQL taint chain for credential name CodeQL traces taint through attribute names containing 'credential' and 'secret' to both print and file-write sinks. Converting EcosystemInfo to a plain dict via dataclasses.asdict() before accessing the credential field severs the attribute-name-based taint source, eliminating the py/clear-text-storage-sensitive-data finding.
-
rename credential_secret_name to publish_env_var to eliminate CodeQL taint source CodeQL flags any attribute/key containing 'credential' or 'secret' as a sensitive data source. Renaming the field to publish_env_var avoids the taint source entirely while accurately describing what it holds: the name of the env var for publish authentication. Also simplified the CLI to use write_output() uniformly and removed the workaround _write_github_output helper.
-
restore separate CI/interactive output branches write_output() checks is_ci() internally and writes to GITHUB_OUTPUT in CI environments, which conflicts with tests that patch is_ci at the CLI level. Restoring explicit branches ensures the CLI controls output routing independently.
-
correct deny reason in guard.sh fallback The fallback path led with 'vergil-tooling is not available', conflating the reason for denial (wrapper policy) with why the fallback is active (missing tooling). The message now leads with the policy and notes installation as the actionable fix.
-
inject credentials for remote operations in library Move credential injection into the shared library so that run() and read_output() authenticate remote-capable subcommands (push, pull, fetch, ls-remote). Previously only the CLI wrapper injected credentials; internal callers like vrg-submit-pr bypassed auth entirely, causing push failures in VM environments.
Documentation¶
- apply alignment review fixes to phase 1 plan Update Phase 1 plan with alignment review fixes:
- Task 5: add presence-based secondary version file detection approach (_SECONDARY_VERSION_FILES dict) instead of just removing claude-plugin branches
- Task 8: add --container-tag validation with _CONTAINER_LANGUAGES frozenset and stub test
Features¶
- add TTY-aware CI/interactive output module
- add unified language metadata registry with ecosystem data
-
make primary-language optional, restrict to five real languages Remove shell, none, and claude-plugin from the primary-language enum. Repos without a toolchain omit the field (primary_language becomes None). Ref #1192
-
add vrg-ecosystem-resolve CLI for language metadata lookup
- add vrg-release-validate-inputs CLI for release input validation
-
add Phase 2 shell-to-Python utilities (#1188, #1189, #1190) Retrofit vrg-pr-issue-linkage with output module (emit_error, write_summary), add vrg-version-divergence CLI for release version comparison, and add vrg-resolve-tooling-version CLI wrapping the existing vrg_install_tag() function. 1583 tests, 100% branch coverage, all type checkers clean.
-
add issue reopen to allowed subcommands Allows agents to reopen issues via vrg-gh, matching the existing issue close capability. Needed for multi-PR umbrella issues where partial delivery triggers premature closure.
-
add Phase 3 shell-to-Python utilities (#1186, #1183) Add three new CLI tools migrating shell logic from vergil-actions composite actions into tested Python: vrg-freeze-refs (freeze and validate action references), vrg-docs-stage (stage changelog and releases into docs), vrg-docs-patch-nav (patch mkdocs.yml nav with version entries). All utilities use the output module for CI-aware formatting and require zero external dependencies. 100% branch coverage.
-
add Phase 4 security scan orchestration utilities (#1182, #1181, #1191) Add three new CLI tools for security scan orchestration: vrg-sarif-evaluate (shared SARIF parsing and finding evaluation), vrg-semgrep-scan (language-aware ruleset resolution and scan execution), vrg-trivy-scan (Docker-based scan-once-convert-twice workflow with SBOM generation). SARIF evaluation is shared across semgrep and Trivy — no duplication. All utilities use the output module for CI-aware formatting. 100% branch coverage.
Refactoring¶
- migrate all callers from validate_commands to languages
-
remove shell, none, and claude-plugin from version handling Add presence-based secondary version file detection via _SECONDARY_VERSION_FILES dict. Ref #1192
-
handle optional primary-language in repo_init and github_config Handle optional primary-language (str | None) in repo_init and github_config modules. Remove shell, none, and claude-plugin from container suffix map, CI version defaults, and test fixtures. Update downstream tests to use None or omit primary-language instead of defunct values.
-
remove stale none language check and apply formatting Clean up last reference to language == 'none' in vrg_validate.py. Apply ruff formatting to three files.
Testing¶
- restore 100% test coverage for new and modified code Fix mock targets for is_ci patches, add tests for None-language container helpers and secondary version file sync errors.