Skip to content

chore: release main #1098

chore: release main

chore: release main #1098

Workflow file for this run

name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
pull_request_review_comment:
types: [created]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
issues: write
id-token: write
jobs:
dep-update-check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
dependency_only: ${{ steps.check.outputs.dependency_only }}
steps:
- uses: actions/github-script@v7
id: check
with:
script: |
const pr = context.payload.pull_request;
if (!pr) {
core.setOutput("dependency_only", "false");
return;
}
const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
per_page: 100,
});
const patterns = [
/(^|\/)package\.json$/,
/(^|\/)bun\.lockb?$/,
/(^|\/)package-lock\.json$/,
/(^|\/)pnpm-lock\.yaml$/,
/(^|\/)yarn\.lock$/,
/(^|\/)Cargo\.toml$/,
/(^|\/)Cargo\.lock$/,
/(^|\/)go\.mod$/,
/(^|\/)go\.sum$/,
/(^|\/)requirements.*\.txt$/,
/(^|\/)pyproject\.toml$/,
/(^|\/)poetry\.lock$/,
/(^|\/)Pipfile(\.lock)?$/,
/(^|\/)Gemfile(\.lock)?$/,
/(^|\/)composer\.(json|lock)$/,
/(^|\/)(build|settings)\.gradle(\.kts)?$/,
/(^|\/)gradle\.lockfile$/,
/(^|\/)gradle\/libs\.versions\.toml$/,
];
const isDependencyFile = (filename) => patterns.some((re) => re.test(filename));
const dependencyOnly = files.length > 0 && files.every((file) => isDependencyFile(file.filename));
core.setOutput("dependency_only", dependencyOnly ? "true" : "false");
# Automatic review on new/updated PRs
claude-code-review:
# Only run for PRs from shepherdjerred on PR events (not comments)
if: |
github.event_name == 'pull_request' &&
github.event.pull_request.user.login == 'shepherdjerred' &&
needs.dep-update-check.outputs.dependency_only != 'true'
needs: [dep-update-check]
runs-on: [monorepo-runner-set]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
- uses: 1password/load-secrets-action/configure@v2
with:
connect-host: http://onepassword-connect.1password.svc.cluster.local:8080
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
- uses: 1password/load-secrets-action@v2
with:
export-env: true
env:
CLAUDE_CODE_OAUTH_TOKEN: op://bic45kuflnwsnxnd67dzcnxjze/5p65mbzr237yyzt2sfnfao3a5a/CLAUDE_CODE_OAUTH_TOKEN
- name: Extract kubectl version
id: kubectl-version
run: |
KUBECTL_VERSION=v1.34.1
echo "version=$KUBECTL_VERSION" >> "$GITHUB_OUTPUT"
- name: Cache kubectl
uses: actions/cache@v4
id: kubectl-cache
with:
path: ~/.local/bin/kubectl
key: kubectl-${{ steps.kubectl-version.outputs.version }}-linux-amd64
- name: Install kubectl
if: steps.kubectl-cache.outputs.cache-hit != 'true'
run: |
mkdir -p ~/.local/bin
curl -LO "https://dl.k8s.io/release/${{ steps.kubectl-version.outputs.version }}/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl ~/.local/bin/
- name: Add kubectl to PATH
run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Extract Dagger version
id: dagger-version
run: |
DAGGER_IMAGE=$(kubectl get pod --selector=name=dagger-dagger-helm-engine --namespace=dagger -o jsonpath='{.items[0].spec.containers[0].image}')
DAGGER_VERSION="${DAGGER_IMAGE##*:v}"
echo "version=$DAGGER_VERSION" >> "$GITHUB_OUTPUT"
- name: Cache Dagger CLI
uses: actions/cache@v4
id: dagger-cache
with:
path: ~/.local/bin/dagger
key: dagger-${{ steps.dagger-version.outputs.version }}-linux-amd64
- name: Install Dagger CLI
if: steps.dagger-cache.outputs.cache-hit != 'true'
run: |
set -euo pipefail
DAGGER_VERSION="${{ steps.dagger-version.outputs.version }}"
BIN_DIR="$HOME/.local/bin"
# Try primary source first
if ! curl -fsSL https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION="$DAGGER_VERSION" BIN_DIR="$BIN_DIR" sh; then
echo "WARNING: Primary source (dl.dagger.io) failed, trying GitHub releases..."
# Fallback to GitHub releases
mkdir -p "$BIN_DIR"
DAGGER_URL="https://github.com/dagger/dagger/releases/download/v${DAGGER_VERSION}/dagger_v${DAGGER_VERSION}_linux_amd64.tar.gz"
echo "Downloading from: $DAGGER_URL"
curl -fsSL "$DAGGER_URL" | tar xz -C /tmp
mv /tmp/dagger "$BIN_DIR/dagger"
chmod +x "$BIN_DIR/dagger"
fi
# Verify installation
if [ ! -f "$BIN_DIR/dagger" ]; then
echo "ERROR: Dagger CLI installation failed"
exit 1
fi
"$BIN_DIR/dagger" version
- name: Get Dagger Engine Pod Name
run: |
DAGGER_ENGINE_POD_NAME="$(kubectl get pod --selector=name=dagger-dagger-helm-engine --namespace=dagger --output=jsonpath='{.items[0].metadata.name}')"
echo "_EXPERIMENTAL_DAGGER_RUNNER_HOST=kube-pod://$DAGGER_ENGINE_POD_NAME?namespace=dagger" >> "$GITHUB_ENV"
- name: Install Dagger module dependencies
working-directory: .dagger
run: bun install --frozen-lockfile
- name: Run Dagger code review
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BASE_BRANCH: ${{ github.event.pull_request.base.ref }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
dagger call code-review \
--source=. \
--github-token=env:GH_TOKEN \
--claude-oauth-token=env:CLAUDE_CODE_OAUTH_TOKEN \
--pr-number="$PR_NUMBER" \
--base-branch="$BASE_BRANCH" \
--head-sha="$HEAD_SHA"
# Interactive responses to @claude mentions in comments
claude-interactive:
# Only run for comments from shepherdjerred that mention @claude
if: |
(github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment') &&
github.event.comment.user.login == 'shepherdjerred' &&
contains(github.event.comment.body, '@claude')
runs-on: [monorepo-runner-set]
# Cancel in-progress runs for the same PR to avoid duplicate responses
concurrency:
group: claude-interactive-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
- uses: 1password/load-secrets-action/configure@v2
with:
connect-host: http://onepassword-connect.1password.svc.cluster.local:8080
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
- uses: 1password/load-secrets-action@v2
with:
export-env: true
env:
CLAUDE_CODE_OAUTH_TOKEN: op://bic45kuflnwsnxnd67dzcnxjze/5p65mbzr237yyzt2sfnfao3a5a/CLAUDE_CODE_OAUTH_TOKEN
- name: Extract kubectl version
id: kubectl-version
run: |
KUBECTL_VERSION=v1.34.1
echo "version=$KUBECTL_VERSION" >> "$GITHUB_OUTPUT"
- name: Cache kubectl
uses: actions/cache@v4
id: kubectl-cache
with:
path: ~/.local/bin/kubectl
key: kubectl-${{ steps.kubectl-version.outputs.version }}-linux-amd64
- name: Install kubectl
if: steps.kubectl-cache.outputs.cache-hit != 'true'
run: |
mkdir -p ~/.local/bin
curl -LO "https://dl.k8s.io/release/${{ steps.kubectl-version.outputs.version }}/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl ~/.local/bin/
- name: Add kubectl to PATH
run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Extract Dagger version
id: dagger-version
run: |
DAGGER_IMAGE=$(kubectl get pod --selector=name=dagger-dagger-helm-engine --namespace=dagger -o jsonpath='{.items[0].spec.containers[0].image}')
DAGGER_VERSION="${DAGGER_IMAGE##*:v}"
echo "version=$DAGGER_VERSION" >> "$GITHUB_OUTPUT"
- name: Cache Dagger CLI
uses: actions/cache@v4
id: dagger-cache
with:
path: ~/.local/bin/dagger
key: dagger-${{ steps.dagger-version.outputs.version }}-linux-amd64
- name: Install Dagger CLI
if: steps.dagger-cache.outputs.cache-hit != 'true'
run: |
set -euo pipefail
DAGGER_VERSION="${{ steps.dagger-version.outputs.version }}"
BIN_DIR="$HOME/.local/bin"
# Try primary source first
if ! curl -fsSL https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION="$DAGGER_VERSION" BIN_DIR="$BIN_DIR" sh; then
echo "WARNING: Primary source (dl.dagger.io) failed, trying GitHub releases..."
# Fallback to GitHub releases
mkdir -p "$BIN_DIR"
DAGGER_URL="https://github.com/dagger/dagger/releases/download/v${DAGGER_VERSION}/dagger_v${DAGGER_VERSION}_linux_amd64.tar.gz"
echo "Downloading from: $DAGGER_URL"
curl -fsSL "$DAGGER_URL" | tar xz -C /tmp
mv /tmp/dagger "$BIN_DIR/dagger"
chmod +x "$BIN_DIR/dagger"
fi
# Verify installation
if [ ! -f "$BIN_DIR/dagger" ]; then
echo "ERROR: Dagger CLI installation failed"
exit 1
fi
"$BIN_DIR/dagger" version
- name: Get Dagger Engine Pod Name
run: |
DAGGER_ENGINE_POD_NAME="$(kubectl get pod --selector=name=dagger-dagger-helm-engine --namespace=dagger --output=jsonpath='{.items[0].metadata.name}')"
echo "_EXPERIMENTAL_DAGGER_RUNNER_HOST=kube-pod://$DAGGER_ENGINE_POD_NAME?namespace=dagger" >> "$GITHUB_ENV"
- name: Install Dagger module dependencies
working-directory: .dagger
run: bun install --frozen-lockfile
- name: Resolve PR number
id: pr-number
run: |
# For issue_comment events, the PR number is in github.event.issue.number
# For pull_request_review_comment events, it's in github.event.pull_request.number
PR_NUMBER="${{ github.event.issue.number || github.event.pull_request.number }}"
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
- name: Run Dagger interactive review
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Pass user-controlled inputs through environment variables for safety
# Dagger's env: prefix treats these as secrets, preventing injection
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_PATH: ${{ github.event.comment.path }}
COMMENT_LINE: ${{ github.event.comment.line }}
COMMENT_DIFF_HUNK: ${{ github.event.comment.diff_hunk }}
PR_NUMBER: ${{ steps.pr-number.outputs.number }}
run: |
ARGS=(
--source=.
--github-token=env:GH_TOKEN
--claude-oauth-token=env:CLAUDE_CODE_OAUTH_TOKEN
--pr-number="$PR_NUMBER"
--comment-body=env:COMMENT_BODY
)
# Add optional context for review comments (using env vars for safety)
if [ -n "$COMMENT_PATH" ]; then
ARGS+=(--comment-path="$COMMENT_PATH")
fi
if [ -n "$COMMENT_LINE" ]; then
ARGS+=(--comment-line="$COMMENT_LINE")
fi
if [ -n "$COMMENT_DIFF_HUNK" ]; then
ARGS+=(--comment-diff-hunk="$COMMENT_DIFF_HUNK")
fi
dagger call code-review-interactive "${ARGS[@]}"