Manual

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.

Ponte de ferro atravessando um rio, simbolizando infraestrutura de workflow agendado confiável
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.

yaml
name: backlink-snapshot
on:
  schedule:
    - cron: '17 6 * * 1'
  workflow_dispatch:
jobs:
  snap:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: python snap.py example.com
        env:
          LZ_KEY: ${{ secrets.LZ_KEY }}
      - run: |
          git config user.name snapshot-bot
          git config user.email "snapshot-bot@localhost"
          git add data
          git commit -m "snapshot $(date -u +%F)" || exit 0
          git push
Jardineiro podando uma muda jovem, representando preparação antes de iniciar o agendamento

Antes de ativar o agendamento

  • 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
ErroO que você vêCorreção
Chave colada no YAMLChave visível no histórico do repositórioGire-a, mova-a para secrets.LZ_KEY
Minuto estranho como 0 0A execução começa 20 minutos atrasadaEscolha 17 6; o início da hora está congestionado
Repositório inativo por 60 diasO GitHub pausa o agendamentoFaça commit de algo ou reative-o na aba Actions
O loop para apenas em uma página vaziaExecução infinita no limite de páginasTambém pare quando len(rows) >= total
Código de saída ignoradoCheck verde, pasta vaziaUse sys.exit em ok: false
O commit falha sem alteraçõesExecução vermelha à toaAdicione || 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.

Bússola e planta em vaso, indicando progresso constante e detecção precoce de problemas

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.