Skip to content
TilloTech Docs

How to add Harbourmaster reviews to a repository

!WARNING This process is currently invite-only. Tillo will announce when this changes.

Add one native Harbourmaster review job to pull requests from branches in the repository. The job guards forks and drafts, ensures the harbourmaster-review label is present, and runs the latest Harbourmaster version merged to the EOS main branch.

An eligible pull request is reviewed automatically only when harbourmaster-review is absent. The job adds the label before reviewing, so later commits do not start another review. Removing and re-adding the label requests another review for the current head.

Prerequisites

Before changing the consuming repository, confirm that:

  • the repository can use actions from TilloTech/eos;
  • the repository uses GitHub-hosted runners.

!IMPORTANT HARBOURMASTER_AWS_ROLE_TO_ASSUME is configured globally for all team repos. The ARN identifies the role but does not grant access to it. OIDC supplies the short-lived AWS credentials at runtime.

The role must allow bedrock-mantle:CreateInference, bedrock-mantle:GetProject, and bedrock-mantle:ListProjects in us-east-1. The action fixes the AWS region to us-east-1 for the bundled GPT-5.6 Terra and Luna models.

Add the workflow

Create .github/workflows/harbourmaster-review.yml:

yaml
name: Harbourmaster review

on:
  pull_request:
    types: [opened, reopened, ready_for_review, synchronize, labeled]

permissions: {}

concurrency:
  group: harbourmaster-review-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  review:
    name: Harbourmaster review
    if: >
      github.event.pull_request.draft == false &&
      github.event.pull_request.head.repo.full_name == github.repository && (
        github.event.action != 'labeled' ||
        github.event.label.name == 'harbourmaster-review'
      )
    permissions:
      contents: read
      id-token: write
      issues: write
      pull-requests: write
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Require a new Harbourmaster review
        if: >
          github.event.action != 'labeled' && contains(
            github.event.pull_request.labels.*.name,
            'harbourmaster-review'
          )
        run: |
          echo "::warning title=Human Harbourmaster re-review required::" \
            "This head is unreviewed. A human must remove and re-add the" \
            "harbourmaster-review label to request a re-review."
          exit 1

      - name: Apply harbourmaster-review label
        if: github.event.action != 'labeled'
        env:
          GH_TOKEN: ${{ github.token }}
          LABEL: harbourmaster-review
          PR: ${{ github.event.pull_request.number }}
          REPO: ${{ github.repository }}
        run: |
          set -euo pipefail

          if ! gh api "repos/${REPO}/labels/${LABEL}" >/dev/null 2>&1; then
            gh label create "$LABEL" \
              --repo "$REPO" \
              --description "Trigger Harbourmaster review" \
              --color "0E8A16" ||
              gh api "repos/${REPO}/labels/${LABEL}" >/dev/null
          fi

          jq -n --arg label "$LABEL" '{labels: [$label]}' |
            gh api \
              --method POST \
              "repos/${REPO}/issues/${PR}/labels" \
              --input - \
              >/dev/null

      - name: Checkout reviewed pull request head
        uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          persist-credentials: false

      - name: Run Harbourmaster reviewer
        uses: TilloTech/eos/apps/harbourmaster@main
        with:
          repo: ${{ github.repository }}
          pull_number: ${{ github.event.pull_request.number }}
          head_sha: ${{ github.event.pull_request.head.sha }}
          mode: comment
          strict_runtime: "true"
          github_token: ${{ github.token }}
          aws_role_to_assume: ${{ vars.HARBOURMASTER_AWS_ROLE_TO_ASSUME }}
          aws_profile: ${{ vars.HARBOURMASTER_AWS_PROFILE }}
          aws_bearer_token_bedrock: ${{ secrets.AWS_BEARER_TOKEN_BEDROCK }}

A new synchronize event can cancel an active review for an older head. The head_sha input uses github.event.pull_request.head.sha, so the action reviews the event head.

The job-level guard blocks fork and draft pull requests before checkout. While harbourmaster-review is present, automatic events fail the native check before review execution. A human must remove and re-add the label to review the latest head. Automation must not request that re-review.

Consumer repositories must use TilloTech/eos/apps/harbourmaster@main. Do not copy the EOS-local ./apps/harbourmaster action reference. For the EOS self-review exception, see The shared-action trust boundary.

See How to request a Harbourmaster review after the workflow is in place. See the GitHub Action reference for inputs and permissions.

Validate the setup

Open a non-draft pull request from a branch in the consuming repository. One native Harbourmaster review check should appear on the pull request. Opening that check should show the label, checkout, and reviewer steps. The workflow should apply harbourmaster-review, publish a Harbourmaster AI Review with a COMMENT event, and finish successfully.

Push another commit while harbourmaster-review is present and confirm that the native check fails with a warning without running the reviewer. Remove and re-add the label as a human operator, then confirm that it reviews the new head SHA and replaces the failure with a successful check.

Mark a pull request as draft or open one from a fork. The review job should be skipped before checkout.

!NOTE Harbourmaster reviews are advisory. Keep the repository's normal build, type-check, test, lint, formatting, documentation, and link checks enabled.

If a later check is skipped or fails, see How to diagnose a Harbourmaster review failure.