Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/chatops-dispatcher.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: ChatOps Dispatcher
on:
issue_comment:
types: [created]

jobs:
dispatch:
runs-on: ubuntu-latest
steps:
- name: Slash Command Dispatch
uses: peter-evans/slash-command-dispatch@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commands: lgtm
# 1. Basic Security: Only allow users with 'write' access to even trigger this
permission: write
issue-type: pull-request
reactions: false
149 changes: 149 additions & 0 deletions .github/workflows/lgtm-commad.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# ============================================================================
# LGTM Command Worker
# ============================================================================
# Handles /lgtm commands from chatops-dispatcher
#
# Flow:
# 1. User comments /lgtm on PR
# 2. chatops-dispatcher catches it and dispatches here
# 3. This workflow:
# - Verifies user is in OWNERS file
# - Checks if PR is draft
# - Checks for blocking labels (hold/wip/do-not-merge)
# - Adds lgtm label
# - Waits 5 minutes (allows gatekeeper to run)
# - Enables auto-merge
# ============================================================================

name: LGTM Command Worker
on:
repository_dispatch:
types: [lgtm-command]

jobs:
apply-lgtm:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4

# -----------------------------------------------------------------------
# STEP 1: AUTHORIZATION - Verify user is in OWNERS file
# -----------------------------------------------------------------------
# Only users listed as approvers in OWNERS can use /lgtm
# This prevents unauthorized users from approving PRs
- name: Check Permissions
id: check
env:
ACTOR: ${{ github.event.client_payload.github.actor }}
run: |
if grep -q "^\s*-\s*$ACTOR\s*$" OWNERS; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This checks the entire OWNERS file?
I think there are different groups in it so this should only be from reviewers or maintainers?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should! It looks like that block was accidentally removed during a previous refactoring cycle. I missed it, but I will restore it now. Thanks for catching that.

echo "authorized=true" >> $GITHUB_OUTPUT
else
echo "::error::User $ACTOR is not an approver."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
echo "::error::User $ACTOR is not an approver."
echo "::error:: User $ACTOR is not an approver."

nit: adding space after ::error:: could make it easier to read.
If you decide to change, please change the same format across all error messages.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks will change.

exit 1
fi

# -----------------------------------------------------------------------
# STEP 2: VALIDATION - Check if PR is in draft mode
# -----------------------------------------------------------------------
# Draft PRs cannot be approved - they must be marked ready for review
# This prevents accidental approval of incomplete work
- name: Check Draft Status
if: steps.check.outputs.authorized == 'true'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to bail out in an earlier step (when not authorized) instead of repeating the check in all steps?
if the repetition is required than steps following this should also check that the PR is not in draft, etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into that. Thanks

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.client_payload.github.payload.issue.number }}
REPO: ${{ github.repository }}
run: |
IS_DRAFT=$(gh pr view $PR_NUMBER --repo "$REPO" --json isDraft --jq '.isDraft')
if [ "$IS_DRAFT" = "true" ]; then
echo "::error::Cannot LGTM a Draft PR."
gh issue comment $PR_NUMBER --repo "$REPO" --body "⚠️ **LGTM Failed**: PR is a Draft."
exit 1
fi

# -----------------------------------------------------------------------
# STEP 3: BLOCKING LABELS - Check for hold/wip/do-not-merge
# -----------------------------------------------------------------------
# If any blocking label exists, fail immediately
# This prevents approving PRs that are explicitly marked as not ready
- name: Check for Blocking Labels
if: steps.check.outputs.authorized == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.client_payload.github.payload.issue.html_url }}
run: |
LABELS=$(gh pr view "$PR_URL" --json labels --jq '.labels[].name')
if echo "$LABELS" | grep -Eiq "^(hold|wip|do-not-merge)$"; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: consider making these a variable at the top of the step for easier changed in the future

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure will do that Thanks

echo "::error::PR is blocked by label."
gh issue comment "$PR_URL" --body " **Merge Blocked**: Please remove the \`hold\`, \`wip\`, or \`do-not-merge\` label before merging."
exit 1
fi

# -----------------------------------------------------------------------
# STEP 4: APPLY LGTM - Add label, wait, then enable auto-merge
# -----------------------------------------------------------------------
# 1. Add lgtm label (triggers gatekeeper to validate)
# 2. Wait 5 minutes (gives time for:
# - Gatekeeper to run and validate
# - CI checks to start
# - Early failure detection)
# 3. Enable auto-merge (PR will merge when all checks pass)
- name: Apply Label & Merge
if: steps.check.outputs.authorized == 'true'
env:
GH_TOKEN: ${{ secrets.BOT_TOKEN }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: how do we issue and maintain a bot token? who owns it (e.g., user associated, expiration time, ...)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to investigate how to properly configure a Personal Access Token (PAT) for this repository.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the workflows to use a GitHub App via tibdex/github-app-token@v1, which generates short-lived access tokens automatically. This eliminates the need for a dedicated, long-lived Personal Access Token (PAT) and ensures that bot-triggered events successfully spawn subsequent workflow runs.

PR_NUMBER: ${{ github.event.client_payload.github.payload.issue.number }}
PR_URL: ${{ github.event.client_payload.github.payload.issue.html_url }}
run: |
# Apply lgtm label
if ! gh issue edit "$PR_NUMBER" --add-label "lgtm"; then
echo "::error::Failed to add lgtm label"
gh issue comment "$PR_URL" --body " **Error**: Failed to add lgtm label to the PR."
exit 1
fi

echo "Waiting 5 minutes before setting auto-merge..."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the sleep required?
having a job wait for 5m slows down the loop. Is there a way to structure the events so the wait is not needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, its not needed and can be removed. I wanted to give the pr writer or other approver an opportunity to take a final look at the checks or the code before the merge sequence officially started when the testing is finishes quickly. I will remove it.

echo "Current time: $(date)"
sleep 300
echo "Wait completed at: $(date)"

# Enable auto-merge with error handling
if ! gh pr merge --auto --squash "$PR_URL" 2>&1 | tee merge_output.txt; then
echo "::error::Failed to enable auto-merge"
ERROR_MSG=$(cat merge_output.txt)
gh issue comment "$PR_URL" --body " **Auto-merge failed**: Could not enable auto-merge on this PR.

**Error details:**
\`\`\`
$ERROR_MSG
\`\`\`

**Common reasons:**
- Branch protection rules not satisfied
- Required status checks not passing
- Merge conflicts present
- Auto-merge not enabled for this repository

Please check the PR status and try again, or merge manually."
exit 1
fi

echo "✅ Auto-merge enabled successfully"
gh issue comment "$PR_URL" --body "✅ **LGTM**: Auto-merge has been enabled. The PR will merge automatically once all checks pass."


# -----------------------------------------------------------------------
# STEP 5: FEEDBACK - Add reaction to comment
# -----------------------------------------------------------------------
# Visual confirmation that the command was processed successfully
- name: React Rocket
if: success()
uses: peter-evans/create-or-update-comment@v3
with:
comment-id: ${{ github.event.client_payload.github.payload.comment.id }}
reactions: rocket
42 changes: 42 additions & 0 deletions .github/workflows/lgtm-gatekeeper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ============================================================================
# LGTM Gatekeeper - Required Status Check
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: there seems to be quite a bit of overlap between this file and the previous. Can you explain how they differ and what purpuse they serve.

Copy link
Author

@revit13 revit13 Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generated a diagram hope it helps to clarify.
output

# ============================================================================
# Rules Enforced:
# 1. PR MUST have "lgtm" label
# 2. PR MUST NOT have blocking labels (hold, wip, do-not-merge)
# ============================================================================

name: LGTM Gatekeeper
on:
pull_request:
# Run on PR open/reopen and label changes
# NOT on synchronize (handled by lgtm-reset.yml)
types: [opened, labeled, unlabeled, reopened]

jobs:
validate-pr:
runs-on: ubuntu-latest
steps:
- name: Enforce LGTM & Blockers
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
run: |
# Fetch current labels
LABELS=$(gh pr view $PR_NUMBER --repo "$REPO" --json labels --jq '.labels[].name')

# Check 1: IS IT BLOCKED?
if echo "$LABELS" | grep -Eiq "^(hold|wip|do-not-merge)$"; then
echo "::error::⛔ FAILED: PR is blocked by a 'hold', 'wip', or 'do-not-merge' label."
exit 1
fi

# Check 2: IS IT APPROVED?
# If Reset workflow removed the label, this check fails immediately.
if ! echo "$LABELS" | grep -Fqx "lgtm"; then
echo "::error::⛔ FAILED: PR is missing the 'lgtm' label."
exit 1
fi

echo "✅ PASSED: LGTM present and no blockers."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: missing newline at end of file

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks will fix that.

39 changes: 39 additions & 0 deletions .github/workflows/lgtm-reset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ============================================================================
# LGTM Reset - Auto-Remove LGTM on New Commits
# ============================================================================
# Kubernetes Prow behavior: When new commits are pushed, approval is invalidated
#
# What It Does:
# 1. Detects when new commits are pushed to a PR
# 2. Removes the "lgtm" label (if present)
# 3. Disables auto-merge (safety net)
# 4. Posts a comment explaining why
# ============================================================================

name: LGTM Reset
on:
pull_request:
types: [synchronize] # Triggers instantly on new commits

jobs:
reset-lgtm:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Invalidate LGTM
env:
GH_TOKEN: ${{ secrets.BOT_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
run: |
echo "🚨 New code pushed. Resetting LGTM status..."

# 1. Remove the label (This triggers the Gatekeeper to run again)
gh pr edit $PR_NUMBER --repo "$REPO" --remove-label "lgtm" || true

# 2. Disable Auto-Merge (Safety net)
gh pr merge --disable-auto $PR_NUMBER --repo "$REPO" || true

# 3. Notify user
gh issue comment $PR_NUMBER --repo "$REPO" --body "🔄 **Reset**: New commits pushed. LGTM removed."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline at end of file

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks will fix that.

3 changes: 1 addition & 2 deletions .github/workflows/prow-github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
steps:
- uses: jpmcb/prow-github-actions@v2.0.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
github-token: "${{ secrets.BOT_TOKEN }}"
prow-commands: "/assign
/unassign
/approve
Expand All @@ -27,7 +27,6 @@ jobs:
/kind
/priority
/remove
/lgtm
/close
/reopen
/lock
Expand Down
18 changes: 0 additions & 18 deletions .github/workflows/prow-pr-automerge.yml

This file was deleted.

11 changes: 0 additions & 11 deletions .github/workflows/prow-pr-remove-lgtm.yml

This file was deleted.

Loading