Skip to content

H-6528: Add approval-freshness check for merge queue events #157

H-6528: Add approval-freshness check for merge queue events

H-6528: Add approval-freshness check for merge queue events #157

# Check TODO Linear Tickets
#
# Searches for TODO comments in the codebase that reference Linear ticket IDs
# found in the PR title. Fails if any are found, as they should be resolved
# before the associated ticket is marked as done.
name: Todo Comments
on:
pull_request:
paths:
- ".github/workflows/preflight-todo-comments.yml"
pull_request_target:
merge_group:
workflow_call:
permissions:
contents: read
jobs:
scan:
name: Scan
runs-on: ubuntu-24.04
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
steps:
- name: Checkout PR head
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install ripgrep
run: |
if ! command -v rg &> /dev/null; then
sudo apt-get update && sudo apt-get install -y ripgrep
fi
- name: Extract ticket IDs from PR title
id: extract-tickets
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
echo "PR Title: $PR_TITLE"
PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
TICKETS=$(echo "$PREFIX" | grep -oiE '[A-Z]+-[0-9]+' | tr '[:lower:]' '[:upper:]' | sort -u | tr '\n' ' ')
if [[ -z "$TICKETS" ]]; then
echo "No ticket IDs found in PR title"
echo "tickets=" >> "$GITHUB_OUTPUT"
echo "has_tickets=false" >> "$GITHUB_OUTPUT"
else
echo "Found ticket IDs: $TICKETS"
echo "tickets=$TICKETS" >> "$GITHUB_OUTPUT"
echo "has_tickets=true" >> "$GITHUB_OUTPUT"
fi
- name: Search for TODO comments with ticket IDs
if: steps.extract-tickets.outputs.has_tickets == 'true'
env:
TICKETS: ${{ steps.extract-tickets.outputs.tickets }}
run: |
echo "Searching for TODO comments containing ticket IDs: $TICKETS"
FOUND_TODOS=""
EXIT_CODE=0
for TICKET in $TICKETS; do
echo ""
echo "=========================================="
echo "Searching for references to $TICKET..."
echo "=========================================="
SINGLE_LINE=$(rg -in "todo.*${TICKET}([^[:alnum:]-]|$)|${TICKET}([^[:alnum:]-]|$).*todo" .) || {
rc=$?
if [[ $rc -ne 1 ]]; then
echo "::error::ripgrep failed with exit code $rc"
exit $rc
fi
}
MULTILINE=$(rg -inU \
-e "todo[\s\S]{0,300}linear\.app/[^/]+/issue/${TICKET}([^[:alnum:]-]|$)" \
-e "linear\.app/[^/]+/issue/${TICKET}([^[:alnum:]-]|$)[\s\S]{0,300}todo" \
.) || {
rc=$?
if [[ $rc -ne 1 ]]; then
echo "::error::ripgrep failed with exit code $rc"
exit $rc
fi
}
MATCHES=$(echo -e "${SINGLE_LINE}\n${MULTILINE}" | grep -v '^$' | sort -u) || true
if [[ -n "$MATCHES" ]]; then
echo "::error::Found TODO comments or Linear URLs referencing $TICKET:"
echo "$MATCHES"
FOUND_TODOS="${FOUND_TODOS}### ${TICKET}"$'\n'"${MATCHES}"$'\n\n'
EXIT_CODE=1
else
echo "No TODO comments found for $TICKET"
fi
done
if [[ $EXIT_CODE -eq 1 ]]; then
echo ""
echo "::error::TODOs associated with tickets in this PR were found in the codebase."
echo "::error::Please resolve these TODOs before merging, as the associated ticket(s) will be marked as done."
echo ""
echo "## Found TODO comments" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "The following TODO comments reference ticket IDs from this PR's title." >> "$GITHUB_STEP_SUMMARY"
echo "Please resolve these TODOs before merging, as the associated ticket(s) will be marked as done." >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
echo "$FOUND_TODOS" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
exit 1
fi
echo "No TODO comments found for any ticket IDs in the PR title"