def build_entry(branch, repo, auth, changelog_path, resolve_backports):
    """Build a python version entry"""
    repo = repo or util.get_repo()
    branch = branch or util.get_branch()

    # Get the new version
    version = util.get_version()

    # Get the existing changelog and run some validation
    changelog = Path(changelog_path).read_text(encoding="utf-8")

    if START_MARKER not in changelog or END_MARKER not in changelog:
        raise ValueError("Missing insert marker for changelog")

    if changelog.find(START_MARKER) != changelog.rfind(START_MARKER):
        raise ValueError("Insert marker appears more than once in changelog")

    # Get changelog entry

    entry = get_version_entry(
        f"origin/{branch}",
        repo,
        version,
        auth=auth,
        resolve_backports=resolve_backports,
    )

    changelog = insert_entry(changelog, entry, version=version)
    Path(changelog_path).write_text(changelog, encoding="utf-8")

    # Stage changelog
    util.run(f"git add {util.normalize_path(changelog_path)}")
Пример #2
0
def draft_changelog(version_spec, branch, repo, auth, dry_run):
    """Create a changelog entry PR"""
    repo = repo or util.get_repo()
    branch = branch or util.get_branch()
    version = util.get_version()

    tags = util.run("git --no-pager tag")
    if f"v{version}" in tags.splitlines():
        raise ValueError(f"Tag v{version} already exists")

    # Check out any unstaged files from version bump
    util.run("git checkout -- .")

    title = f"{changelog.PR_PREFIX} for {version} on {branch}"
    commit_message = f'git commit -a -m "{title}"'
    body = title

    # Check for multiple versions
    if util.PACKAGE_JSON.exists():
        body += npm.get_package_versions(version)

    body += '\n\nAfter merging this PR run the "Draft Release" Workflow with the following inputs'
    body += f"""
| Input  | Value |
| ------------- | ------------- |
| Target | {repo}  |
| Branch  | {branch}  |
| Version Spec | {version_spec} |
"""
    util.log(body)

    make_changelog_pr(auth, branch, repo, title, commit_message, body, dry_run=dry_run)
Пример #3
0
def check_entry(branch, repo, auth, changelog_path, since, resolve_backports,
                output):
    """Check changelog entry"""
    branch = branch or util.get_branch()

    # Get the new version
    version = util.get_version()

    # Finalize changelog
    changelog = Path(changelog_path).read_text(encoding="utf-8")

    start = changelog.find(START_MARKER)
    end = changelog.find(END_MARKER)

    if start == -1 or end == -1:  # pragma: no cover
        raise ValueError("Missing new changelog entry delimiter(s)")

    if start != changelog.rfind(START_MARKER):  # pragma: no cover
        raise ValueError("Insert marker appears more than once in changelog")

    final_entry = changelog[start + len(START_MARKER):end]

    repo = repo or util.get_repo()

    raw_entry = get_version_entry(
        f"origin/{branch}",
        repo,
        version,
        since=since,
        auth=auth,
        resolve_backports=resolve_backports,
    )

    if f"# {version}" not in final_entry:  # pragma: no cover
        util.log(final_entry)
        raise ValueError(f"Did not find entry for {version}")

    final_prs = re.findall(r"\[#(\d+)\]", final_entry)
    raw_prs = re.findall(r"\[#(\d+)\]", raw_entry)

    for pr in raw_prs:
        # Allow for changelog PR to not be in changelog itself
        skip = False
        for line in raw_entry.splitlines():
            if f"[#{pr}]" in line and "changelog" in line.lower():
                skip = True
                break
        if skip:
            continue
        if not f"[#{pr}]" in final_entry:  # pragma: no cover
            raise ValueError(f"Missing PR #{pr} in changelog")
    for pr in final_prs:
        if not f"[#{pr}]" in raw_entry:  # pragma: no cover
            raise ValueError(
                f"PR #{pr} does not belong in changelog for {version}")

    if output:
        Path(output).write_text(final_entry, encoding="utf-8")
Пример #4
0
def tag_release(branch, repo, dist_dir, no_git_tag_workspace):
    """Create release commit and tag"""
    # Get the new version
    version = util.get_version()

    # Get the branch
    branch = branch or util.get_branch()

    # Create the release commit
    util.create_release_commit(version, dist_dir)

    # Create the annotated release tag
    tag_name = f"v{version}"
    util.run(f'git tag {tag_name} -a -m "Release {tag_name}"')

    # Create annotated release tags for workspace packages if given
    if not no_git_tag_workspace:
        npm.tag_workspace_packages()
Пример #5
0
def test_extract_dist_py(py_package, runner, mocker, open_mock, tmp_path,
                         git_prep):
    changelog_entry = mock_changelog_entry(py_package, runner, mocker)

    # Create the dist files
    run("python -m build .", cwd=util.CHECKOUT_NAME)

    # Finalize the release
    runner(["tag-release"])

    os.makedirs("staging")
    shutil.move(f"{util.CHECKOUT_NAME}/dist", "staging")

    def helper(path, **kwargs):
        return MockRequestResponse(f"staging/dist/{path}")

    get_mock = mocker.patch("requests.get", side_effect=helper)

    tag_name = f"v{VERSION_SPEC}"

    dist_names = [osp.basename(f) for f in glob("staging/dist/*.*")]
    releases = [
        dict(
            tag_name=tag_name,
            target_commitish=util.get_branch(),
            assets=[
                dict(name=dist_name, url=dist_name) for dist_name in dist_names
            ],
        )
    ]
    sha = run("git rev-parse HEAD", cwd=util.CHECKOUT_NAME)

    tags = [dict(ref=f"refs/tags/{tag_name}", object=dict(sha=sha))]
    url = normalize_path(osp.join(os.getcwd(), util.CHECKOUT_NAME))
    open_mock.side_effect = [
        MockHTTPResponse(releases),
        MockHTTPResponse(tags),
        MockHTTPResponse(dict(html_url=url)),
    ]

    runner(["extract-release", HTML_URL])
    assert len(open_mock.mock_calls) == 3
    assert len(get_mock.mock_calls) == len(dist_names) == 2
Пример #6
0
def draft_release(
    ref,
    branch,
    repo,
    auth,
    changelog_path,
    version_cmd,
    dist_dir,
    dry_run,
    post_version_spec,
    assets,
):
    """Publish Draft GitHub release and handle post version bump"""
    branch = branch or util.get_branch()
    repo = repo or util.get_repo()
    assets = assets or glob(f"{dist_dir}/*")
    version = util.get_version()
    body = changelog.extract_current(changelog_path)
    prerelease = util.is_prerelease(version)

    # Bump to post version if given
    if post_version_spec:
        post_version = bump_version(post_version_spec, version_cmd)

        util.log(f"Bumped version to {post_version}")
        util.run(f'git commit -a -m "Bump to {post_version}"')

    if dry_run:
        return

    owner, repo_name = repo.split("/")
    gh = GhApi(owner=owner, repo=repo_name, token=auth)

    # Remove draft releases over a day old
    if bool(os.environ.get("GITHUB_ACTIONS")):
        for release in gh.repos.list_releases():
            if str(release.draft).lower() == "false":
                continue
            created = release.created_at
            d_created = datetime.strptime(created, r"%Y-%m-%dT%H:%M:%SZ")
            delta = datetime.utcnow() - d_created
            if delta.days > 0:
                gh.repos.delete_release(release.id)

    remote_url = util.run("git config --get remote.origin.url")
    if not os.path.exists(remote_url):
        util.run(f"git push origin HEAD:{branch} --follow-tags --tags")

    util.log(f"Creating release for {version}")
    util.log(f"With assets: {assets}")
    release = gh.create_release(
        f"v{version}",
        branch,
        f"Release v{version}",
        body,
        True,
        prerelease,
        files=assets,
    )

    # Set the GitHub action output
    util.actions_output("release_url", release.html_url)
Пример #7
0
def test_get_branch(git_repo):
    assert util.get_branch() == "bar"
    run("git checkout foo")
    assert util.get_branch() == "foo"
def test_prep_git_pr(py_package, runner):
    """With RH_BRANCH"""
    env = dict(RH_BRANCH="foo", GITHUB_ACTIONS="")
    result = runner(["prep-git", "--git-url", py_package], env=env)
    os.chdir(util.CHECKOUT_NAME)
    assert util.get_branch() == "foo", util.get_branch()
def test_prep_git_simple(py_package, runner):
    """Standard local run with no env variables."""
    result = runner(["prep-git", "--git-url", py_package], env=dict(GITHUB_ACTIONS=""))
    os.chdir(util.CHECKOUT_NAME)
    assert util.get_branch() == "bar", util.get_branch()