Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,20 @@ jobs:
- name: Require a complete run with full rows
run: |
python3 -c "
import json, os
import json, os, sys, traceback
def annotate(kind, exc, tb):
traceback.print_exception(kind, exc, tb)
print('::error::canary row check failed: %s: %s' % (kind.__name__, str(exc)[:400].replace(chr(10), ' ')))
sys.excepthook = annotate
code = int(os.environ['canary_exit'])
print(f'exit {code}')
if code != 0:
if os.environ.get('HAS_PROXY') != 'true':
print('::error::The direct run from the GitHub runner did not complete (exit %d). '
'If it was refused (exit 3), set the INSTAGRAM_PROXY repo secret (a residential '
'http://login:password@host:port proxy) so the canary can reach the site.' % code)
else:
print('::error::canary exit %d through the INSTAGRAM_PROXY secret (1 crash, 3 blocked, 4 zero rows, 5 content never obtained, 6 partial). A proxy that rejects its credential (HTTP 407) reaches Chromium as a navigation timeout, so on exit 5 check the INSTAGRAM_PROXY secret first.' % code)
raise SystemExit(f'canary requires EXIT_OK=0, got {code}')
meta = json.load(open('canary.json.meta.json'))
print(json.dumps(meta, indent=2))
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ that changes a default is called out at the top of its entry.

### Changed

- CI only: a failed canary check now always ends with an `::error::` line. A run
through the `INSTAGRAM_PROXY` secret that exited nonzero used to end red with no
annotation, and a missing or wrong output file showed only a traceback.
The message notes that a proxy rejecting its credential (HTTP 407) shows
up in Chromium as a navigation timeout (exit 5), not as a 407.
- CI only: the canary now runs weekly (Mondays 06:41 UTC) and on a manual dispatch, with its optional secret `INSTAGRAM_PROXY` passed on every run; the daily schedule is removed.

## [0.3.0] - 2026-10-15
Expand Down
43 changes: 43 additions & 0 deletions smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import asyncio
import inspect as _inspect
import json
import os
import tempfile
from pathlib import Path

Expand Down Expand Up @@ -1314,6 +1315,48 @@ def _():
assert 'log.info("Fingerprint applied: user agent %s", user_agent)' in (ROOT / path).read_text(encoding="utf-8"), path


def _canary_check_snippets():
"""Every `python3 -c "..."` block in the canary workflow that reads canary_exit."""
import textwrap
lines = (ROOT / ".github" / "workflows" / "canary.yml").read_text(encoding="utf-8").splitlines()
snippets, i = [], 0
while i < len(lines):
if lines[i].strip() == 'python3 -c "':
body = []
i += 1
while lines[i].strip() != '"':
body.append(lines[i])
i += 1
text = textwrap.dedent("\n".join(body))
if "canary_exit" in text:
# bash would expand these inside the double quotes; this check runs the text as-is
assert not any(ch in text for ch in "$`\\"), "canary snippet uses a bash-special character"
snippets.append(text)
i += 1
return snippets


@check("every way the canary check step fails prints an ::error:: line: a nonzero exit with or without the proxy secret, and a missing or wrong output file (a red job with no annotation hid a proxy failure on 2026-10-20)")
def _():
import subprocess
import sys
if not (ROOT / ".github").is_dir():
return # the Docker image ships no workflows; the repository's own CI runs this check
snippets = _canary_check_snippets()
assert snippets, "no canary check step found in .github/workflows/canary.yml"
with tempfile.TemporaryDirectory() as tmp:
for snippet in snippets:
for has_proxy in ("true", "false"):
for code in ("0", "1", "3", "4", "5", "6"):
env = dict(os.environ, HAS_PROXY=has_proxy, canary_exit=code,
canary_details_exit=code, CANARY_REGION="US")
proc = subprocess.run([sys.executable, "-c", snippet], cwd=tmp, env=env,
capture_output=True, text=True, timeout=60)
# code 0 in an empty directory: the sidecar is missing, which must fail too
assert proc.returncode != 0, (has_proxy, code, "an empty directory passed")
assert "::error::" in proc.stdout, (has_proxy, code, proc.stdout[-300:], proc.stderr[-300:])


def run() -> int:
"""All @check-decorated functions above already ran at import time
(that's the point — see the `check()` docstring) and self-registered
Expand Down
Loading