La trampa del «siempre verdadero»
La más comúnGitHub solo evalúa lo que está dentro de ${{ }}. Los operadores que quedan fuera se convierten en texto literal tras la sustitución — una cadena no vacía, que siempre es verdadera. El evaluador marca esto (actions/runner#1173).
Siempre verdadero
# ALWAYS TRUE — operators sit OUTSIDE ${{ }}
jobs:
deploy:
if: ${{ github.ref }} == 'refs/heads/main'
# after substitution this is the literal string
# refs/heads/main == 'refs/heads/main'
# a non-empty string => truthy => runs on EVERY branch Corregido
# CORRECT — wrap the WHOLE condition in one ${{ }}
jobs:
deploy:
if: ${{ github.ref == 'refs/heads/main' }}
# now GitHub evaluates the comparison, not a literal string