Fazer rebase de um PR de afiliados sobre um build que o dependabot quebrou silenciosamente
A tarefa em si era pequena: trocar uma tag de rastreamento da Amazon que era só um placeholder pela real, numa branch que já estava pronta havia um dia. Rebase, push, pronto. Em vez disso, virou uma descoberta de que a main não compilava de jeito nenhum, e nenhuma das duas coisas quebrando isso tinha qualquer relação com a branch que eu estava mexendo.
O contexto
A branch de afiliados conectava a @vdaluz/astro-affiliate ao imperfectsystems.com: config do site, um plugin remark que reescreve links markdown affiliate:key para URLs reais da Amazon, um componente de aviso de FTC. O PR estava completo e com todos os itens marcados, exceto um: uma string literal de placeholder no lugar de um ID real de rastreamento da Amazon Associates, porque conseguir um exige passar manualmente pelo painel da Amazon.
Peguei a tag real, imperfectsystems-20, e fui fazer o rebase da branch, que já tinha uma semana, sobre a main antes de trocar o valor. Foi aí que a primeira tentativa de rebase lançou um conflito que eu não esperava em package.json, e não vindo da minha branch, mas da própria main tendo se movido por baixo dela.
O que tinha entrado na main
Mais cedo na mesma sessão, eu tinha mesclado um PR do dependabot: “bump the npm_and_yarn group across 1 directory with 12 updates”. Bumps agrupados assim são o comportamento normal do dependabot, e o gh pr checks não mostrou nada bloqueando, então entrou como manutenção de rotina.
Não era rotina. Escondida entre essas 12 atualizações estava a tailwindcss saindo da versão 3 para a 4, uma major. O Tailwind v4 moveu seu plugin do PostCSS para um pacote separado, o que quebra o @astrojs/tailwind (a integração que este site ainda usava) na hora:
[ERROR] [@astrojs/tailwind] An unhandled error occurred while running the "astro:config:setup" hook
It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin. The PostCSS plugin
has moved to a separate package...
Mesmo erro localmente e no ambiente de build real do Cloudflare, então não era uma falha isolada da minha máquina. O push já tinha ido para o ar e o deploy gate do Cloudflare rejeitou corretamente o build quebrado, então a produção nunca chegou a ser afetada de fato. Ela só ficou servindo o último deploy bom enquanto o HEAD da main ficava sem compilar, o que significava que nada mais podia ser enviado até alguém perceber e corrigir. Essa pessoa acabou sendo eu, no meio de um rebase, para um PR sem nenhuma relação.
A correção rápida: fixar o tailwindcss de volta em ^3.4.17, regenerar o lockfile, confirmar que o build passa tanto localmente quanto no ambiente real do Cloudflare antes de dar push. Uma migração de verdade para o plugin nativo do Vite no Tailwind v4 é trabalho real, que registrei separadamente em vez de apressar como hotfix.
A segunda quebra, quando voltei ao rebase
Com a main corrigida, voltei para a branch de afiliados e refiz o rebase. O gate do astro check disparou imediatamente um erro diferente, dessa vez vindo do próprio Astro:
`markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` run on the
`unified` processor from `@astrojs/markdown-remark`, which is no longer installed by default.
Install it with:
npm install @astrojs/markdown-remark
O mesmo PR do dependabot também tinha subido uma major do Astro, e a versão nova parou de empacotar seu processador de markdown legado por padrão. A própria branch main nunca usa remarkPlugins, então essa quebra ficou completamente invisível até que uma branch que usa (o plugin remark da integração de afiliados, que reescreve links affiliate:key) tentasse compilar contra ela. Duas mudanças que quebram compatibilidade, vindas de um único bump agrupado, e nenhuma delas teria aparecido sem algo específico para disparar cada uma.
npm install @astrojs/markdown-remark e o erro sumiu. Nenhuma mudança de config necessária além de ter o pacote presente.
Verificando se a tag real realmente funcionava
Com as duas quebras resolvidas, troquei pela tag real e fiz a mesma checagem pela qual a branch já tinha passado uma vez com o placeholder: um post de blog de teste com um link affiliate: real, uma entrada temporária no catálogo, um build completo, e depois uma busca no HTML renderizado de verdade em vez de simplesmente confiar num build verde:
href="https://www.amazon.com/dp/B07RFSSYBH/ref=nosim?tag=imperfectsystems-20"
Tag real, formato de URL correto, parágrafo de aviso renderizando acima dele. Apaguei o post de teste e a entrada do catálogo, fiz commit só da troca de uma linha na tag, e dei push.
O que eu faria diferente
O título do PR agrupado do dependabot não dizia nada sobre uma major escondida ali dentro, e este repositório não tem checagem de CI antes do merge para pegar isso também, o build quebrado só aparece depois do merge, que foi exatamente o que aconteceu. A partir de agora, antes de mesclar qualquer atualização agrupada, vou comparar especificamente os intervalos de versão do package.json, não só passar os olhos pelo lockfile, já que é o único lugar onde uma major realmente se anuncia.
A outra coisa que vale lembrar: um bump de dependência pode quebrar algo que nem parece visivelmente relacionado com o que mudou. O Tailwind v4 quebrou na hora e de forma barulhenta. A major do Astro quebrou silenciosamente e só para uma funcionalidade que ainda nem tinha sido mesclada. Se eu tivesse testado só a main depois do merge do dependabot, teria dado como corrigido e seguido em frente, e o PR de afiliados teria batido nesse segundo erro sem nenhum contexto do porquê.
Leitura relacionada
A página de marketing que competia na categoria errada
A página de marketing vendia rastreamento de lançamentos, território de um concorrente estabelecido, enquanto a view model tinha a proposta real o tempo todo.
Dando um rosto para cada link compartilhado
Uma proteção de og:image que nunca disparava, um valor padrão de uma linha que resolveu, um card de terminal feito sob medida, e uma pegadinha de retina no Chrome headless.
O favicon que ficou quebrado por meses e ninguém teria percebido
Um lote de performance com uma metade fácil (prerender, PNG) e uma falha silenciosa: um favicon SVG cuja imagem externa os navegadores descartam sem avisar.
Você também pode achar útil
RackNerd VPS
Hospedagem VPS econômica para serviços leves que funcionam continuamente.
Como afiliado da RackNerd, ganho com compras qualificadas.
Saiba maisProton VPN
VPN comercial com filtragem NetShield e interruptor de desligamento automático.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba maisProton Pass
Gerenciador de senhas focado em privacidade, da equipe por trás do Proton Mail.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba mais