Skip to content

ci: add direct-push detector sentinel (replaces #68)#89

Merged
adm01-debug merged 1 commit into
mainfrom
chore/add-direct-push-sentinel
May 8, 2026
Merged

ci: add direct-push detector sentinel (replaces #68)#89
adm01-debug merged 1 commit into
mainfrom
chore/add-direct-push-sentinel

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 8, 2026

Resumo

Adiciona um workflow CI complementar que detecta pushes diretos em main sem padrão de PR/bot/release — defesa em profundidade junto com a regra de branch protection do GitHub.

Substitui PR #68 (fechado)

O #68 tentava criar um arquivo branch-protection-sentinel.yml mas esse nome já está ocupado em main por um sentinel diferente (que checa qualidade — console.log e :any count > 200 em PRs). Mergear o #68 sobrescreveria o sentinel de qualidade.

Solução: arquivo renomeado pra branch-protection-direct-push.yml — os dois coexistem.

Diferenças vs sentinel existente

Arquivo Trigger Função
branch-protection-sentinel.yml (já em main) pull_request Checa qualidade do código (console.log, :any count)
branch-protection-direct-push.yml (este PR) push para main Verifica padrão de commit (PR/bot/release)

O que o workflow faz

Roda em push em main e em workflow_dispatch. Inspeciona o último commit:

Padrão Ação
Mensagem termina com (#NNN) (squash merge) ✅ ok
Mensagem começa com Merge pull request #NNN ✅ ok
Autor é github-actions[bot], dependabot[bot], lovable-dev[bot], ou renovate[bot] ✅ ok
Mensagem começa com chore(release): ✅ ok
Nada do acima ❌ falha (exit 1) com aviso no STEP_SUMMARY

Test plan

  • YAML estruturalmente válido (sem tabs, indentação consistente)
  • Branch criada de main@7b1f478e (atualizada)
  • CI rodar em PR (não dispara nada — workflow só roda em push para main)
  • Após merge: o próprio merge commit dispara o workflow → primeiro run válida que ele detecta squash merges corretamente
  • Branch protection rule do GitHub ainda precisa ser ativada na UI (ver docs/BRANCH_PROTECTION.md)

Notas

  • Lógica copiada do PR Claude/p1 branch protection policy #68, apenas com name: ajustado e 4 linhas de comentário explicando coexistência
  • O sentinel não bloqueia force-pushes diretamente — isso só a branch protection rule pode fazer. Mas detecta e alerta no Actions tab + via email/notificação.

Summary by CodeRabbit

  • Chores
    • Adicionada verificação automatizada que detecta pushes diretos na branch principal, com exceções para merges de PRs, commits de bots autorizados e commits de release.

Add a complementary CI sentinel that runs on push to main and verifies
the latest commit follows expected merge patterns: PR squash merge,
PR merge commit, oficial bot, or release commit. Falls into failure
state for direct pushes that don't match.

Defense-in-depth alongside the GitHub branch protection rule and the
existing branch-protection-sentinel.yml (which checks code quality
on PRs — different responsibility).

Replaces obsolete PR #68. Renamed file to avoid name collision with
the quality sentinel that now lives in main.
Copilot AI review requested due to automatic review settings May 8, 2026 16:41
@vercel
Copy link
Copy Markdown

vercel Bot commented May 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
zapp-web Ready Ready Preview, Comment May 8, 2026 4:42pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

Walkthrough

Novo workflow GitHub Actions que detecta e bloqueia pushes diretos não-autorizados em main. Valida commits como merges de PR, commits de bots aprovados ou releases; rejeita outros padrões com anotação de erro e guia para configurações de proteção.

Changes

Proteção de Branch — Detector de Push Direto

Layer / Arquivo(s) Resumo
Configuração de Workflow
.github/workflows/branch-protection-direct-push.yml
Workflow que roda em push para main e dispatch manual, extrai mensagem e autor do commit, valida contra padrões permitidos (squash merge (#N), merge commit Merge pull request #N``, bots github-actions[bot], `dependabot[bot]`, `lovable-dev[bot]`, `renovate[bot]`, release `chore(release):`), e falha com anotação de erro + resumo direcionado a branch protection para qualquer outro padrão.

Estimated code review effort

🎯 2 (Simples) | ⏱️ ~8 minutos

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título reflete com precisão a mudança principal: adicionar um workflow de detecção de push direto, sendo específico quanto ao propósito (direct-push detector sentinel) e ao contexto (substitui #68).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/add-direct-push-sentinel

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25ae0c2af8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +35 to +40
if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi

if echo "$MSG" | head -1 | grep -qE '^Merge pull request #[0-9]+'; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow PRs merged with rebase

If the repository has GitHub’s “Rebase and merge” option enabled, a legitimate PR merge lands as the PR’s individual commits without a Merge pull request line or appended (#NNN) squash title, so this check will classify that valid PR merge as a direct push and fail the main-branch workflow. Either disable rebase merges in repo settings/documentation or add a way to recognize the push as PR-originated instead of only accepting squash/merge-commit message formats.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/branch-protection-direct-push.yml:
- Around line 26-27: The script currently sets AUTHOR from the commit metadata
using git log --pretty=%an which is spoofable; change the AUTHOR assignment to
use the authenticated actor value provided by GitHub Actions (GITHUB_ACTOR /
github.actor) instead of git log --pretty=%an so bots cannot be impersonated;
update the assignment that references AUTHOR to pull from the environment
variable (e.g., AUTHOR from GITHUB_ACTOR) and leave MSG (git log -1 --pretty=%B)
as-is for the commit message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 74a5375d-5e8c-4ae5-8974-6b68eb8ff784

📥 Commits

Reviewing files that changed from the base of the PR and between 7b1f478 and 25ae0c2.

📒 Files selected for processing (1)
  • .github/workflows/branch-protection-direct-push.yml

Comment on lines +26 to +27
MSG=$(git log -1 --pretty=%B)
AUTHOR=$(git log -1 --pretty=%an)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

No GitHub Actions (evento push), git log --pretty=%an pode ser forjado por quem criou o commit? Qual campo representa o ator autenticado do push (github.actorougithub.event.sender.login)?

💡 Result:

Sim. Quem tiver permissão para empurrar (push) commits para o repositório pode forjar o autor exibido pelo git log --pretty=%an, porque %an é o “author name” armazenado no objeto commit do Git (campo “author” do commit), e ele pode ser definido/alterado no momento do commit (ex.: com --author ou GIT_AUTHOR_NAME/EMAIL). O GitHub Actions também pode reagir a esses commits sem validar se o nome do autor bate com a conta do “pusher”. [1][2] Sobre qual campo representa o ator autenticado do push no GitHub Actions: - O contexto github.actor é “o username do usuário que iniciou a execução do workflow”. [3] - No payload do webhook de push, existe sender.login (no payload de webhook “sender” é o usuário que enviou o evento). [4][5] Assim, em geral para on: push, para identificar o ator que disparou o workflow, use github.actor (não github.event.sender.login diretamente, já que ambos apontam para a mesma noção de “triggering user” no payload/context). [3][4] Alternativa: se você estiver usando o REST API “events”, o campo comum é actor.login (equivalente ao “quem disparou”). [6] Resumo prático: - git log --pretty=%an: representa o “author” do commit (forjável por quem cria/reescreve o commit). [1] - github.actor: representa o usuário que iniciou a execução do workflow (ator do push que gerou o evento). [3] - github.event.sender.login: também representa o “sender” do webhook (ator do evento). [4]

Citations:


🏁 Script executed:

fd -t f "branch-protection-direct-push.yml" --exec cat -n {} \;

Repository: adm01-debug/zapp-web

Length of output: 46


🏁 Script executed:

find .github/workflows -type f -name "*.yml" -o -name "*.yaml" | head -20

Repository: adm01-debug/zapp-web

Length of output: 294


🏁 Script executed:

cat -n .github/workflows/branch-protection-direct-push.yml

Repository: adm01-debug/zapp-web

Length of output: 2624


Use ${{ github.actor }} para autorizar bots — git log --pretty=%an é spoofável.

O campo %an (author name) é metadado do commit e pode ser forjado por quem faz o push — alguém consegue registrar --author="github-actions[bot]" e contornar esse sentinel. Use ${{ github.actor }} (identidade autenticada do webhook), que não pode ser falsificada.

Patch
       - name: Inspect last commit on main
         run: |
           MSG=$(git log -1 --pretty=%B)
           AUTHOR=$(git log -1 --pretty=%an)
+          ACTOR="${{ github.actor }}"
           SHA=$(git log -1 --pretty=%H)
 
           echo "### Commit inspecionado" >> $GITHUB_STEP_SUMMARY
           echo "- SHA: \`$SHA\`" >> $GITHUB_STEP_SUMMARY
           echo "- Autor: $AUTHOR" >> $GITHUB_STEP_SUMMARY
           echo "- Mensagem: $MSG" >> $GITHUB_STEP_SUMMARY
 
           if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
             echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
             exit 0
           fi
 
           if echo "$MSG" | head -1 | grep -qE '^Merge pull request #[0-9]+'; then
             echo "OK: merge commit de PR" >> $GITHUB_STEP_SUMMARY
             exit 0
           fi
 
-          case "$AUTHOR" in
+          case "$ACTOR" in
             "github-actions[bot]"|"dependabot[bot]"|"lovable-dev[bot]"|"renovate[bot]")
-              echo "OK: bot oficial ($AUTHOR)" >> $GITHUB_STEP_SUMMARY
+              echo "OK: bot oficial ($ACTOR)" >> $GITHUB_STEP_SUMMARY
               exit 0
               ;;
           esac
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MSG=$(git log -1 --pretty=%B)
AUTHOR=$(git log -1 --pretty=%an)
- name: Inspect last commit on main
run: |
MSG=$(git log -1 --pretty=%B)
AUTHOR=$(git log -1 --pretty=%an)
ACTOR="${{ github.actor }}"
SHA=$(git log -1 --pretty=%H)
echo "### Commit inspecionado" >> $GITHUB_STEP_SUMMARY
echo "- SHA: \`$SHA\`" >> $GITHUB_STEP_SUMMARY
echo "- Autor: $AUTHOR" >> $GITHUB_STEP_SUMMARY
echo "- Mensagem: $MSG" >> $GITHUB_STEP_SUMMARY
if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi
if echo "$MSG" | head -1 | grep -qE '^Merge pull request #[0-9]+'; then
echo "OK: merge commit de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi
case "$ACTOR" in
"github-actions[bot]"|"dependabot[bot]"|"lovable-dev[bot]"|"renovate[bot]")
echo "OK: bot oficial ($ACTOR)" >> $GITHUB_STEP_SUMMARY
exit 0
;;
esac
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/branch-protection-direct-push.yml around lines 26 - 27,
The script currently sets AUTHOR from the commit metadata using git log
--pretty=%an which is spoofable; change the AUTHOR assignment to use the
authenticated actor value provided by GitHub Actions (GITHUB_ACTOR /
github.actor) instead of git log --pretty=%an so bots cannot be impersonated;
update the assignment that references AUTHOR to pull from the environment
variable (e.g., AUTHOR from GITHUB_ACTOR) and leave MSG (git log -1 --pretty=%B)
as-is for the commit message.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a complementary GitHub Actions workflow to detect direct pushes to main that don’t match expected PR-merge/bot/release patterns, providing defense-in-depth alongside GitHub branch protection settings.

Changes:

  • Introduces branch-protection-direct-push.yml that runs on push to main (and workflow_dispatch) and inspects the latest commit’s author/message.
  • Emits a clear failure (exit 1) plus GITHUB_STEP_SUMMARY guidance when the push doesn’t match allowed patterns.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +30 to +61
echo "### Commit inspecionado" >> $GITHUB_STEP_SUMMARY
echo "- SHA: \`$SHA\`" >> $GITHUB_STEP_SUMMARY
echo "- Autor: $AUTHOR" >> $GITHUB_STEP_SUMMARY
echo "- Mensagem: $MSG" >> $GITHUB_STEP_SUMMARY

if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi

if echo "$MSG" | head -1 | grep -qE '^Merge pull request #[0-9]+'; then
echo "OK: merge commit de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi

case "$AUTHOR" in
"github-actions[bot]"|"dependabot[bot]"|"lovable-dev[bot]"|"renovate[bot]")
echo "OK: bot oficial ($AUTHOR)" >> $GITHUB_STEP_SUMMARY
exit 0
;;
esac

if echo "$MSG" | head -1 | grep -qE '^chore\(release\):'; then
echo "OK: release commit" >> $GITHUB_STEP_SUMMARY
exit 0
fi

echo "::error::Push em main sem padrao de PR/bot/release detectado."
echo "### Direct push detectado" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Verificar se branch protection esta ativa em:" >> $GITHUB_STEP_SUMMARY
echo "https://github.com/${{ github.repository }}/settings/branches" >> $GITHUB_STEP_SUMMARY
Comment on lines +57 to +60
echo "::error::Push em main sem padrao de PR/bot/release detectado."
echo "### Direct push detectado" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Verificar se branch protection esta ativa em:" >> $GITHUB_STEP_SUMMARY
Comment on lines +26 to +61
MSG=$(git log -1 --pretty=%B)
AUTHOR=$(git log -1 --pretty=%an)
SHA=$(git log -1 --pretty=%H)

echo "### Commit inspecionado" >> $GITHUB_STEP_SUMMARY
echo "- SHA: \`$SHA\`" >> $GITHUB_STEP_SUMMARY
echo "- Autor: $AUTHOR" >> $GITHUB_STEP_SUMMARY
echo "- Mensagem: $MSG" >> $GITHUB_STEP_SUMMARY

if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi

if echo "$MSG" | head -1 | grep -qE '^Merge pull request #[0-9]+'; then
echo "OK: merge commit de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi

case "$AUTHOR" in
"github-actions[bot]"|"dependabot[bot]"|"lovable-dev[bot]"|"renovate[bot]")
echo "OK: bot oficial ($AUTHOR)" >> $GITHUB_STEP_SUMMARY
exit 0
;;
esac

if echo "$MSG" | head -1 | grep -qE '^chore\(release\):'; then
echo "OK: release commit" >> $GITHUB_STEP_SUMMARY
exit 0
fi

echo "::error::Push em main sem padrao de PR/bot/release detectado."
echo "### Direct push detectado" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Verificar se branch protection esta ativa em:" >> $GITHUB_STEP_SUMMARY
echo "https://github.com/${{ github.repository }}/settings/branches" >> $GITHUB_STEP_SUMMARY
if echo "$MSG" | head -1 | grep -qE '\(#[0-9]+\)$'; then
echo "OK: squash merge de PR" >> $GITHUB_STEP_SUMMARY
exit 0
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The branch protection workflow fails to recognize "Rebase and merge" as a valid PR merge strategy, causing false positive alerts

Fix on Vercel

@adm01-debug adm01-debug merged commit f8edd42 into main May 8, 2026
13 of 15 checks passed
@adm01-debug adm01-debug deleted the chore/add-direct-push-sentinel branch May 8, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants