Ablaufhandbuch

Wöchentliche Backlink-Snapshots mit GitHub Actions: Ein Ablaufhandbuch

Ziel: Jeden Montag schreibt ein Workflow die aktuellen verweisenden Domains und Anchor-Texte in das Repository. Nichts weiter. Der Abgleich erfolgt später.

Iron bridge spanning a river, symbolizing reliable scheduled workflow infrastructure
Bevor Sie beginnen

Sie benötigen ein Repository, einen Linkzoid-Schlüssel, der als Secret LZ_KEY gespeichert ist, und eine Domain, die Ihnen gehört. Budget: ca. 6 Credits pro Ziel pro Durchlauf, was 0,0006 $ entspricht. Ein Snapshot ist eine Momentaufnahme für einen Monat, daher werden wöchentliche Durchläufe meist denselben Index erneut abrufen. Die Einrichtung dieser Methode zur Überprüfung der Backlinks für meine Website dauert einen Abend.

Das Ablaufhandbuch, Schritt für Schritt

01

1. Secret hinzufügen

Repository-Einstellungen, dann Secrets und Variablen, dann Actions. Nennen Sie es LZ_KEY. Wenn Sie ihn in die Workflow-Datei einfügen, rotieren Sie den Schlüssel noch heute.

02

2. Skript committen

Speichern Sie das folgende Python-Skript als snap.py. Es schreibt data/YYYY-MM-DD/refdomains.json und schlägt bei jeder Antwort fehl, bei der ok false ist.

03

3. Workflow committen

Verwenden Sie die folgende YAML. Führen Sie ihn einmal manuell mit dem Trigger workflow_dispatch aus und lesen Sie das Protokoll, bevor Sie dem Zeitplan vertrauen.

04

4. Die erste Datei überprüfen

Öffnen Sie das JSON. Bestätigen Sie die Zeilenanzahl gegenüber total und vergleichen Sie die Zahl mit dem, was der kostenlose overview-Aufruf für Ihre Domain meldet.

05

5. Alarm hinzufügen

Ein fehlgeschlagener Job sendet standardmäßig eine E-Mail an den Repository-Inhaber. Lassen Sie das so. Ein Job, der stillschweigend stoppt, ist der übliche Weg, wie solche Setups scheitern.

snap.py

Standardbibliothek. Die Schleife endet bei der Anzahl, niemals bei einer Schätzung.

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

Cron-Jobs in GitHub laufen in UTC und können verzögert starten, wenn die Runner beschäftigt sind. Bauen Sie nichts darauf auf, das vom genauen Minutenwert abhängt.

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
Gardener pruning a young sapling, representing preparation before starting the schedule

Bevor Sie den Zeitplan aktivieren

  • Der Schlüssel befindet sich in den Repository-Secrets, und die YAML verweist nur über den Namen darauf.
  • Die Workflow-Datei liegt im Standard-Branch, da dies die Kopie ist, die der Zeitplan liest.
  • Ein manueller Lauf mit workflow_dispatch ist abgeschlossen und hat einen datierten Ordner erstellt.
  • Die Zeilenanzahl in der Datei entspricht der Gesamtzahl, die die API für diesen Aufruf zurückgegeben hat.
  • Der Job gibt bei einer fehlerhaften Antwort einen Fehlercode zurück, sodass ein Fehler den Lauf rot markiert.

Fehler und Korrekturen

Was bei einem geplanten Backlink-Job zuerst kaputtgeht
FehlerWas Sie sehenKorrektur
Schlüssel in der YAML eingefügtSchlüssel im Repository-Verlauf sichtbarRotieren, in secrets.LZ_KEY verschieben
Ungerade Minute wie 0 0Der Start verzögert sich um 20 MinutenWählen Sie 17 6; die vollen Stunden sind überlastet
Repository 60 Tage inaktivGitHub pausiert den ZeitplanCommitten Sie etwas oder aktivieren Sie es im Actions-Tab erneut
Schleife endet nur bei leerer SeiteEndlosschleife bei SeitenlimitAuch stoppen, wenn len(rows) >= total
Exit-Code ignoriertGrüner Haken, leerer OrdnerVerwenden Sie sys.exit bei ok: false
Commit schlägt bei keiner Änderung fehlRoter Lauf umsonstFügen Sie nach dem Commit || exit 0 hinzu

Schlüssel und Repository sicher halten

Der Schlüssel ist das Einzige in diesem Setup, das geschützt werden muss. Behandeln Sie ihn wie ein Passwort, denn jeder, der ihn besitzt, kann Ihr Guthaben verbrauchen.

Geplante Jobs lecken leise. Ein Schlüssel, der in einem Protokoll landet, ein Workflow, der in ein öffentliches Repository kopiert wird, oder ein ehemaliger Mitarbeiter mit Schreibzugriff sind die üblichen Wege. Überprüfen Sie jeden dieser Punkte einmal pro Quartal.

Schlüssel rotieren, wenn jemand geht

Wenn ein Mitarbeiter mit Zugriff geht, erstellen Sie einen neuen Schlüssel, aktualisieren Sie das Secret und deaktivieren Sie den alten. Bestätigen Sie dann, dass der nächste Durchlauf erfolgreich ist. Ein grüner Lauf nach der Änderung ist der günstigste Test, den Sie das ganze Jahr über durchführen werden. Notieren Sie das Rotationsdatum auch in den Repository-Notizen, damit die nächste Rotation keine Überraschung ist.

Einschränken, wer den Workflow bearbeiten kann

Jeder, der die YAML bearbeiten kann, kann das Secret in einem Lauf ausgeben. Halten Sie den Schreibzugriff kurz, und prüfen Sie Änderungen an der Workflow-Datei so, wie Sie Code prüfen. Zwei Personen mit Schreibzugriff reichen für ein kleines Repository normalerweise aus.

Die Anfrage-URL niemals ausgeben

Geben Sie das Guthaben und die Zeilenanzahl aus, niemals die Anfrage-URL. Der Schlüssel ist in der Query-String enthalten, daher schreibt eine Debug-Zeile, die die URL ausgibt, den Schlüssel in das Protokoll. Wenn Sie eine Anfrage in einem Issue teilen müssen, ersetzen Sie den Schlüssel zuerst durch einen Platzhalter.

Compass and potted plant, indicating steady progress and early issue detection

Was der Snapshot ist und nicht ist

Was Sie erhalten, ist ein monatliches Bild. Unser eigener Crawler aktualisiert den Index etwa einmal im Monat, daher liefern zwei Montags-Durchläufe im selben Monat oft dieselben Zeilen. Das ist erwartet.

Ein wöchentlicher Rhythmus funktioniert. Er hält die Gewohnheit am Leben, und Sie bemerken einen fehlgeschlagenen Job innerhalb von sieben Tagen statt innerhalb von dreißig. Wenn ein von Ihnen aufgebauter Link am Dienstag fehlt, warten Sie auf die nächste Aktualisierung, bevor Sie in Panik verfallen.

Wenn Sie drei oder vier datierte Ordner haben, gehen Sie zu dem SQLite-Diff. Wenn Sie bei einem hartnäckigen Antwortcode stecken bleiben, listet die Rate-Limit-Tabelle auf, was jeder Status für eine Schleife bedeutet.

Behalten Sie den ersten Ordner als Basis. Jeder spätere Vergleich bezieht sich darauf, und ein nach Datum benannter Ordner ist vertrauenswürdiger als die Erinnerung daran, wie die Zahlen im letzten Frühling aussahen. Bleiben Sie konsistent.

Anchor-Texte und Top-Seiten hinzufügen

Eine Aktion pro Datei hält Diffs lesbar. Kopieren Sie die Schleife in snap.py, ändern Sie refdomains in anchors oder toppages und schreiben Sie in einen zweiten Dateinamen. Jeder kostet 2 Credits.

Eine kombinierte Datei verbirgt, welcher Teil geändert wurde, und ein Reviewer, der einen Pull Request durchscrollt, möchte ein Konzept pro Diff sehen. Halten Sie sie getrennt. Wenn Sie drei Domains verfolgen, schleifen Sie eine kurze Liste im Workflow mit einer Matrix, sodass jedes Ziel seinen eigenen Job und seinen eigenen Fehler hat.

Anchor-Texte sind eine zweite Datei mit ihrem eigenen Limit im Diff, also prüfen Sie sie separat von den verweisenden Domains. Jeder Lauf bleibt günstig und wiederholbar, das ist die ganze Idee.

Das Laufprotokoll lesen

Öffnen Sie das Protokoll des ersten Laufs. Tun Sie dies, bevor Sie dem Zeitplan vertrauen. Achten Sie auf die Zeilenanzahl, das Guthaben und die Commit-Zeile. Wenn einer der drei Werte fehlt, hat der Job weniger getan, als er vorgibt. Führen Sie auch eine kurze Notiz über das Guthaben bei jedem Lauf, damit die monatlichen Ausgaben sichtbar sind, ohne das Dashboard zu öffnen.

Ein grüner Haken sagt wenig aus. Er bedeutet nur, dass der Prozess sauber beendet wurde. Er sagt nicht, dass die Datei die richtigen Zeilen enthält, weshalb das Skript seine eigene Zusammenfassung ausgibt. Behalten Sie diese Zusammenfassungszwischen Zeilen zwischen Skriptversionen unverändert, damit ein Diff von zwei Protokollen nur echte Änderungen zeigt.

Wie ein gesundes Protokoll aussieht

Ein gesunder Lauf gibt eine Zeile mit der Zeilenanzahl und dem Credit-Guthaben aus, gefolgt von einem Commit mit dem heutigen Datum. Alles, was diese Zeilen unter zusätzlicher Rauschen begräbt, ist eine zweite Überprüfung wert.

Stille Fehler erkennen

Achten Sie auf einen leeren Ordner, einen Commit, der nie erscheint, oder eine Zeilenanzahl, die von total abweicht. Jeder dieser Punkte deutet auf die Schleife oder die Analyse hin, nicht auf die API selbst. Speichern Sie das erste gesunde Protokoll als Referenz für spätere Vergleiche.

Einige Fehler hinterlassen einen Ordner mit weniger Zeilen als üblich. Vergleichen Sie die Anzahl mit der Vorwoche, bevor Sie einen grünen Lauf feiern, denn eine stille Kürzung sieht genau wie ein stiller Monat aus.

Ein zweites Ziel sicher hinzufügen

Eine zweite Domain ist ein Matrix-Eintrag, keine Kopie des gesamten Workflows. Geben Sie jedem Ziel einen eigenen Job, damit ein Fehler einen anderen nicht verdeckt. Halten Sie jeden Job getrennt. Stellen Sie sicher, dass die Pfade den Domainnamen enthalten, damit zwei Durchläufe nie in dieselbe Datei schreiben.

Beginnen Sie mit dem zweiten Ziel allein. Sobald sein Ordner richtig aussieht, fügen Sie den Rest hinzu. Eine Matrix, die zur Hälfte fehlschlägt, ist schwerer zu lesen als zwei einfache Durchläufe.

Ordner nach Ziel benennen

Setzen Sie die Domain in den Pfad, z. B. data/<domain>/YYYY-MM-DD, und die Ordner bleiben getrennt, auch wenn zwei Jobs in derselben Minute laufen. Alte Ordner können dort bleiben, wo sie sind, da ein Datum im Pfad sie leicht auffindbar macht.

Verwenden Sie für jedes Ziel dieselbe Namensregel. Ein Skript kann dann die Ordner ohne Sonderfälle auflisten.

Das Credit-Budget zuerst planen

Multiplizieren Sie die Aufrufe pro Ziel mit der Anzahl der Ziele und prüfen Sie die Gesamtzahl gegenüber Ihrem Guthaben vor dem ersten Lauf. Eine Matrix multipliziert die Ausgaben so schnell wie sie die Jobs multipliziert. Schreiben Sie die erwartete monatliche Gesamtsumme ins Repository neben den Workflow. Wenn das Guthaben schneller sinkt als erwartet, holt eine Schleife wahrscheinlich Seiten erneut ab, und Sie können sie stoppen, bevor der nächste Lauf beginnt.

Fragen, die in der ersten Woche auftauchen

Kann ich das auf einem privaten Repository kostenlos ausführen?
Normalerweise ja, innerhalb der monatlichen Minuten, die GitHub kostenlosen Konten zur Verfügung stellt. Ein Snapshot-Job dauert weniger als eine Minute, daher nutzt ein wöchentlicher Zeitplan nur einen winzigen Anteil. Prüfen Sie das aktuelle Kontingent Ihres eigenen Plans, da GitHub dies von Zeit zu Zeit ändert.
Wo sollte der Schlüssel gespeichert werden, wenn mehrere Personen Commits durchführen?
In einem Organisations- oder Repository-Secret, niemals in den Dateien. Jeder, der den Workflow bearbeiten kann, kann ein Secret in einem Protokoll ausgeben, also beschränken Sie den Schreibzugriff und rotieren Sie den Schlüssel, wenn jemand das Projekt verlässt.
Warum hat mein geplanter Lauf nicht ausgelöst?
Drei übliche Gründe. Die Workflow-Datei befindet sich nicht im Standard-Branch, das Repository war 60 Tage inaktiv und GitHub hat den Zeitplan pausiert, oder die Cron-Zeichenfolge enthält einen Tippfehler. Führen Sie ihn einmal mit workflow_dispatch aus, um das Skript selbst auszuschließen.
Wie groß werden die Datenordner?
Klein. Tausend verweisende Domains sind ein paar hundert Kilobyte JSON. Ein Jahr wöchentlicher Dateien für eine Domain bleibt weit unter hundert Megabyte, was für Git in Ordnung ist, obwohl Sie ältere Ordner komprimieren können, wenn es Sie stört.