feat: migrate 11 standalone repos into monorepo #1089
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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[@]}" |