Capturas semanais de backlinks no GitHub Actions: um manual
Objetivo: toda segunda-feira, um workflow grava os domínios de referência e as âncoras do dia no repositório. Nada mais. A comparação (diff) vem depois.
Equipe editorial do Linkzoid ·
Antes de começar
Você precisa de um repositório, uma chave do Linkzoid armazenada como o segredo LZ_KEY e um domínio de sua propriedade. Orçamento: cerca de 6 créditos por alvo por execução, o que equivale a $0.0006. Uma captura é um registro de um mês, então execuções semanais geralmente re-buscam o mesmo índice. Configurar essa forma de verificar backlinks para o meu site leva uma noite.
O manual, em ordem
01
1. Adicione o segredo
Configurações do repositório, depois Segredos e variáveis, depois Actions. Nomeie como LZ_KEY. Se você colar a chave no arquivo do workflow, gire a chave hoje.
02
2. Faça commit do script
Salve o Python abaixo como snap.py. Ele grava data/YYYY-MM-DD/refdomains.json e falha em qualquer resposta onde ok seja falso.
03
3. Faça commit do workflow
Use o YAML abaixo. Execute-o uma vez manualmente com o gatilho workflow_dispatch e leia o log antes de confiar no agendamento.
04
4. Verifique o primeiro arquivo
Abra o JSON. Confirme a contagem de linhas contra total e compare o número com o que a chamada overview gratuita relata para o seu domínio.
05
5. Adicione o alerta
Um trabalho falho envia um e-mail ao proprietário do repositório por padrão. Deixe isso assim. Um trabalho que para silenciosamente é a forma usual como essas configurações morrem.
snap.py
Biblioteca padrão. O loop termina pela contagem, nunca por um palpite.
python
import json, os, sys, datetime, pathlib, urllib.request as u
KEY = os.environ['LZ_KEY']
TARGET = sys.argv[1]
def get(**p):
q = '&'.join(f'{k}={v}' for k, v in p.items())
url = f'https://linkzoid.pro/api.php?{q}&key={KEY}'
with u.urlopen(url, timeout=30) as r:
return json.load(r)
rows, page = [], 1
while True:
d = get(action='refdomains', q=TARGET, page=page, per=1000)
if not d['ok']:
sys.exit(f'bad response: {d}')
rows += d['rows']
if not d['rows'] or len(rows) >= d['total']:
break
page += 1
day = datetime.date.today().isoformat()
out = pathlib.Path('data') / day
out.mkdir(parents=True, exist_ok=True)
(out / 'refdomains.json').write_text(json.dumps(rows))
print(len(rows), 'rows, balance', d['_credits'])
.github/workflows/snapshot.yml
O cron do GitHub executa em UTC e pode iniciar atrasado quando os runners estão ocupados. Não construa nada que dependa do minuto.
A chave fica nos segredos do repositório, e o YAML apenas a referencia pelo nome.
O arquivo do workflow está na branch padrão, porque essa é a cópia que o agendamento lê.
Uma execução manual com workflow_dispatch terminou e escreveu uma pasta datada.
A contagem de linhas no arquivo corresponde ao total que a API retornou para essa chamada.
O trabalho sai com código não-zero em uma resposta ruim, então uma falha torna a execução vermelha.
Erros e correções
O que quebra primeiro em um trabalho agendado de backlinks
Erro
O que você vê
Correção
Chave colada no YAML
Chave visível no histórico do repositório
Gire-a, mova-a para secrets.LZ_KEY
Minuto estranho como 0 0
A execução começa 20 minutos atrasada
Escolha 17 6; o início da hora está congestionado
Repositório inativo por 60 dias
O GitHub pausa o agendamento
Faça commit de algo ou reative-o na aba Actions
O loop para apenas em uma página vazia
Execução infinita no limite de páginas
Também pare quando len(rows) >= total
Código de saída ignorado
Check verde, pasta vazia
Use sys.exit em ok: false
O commit falha sem alterações
Execução vermelha à toa
Adicione || exit 0 após o commit
Mantendo a chave e o repositório seguros
A chave é a única coisa nesta configuração que vale a pena proteger. Trate-a como uma senha, porque qualquer um que a tiver pode gastar seu saldo.
Trabalhos agendados vazam silenciosamente. Uma chave colada em um log, um workflow copiado para um repositório público ou um ex-colega com acesso de gravação são as rotas usuais. Verifique cada um uma vez por trimestre.
Gire a chave quando alguém sair
Quando um colega com acesso sai, crie uma nova chave, atualize o segredo e desative a antiga. Depois, confirme se a próxima execução passa. Uma execução verde após a alteração é o teste mais barato que você fará no ano. Escreva a data da rotação nas notas do repositório também, para que a próxima rotação não seja uma surpresa.
Limite quem pode editar o workflow
Qualquer um que possa editar o YAML pode imprimir o segredo em uma execução. Mantenha o acesso de gravação restrito e revise as alterações no arquivo do workflow como faria com o código. Duas pessoas com acesso de gravação geralmente são suficientes para um repositório pequeno.
Nunca imprima a URL da solicitação
Imprima o saldo e a contagem de linhas, nunca a URL da solicitação. A chave viaja na string de consulta, então uma linha de debug que imprime a URL grava a chave no log. Se você precisar compartilhar uma solicitação em uma issue, substitua a chave por um placeholder primeiro.
O que a captura é e não é
O que você recebe é uma foto mensal. Nosso próprio crawler atualiza o índice cerca de uma vez por mês, então duas execuções de segunda-feira no mesmo mês frequentemente retornam as mesmas linhas. Isso é esperado.
Uma cadência semanal funciona. Mantém o hábito vivo e você detecta um trabalho falho dentro de sete dias em vez de trinta. Se um link que você construiu na terça-feira estiver faltando na segunda-feira, aguarde a próxima atualização antes de entrar em pânico.
Quando você tiver três ou quatro pastas datadas, avance para o diff do SQLite. Se você está preso em um código de resposta teimoso, a tabela de limite de taxa lista o que cada status significa para um loop.
Mantenha a primeira pasta como linha de base. Toda comparação posterior aponta de volta para ela, e uma pasta nomeada por data é muito mais fácil de confiar do que a memória de como os números pareciam na primavera passada. Mantenha a consistência.
Adicionando âncoras e páginas principais
Uma ação por arquivo mantém os diffs legíveis. Copie o loop em snap.py, altere refdomains para anchors ou toppages e escreva em um segundo nome de arquivo. Cada um custa 2 créditos.
Um arquivo combinado esconde qual parte mudou, e um revisor que rola um pull request quer ver um conceito por diff. Mantenha-os separados. Se você rastrear três domínios, faça loop sobre uma lista curta no workflow com uma matriz, para que cada alvo tenha seu próprio trabalho e sua própria falha.
As âncoras são um segundo arquivo com seu próprio limite no diff, então revise-as separadamente dos domínios de referência. Cada execução permanece barata e repetível, que é a ideia principal.
Lendo o log da execução
Abra o log da primeira execução. Faça isso antes de confiar no agendamento. Procure a contagem de linhas, o saldo e a linha de commit. Se qualquer um dos três estiver ausente, o trabalho fez menos do que afirma. Mantenha uma nota curta do saldo em cada execução também, para que o gasto mensal seja visível sem abrir o painel.
Um check verde diz pouco. Ele apenas significa que o processo saiu limpo. Não diz se o arquivo contém as linhas certas, é por isso que o script imprime seu próprio resumo. Mantenha essas linhas de resumo inalteradas entre versões do script, para que um diff de dois logs mostre apenas alterações reais.
Como parece um log saudável
Uma execução saudável imprime uma linha com a contagem de linhas e o saldo de créditos, depois um commit com a data de hoje. Qualquer coisa que enterre essas linhas sob ruído extra merece uma segunda olhada.
Detectando uma falha silenciosa
Observe uma pasta vazia, um commit que nunca aparece ou uma contagem de linhas que difere do total. Cada um desses pontos para o loop ou o parse, não para a API em si. Salve o primeiro log saudável como referência para comparações futuras.
Algumas falhas deixam uma pasta para trás com menos linhas do que o habitual. Compare a contagem com a semana anterior antes de celebrar uma execução verde, porque uma truncamento silencioso parece exatamente como um mês silencioso.
Adicionando um segundo alvo com segurança
Um segundo domínio é uma entrada de matriz, não uma cópia de todo o workflow. Dê a cada alvo seu próprio trabalho para que uma falha não esconda outra. Mantenha cada trabalho separado. Verifique se os caminhos incluem o nome do domínio, para que duas execuções nunca escrevam no mesmo arquivo.
Comece apenas com o segundo alvo. Quando sua pasta parecer correta, adicione o resto. Uma matriz que falha no meio é mais difícil de ler do que duas execuções simples.
Nomeie pastas por alvo
Coloque o domínio no caminho, por exemplo data/<domain>/YYYY-MM-DD, e as pastas permanecem separadas mesmo quando dois trabalhos são executados no mesmo minuto. Pastas antigas podem permanecer onde estão, já que uma data no caminho as torna fáceis de encontrar.
Use a mesma regra de nomenclatura para todos os alvos. Um script pode então listar as pastas sem casos especiais.
Planeje o orçamento de créditos primeiro
Multiplique as chamadas por alvo pelo número de alvos, depois verifique o total contra seu saldo antes da primeira execução. Uma matriz multiplica o gasto tão rápido quanto multiplica os trabalhos. Escreva o total mensal esperado no repositório ao lado do workflow. Quando o saldo cair mais rápido do que isso, um loop provavelmente está re-buscando páginas, e você pode pará-lo antes da próxima execução.
Perguntas que surgem na primeira semana
Posso executar isso em um repositório privado gratuitamente?
Geralmente sim, dentro dos minutos mensais que o GitHub oferece para contas gratuitas. Um trabalho de captura executa em menos de um minuto, então um agendamento semanal usa uma pequena parte. Verifique a cota atual do seu plano, porque o GitHub altera isso de vez em quando.
Onde a chave deve ficar se várias pessoas fizerem push?
Em um segredo de organização ou repositório, nunca nos arquivos. Qualquer um que possa editar o workflow pode imprimir um segredo em um log, então limite quem tem acesso de gravação e gire a chave se alguém sair do projeto.
Por que minha execução agendada não disparou?
Três motivos comuns. O arquivo do workflow não está na branch padrão, o repositório ficou inativo por 60 dias e o GitHub pausou o agendamento, ou a string cron tem um erro de digitação. Execute-o uma vez com workflow_dispatch para descartar o script em si.
Quão grandes ficam as pastas de dados?
Pequenas. Mil domínios de referência são algumas centenas de kilobytes de JSON. Um ano de arquivos semanais para um domínio permanece bem abaixo de cem megabytes, o que é bom para o git, embora você possa compactar pastas mais antigas se isso incomodar.