Skip to content

Commit

Permalink
Merge pull request #220 from artichoke/lopopolo/stamina
Browse files Browse the repository at this point in the history
Replace bespoke retry logic with `stamina`
  • Loading branch information
lopopolo authored Jan 28, 2024
2 parents d412ba5 + 4651886 commit 26509cb
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 52 deletions.
8 changes: 8 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ ruff==0.1.9 \
--hash=sha256:e6837202c2859b9f22e43cb01992373c2dbfeae5c0c91ad691a4a2e725392464 \
--hash=sha256:e6a212f436122ac73df851f0cf006e0c6612fe6f9c864ed17ebefce0eff6a5fd
# via artichoke-nightly (pyproject.toml)
stamina==24.1.0 \
--hash=sha256:0382013a3072c9db02f18240d36d6212e590643a45a8662cabc4584c5d1a8919 \
--hash=sha256:de14695610e4ea8da0624fc368607e95d923b25bfe45f4eaa10e226360bc9e02
# via artichoke-nightly (pyproject.toml)
tenacity==8.2.3 \
--hash=sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a \
--hash=sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c
# via stamina
typing-extensions==4.9.0 \
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
--hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
Expand Down
87 changes: 35 additions & 52 deletions macos_sign_and_notarize.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
from dataclasses import dataclass
from pathlib import Path
from tempfile import TemporaryDirectory
from time import sleep
from typing import Optional
from urllib.request import urlopen

import stamina
import validators

MACOS_SIGN_AND_NOTARIZE_VERSION = "0.5.0"
MACOS_SIGN_AND_NOTARIZE_VERSION = "0.6.0"

MACOS_MONTEREY_MAJOR_VERSION = 12

Expand All @@ -38,6 +38,10 @@ class NotaryToolError(Exception):
pass


class NotaryToolInternalServerError(NotaryToolError):
pass


class MissingNotarizePasswordError(Exception):
def __init__(self: "MissingNotarizePasswordError") -> None:
super().__init__("MACOS_NOTARIZE_APP_PASSWORD environment variable is required")
Expand All @@ -55,9 +59,8 @@ def __init__(self: "MissingCodeSigningCertificatePassphraseError") -> None:
)


def run_notarytool(
command: list[str], *, retries: int = 3, backoff_s: float = 5.0
) -> str:
@stamina.retry(on=NotaryToolInternalServerError, attempts=3)
def run_notarytool(command: list[str]) -> str:
"""
Run the given notarytool command as a subprocess and return its stdout
contents on success.
Expand All @@ -73,37 +76,33 @@ def run_notarytool(
"run_notarytool requires `/usr/bin/xcrun notarytool` command prefix"
)

attempt = 0
while attempt < retries:
proc = subprocess.run(
command,
check=False,
capture_output=True,
text=True,
)
if proc.stderr:
print(proc.stderr, file=sys.stderr)

if proc.returncode == 0:
return proc.stdout
proc = subprocess.run(
command,
check=False,
capture_output=True,
text=True,
)
if proc.stderr:
print(proc.stderr, file=sys.stderr)

# Sometimes, the API that backs `notarytool` returns 500 errors. Try to
# inspect stderr for known 500s and retry with exponential backoff.
#
# See: https://github.com/artichoke/nightly/issues/129
if "Error: HTTP status code: 500. Internal Server Error" in proc.stderr:
sleep(backoff_s)
backoff_s *= 1.5
if proc.returncode == 0:
return proc.stdout

attempt += 1
# Sometimes, the API that backs `notarytool` returns 500 errors. Try to
# inspect stderr for known 500s and retry with exponential backoff.
#
# See: https://github.com/artichoke/nightly/issues/129
if "Error: HTTP status code: 500. Internal Server Error" in proc.stderr:
raise NotaryToolInternalServerError(proc.stderr)

raise NotaryToolError(" ".join(command))
raise NotaryToolError(proc.stderr)


def run_command_with_merged_output(command: list[str], *, max_retries: int = 3) -> None:
@stamina.retry(on=subprocess.CalledProcessError, attempts=3)
def run_command_with_merged_output(command: list[str]) -> None:
"""
Run the given command as a subprocess and merge its stdout and stderr
streams. The command will retry the command on any error, up to `max_retries`
streams. This function will retry the given command on any error, up to 3
times.
This is useful for funnelling all output of a command into a GitHub Actions
Expand All @@ -112,29 +111,13 @@ def run_command_with_merged_output(command: list[str], *, max_retries: int = 3)
This command uses `check=True` when delegating to `subprocess`.
"""

attempt = 1
while attempt <= max_retries:
try:
proc = subprocess.run(
command,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
except subprocess.CalledProcessError as e:
cmd_string = " ".join(command)
print(f"command [{cmd_string}] failed attempt #{attempt}")
if attempt == max_retries:
print(
f"command [{cmd_string}] exceeded {max_retries} max retry attempts."
" failing permanently"
)
raise e from None
attempt += 1
print(f"retrying command [{cmd_string}]")
else:
break
proc = subprocess.run(
command,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)

for line in proc.stdout.splitlines():
if line:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0"
license = {file = "LICENSE"}
classifiers = ["Private :: Do Not Upload"]
dependencies = [
"stamina==24.1.0",
"validators==0.22.0",
]
requires-python = ">= 3.12"
Expand Down
8 changes: 8 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
#
# pip-compile --generate-hashes --output-file=requirements.txt pyproject.toml
#
stamina==24.1.0 \
--hash=sha256:0382013a3072c9db02f18240d36d6212e590643a45a8662cabc4584c5d1a8919 \
--hash=sha256:de14695610e4ea8da0624fc368607e95d923b25bfe45f4eaa10e226360bc9e02
# via artichoke-nightly (pyproject.toml)
tenacity==8.2.3 \
--hash=sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a \
--hash=sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c
# via stamina
validators==0.22.0 \
--hash=sha256:61cf7d4a62bbae559f2e54aed3b000cea9ff3e2fdbe463f51179b92c58c9585a \
--hash=sha256:77b2689b172eeeb600d9605ab86194641670cdb73b60afd577142a9397873370
Expand Down

0 comments on commit 26509cb

Please sign in to comment.