Skip to content

feat(ci): automate Go toolchain version updates via govulncheck failures#3267

Draft
dmihalcik-virtru wants to merge 4 commits intomainfrom
DSPX-2565-golang-update
Draft

feat(ci): automate Go toolchain version updates via govulncheck failures#3267
dmihalcik-virtru wants to merge 4 commits intomainfrom
DSPX-2565-golang-update

Conversation

@dmihalcik-virtru
Copy link
Copy Markdown
Member

@dmihalcik-virtru dmihalcik-virtru commented Apr 7, 2026

Adds a workflow that detects govulncheck failures on main and release/**
branches and automatically opens a PR bumping the Go toolchain to the
latest supported patch (or latest minor if the current one is EOL).

  • .github/scripts/bump-go-version.sh: standalone script that updates
    the toolchain directive in go.work and all go.mod files, and
    syncs the hardcoded Go version in checks.yaml and sonarcloud.yml.
    Supports --dry-run (prints unified diff, no file changes), --target
    (skip API lookup), and --api-url (mock for tests).
  • .github/scripts/bump-go-version.bats: 9 BATS unit tests covering
    patch bumps, minor-version bumps, EOL detection, dry-run mode, and
    already-at-latest no-op behaviour.
  • .github/scripts/fixtures/go-versions.json: mock go.dev API response
    for offline test runs.
  • .github/workflows/go-version-update.yaml: automation workflow
    (workflow_dispatch + weekly schedule) that calls the script and
    creates/updates a PR as opentdf-automation[bot] with the autobump
    label.
  • .github/workflows/checks.yaml: adds trigger-go-version-update job
    (dispatches the update workflow when govulncheck artifacts are found on
    push to main/release/**) and script-tests job (runs the BATS tests;
    added to the ci gate).
  • .policy.yml: extends the autobump rule's branch pattern to also
    match chore/bump-go-toolchain(-...)? so bot PRs auto-merge on CI pass.
  • AGENTS.md: documents that Go toolchain bumps should go through this
    automation rather than being done by hand in feature PRs.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Signed-off-by: Dave Mihalcik dmihalcik@virtru.com

Proposed Changes

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

Summary by CodeRabbit

  • New Features

    • Automated Go toolchain bump workflow that creates PRs to update pinned Go versions
  • Documentation

    • Added Go Toolchain Version Management guide with usage and dry-run instructions
  • Tests

    • New test suite validating bumping, dry-run, no-op, and CI workflow updates
  • Chores

    • CI workflows and approval policy updated to integrate automated toolchain updates

Adds a workflow that detects govulncheck failures on main and release/**
branches and automatically opens a PR bumping the Go toolchain to the
latest supported patch (or latest minor if the current one is EOL).

- `.github/scripts/bump-go-version.sh`: standalone script that updates
  the `toolchain` directive in `go.work` and all `go.mod` files, and
  syncs the hardcoded Go version in `checks.yaml` and `sonarcloud.yml`.
  Supports `--dry-run` (prints unified diff, no file changes), `--target`
  (skip API lookup), and `--api-url` (mock for tests).
- `.github/scripts/bump-go-version.bats`: 9 BATS unit tests covering
  patch bumps, minor-version bumps, EOL detection, dry-run mode, and
  already-at-latest no-op behaviour.
- `.github/scripts/fixtures/go-versions.json`: mock go.dev API response
  for offline test runs.
- `.github/workflows/go-version-update.yaml`: automation workflow
  (workflow_dispatch + weekly schedule) that calls the script and
  creates/updates a PR as `opentdf-automation[bot]` with the `autobump`
  label.
- `.github/workflows/checks.yaml`: adds `trigger-go-version-update` job
  (dispatches the update workflow when govulncheck artifacts are found on
  push to main/release/**) and `script-tests` job (runs the BATS tests;
  added to the `ci` gate).
- `.policy.yml`: extends the `autobump` rule's branch pattern to also
  match `chore/bump-go-toolchain(-...)?` so bot PRs auto-merge on CI pass.
- `AGENTS.md`: documents that Go toolchain bumps should go through this
  automation rather than being done by hand in feature PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru dmihalcik-virtru requested review from a team as code owners April 7, 2026 18:49
@github-actions github-actions bot added comp:ci Github Actions Work size/l labels Apr 7, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Adds an automated Go toolchain bump flow: a new Bash script to update toolchain and go directives, Bats tests and fixtures, a scheduled/manual GitHub Actions workflow that selects target versions via the Go release API, CI/job updates to run the tests, policy regex tweak, and documentation describing the process.

Changes

Cohort / File(s) Summary
Script & Test Suite
​.github/scripts/bump-go-version.sh, ​.github/scripts/bump-go-version.bats, ​.github/scripts/fixtures/go-versions.json
New executable script to resolve/apply Go toolchain bumps (supports --dry-run, --target, API lookup, module/CI edits); comprehensive Bats tests exercising patch/minor/no-op/dry-run and workflow updates; JSON fixture of Go releases for tests.
Workflows
​.github/workflows/checks.yaml, ​.github/workflows/go-version-update.yaml
Adds script test job to checks.yaml and a new go-version-update.yaml workflow that fetches Go release data, decides target version, runs the bump script, commits changes, and creates/updates a PR.
Policy & Docs
​.policy.yml, AGENTS.md
Updates autobump branch-pattern to include chore/bump-go-toolchain(-<suffix>); documents Go toolchain pinning, automated bump process, and dry-run/manual commands.

Sequence Diagram

sequenceDiagram
    participant Scheduler as "GitHub Actions (scheduler/dispatch)"
    participant Workflow as "go-version-update.yaml"
    participant API as "go.dev download API"
    participant Script as "bump-go-version.sh"
    participant Repo as "Repository files (go.work, go.mod, workflows)"
    participant PR as "Pull Request"

    Scheduler->>Workflow: trigger (cron or workflow_dispatch)
    Workflow->>API: GET release JSON
    API-->>Workflow: release list
    Workflow->>Repo: read current toolchain from go.work
    Workflow->>Script: run (--target or resolved version)
    Script->>Repo: update go.work toolchain and optional go directive
    Script->>Repo: run go mod edit on module go.mod files
    Script->>Repo: update CI workflow YAMLs
    Script-->>Workflow: report diffs/changes
    Workflow->>Repo: commit changes on bump branch
    Workflow->>PR: create or update PR with changes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

size/m

Suggested reviewers

  • jhaage-virtru
  • pflynn-virtru

Poem

🐰 I hopped through files to patch and test,
I nudged the toolchain to its very best,
Workflows hum weekly, scripts skip a chore,
CI and PRs tidy the version floor —
A carrot-sized bump, and developers rest.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main objective of the changeset: automating Go toolchain version updates triggered by govulncheck failures.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-2565-golang-update

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

id: app-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with:
app-id: ${{ secrets.APP_ID }}
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements an automated lifecycle management system for the Go toolchain version across the monorepo. By integrating with govulncheck, the system proactively identifies when the project's Go version falls behind or becomes EOL, triggering an automated process to update the necessary configuration files. This reduces manual maintenance overhead and ensures the project remains on supported, secure toolchain versions.

Highlights

  • Automated Go Toolchain Updates: Introduced a new CI workflow that automatically detects outdated Go toolchain versions via govulncheck failures and opens PRs to bump to the latest supported version.
  • Tooling and Automation Script: Added a robust bash script (bump-go-version.sh) that manages updates across go.work, all go.mod files, and CI configuration files, complete with dry-run capabilities and BATS unit tests.
  • Policy and Documentation: Updated .policy.yml to allow auto-merging of bot-generated toolchain bump PRs and added documentation in AGENTS.md to standardize the update process.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/checks.yaml
    • .github/workflows/go-version-update.yaml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


The toolchain drifts as time goes by, We watch the govulncheck go dry. A script awakes to set it right, And keeps our builds both clean and bright.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds CI automation to detect govulncheck failures on protected branches and automatically open/update a PR that bumps the repo’s pinned Go toolchain version consistently across workspace/modules and CI workflows.

Changes:

  • Introduces a go-version-update workflow (scheduled + dispatchable) that bumps Go toolchain versions and opens/updates an autobump PR.
  • Adds a repo-wide bump-go-version.sh script (with BATS unit tests + fixtures) to update go.work, all go.mod files, and relevant workflow pins.
  • Extends CI (checks.yaml) to trigger the updater on govulncheck failure artifacts and to run script unit tests; updates policy/docs to reflect the new process.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
AGENTS.md Documents the new Go toolchain bump process and discourages manual edits in feature PRs.
.policy.yml Expands autobump branch pattern to include the new go-toolchain bump branches for auto-merge.
.github/workflows/go-version-update.yaml New workflow to compute latest Go version and create/update an automation PR.
.github/workflows/checks.yaml Adds a dispatcher job for go-version-update on govulncheck failures and a BATS script test job wired into the CI gate.
.github/scripts/fixtures/go-versions.json Provides a mock go.dev API response for offline/unit testing.
.github/scripts/bump-go-version.sh New script to bump toolchain/go directives across workspace/modules and sync workflow hardcoded versions.
.github/scripts/bump-go-version.bats Adds unit tests covering patch/minor bumps, EOL detection, dry-run behavior, and no-op exits.

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

Comment on lines +60 to +65
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true ;;
--target) TARGET_VERSION="$2"; shift ;;
--repo-root) REPO_ROOT="$2"; shift ;;
--api-url) API_URL="$2"; shift ;;
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Option parsing assumes a value exists for flags like --target/--repo-root/--api-url (e.g., TARGET_VERSION="$2") while set -u is enabled. Calling the script with a missing value will crash with an unbound-variable error rather than producing a clear usage message. Add an explicit check that $# -ge 2 (or that $2 is set) for these options and fail with a helpful error + usage output.

Suggested change
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true ;;
--target) TARGET_VERSION="$2"; shift ;;
--repo-root) REPO_ROOT="$2"; shift ;;
--api-url) API_URL="$2"; shift ;;
missing_option_value() {
echo "[ERROR] Missing value for option: $1" >&2
usage
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true ;;
--target)
[[ $# -ge 2 ]] || missing_option_value "$1"
TARGET_VERSION="$2"
shift
;;
--repo-root)
[[ $# -ge 2 ]] || missing_option_value "$1"
REPO_ROOT="$2"
shift
;;
--api-url)
[[ $# -ge 2 ]] || missing_option_value "$1"
API_URL="$2"
shift
;;

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +155
# Extract all distinct minor versions from stable releases, sorted ascending.
ALL_MINORS="$(
echo "$VERSIONS_JSON" \
| jq -r '[
.[].version
| ltrimstr("go")
| split(".")
| .[0:2]
| join(".")
] | unique | sort_by(split(".") | map(tonumber)) | .[]'
)"

LATEST_MINOR="$(echo "$ALL_MINORS" | tail -1)"
PREV_MINOR="$(echo "$ALL_MINORS" | tail -2 | head -1)"

NEEDS_MINOR_BUMP=false
if [[ "$CURRENT_MINOR" != "$LATEST_MINOR" && "$CURRENT_MINOR" != "$PREV_MINOR" ]]; then
log "Go ${CURRENT_MINOR} is no longer in the two most-recent supported minors" \
"(${PREV_MINOR}, ${LATEST_MINOR}); upgrading minor version."
TARGET_MINOR="$LATEST_MINOR"
NEEDS_MINOR_BUMP=true
else
TARGET_MINOR="$CURRENT_MINOR"
fi

# Latest patch release for the target minor.
LATEST_PATCH="$(
echo "$VERSIONS_JSON" \
| jq -r --arg prefix "go${TARGET_MINOR}." \
'[.[].version | select(startswith($prefix))] | first | ltrimstr("go")'
)"
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The go.dev download JSON includes entries where stable is false (betas/RCs). This jq query doesn’t filter on .stable == true, so the script can accidentally select a prerelease as the "latest" patch/minor. Filter to stable releases and ensure the patch selection picks the highest patch for the target minor (don’t rely on API ordering + first).

Copilot uses AI. Check for mistakes.
Comment on lines +249 to +251
diff -u "$orig" "$modified" \
--label "a/${rel}" \
--label "b/${rel}" \
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

diff --label is a GNU diff option and will fail on macOS/BSD diff, which makes --dry-run non-portable. Use BSD-compatible flags (e.g., diff -u -L a/... -L b/...) or omit labels so the dry-run works on both Linux and macOS as the script intends.

Suggested change
diff -u "$orig" "$modified" \
--label "a/${rel}" \
--label "b/${rel}" \
diff -u \
-L "a/${rel}" \
-L "b/${rel}" \
"$orig" "$modified" \

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +100
VERSIONS_JSON=$(curl -sf "https://go.dev/dl/?mode=json")

# Current toolchain from go.work (e.g. "1.25.8")
CURRENT=$(grep "^toolchain " go.work | sed 's/toolchain go//')
CURRENT_MINOR=$(echo "$CURRENT" | cut -d. -f1,2)

# All distinct minor versions in stable releases, sorted ascending.
ALL_MINORS=$(
echo "$VERSIONS_JSON" \
| jq -r '[
.[].version
| ltrimstr("go")
| split(".")
| .[0:2]
| join(".")
] | unique | sort_by(split(".") | map(tonumber)) | .[]'
)

LATEST_MINOR=$(echo "$ALL_MINORS" | tail -1)
PREV_MINOR=$(echo "$ALL_MINORS" | tail -2 | head -1)

TARGET_MINOR="$CURRENT_MINOR"
if [[ "$CURRENT_MINOR" != "$LATEST_MINOR" && "$CURRENT_MINOR" != "$PREV_MINOR" ]]; then
echo "Go ${CURRENT_MINOR} is EOL; upgrading to ${LATEST_MINOR}"
TARGET_MINOR="$LATEST_MINOR"
fi

LATEST_PATCH=$(
echo "$VERSIONS_JSON" \
| jq -r --arg prefix "go${TARGET_MINOR}." \
'[.[].version | select(startswith($prefix))] | first | ltrimstr("go")'
)
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The go.dev JSON feed contains non-stable releases (betas/RCs). The jq queries here don’t filter on stable == true, so this workflow can bump to a prerelease toolchain and open an automation PR that breaks CI. Filter to stable releases and make the patch selection compute the max patch for TARGET_MINOR rather than relying on API ordering + first.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 206.616473ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 105.816221ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 404.412813ms
Throughput 247.27 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.015692742s
Average Latency 418.126571ms
Throughput 119.00 requests/second

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an automated script (bump-go-version.sh) and its corresponding unit tests (bump-go-version.bats) to manage Go toolchain versions across the monorepo. The script updates go.work, go.mod files, and GitHub Actions workflows, supporting both patch and minor version bumps, including EOL minor version upgrades. Documentation (AGENTS.md) and policy (.policy.yml) are updated to reflect this automation. Feedback suggests improving the script's robustness by dynamically discovering Go modules instead of using a hardcoded list, adding timeouts to the curl command for API calls to prevent hanging, and making the jq filter for selecting the latest patch version more resilient to potential API response sorting changes.

Comment on lines +41 to +52
MODULE_DIRS=(
examples
sdk
service
lib/fixtures
lib/flattening
lib/identifier
lib/ocrypto
protocol/go
tests-bdd
test/integration
)
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.

medium

The list of module directories is hardcoded, which creates a maintenance burden. Any new module added to the repository in the future will be skipped by this automation unless this script is manually updated. Consider dynamically discovering all subdirectories that contain a go.mod file to ensure the toolchain remains consistent across the entire monorepo.

fi
else
log "Fetching Go release list from ${API_URL}"
VERSIONS_JSON="$(curl -sf "$API_URL")"
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.

medium

The curl command is missing a timeout. In a CI/CD environment, network issues or an unresponsive API could cause the workflow to hang indefinitely. It is recommended to add --connect-timeout and --max-time to ensure the script fails gracefully.

Suggested change
VERSIONS_JSON="$(curl -sf "$API_URL")"
VERSIONS_JSON="$(curl -sf --connect-timeout 5 --max-time 10 "$API_URL")"

LATEST_PATCH="$(
echo "$VERSIONS_JSON" \
| jq -r --arg prefix "go${TARGET_MINOR}." \
'[.[].version | select(startswith($prefix))] | first | ltrimstr("go")'
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.

medium

The jq filter uses first to select the latest patch version, which assumes the API response is always sorted in descending order. While this is currently true for the Go release API, explicitly sorting the versions numerically (e.g., ensuring 1.25.10 is recognized as newer than 1.25.9) makes the script more robust against potential changes in the API's response format.

Suggested change
'[.[].version | select(startswith($prefix))] | first | ltrimstr("go")'
'[.[].version | select(startswith($prefix))] | sort_by(ltrimstr("go") | split(".") | map(tonumber)) | last | ltrimstr("go")'

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.policy.yml (1)

98-107: ⚠️ Potential issue | 🟠 Major

Add opentdf-automation[bot] to has_contributor_in.

The new workflow commits as opentdf-automation[bot] (lines 131–132 of .github/workflows/go-version-update.yaml), but the autobump rule's has_contributor_in only allows github-actions[bot]. Since this condition evaluates commit authors/committers, the PRs created by this workflow won't satisfy the autobump rule without updating it.

Suggested fix
       has_contributor_in:
         users:
           - "github-actions[bot]"
+          - "opentdf-automation[bot]"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.policy.yml around lines 98 - 107, The autobump rule's has_contributor_in
list only allows "github-actions[bot]" but the workflow commits are
authored/committed by "opentdf-automation[bot]"; update the rule by adding
"opentdf-automation[bot]" to the has_contributor_in users array so the autobump
condition matches those workflow-created PRs (modify the has_contributor_in
block alongside has_author_in within the autobump rule to include the new bot).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/bump-go-version.sh:
- Around line 165-169: The current early-exit check using CURRENT ==
LATEST_PATCH is unsafe because apply_changes_to() also updates workflow files;
change the no-op logic to detect whether any managed files (e.g., go.work plus
.github/workflows/checks.yaml and .github/workflows/sonarcloud.yml that
apply_changes_to() touches) would be modified rather than only comparing CURRENT
and LATEST_PATCH, so replace the CURRENT/LATEST_PATCH equality check with a
dry-run or diff step that simulates apply_changes_to() and only exits when no
files would change; update the bump-go-version.sh logic accordingly (referencing
the CURRENT, LATEST_PATCH variables and apply_changes_to() call) and add a Bats
regression test that simulates "drift-only" (go.work already at LATEST_PATCH but
workflow pins differ) to ensure the script does not early-exit.

In @.github/workflows/checks.yaml:
- Around line 661-664: Disable setup-go's module caching in the script-tests job
by adding the cache setting to the actions/setup-go step: locate the
actions/setup-go usage (uses:
actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5) in the script-tests
job and add with: cache: false so the step does not restore/save Go module cache
during those Bats tests.
- Around line 624-629: The trigger-go-version-update job is skipped when the
prior go job fails, hiding the previously uploaded govulncheck-failure-*
artifact; update the trigger-go-version-update job (job name:
trigger-go-version-update) to include an unconditional job-level guard by adding
if: always() (while preserving the existing event/ref checks) so this job runs
even when the go job fails and the artifact was produced.

In @.github/workflows/go-version-update.yaml:
- Around line 44-48: The run block in the "Determine base branch" step (id:
base) is interpolating ${{ inputs.base_branch }} directly into the shell which
is unsafe; instead, pass the input through env: (e.g., BASE_BRANCH: ${{
inputs.base_branch || 'main' }}), read it in the run script from the
environment, validate it using git check-ref-format --branch "$BASE_BRANCH" and
then echo the validated value to GITHUB_OUTPUT, and apply the same env
indirection pattern wherever you read dynamic values from
steps.versions.outputs.* and steps.base.outputs.branch in later run steps so
those values are not directly expanded into shell commands.

---

Outside diff comments:
In @.policy.yml:
- Around line 98-107: The autobump rule's has_contributor_in list only allows
"github-actions[bot]" but the workflow commits are authored/committed by
"opentdf-automation[bot]"; update the rule by adding "opentdf-automation[bot]"
to the has_contributor_in users array so the autobump condition matches those
workflow-created PRs (modify the has_contributor_in block alongside
has_author_in within the autobump rule to include the new bot).
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 81f2dfaa-302f-4ae5-b5d8-f4d3a6a05e46

📥 Commits

Reviewing files that changed from the base of the PR and between ee8177c and a5da3c4.

📒 Files selected for processing (7)
  • .github/scripts/bump-go-version.bats
  • .github/scripts/bump-go-version.sh
  • .github/scripts/fixtures/go-versions.json
  • .github/workflows/checks.yaml
  • .github/workflows/go-version-update.yaml
  • .policy.yml
  • AGENTS.md

Comment on lines +165 to +169
# ── Early exit if already current ─────────────────────────────────────────────

if [[ "$CURRENT" == "$LATEST_PATCH" ]]; then
log "Already at Go ${LATEST_PATCH}; nothing to do."
exit 2
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

CURRENT == LATEST_PATCH is not a safe no-op check.

apply_changes_to() also rewrites .github/workflows/checks.yaml and .github/workflows/sonarcloud.yml, so a repo can still need updates even when go.work is already on the latest toolchain. With this check, drift in those CI pins is treated as “already current”; the mirrored up_to_date logic in .github/workflows/go-version-update.yaml then skips the script entirely. Base the no-op path on whether any managed file would actually change, and add a Bats regression case for the drift-only scenario.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/bump-go-version.sh around lines 165 - 169, The current
early-exit check using CURRENT == LATEST_PATCH is unsafe because
apply_changes_to() also updates workflow files; change the no-op logic to detect
whether any managed files (e.g., go.work plus .github/workflows/checks.yaml and
.github/workflows/sonarcloud.yml that apply_changes_to() touches) would be
modified rather than only comparing CURRENT and LATEST_PATCH, so replace the
CURRENT/LATEST_PATCH equality check with a dry-run or diff step that simulates
apply_changes_to() and only exits when no files would change; update the
bump-go-version.sh logic accordingly (referencing the CURRENT, LATEST_PATCH
variables and apply_changes_to() call) and add a Bats regression test that
simulates "drift-only" (go.work already at LATEST_PATCH but workflow pins
differ) to ensure the script does not early-exit.

Comment on lines +624 to +629
trigger-go-version-update:
if: |
!cancelled() &&
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))
needs: go
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In GitHub Actions, if a job has needs: another-joband anif:condition withoutalways(), is it skipped when another-job fails?

💡 Result:

Yes. By default, if a job listed in needs: fails, any jobs that need it are skipped unless you use a conditional that explicitly allows continuing. [1]

Also, an if: condition that doesn’t include a status-check function is treated as if it were prefixed with success(), so it won’t run after a failed dependency unless you add something like always() / failure() / etc. [2]

Example to run anyway:

if: ${{ always() && <your condition> }}

Sources: [1] (docs.github.com) [2] (docs.github.com)

Citations:


🏁 Script executed:

cat -n .github/workflows/checks.yaml | sed -n '620,680p'

Repository: opentdf/platform

Length of output: 2491


🏁 Script executed:

grep -n "govulncheck-failure" .github/workflows/checks.yaml

Repository: opentdf/platform

Length of output: 581


🏁 Script executed:

cat -n .github/workflows/checks.yaml | sed -n '50,150p'

Repository: opentdf/platform

Length of output: 4859


Use always() on the dispatch job to prevent skipping when unrelated lint/test failures occur.

The govulncheck-failure-* artifact is uploaded at line 85-88 (when govulncheck fails), but golangci-lint and subsequent tests run after (lines 90-117). If any of these later steps fail, the go job fails. Since trigger-go-version-update has needs: go without always(), the job is skipped whenever go fails—even though the govulncheck artifact was successfully uploaded. This suppresses the automation when it should run.

Suggested fix
   trigger-go-version-update:
     if: |
+      always() &&
       !cancelled() &&
       github.event_name == 'push' &&
       (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
trigger-go-version-update:
if: |
!cancelled() &&
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))
needs: go
trigger-go-version-update:
if: |
always() &&
!cancelled() &&
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))
needs: go
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/checks.yaml around lines 624 - 629, The
trigger-go-version-update job is skipped when the prior go job fails, hiding the
previously uploaded govulncheck-failure-* artifact; update the
trigger-go-version-update job (job name: trigger-go-version-update) to include
an unconditional job-level guard by adding if: always() (while preserving the
existing event/ref checks) so this job runs even when the go job fails and the
artifact was produced.

dmihalcik-virtru and others added 2 commits April 7, 2026 15:29
- Script: guard option flags against missing values (--target, --repo-root,
  --api-url) with a clear error message rather than crashing on unbound var
- Script/workflow: filter .stable == true in all jq queries to exclude betas
  and release candidates from version selection
- Script/workflow: sort by version numerically and take last entry instead of
  relying on API response ordering (guard against go1.25.10 > go1.25.9)
- Script: add --connect-timeout 5 --max-time 30 to curl to prevent hangs
- Script: replace GNU-only diff --label with portable -L flags
- Workflow: move all ${{ }} template expansions in run: blocks to env: vars
  to prevent code injection (zizmor finding)
- Fixture: add go1.26rc1 (stable: false) entry; add BATS test verifying
  prereleases are excluded from version selection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.AUTOMATION_KEY }}
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 194.63287ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 95.23669ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 384.824602ms
Throughput 259.86 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.135409624s
Average Latency 400.079715ms
Throughput 124.58 requests/second

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
.github/scripts/bump-go-version.sh (1)

179-184: ⚠️ Potential issue | 🟠 Major

Early exit skips YAML drift fixes when toolchain is already current.

The check CURRENT == LATEST_PATCH exits early without calling apply_changes_to(). However, the CI workflow YAMLs (.github/workflows/checks.yaml and .github/workflows/sonarcloud.yml) might still have outdated versions that need updating. This creates a scenario where the toolchain is current but YAMLs remain stale.

Consider checking whether any managed file would change before declaring "nothing to do":

Suggested approach
-if [[ "$CURRENT" == "$LATEST_PATCH" ]]; then
-  log "Already at Go ${LATEST_PATCH}; nothing to do."
-  exit 2
-fi
+# Check if any files would actually change (handles YAML-only drift)
+TMPDIR_CHECK="$(mktemp -d)"
+trap 'rm -rf "$TMPDIR_CHECK"' EXIT
+while IFS= read -r rel; do
+  local_file="${REPO_ROOT}/${rel}"
+  if [[ -f "$local_file" ]]; then
+    mkdir -p "${TMPDIR_CHECK}/$(dirname "$rel")"
+    cp "$local_file" "${TMPDIR_CHECK}/${rel}"
+  fi
+done < <(target_files)
+
+apply_changes_to "$TMPDIR_CHECK"
+
+HAS_CHANGES=false
+while IFS= read -r rel; do
+  if [[ -f "${REPO_ROOT}/${rel}" && -f "${TMPDIR_CHECK}/${rel}" ]]; then
+    if ! diff -q "${REPO_ROOT}/${rel}" "${TMPDIR_CHECK}/${rel}" > /dev/null 2>&1; then
+      HAS_CHANGES=true
+      break
+    fi
+  fi
+done < <(target_files)
+
+if [[ "$HAS_CHANGES" == "false" ]]; then
+  log "All files already at target; nothing to do."
+  exit 2
+fi

This requires moving target_files() and apply_changes_to() above this check.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/bump-go-version.sh around lines 179 - 184, The early-exit
compares CURRENT and LATEST_PATCH and returns before running target_files() /
apply_changes_to(), so YAML workflow files may remain stale; move the calls to
target_files() and apply_changes_to() above the CURRENT == LATEST_PATCH check
and replace the unconditional exit with a conditional: run target_files() to
collect managed files, run a dry-run or diff via apply_changes_to() (or have
apply_changes_to() return whether it would modify any file), and only log
"nothing to do" and exit when both the toolchain is current (CURRENT ==
LATEST_PATCH) AND apply_changes_to() reports no file changes; keep references to
CURRENT, LATEST_PATCH, target_files(), and apply_changes_to() to locate the
logic.
.github/workflows/checks.yaml (1)

624-629: ⚠️ Potential issue | 🟠 Major

Add always() to ensure dispatch runs even when unrelated lint/test failures occur.

The trigger-go-version-update job depends on go via needs: go. If govulncheck fails and uploads an artifact (lines 84-88), but a later step in go (like golangci-lint or tests) also fails, the entire go job fails. Without always() in the if: condition, this job is skipped—even though the govulncheck artifact was successfully uploaded.

Suggested fix
   trigger-go-version-update:
     if: |
+      always() &&
       !cancelled() &&
       github.event_name == 'push' &&
       (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/checks.yaml around lines 624 - 629, The
trigger-go-version-update job is currently skipped when its dependency job
(needs: go) fails even if govulncheck uploaded artifacts; update the job's if
expression to include always() so the job still runs regardless of failures in
its predecessors. Specifically modify the if condition for the
trigger-go-version-update job (which currently checks !cancelled(),
github.event_name and github.ref) to add always() at the start of the expression
so the job runs even when the go job fails after govulncheck; keep the existing
checks for event and ref intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/bump-go-version.bats:
- Around line 179-189: Add a new Bats test that exercises the YAML-only drift
case: call build_repo with the repo toolchain set to the requested target (e.g.,
"1.25.9") but leave the workflow YAMLs at an older version, then run the SCRIPT
with --target "1.25.9" and assert the script exits success and updates the YAMLs
(grep for go-version-input and go-version equal to the target). Ensure the new
test mirrors existing tests (use the same local root setup and build_repo
helper) but does not rely on a toolchain bump so it will catch the early-exit
behavior in bump-go-version.sh (the branch that currently returns a no-op when
toolchain is current) and verifies YAML-only updates are performed.

In @.github/workflows/go-version-update.yaml:
- Around line 37-42: Add an environment protection by specifying environment:
automation at the job level that contains the "Obtain app token" step (the step
with id "app-token" that uses actions/create-github-app-token and reads
secrets.APP_ID and secrets.AUTOMATION_KEY); create the "automation" environment
in repo settings with the desired protection rules, then add environment:
automation to the job so the step runs under that protected environment.

---

Duplicate comments:
In @.github/scripts/bump-go-version.sh:
- Around line 179-184: The early-exit compares CURRENT and LATEST_PATCH and
returns before running target_files() / apply_changes_to(), so YAML workflow
files may remain stale; move the calls to target_files() and apply_changes_to()
above the CURRENT == LATEST_PATCH check and replace the unconditional exit with
a conditional: run target_files() to collect managed files, run a dry-run or
diff via apply_changes_to() (or have apply_changes_to() return whether it would
modify any file), and only log "nothing to do" and exit when both the toolchain
is current (CURRENT == LATEST_PATCH) AND apply_changes_to() reports no file
changes; keep references to CURRENT, LATEST_PATCH, target_files(), and
apply_changes_to() to locate the logic.

In @.github/workflows/checks.yaml:
- Around line 624-629: The trigger-go-version-update job is currently skipped
when its dependency job (needs: go) fails even if govulncheck uploaded
artifacts; update the job's if expression to include always() so the job still
runs regardless of failures in its predecessors. Specifically modify the if
condition for the trigger-go-version-update job (which currently checks
!cancelled(), github.event_name and github.ref) to add always() at the start of
the expression so the job runs even when the go job fails after govulncheck;
keep the existing checks for event and ref intact.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1845c76d-f65b-4e17-803a-417921d57f64

📥 Commits

Reviewing files that changed from the base of the PR and between a5da3c4 and f37a566.

📒 Files selected for processing (5)
  • .github/scripts/bump-go-version.bats
  • .github/scripts/bump-go-version.sh
  • .github/scripts/fixtures/go-versions.json
  • .github/workflows/checks.yaml
  • .github/workflows/go-version-update.yaml

Comment on lines +179 to +189
@test "CI YAML files are updated unconditionally even if they lag the toolchain" {
local root="${BATS_TEST_TMPDIR}/repo"
# Repo toolchain is 1.25.8 but YAML files still reference 1.25.7
build_repo "$root" "1.25.8" "1.25.0"

run "$SCRIPT" --repo-root "$root" --target "1.25.9"
[ "$status" -eq 0 ]

grep -q 'go-version-input: "1.25.9"' "${root}/.github/workflows/checks.yaml"
grep -q 'go-version: "1.25.9"' "${root}/.github/workflows/sonarcloud.yml"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Test does not cover pure YAML-drift scenario.

This test verifies YAML files are updated when the toolchain also needs bumping (1.25.8 → 1.25.9). However, it doesn't cover the case where go.work is already at the target (e.g., 1.25.9) but the YAML files still reference an older version (e.g., 1.25.7). The script's early exit at line 181-184 of bump-go-version.sh would skip updates in that scenario.

Consider adding a test like:

`@test` "YAML-only drift is updated even when toolchain is current" {
  local root="${BATS_TEST_TMPDIR}/repo"
  # Toolchain at 1.25.9 but YAMLs still at 1.25.7 (via build_repo default)
  build_repo "$root" "1.25.9" "1.25.0"

  run "$SCRIPT" --repo-root "$root" --target "1.25.9"
  # Current behavior: exits 2 (no-op) - is this intended?
  # If YAML drift should be fixed, expect exit 0 and updated YAMLs
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/bump-go-version.bats around lines 179 - 189, Add a new Bats
test that exercises the YAML-only drift case: call build_repo with the repo
toolchain set to the requested target (e.g., "1.25.9") but leave the workflow
YAMLs at an older version, then run the SCRIPT with --target "1.25.9" and assert
the script exits success and updates the YAMLs (grep for go-version-input and
go-version equal to the target). Ensure the new test mirrors existing tests (use
the same local root setup and build_repo helper) but does not rely on a
toolchain bump so it will catch the early-exit behavior in bump-go-version.sh
(the branch that currently returns a no-op when toolchain is current) and
verifies YAML-only updates are performed.

Comment on lines +37 to +42
- name: Obtain app token
id: app-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.AUTOMATION_KEY }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding an environment for secret protection.

The workflow accesses secrets.APP_ID and secrets.AUTOMATION_KEY without a dedicated environment. While functionally correct, using an environment (e.g., environment: automation) would enable environment protection rules, required reviewers, or deployment gates for additional security.

Suggested change
   update:
     name: bump Go toolchain
     runs-on: ubuntu-22.04
+    environment: automation
     permissions:
       contents: write
       pull-requests: write

This requires creating the automation environment in repository settings with appropriate protection rules.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Obtain app token
id: app-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.AUTOMATION_KEY }}
update:
name: bump Go toolchain
runs-on: ubuntu-22.04
environment: automation
permissions:
contents: write
pull-requests: write
🧰 Tools
🪛 GitHub Check: zizmor

[warning] 41-41:
secrets referenced without a dedicated environment


[warning] 42-42:
secrets referenced without a dedicated environment

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/go-version-update.yaml around lines 37 - 42, Add an
environment protection by specifying environment: automation at the job level
that contains the "Obtain app token" step (the step with id "app-token" that
uses actions/create-github-app-token and reads secrets.APP_ID and
secrets.AUTOMATION_KEY); create the "automation" environment in repo settings
with the desired protection rules, then add environment: automation to the job
so the step runs under that protected environment.

…ce of truth

Remove the `toolchain` directive from all go.mod files. The Go spec makes
this directive local-only (it never affects downstream consumers), and in a
workspace the go.work toolchain takes precedence. Experimentally verified
that `go mod tidy` does not re-add it.

Replace all hardcoded Go version strings in CI workflows with
`go-version-file: go.work`:
- checks.yaml govulncheck: `go-version-input: ""` + `go-version-file: go.work`
- sonarcloud.yml: `go-version-file: go.work`

Update work-init.sh to preserve the toolchain directive when regenerating
go.work for release branches, so govulncheck continues to read the correct
version.

Simplify bump-go-version.sh: patch bumps now update only go.work (1 file
instead of 13). Minor bumps additionally update go directives in go.mod
files. No YAML edits needed in either case.

Before: patch bump touched go.work + 10 go.mod + 2 YAML = 13 files
After:  patch bump touches go.work = 1 file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru dmihalcik-virtru requested a review from a team as a code owner April 8, 2026 18:46
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 189.966899ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 90.836678ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 424.535261ms
Throughput 235.55 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.058453526s
Average Latency 419.103972ms
Throughput 118.88 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

@dmihalcik-virtru dmihalcik-virtru marked this pull request as draft April 9, 2026 12:45
@dmihalcik-virtru
Copy link
Copy Markdown
Member Author

This seems far too complicated. I've instead proposed #3285 to simplify the amount of work that needs to happen to update the golang target, which maybe will make workflow simpler or, better yet, unnecessary

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

Labels

comp:ci Github Actions Work size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants