fix: address review findings
CI / test (pull_request) Successful in 14s
CI / review (pull_request) Successful in 5m3s

- install.sh: verify SHA-256 checksum before installing binary
- install.sh: fallback to ~/.local/bin if /usr/local/bin not writable
- install.sh: use sed instead of grep for POSIX-safe JSON parsing
- release.yml: remove jq dependency, parse release ID with sed
- llm: make temperature configurable via --llm-temperature / LLM_TEMPERATURE
- llm: add WithTemperature builder method on Client
- llm: omit temperature from request when zero (uses server default)
This commit is contained in:
Rodin
2026-05-01 11:22:31 -07:00
parent b6277216f7
commit 4b3cac66c3
4 changed files with 82 additions and 9 deletions
+15 -5
View File
@@ -38,17 +38,27 @@ jobs:
GITEA_URL="${{ github.server_url }}"
REPO="${{ github.repository }}"
# Create release
RELEASE_ID=$(curl -sSf -X POST \
# Create release (parse ID without jq using grep/sed)
RESPONSE=$(curl -sSf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases" \
-d "{\"tag_name\": \"${VERSION}\", \"name\": \"${VERSION}\", \"body\": \"Release ${VERSION}\", \"draft\": false, \"prerelease\": false}" \
| jq -r '.id')
-d "{\"tag_name\": \"${VERSION}\", \"name\": \"${VERSION}\", \"body\": \"Release ${VERSION}\", \"draft\": false, \"prerelease\": false}")
RELEASE_ID=$(echo "$RESPONSE" | sed -n 's/.*"id":\([0-9]*\).*/\1/p' | head -1)
if [ -z "$RELEASE_ID" ]; then
echo "Failed to create release" >&2
echo "$RESPONSE" >&2
exit 1
fi
echo "Created release ID: ${RELEASE_ID}"
# Upload each asset
for file in dist/*; do
filename=$(basename "$file")
echo "Uploading ${filename}..."
curl -sSf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/octet-stream" \
@@ -56,4 +66,4 @@ jobs:
--data-binary "@${file}"
done
echo "Release ${VERSION} created with $(ls dist/* | wc -l) assets"
echo "Release ${VERSION} created with assets"
+14
View File
@@ -28,6 +28,7 @@ func main() {
llmModel := flag.String("llm-model", envOrDefault("LLM_MODEL", ""), "LLM model name")
conventionsFile := flag.String("conventions-file", envOrDefault("CONVENTIONS_FILE", ""), "Conventions file path in repo (e.g. CLAUDE.md)")
dryRun := flag.Bool("dry-run", false, "Print review to stdout instead of posting")
llmTemp := flag.Float64("llm-temperature", envOrDefaultFloat("LLM_TEMPERATURE", 0), "LLM temperature (0 = server default)")
flag.Parse()
@@ -55,6 +56,9 @@ func main() {
// Initialize clients
giteaClient := gitea.NewClient(*giteaURL, *reviewerToken)
llmClient := llm.NewClient(*llmBaseURL, *llmAPIKey, *llmModel)
if *llmTemp > 0 {
llmClient.WithTemperature(*llmTemp)
}
log.Printf("Reviewing PR #%d on %s/%s", prNumber, owner, repoName)
@@ -169,3 +173,13 @@ func envOrDefault(key, defaultVal string) string {
}
return defaultVal
}
func envOrDefaultFloat(key string, defaultVal float64) float64 {
if v := os.Getenv(key); v != "" {
f, err := strconv.ParseFloat(v, 64)
if err == nil {
return f
}
}
return defaultVal
}
+44 -4
View File
@@ -6,7 +6,18 @@ set -euo pipefail
GITEA_URL="${GITEA_URL:-https://gitea.weiker.me}"
REPO="rodin/review-bot"
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
INSTALL_DIR="${INSTALL_DIR:-}"
# Determine install directory with fallback
if [ -z "$INSTALL_DIR" ]; then
if [ -w /usr/local/bin ]; then
INSTALL_DIR="/usr/local/bin"
else
INSTALL_DIR="${HOME}/.local/bin"
mkdir -p "$INSTALL_DIR"
echo "Note: Installing to $INSTALL_DIR (add to PATH if needed)"
fi
fi
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
@@ -18,8 +29,8 @@ esac
BINARY="review-bot-${OS}-${ARCH}"
# Get latest release tag
LATEST=$(curl -sSf "${GITEA_URL}/api/v1/repos/${REPO}/releases?limit=1" | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4)
# Get latest release tag (POSIX-safe parsing without jq)
LATEST=$(curl -sSf "${GITEA_URL}/api/v1/repos/${REPO}/releases?limit=1" | sed -n 's/.*"tag_name":"\([^"]*\)".*/\1/p' | head -1)
if [ -z "$LATEST" ]; then
echo "Failed to determine latest release" >&2
@@ -29,7 +40,36 @@ fi
echo "Installing review-bot ${LATEST} (${OS}/${ARCH})..."
DOWNLOAD_URL="${GITEA_URL}/${REPO}/releases/download/${LATEST}/${BINARY}"
curl -sSfL -o "${INSTALL_DIR}/review-bot" "$DOWNLOAD_URL"
CHECKSUM_URL="${GITEA_URL}/${REPO}/releases/download/${LATEST}/checksums.txt"
# Download binary and checksums
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
curl -sSfL -o "${TMPDIR}/${BINARY}" "$DOWNLOAD_URL"
curl -sSfL -o "${TMPDIR}/checksums.txt" "$CHECKSUM_URL"
# Verify checksum
cd "$TMPDIR"
EXPECTED=$(grep "${BINARY}" checksums.txt | awk '{print $1}')
ACTUAL=$(sha256sum "${BINARY}" | awk '{print $1}')
if [ -z "$EXPECTED" ]; then
echo "Error: no checksum found for ${BINARY} in checksums.txt" >&2
exit 1
fi
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo "Error: checksum mismatch!" >&2
echo " Expected: $EXPECTED" >&2
echo " Actual: $ACTUAL" >&2
exit 1
fi
echo "Checksum verified ✓"
# Install
cp "${TMPDIR}/${BINARY}" "${INSTALL_DIR}/review-bot"
chmod +x "${INSTALL_DIR}/review-bot"
echo "Installed review-bot ${LATEST} to ${INSTALL_DIR}/review-bot"
+9
View File
@@ -14,6 +14,7 @@ type Client struct {
BaseURL string
APIKey string
Model string
Temperature float64
HTTP *http.Client
}
@@ -27,6 +28,13 @@ func NewClient(baseURL, apiKey, model string) *Client {
}
}
// WithTemperature sets the temperature for LLM requests.
// If not set (zero value), the server default is used.
func (c *Client) WithTemperature(t float64) *Client {
c.Temperature = t
return c
}
// Message represents a chat message.
type Message struct {
Role string `json:"role"`
@@ -53,6 +61,7 @@ type ChatResponse struct {
func (c *Client) Complete(messages []Message) (string, error) {
reqBody := ChatRequest{
Model: c.Model,
Temperature: c.Temperature,
Messages: messages,
}