Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add silent option #526

Merged
merged 28 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
49f7071
Add silent option
fcollonval Sep 14, 2023
91bd9c4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 14, 2023
14323dd
Add action and workflow to remove changelog silent entry
fcollonval Sep 15, 2023
70c9cd0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 15, 2023
6f7b9fe
Make the CI happier
fcollonval Sep 15, 2023
9437da6
Add unit test for remove placeholder
fcollonval Sep 18, 2023
5b0acdc
Fix typing
fcollonval Sep 18, 2023
7531de1
TO REMOVE point to the current branch
fcollonval Sep 18, 2023
e8c9d5d
Fix logic to silent the entry in the changelog only when releasing
fcollonval Sep 18, 2023
07e8dcd
Don't get the changelog for silent GH release in populate release
fcollonval Sep 18, 2023
b6b9d60
Debug populate-release
fcollonval Sep 18, 2023
6dc07a2
Don't request metadata uselessly
fcollonval Sep 18, 2023
351b40e
Ignore release missing known tagged released
fcollonval Sep 18, 2023
bc95ea1
Fix removing placeholder in changelong
fcollonval Sep 18, 2023
e8767fb
Remove debug log
fcollonval Sep 18, 2023
0ad0f61
Revert "TO REMOVE point to the current branch"
fcollonval Sep 18, 2023
b56dfdc
Add documentation
fcollonval Sep 20, 2023
b3e3c0b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 20, 2023
18471a4
Don't print the changelog in the job log if the release is silent
fcollonval Sep 25, 2023
63c70b0
Merge branch 'main' into enh/allow-silent-release
fcollonval Nov 6, 2023
010b558
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 6, 2023
1edfbed
Fix mypy errors
fcollonval Nov 6, 2023
32126aa
Add ruff exception
fcollonval Nov 6, 2023
2c63b7a
[skip ci] Comment new flag silent
fcollonval Nov 16, 2023
cd0154c
[skip ci] Comment new flag in example
fcollonval Nov 16, 2023
2642722
Merge branch 'main' into enh/allow-silent-release
blink1073 Nov 16, 2023
c38ab98
Merge branch 'main' into enh/allow-silent-release
fcollonval Nov 20, 2023
438c428
Fix doc
fcollonval Nov 20, 2023
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
5 changes: 5 additions & 0 deletions .github/actions/prep-release/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ inputs:
description: "If set, do not make a PR"
default: "false"
required: false
silent:
description: "Set a placeholder in the changelog and don't publish the release."
required: false
type: boolean
since:
description: "Use PRs with activity since this date or git reference"
required: false
Expand Down Expand Up @@ -55,6 +59,7 @@ runs:
export RH_VERSION_SPEC=${{ inputs.version_spec }}
export RH_POST_VERSION_SPEC=${{ inputs.post_version_spec }}
export RH_DRY_RUN=${{ inputs.dry_run }}
export RH_SILENT=${{ inputs.silent }}
export RH_SINCE=${{ inputs.since }}
export RH_SINCE_LAST_STABLE=${{ inputs.since_last_stable }}

Expand Down
49 changes: 49 additions & 0 deletions .github/actions/publish-changelog/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: "Publish Changelog"
description: "Remove silent placeholder entries in the changelog file."
inputs:
token:
description: "GitHub access token"
required: true
target:
description: "The owner/repo GitHub target"
required: true
branch:
description: "The branch to target"
required: false
dry_run:
description: "If set, do not make a PR"
default: "false"
required: false
outputs:
pr_url:
description: "The html URL of the draft GitHub release"
value: ${{ steps.publish-changelog.outputs.pr_url }}
runs:
using: "composite"
steps:
- name: install-releaser
shell: bash -eux {0}
run: |
# Install Jupyter Releaser from git unless we are testing Releaser itself
if ! command -v jupyter-releaser &> /dev/null
then
pip install -q git+https://github.com/jupyter-server/jupyter_releaser.git@v2
fi

- id: publish-changelog
shell: bash -eux {0}
run: |
export GITHUB_ACCESS_TOKEN=${{ inputs.token }}
export GITHUB_ACTOR=${{ github.triggering_actor }}
export RH_REPOSITORY=${{ inputs.target }}
if [ ! -z ${{ inputs.branch }} ]; then
export RH_BRANCH=${{ inputs.branch }}
fi
export RH_DRY_RUN=${{ inputs.dry_run }}

python -m jupyter_releaser.actions.publish_changelog

- shell: bash -eux {0}
run: |
echo "## Next Step" >> $GITHUB_STEP_SUMMARY
echo "Merge the changelog update PR: ${{ steps.publish-changelog.outputs.pr_url }}" >> $GITHUB_STEP_SUMMARY
5 changes: 5 additions & 0 deletions .github/workflows/prep-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ on:
post_version_spec:
description: "Post Version Specifier"
required: false
silent:
description: "Set a placeholder in the changelog and don't publish the release."
required: false
type: boolean
since:
description: "Use PRs with activity since this date or git reference"
required: false
Expand All @@ -41,6 +45,7 @@ jobs:
post_version_spec: ${{ github.event.inputs.post_version_spec }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}
silent: ${{ github.event.inputs.silent }}
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/publish-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: "Publish Changelog"
on:
workflow_dispatch:
inputs:
token:
description: "GitHub access token"
required: true
target:
description: "The owner/repo GitHub target"
required: true
branch:
description: "The branch to target"
required: false

jobs:
publish_changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Install Dependencies
shell: bash
run: |
pip install -e .
- name: Publish changelog
id: publish-changelog
uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}

- name: "** Next Step **"
run: |
echo "Merge the changelog update PR: ${{ steps.publish-changelog.outputs.pr_url }}"
14 changes: 13 additions & 1 deletion docs/source/get_started/making_release_from_releaser.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,22 @@ already uses Jupyter Releaser.
to the next minor version directly. Note: The "next" and "patch" options
are not available when using dev versions, you must use explicit versions
instead.

- Use the "since" field to select PRs prior to the latest tag to include in the release
- Type "true" in the "since the last stable git tag" if you would like to include PRs since the last non-prerelease version tagged on the target repository and branch.

- Check "Use PRs with activity since the last stable git tag" if you would like to include PRs since the last non-prerelease version tagged on the target repository and branch.

- Check "Set a placeholder in the changelog and don't publish the release" if
you want to carry a silent release (e.g. in case of a security release).
That option will change the default behavior by keeping the version
changelog only in the GitHub release and keeping it private (aka in _Draft_
state). The changelog file will only contains a placeholder to be replaced
by the release body once the maintainers have chosen to publish the release.

- The additional "Post Version Spec" field should be used if your repo uses a dev version (e.g. 0.7.0.dev0)

- The workflow will use the GitHub API to find the relevant pull requests and make an appropriate changelog entry.

- The workflow will create a draft GitHub release to the target
repository and branch, with the draft changelog contents.

Expand Down
9 changes: 8 additions & 1 deletion docs/source/get_started/making_release_from_repo.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ already uses Jupyter Releaser using workflows on its own repository.

- Use the "since" field to select PRs prior to the latest tag to include in the release

- Type "true" in the "since the last stable git tag" if you would like to include PRs since the last non-prerelease version tagged on the target repository and branch.
- Check "Use PRs with activity since the last stable git tag" if you would like to include PRs since the last non-prerelease version tagged on the target repository and branch.

- The additional "Post Version Spec" field should be used if your repo uses a dev version (e.g. 0.7.0.dev0)

- Check "Set a placeholder in the changelog and don't publish the release" if
you want to carry a silent release (e.g. in case of a security release).
That option will change the default behavior by keeping the version
changelog only in the GitHub release and keeping it private (aka in _Draft_
state). The changelog file will only contains a placeholder to be replaced
by the release body once the maintainers have chosen to publish the release.

- The workflow will use the GitHub API to find the relevant pull requests and make an appropriate changelog entry.

- The workflow will create a draft GitHub release to the target
Expand Down
Binary file modified docs/source/images/prep_release.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/source/images/prep_release_repo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions example-workflows/full-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
post_version_spec:
description: "Post Version Specifier"
required: false
# silent:
# description: "Set a placeholder in the changelog and don't publish the release."
# required: false
# type: boolean
since:
description: "Use PRs with activity since this date or git reference"
required: false
Expand Down Expand Up @@ -40,6 +44,7 @@ jobs:
version_spec: ${{ github.event.inputs.version_spec }}
post_version_spec: ${{ github.event.inputs.post_version_spec }}
branch: ${{ github.event.inputs.branch }}
# silent: ${{ github.event.inputs.silent }}
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

Expand Down
5 changes: 5 additions & 0 deletions example-workflows/prep-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
post_version_spec:
description: "Post Version Specifier"
required: false
# silent:
# description: "Set a placeholder in the changelog and don't publish the release."
# required: false
# type: boolean
since:
description: "Use PRs with activity since this date or git reference"
required: false
Expand All @@ -33,6 +37,7 @@ jobs:
version_spec: ${{ github.event.inputs.version_spec }}
post_version_spec: ${{ github.event.inputs.post_version_spec }}
branch: ${{ github.event.inputs.branch }}
# silent: ${{ github.event.inputs.silent }}
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

Expand Down
29 changes: 29 additions & 0 deletions example-workflows/publish-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: "Publish Changelog"
on:
release:
types: [published]

workflow_dispatch:
inputs:
token:
description: "GitHub access token"
required: true
branch:
description: "The branch to target"
required: false

jobs:
publish_changelog:
runs-on: ubuntu-latest
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Publish changelog
id: publish-changelog
uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
branch: ${{ github.event.inputs.branch }}

- name: "** Next Step **"
run: |
echo "Merge the changelog update PR: ${{ steps.publish-changelog.outputs.pr_url }}"
20 changes: 20 additions & 0 deletions jupyter_releaser/actions/publish_changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Remove silent placeholder entries in the changelog."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import os

from jupyter_releaser.actions.common import run_action, setup
from jupyter_releaser.util import CHECKOUT_NAME, get_default_branch

setup(False)

run_action("jupyter-releaser prep-git")

# Handle the branch.
if not os.environ.get("RH_BRANCH"):
cur_dir = os.getcwd()
os.chdir(CHECKOUT_NAME)
os.environ["RH_BRANCH"] = get_default_branch() or ""
os.chdir(cur_dir)

run_action("jupyter-releaser publish-changelog")
92 changes: 87 additions & 5 deletions jupyter_releaser/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
# Distributed under the terms of the Modified BSD License.
import re
from pathlib import Path
from typing import Optional

import mdformat
from fastcore.net import HTTP404NotFoundError # type:ignore[import-untyped]
from github_activity import generate_activity_md # type:ignore[import-untyped]

from jupyter_releaser import util

START_MARKER = "<!-- <START NEW CHANGELOG ENTRY> -->"
END_MARKER = "<!-- <END NEW CHANGELOG ENTRY> -->"
START_SILENT_MARKER = "<!-- START SILENT CHANGELOG ENTRY -->"
END_SILENT_MARKER = "<!-- END SILENT CHANGELOG ENTRY -->"
PR_PREFIX = "Automated Changelog Entry"
PRECOMMIT_PREFIX = "[pre-commit.ci] pre-commit autoupdate"

Expand Down Expand Up @@ -171,7 +176,7 @@ def build_entry(
update_changelog(changelog_path, entry)


def update_changelog(changelog_path, entry):
def update_changelog(changelog_path, entry, silent=False):
"""Update a changelog with a new entry."""
# Get the new version
version = util.get_version()
Expand All @@ -187,14 +192,86 @@ def update_changelog(changelog_path, entry):
msg = "Insert marker appears more than once in changelog"
raise ValueError(msg)

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


def insert_entry(changelog, entry, version=None):
def remove_placeholder_entries(
repo: str,
auth: Optional[str],
changelog_path: str,
dry_run: bool,
) -> int:
"""Replace any silent marker with the GitHub release body
if the release has been published.

Parameters
----------
repo : str
The GitHub owner/repo
auth : str
The GitHub authorization token
changelog_path : str
The changelog file path
dry_run: bool

Returns
-------
int
Number of placeholders removed
"""

changelog = Path(changelog_path).read_text(encoding="utf-8")
start_count = changelog.count(START_SILENT_MARKER)
end_count = changelog.count(END_SILENT_MARKER)
if start_count != end_count:
msg = ""
raise ValueError(msg)

repo = repo or util.get_repo()
owner, repo_name = repo.split("/")
gh = util.get_gh_object(dry_run=dry_run, owner=owner, repo=repo_name, token=auth)

# Replace silent placeholder by release body if it has been published
previous_index = None
changes_count = 0
for _ in range(start_count):
start = changelog.index(START_SILENT_MARKER, previous_index)
end = changelog.index(END_SILENT_MARKER, start)

version = _extract_version(changelog[start + len(START_SILENT_MARKER) : end])
try:
util.log(f"Getting release for tag '{version}'...")
release = gh.repos.get_release_by_tag(owner=owner, repo=repo_name, tag=f"v{version}")
except HTTP404NotFoundError:
# Skip this version
pass
else:
if not release.draft:
changelog_text = mdformat.text(release.body)
changelog = (
changelog[:start]
+ f"\n\n{changelog_text}\n\n"
+ changelog[end + len(END_SILENT_MARKER) :]
)
changes_count += 1

previous_index = end

# Write back the new changelog
Path(changelog_path).write_text(format(changelog), encoding="utf-8")
return changes_count


def insert_entry(
changelog: str, entry: str, version: Optional[str] = None, silent: bool = False
) -> str:
"""Insert the entry into the existing changelog."""
# Test if we are augmenting an existing changelog entry (for new PRs)
# Preserve existing PR entries since we may have formatted them
if silent:
entry = f"{START_SILENT_MARKER}\n\n## {version}\n\n{END_SILENT_MARKER}"

new_entry = f"{START_MARKER}\n\n{entry}\n\n{END_MARKER}"
prev_entry = changelog[
changelog.index(START_MARKER) : changelog.index(END_MARKER) + len(END_MARKER)
Expand All @@ -218,7 +295,7 @@ def insert_entry(changelog, entry, version=None):
return format(changelog)


def format(changelog): # noqa
def format(changelog: str) -> str: # noqa A001
"""Clean up changelog formatting"""
changelog = re.sub(r"\n\n+", r"\n\n", changelog)
return re.sub(r"\n\n+$", r"\n", changelog)
Expand Down Expand Up @@ -349,7 +426,12 @@ def extract_current(changelog_path):
def extract_current_version(changelog_path):
"""Extract the current released version from the changelog"""
body = extract_current(changelog_path)
match = re.match(r"#+ (\d\S+)", body.strip())
return _extract_version(body)


def _extract_version(entry: str) -> str:
"""Extract version from entry"""
match = re.match(r"#+ (\d\S+)", entry.strip())
if not match:
msg = "Could not find previous version"
raise ValueError(msg)
Expand Down
Loading