Skip to content

chore(go): bump go version and golang.org/x dependencies #423

chore(go): bump go version and golang.org/x dependencies

chore(go): bump go version and golang.org/x dependencies #423

# Copyright (c) 2025 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Reviewer-bot — follow-up: responds to replies on the reviewer's own threads
# (verifies the fix against the PR diff, then resolves or pushes back). Completes
# the conversation half of the loop: reviewer-bot posts findings -> engineer-bot
# replies/fixes -> this re-checks and resolves.
#
# ⚠️ DRAFT / NOT YET FUNCTIONAL. Requires (see .bot/SETUP.md):
# - secrets BOT_ENGINE_PAT, REVIEW_BOT_APP_ID/PRIVATE_KEY (DATABRICKS_HOST + DATABRICKS_TOKEN already exist in adbc CI)
# - the reviewer-bot App needs Contents: READ & WRITE (not just Read): the
# resolveReviewThread mutation is gated behind Contents:write, NOT
# Pull-requests:write (GitHub gotcha). Pull requests: Read & write too.
#
# Self-contained (a cross-org `uses:` of the hub's internal composite action does
# NOT work) — installs the engine via the PAT + the Claude SDK/CLI inline.
# Supply-chain pin: ENGINE_REF in the install step is pinned to an immutable commit SHA
# (never @main); claude-agent-sdk / @anthropic-ai/claude-code are unpinned to match the hub.
# When the engine repo goes public, drop the PAT (anonymous install) but keep ENGINE_REF pinned.
name: Reviewer Bot — Follow-up
on:
# Fast path: a new inline reply on a thread.
pull_request_review_comment:
types: [created]
# Reliable fallback: GitHub does NOT guarantee a workflow run for every
# automation-generated review_comment, so the comment event alone silently
# drops threads. The engineer-bot's fix always pushes -> synchronize -> the
# catch-up sweep re-checks ALL open threads and self-heals the missed event.
pull_request:
types: [synchronize]
permissions:
contents: read # the App token (Contents R/W) does the resolve mutation
pull-requests: write # the App token posts inline replies
id-token: write # model OIDC, if your endpoint uses it; drop otherwise
concurrency:
# One followup per PR; queue (don't cancel). Catch-up mode means the survivor
# sweeps ALL open threads, so cancelled queued runs are harmless.
group: reviewer-bot-followup-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
followup:
# SECURITY: skip fork PRs — keep model/LLM secrets out of untrusted code's reach.
# Same `review-bot` label gate as reviewer-bot.yml — the follow-up only acts on
# PRs the reviewer was allowed to review.
if: >-
github.event.pull_request.head.repo.fork == false
&& github.event.pull_request.state == 'open'
&& contains(github.event.pull_request.labels.*.name, 'review-bot')
runs-on: [self-hosted, Linux, X64, peco-driver]
timeout-minutes: 15
steps:
- name: Mint review-bot App token
id: app-token
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0
with:
app-id: ${{ secrets.REVIEW_BOT_APP_ID }}
private-key: ${{ secrets.REVIEW_BOT_PRIVATE_KEY }}
# Cheap pre-checkout filter — skip the heavy checkout/install when the event
# is provably a no-op. followup.py re-checks everything (source of truth), so
# this is purely a cost filter + defense in depth.
- name: Cheap pre-checkout filter
id: filter
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
IN_REPLY_TO: ${{ github.event.comment.in_reply_to_id }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
# synchronize fallback: no trigger comment — its job is the catch-up
# sweep. The sweep only acts on OPEN threads that already have a reply,
# so a push to a PR the bot never touched no-ops after an expensive
# setup. One GraphQL call counts reply-bearing open threads; skip iff a
# confident, complete count of 0 (truncated page -> "more" -> run).
if [ "${{ github.event_name }}" != "pull_request_review_comment" ]; then
reply_threads=$(gh api graphql \
-f query='query($owner:String!,$repo:String!,$pr:Int!){
repository(owner:$owner,name:$repo){
pullRequest(number:$pr){
reviewThreads(first:100){
pageInfo{ hasNextPage }
nodes{ isResolved comments(last:1){ nodes{ replyTo{ id } } } }
}
}
}
}' \
-f owner="${REPO%/*}" -f repo="${REPO#*/}" -F pr="$PR_NUMBER" \
--jq '.data.repository.pullRequest.reviewThreads as $t
| ([$t.nodes[]
| select(.isResolved == false)
| select(.comments.nodes[0].replyTo != null)] | length) as $n
| if $t.pageInfo.hasNextPage and $n == 0 then "more" else ($n | tostring) end' \
2>/dev/null) || reply_threads=""
if [ "$reply_threads" = "0" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "reason=synchronize fallback: no open review thread has a reply — sweep would no-op" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# review_comment path:
# Filter 1: must be a reply to another inline comment (a thread reply).
if [ -z "$IN_REPLY_TO" ] || [ "$IN_REPLY_TO" = "null" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "reason=no in_reply_to_id (top-level review comment, not a thread reply)" >> "$GITHUB_OUTPUT"
exit 0
fi
# Filter 2: skip our own followup / reconcile replies (loop prevention, MARKER-based).
if printf '%s' "$COMMENT_BODY" | grep -q '<!-- pr-review-bot:v1 followup'; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "reason=trigger comment is itself a bot follow-up (loop prevention)" >> "$GITHUB_OUTPUT"
exit 0
fi
if printf '%s' "$COMMENT_BODY" | grep -q '<!-- pr-review-bot:v1 reconcile -->'; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "reason=trigger comment is itself a bot reconcile reply (loop prevention)" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "skip=false" >> "$GITHUB_OUTPUT"
- name: Announce skip in step summary
if: steps.filter.outputs.skip == 'true'
run: |
{
echo "## Reviewer Bot — Follow-up"
echo ""
echo "**Skipped:** ${{ steps.filter.outputs.reason }}"
} >> "$GITHUB_STEP_SUMMARY"
- name: Checkout
if: steps.filter.outputs.skip != 'true'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
# The followup reads this checkout (grep/read); keep the GITHUB_TOKEN
# OUT of .git/config so it can't be read+leaked. The followup only POSTS
# via the minted App token; it never uses the checkout's git creds.
persist-credentials: false
- name: Setup Python
if: steps.filter.outputs.skip != 'true'
shell: bash
# actions/setup-python can't provision on this self-hosted runner
# (no hosted tool-cache). The runner is provisioned with system
# python3.11; use it via a venv so pip installs stay isolated and
# `pip` / `python -m` resolve to 3.11 for the later steps.
run: |
python3.11 -m venv "$RUNNER_TEMP/bot-venv"
echo "$RUNNER_TEMP/bot-venv/bin" >> "$GITHUB_PATH"
- name: Install bot engine (interim PAT git-install) + Claude SDK/CLI
if: steps.filter.outputs.skip != 'true'
env:
ENGINE_PAT: ${{ secrets.BOT_ENGINE_PAT }}
# SUPPLY-CHAIN PIN: the engine is pinned to an immutable commit SHA — never
# install from the force-pushable `@main` ref in a secret-bearing job. Bump
# ENGINE_REF to adopt engine changes (prefer a release tag once the engine
# repo cuts one). claude-agent-sdk / @anthropic-ai/claude-code are left
# unpinned to match the hub (databricks-driver-test); pin them to exact
# versions here if you want full reproducibility.
ENGINE_REF: 5fbcee18e479c58656a94e7704dabfe7edaf2b26
run: |
set -euo pipefail
: "${ENGINE_REF:?pin the engine to a tag/SHA before activation (refusing @main)}"
python -m pip install --upgrade pip
# Drop the `x-access-token:${ENGINE_PAT}@` prefix once the engine repo is public; ENGINE_REF stays pinned.
pip install "databricks-bot-engine @ git+https://x-access-token:${ENGINE_PAT}@github.com/databricks/databricks-bot-engine@${ENGINE_REF}"
pip install claude-agent-sdk
# Global npm dir (/usr/local/lib) is root-owned on the self-hosted
# runner; install to a per-job prefix the runner user owns and put
# it on PATH so later steps find the `claude` CLI the SDK shells to.
export NPM_CONFIG_PREFIX="$RUNNER_TEMP/npm-global"
mkdir -p "$NPM_CONFIG_PREFIX/bin"
npm install -g @anthropic-ai/claude-code
echo "$RUNNER_TEMP/npm-global/bin" >> "$GITHUB_PATH"
- name: Run follow-up agent
if: steps.filter.outputs.skip != 'true'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
TRIGGER_COMMENT_ID: ${{ github.event.comment.id }}
# SHA range for the PR — restricts `git show` to commits in this PR
# (allowlist for the reviewer's SHA-diff verification).
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
# Model serving on the same Databricks workspace as adbc's CI: DATABRICKS_HOST is
# the bare hostname hosting the databricks-claude-opus-4-8 serving endpoint;
# DATABRICKS_TOKEN authenticates it (Bearer). Both already exist as adbc CI secrets.
MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/databricks-claude-opus-4-8/invocations
REPO_RULES_FILES: csharp/CLAUDE.md,rust/CLAUDE.md # adbc keeps conventions per-language (no root CLAUDE.md)
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
DRY_RUN: 'false'
RUNNER_TEMP: ${{ runner.temp }}
run: python -m databricks_bot_engine.reviewer_bot.followup