Tygodniowe snapshoty backlinków na GitHub Actions: instrukcja obsługi
Cel: każdego poniedziałku workflow zapisuje dzisiejsze domeny odsyłające i kotwice w repozytorium. Nic więcej. Porównania (diffing) pojawią się później.
Zespół redakcyjny Linkzoid ·
Zanim zaczniesz
Potrzebujesz repozytorium, klucza Linkzoid przechowywanego jako sekret LZ_KEY oraz jednej domeny, którą posiadasz. Budżet: około 6 kredytów na cel przy każdym uruchomieniu, co daje $0.0006. Snapshot to fakt dotyczący jednego miesiąca, więc cotygodniowe uruchomienia pobierają głównie ten sam indeks. Konfiguracja sposobu sprawdzania backlinków do Twojej strony w ten sposób zajmie jeden wieczór.
Instrukcja obsługi, krok po kroku
01
1. Dodaj sekret
Ustawienia repozytorium, następnie Secrets and variables, potem Actions. Nazwij go LZ_KEY. Jeśli wkleisz go do pliku workflow, obróć klucz jeszcze dziś.
02
2. Zatwierdź skrypt
Zapisz poniższy kod Pythona jako snap.py. Zapisuje on data/YYYY-MM-DD/refdomains.json i kończy działanie przy dowolnej odpowiedzi, gdzie ok jest false.
03
3. Zatwierdź workflow
Użyj poniższego YAML. Uruchom go raz ręcznie za pomocą wyzwalacza workflow_dispatch i przeczytaj log przed zaufaniem harmonogramowi.
04
4. Sprawdź pierwszy plik
Otwórz JSON. Potwierdź liczbę wierszy względem total i porównaj liczbę z tym, co zgłasza darmowe wywołanie overview dla Twojej domeny.
05
5. Dodaj alert
Nieudana praca domyślnie wysyła e-mail do właściciela repozytorium. Zostaw to tak jest. Praca, która cicho się kończy, to zwykle sposób, w jaki takie konfiguracje upadają.
snap.py
Biblioteka standardowa. Pętla kończy się na podstawie licznika, a nie na podstawie zgadywania.
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 w GitHub działa w UTC i może się rozpocząć z opóźnieniem, gdy runnerzy są zajęci. Nie buduj niczego, co zależy od minuty.
Klucz znajduje się w sekretach repozytorium, a YAML odwołuje się do niego tylko po nazwie.
Plik workflow znajduje się na domyślnej gałęzi, ponieważ to ta kopia jest odczytywana przez harmonogram.
Ręczne uruchomienie z workflow_dispatch zakończyło się i utworzyło jeden folder z datą.
Liczba wierszy w pliku odpowiada całkowitej liczbie zwróconej przez API dla tego wywołania.
Praca kończy się kodem niezerowym przy złej odpowiedzi, więc awaria oznacza czerwony wynik uruchomienia.
Błędy i poprawki
Co psuje się najpierw w zaplanowanej pracy dotyczącej backlinków
Błąd
Co widzisz
Poprawka
Klucz wklejony w YAML
Klucz widoczny w historii repozytorium
Obróć go, przenieś do secrets.LZ_KEY
Nierówna minuta, np. 0 0
Uruchomienie zaczyna się 20 minut później
Wybierz 17 6; początek godziny jest zatłoczony
Repozytorium bezczynne przez 60 dni
GitHub wstrzymuje harmonogram
Zatwierdź coś lub ponownie włącz go w zakładce Actions
Pętla zatrzymuje się tylko na pustej stronie
Nieskończone uruchomienie przy limicie stron
Zatrzymaj się również, gdy len(rows) >= total
Kod wyjścia ignorowany
Zielony znacznik, pusty folder
Użyj sys.exit przy ok: false
Zatwierdzenie nie udaje się przy braku zmian
Czerwone uruchomienie bez powodu
Dodaj || exit 0 po zatwierdzeniu
Bezpieczne przechowywanie klucza i repozytorium
Klucz to jedyna rzecz w tej konfiguracji warta ochrony. Traktuj go jak hasło, ponieważ każdy, kto go posiada, może wydać Twój balans.
Zaplanowane zadania cicho wyciekają. Klucz wklejony w log, workflow skopiowany do publicznego repozytorium lub były współpracownik z dostępem do zapisu to typowe ścieżki. Sprawdź każdą z nich raz na kwartał.
Obróć klucz, gdy ktoś odejdzie
Gdy współpracownik z dostępem odejdzie, utwórz nowy klucz, zaktualizuj sekret i wycofaj stary. Następnie potwierdź, że kolejne uruchomienie powiedzie się. Jedno zielone uruchomienie po zmianie to najtańszy test, jaki zrobisz w tym roku. Zapisz też datę obrotu w notatkach repozytorium, aby następny obrót nie był zaskoczeniem.
Ogranicz osobę, która może edytować workflow
Każdy, kto może edytować YAML, może wydrukować sekret w uruchomieniu. Ogranicz dostęp do zapisu i przeglądaj zmiany w pliku workflow tak, jak przeglądasz kod. Dwie osoby z dostępem do zapisu to zwykle wystarczająco dla małego repozytorium.
Nigdy nie drukuj URL żądania
Wydrukuj balans i liczbę wierszy, nigdy URL żądania. Klucz podróżuje w stringu zapytania, więc linia debugująca, która drukuje URL, zapisuje klucz w logu. Jeśli musisz udostępnić żądanie w issue, najpierw zamień klucz na placeholder.
Czym jest snapshot, a czym nie
To, co otrzymasz, to obraz miesięczny. Nasz własny crawler odświeża indeks około raz w miesiącu, więc dwa poniedziałkowe uruchomienia w tym samym miesiącu często zwracają te same wiersze. To jest oczekiwane.
Co tydzień to dobra częstotliwość. Utrzymuje nawyk przy życiu, a zauważysz awarię pracy w ciągu siedmiu dni, a nie trzydziestu. Jeśli link, który zbudowałeś we wtorek, brakuje w poniedziałek, poczekaj na następne odświeżenie, zanim zaczniesz panikować.
Zachowaj pierwszy folder jako punkt odniesienia. Każde późniejsze porównanie odnosi się do niego, a folder nazwany datą jest znacznie łatwiejszy do zaufania niż pamięć tego, jak wyglądały liczby zeszłej wiosny. Bądź konsekwentny.
Dodawanie kotwic i najlepszych podstron
Jedna akcja na plik utrzymuje czytelność diffów. Skopiuj pętlę w snap.py, zmień refdomains na anchors lub toppages i zapisz do drugiego pliku. Każda kosztuje 2 kredyty.
Połączony plik ukrywa, która część się zmieniła, a recenzent przewijający pull request chce widzieć jedną koncepcję na diff. Trzymaj je oddzielnie. Jeśli śledzisz trzy domeny, zmapuj krótką listę w workflow za pomocą macierzy, aby każdy cel miał własne zadanie i własną awarię.
Kotwice to drugi plik z własnym limitem w diffie, więc przeglądaj je oddzielnie od domen odsyłających. Każde uruchomienie pozostaje tanie i powtarzalne, co jest głównym celem.
Czytanie logu uruchomienia
Otwórz log pierwszego uruchomienia. Zrób to przed zaufaniem harmonogramowi. Szukaj liczby wierszy, balansu i linii zatwierdzenia. Jeśli którakolwiek z tych trzech rzeczy brakuje, praca zrobiła mniej, niż twierdzi. Zapisuj też krótką notatkę z balansem przy każdym uruchomieniu, aby miesięczny wydatek był widoczny bez otwierania panelu.
Zielony znacznik mówi niewiele. Oznacza tylko, że proces zakończył się czysto. Nie mówi, że plik zawiera właściwe wiersze, dlatego skrypt drukuje własne podsumowanie. Zostaw te linie podsumowania niezmienione między wersjami skryptu, aby diff dwóch logów pokazywał tylko prawdziwe zmiany.
Jak wygląda zdrowy log
Zdrowe uruchomienie drukuje jedną linię z liczbą wierszy i balansem kredytów, a następnie zatwierdzenie z dzisiejszą datą. Wszystko, co zagrzebuje te linie pod dodatkowym szumem, warte jest drugiego spojrzenia.
Wykrywanie cichej awarii
Obserwuj pusty folder, zatwierdzenie, które nigdy nie pojawia się, lub liczbę wierszy, która różni się od total. Każda z tych rzeczy wskazuje na pętlę lub parsowanie, a nie na samo API. Zapisz pierwszy zdrowy log jako odniesienie do późniejszych porównań.
Niektóre awarie pozostawiają folder z mniejszą liczbą wierszy niż zwykle. Porównaj liczbę z poprzednim tygodniem, zanim zataczasz się od radości z zielonego wyniku, ponieważ cicha truncacja wygląda dokładnie jak cichy miesiąc.
Bezpieczne dodanie drugiego celu
Druga domena to wpis macierzy, a nie kopia całego workflow. Nadaj każdemu celowi własne zadanie, aby jedna awaria nie ukrywała innej. Trzymaj każde zadanie oddzielnie. Sprawdź, czy ścieżki zawierają nazwę domeny, aby dwa uruchomienia nigdy nie zapisywały się do tego samego pliku.
Zacznij od samego drugiego celu. Gdy jego folder wygląda poprawnie, dodaj resztę. Macierz, która zawodzi w połowie, jest trudniejsza do odczytania niż dwa proste uruchomienia.
Nazwij foldery według celu
Umieść domenę w ścieżce, np. data/<domain>/YYYY-MM-DD, a foldery pozostaną oddzielne, nawet gdy dwa zadania uruchomią się w tej samej minucie. Stare foldery mogą pozostać tam, gdzie są, ponieważ data w ścieżce ułatwia ich znalezienie.
Używaj tej samej reguły nazewnictwa dla każdego celu. Skrypt może wtedy listować foldery bez przypadków specjalnych.
Zaplanuj budżet kredytów najpierw
Pomnóż wywołania na cel przez liczbę celów, a następnie sprawdź całkowitą liczbę przeciwko swojemu balansowi przed pierwszym uruchomieniem. Macierz mnoży wydatki tak szybko, jak mnoży zadania. Zapisz spodziewany miesięczny total w repozytorium obok workflow. Gdy balans spada szybciej niż ten, prawdopodobnie pętla ponownie pobiera strony i możesz ją zatrzymać przed kolejnym uruchomieniem.
Pytania, które pojawiają się w pierwszym tygodniu
Czy mogę uruchomić to na prywatnym repozytorium za darmo?
Zazwyczaj tak, w ramach miesięcznych minut, które GitHub daje kontom darmowym. Zadanie snapshotu wykonuje się w znacznie mniej niż minutę, więc cotygodniowy harmonogram zużywa niewielką część. Sprawdź aktualne przydziały swojego planu, ponieważ GitHub zmienia je od czasu do czasu.
Gdzie powinien znajdować się klucz, jeśli kilku osób robi push?
W sekretach organizacji lub repozytorium, nigdy w plikach. Każdy, kto może edytować workflow, może wydrukować sekret w logu, więc ogranicz dostęp do zapisu i obróć klucz, jeśli ktoś opuści projekt.
Dlaczego moje zaplanowane uruchomienie nie wystąpiło?
Trzy typowe przyczyny. Plik workflow nie jest na domyślnej gałęzi, repozytorium było bezczynne przez 60 dni i GitHub wstrzymał harmonogram, lub ciąg cron ma literówkę. Uruchom go raz z workflow_dispatch, aby wykluczyć sam skrypt.
Jak duże stają się foldery danych?
Małe. Tysiąc domen odsyłających to kilka setek kilobajtów JSON. Rok cotygodniowych plików dla jednej domeny mieści się dobrze w stu megabajtach, co jest w porządku dla git, choć możesz skompresować starsze foldery, jeśli ci to przeszkadza.