Skip to content

Commit

Permalink
MRG: Merge pull request #1 from octue/enhancement/finish-github-action
Browse files Browse the repository at this point in the history
Finish GitHub action
  • Loading branch information
cortadocodes authored Oct 3, 2022
2 parents 2ba63f6 + 1e7929a commit 1b80042
Show file tree
Hide file tree
Showing 18 changed files with 474 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ jobs:
- name: Build and push
uses: docker/[email protected]
with:
context: ./generate_pull_request_description
context: .
push: true
tags: octue/generate-pull-request-description:${{ github.event.inputs.tag }}
11 changes: 9 additions & 2 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
fetch-depth: 0
- uses: octue/conventional-commits/[email protected]
with:
version_source_type: setup.py
version_source_type: pyproject.toml

tests:
if: "!contains(github.event.head_commit.message, 'skipci')"
Expand All @@ -28,18 +28,25 @@ jobs:
USING_COVERAGE: '3.10'
strategy:
matrix:
python: [3.10]
python: ['3.10']
steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}

- name: Install Poetry
uses: snok/install-poetry@v1

- name: Install tox
run: pip install tox

- name: Run tests
run: tox

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
Expand Down
25 changes: 17 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,25 @@ jobs:
if: "github.event.pull_request.merged == true"
runs-on: ubuntu-latest
env:
USING_COVERAGE: '3.8'
strategy:
matrix:
python: [ 3.8 ]
USING_COVERAGE: '3.10'
steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
python-version: '3.10'

- name: Install Poetry
uses: snok/install-poetry@v1

- name: Install tox
run: pip install tox

- name: Run tests
run: tox

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
Expand All @@ -39,8 +43,13 @@ jobs:
needs: tests
steps:
- uses: actions/checkout@v3

- name: Install Poetry
uses: snok/install-poetry@v1

- name: Get package version
run: echo "PACKAGE_VERSION=$(python setup.py --version)" >> $GITHUB_ENV
run: echo "PACKAGE_VERSION=$(poetry version -s)" >> $GITHUB_ENV

- name: Create Release
uses: actions/create-release@v1
env:
Expand All @@ -60,7 +69,7 @@ jobs:
uses: actions/checkout@v3

- name: Get package version
run: echo "PACKAGE_VERSION=$(python setup.py --version)" >> $GITHUB_ENV
run: echo "PACKAGE_VERSION=$(poetry version -s)" >> $GITHUB_ENV

- name: Log in to DockerHub
uses: docker/login-action@v2
Expand All @@ -71,6 +80,6 @@ jobs:
- name: Build and push
uses: docker/[email protected]
with:
context: ./generate_pull_request
context: .
push: true
tags: octue/generate-pull-request-description:${{ env.PACKAGE_VERSION }},octue/generate-pull-request-description:latest
4 changes: 3 additions & 1 deletion .github/workflows/update-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: octue/generate-pull-request-description@main
with:
pull_request_url: ${{ github.event.pull_request.url }}
api_token: ${{ secrets.GITHUB_TOKEN }}

- name: Update pull request body
uses: riskledger/update-pr-description@v2
with:
body: ${{ env.RELEASE_NOTES }}
body: ${{ env.PULL_REQUEST_DESCRIPTION }}
token: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea/
__pycache__
53 changes: 53 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
exclude: 'build|.git|.tox|dist|octue.egg-info'
default_stages: [commit]
fail_fast: true
default_language_version:
python: python3 # force all unspecified python hooks to run python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files

- repo: https://github.com/PyCQA/isort
rev: 5.8.0
hooks:
- id: isort

- repo: https://github.com/psf/black
rev: 21.5b2
hooks:
- id: black
args: ['--line-length', '120']

- repo: https://gitlab.com/pycqa/flake8
rev: 3.9.2
hooks:
- id: flake8
language_version: python3

- repo: https://github.com/windpioneers/pre-commit-hooks
rev: 0.0.5
hooks:
- id: check-branch-name
args:
- '^main$'
- '^development$'
- '^devops/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^doc/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^enhancement/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^feature/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^fix/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^hotfix/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^review/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^refactor/([a-z][a-z0-9]*)(-[a-z0-9]+)*$'
- '^release/(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'

- repo: https://github.com/octue/conventional-commits
rev: 0.7.0
hooks:
- id: check-commit-message-is-conventional
stages: [commit-msg]
4 changes: 2 additions & 2 deletions generate_pull_request_description/Dockerfile → Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ FROM python:3.10.7-slim

RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*

RUN pip3 install git+https://github.com/octue/generate-pull-request-description.git@main
RUN pip3 install git+https://github.com/octue/generate-pull-request-description.git@1.0.0.beta-0

COPY entrypoint.sh /entrypoint.sh
COPY generate_pull_request_description/entrypoint.sh /entrypoint.sh

RUN chmod +x entrypoint.sh

Expand Down
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Pull request description generator
A GitHub action and command-line tool that generates pull request descriptions from Conventional Commit messages on a
branch. These descriptions can be used with other GitHub actions to automate release notes.

**Features**
- Automatic breaking change highlighting and upgrade instructions
- Automatic categorisation of all commit messages in the pull request branch
- Choosing which part of the description to generate, enabling descriptions containing a generated section alongside
static/developer-written sections
- Easy skipping of description updating when you're ready to fine-tune and edit the description

## GitHub action
The generator can easily be used as a step in a GitHub workflow alongside the
[`riskledger/update-pr-description`](https://github.com/riskledger/update-pr-description) action:

```yaml
steps:
- uses: actions/checkout@v3

- uses: octue/[email protected]
with:
pull_request_url: ${{ github.event.pull_request.url }}
api_token: ${{ secrets.GITHUB_TOKEN }}

- name: Update pull request body
uses: riskledger/update-pr-description@v2
with:
body: ${{ env.PULL_REQUEST_DESCRIPTION }}
token: ${{ secrets.GITHUB_TOKEN }}
```
The generated description is available from the environment variable `PULL_REQUEST_DESCRIPTION` instead of as an output
of the action (`::set-output...` only works with single-line outputs). It's accessible from
`${{ env.PULL_REQUEST_DESCRIPTION }}` at any point in the workflow job it was used in.

## CLI
```shell
usage: generate-pull-request-description [-h] [--pull-request-url PULL_REQUEST_URL] [--api-token API_TOKEN] [--header HEADER] [--list-item-symbol LIST_ITEM_SYMBOL] [--no-link-to-pull-request] {LAST_RELEASE,PULL_REQUEST_START}
positional arguments:
{LAST_RELEASE,PULL_REQUEST_START}
The point in the git history to stop compiling commits into the pull request description.
options:
-h, --help show this help message and exit
--pull-request-url PULL_REQUEST_URL
Provide the API URL of a pull request (e.g. https://api.github.com/repos/octue/conventional-commits/pulls/1) if you want to update a pull request's description with the generated release notes. It must be
provided alongside --api-token if the repository is private.
--api-token API_TOKEN
A valid GitHub API token for the repository the pull request belongs to. There is no need to provide this if the repository is public.
--header HEADER The header (including MarkDown styling) to put the release notes under. Default is '# Contents'
--list-item-symbol LIST_ITEM_SYMBOL
The MarkDown list item symbol to use for listing commit messages in the release notes. Default is '- '
--no-link-to-pull-request
If provided, don't add a link to the given pull request in the release notes.
```

## Features

### Breaking change highlighting
If breaking changes are indicated in any of the commit messages' bodies via `BREAKING CHANGE:` or `BREAKING-CHANGE:`,
these commits are marked and a warning is added to the top of the release notes. Any other text in these sections is
treated as upgrade instructions and added to the end of the pull request description.

### Choosing which section of the description to update
The only part of the pull request description that is updated by the action is the section bounded by:
- `<!--- START AUTOGENERATED NOTES --->`
- `<!--- END AUTOGENERATED NOTES --->`

This section will always be replaced with a summary of all the commit messages in the pull request so far. The markers
(invisible in rendered markdown) are added in automatically when the action first runs, but you can move them manually.
Any text you add outside of these will remain untouched so you can add, for example, your own static summary of the
pull request while having a dynamic summary of the commits.

### Skipping description updates
Updating the description is skipped if the `<!--- SKIP AUTOGENERATED NOTES --->` marker is present anywhere in the pull
request description. This allows commits to be documented in the description until you're ready to fine-tune or
cherry-pick commit descriptions when your pull request is ready for review.
5 changes: 1 addition & 4 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ inputs:
description: 'The MarkDown list item symbol to use for listing commit messages in the release notes.'
required: false
default: '-'
outputs:
release_notes:
description: 'The release notes generated from the Conventional Commits on the pull request branch.'
runs:
using: 'docker'
image: 'Dockerfile'
image: 'docker://octue/generate-pull-request-description:1.0.0.beta-0'
args:
- ${{ inputs.pull_request_url }}
- ${{ inputs.api_token }}
Expand Down
Empty file.
4 changes: 2 additions & 2 deletions generate_pull_request_description/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh -l
cd $GITHUB_WORKSPACE

echo 'RELEASE_NOTES<<EOF' >> $GITHUB_ENV
echo "$(compile-release-notes PULL_REQUEST_START --pull-request-url="$1" --api-token="$2" --header="$3" --list-item-symbol="$4")" >> $GITHUB_ENV
echo 'PULL_REQUEST_DESCRIPTION<<EOF' >> $GITHUB_ENV
echo "$(generate-pull-request-description PULL_REQUEST_START --pull-request-url="$1" --api-token="$2" --header="$3" --list-item-symbol="$4")" >> $GITHUB_ENV
echo EOF >> $GITHUB_ENV
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@
SKIP_INDICATOR = "<!--- SKIP AUTOGENERATED NOTES --->"


class ReleaseNotesCompiler:
"""A release/pull request notes compiler. The notes are pulled together from Conventional Commit messages, stopping
at the specified stop point. The stop point can either be the last merged pull request in the branch or the last
semantically-versioned release tagged in the branch. If previous notes are provided, only the text between the
comment lines `<!--- START AUTOGENERATED NOTES --->` and `<!--- END AUTOGENERATED NOTES --->` will be replaced -
anything outside of this will appear in the new release notes.
class PullRequestDescriptionGenerator:
"""A pull request description generator that can be used to generate release notes. The notes are pulled together
from Conventional Commit messages, stopping at the specified stop point. The stop point can either be the last
merged pull request in the branch or the last semantically-versioned release tagged in the branch. If previous
notes are provided, only the text between the comment lines `<!--- START AUTOGENERATED NOTES --->` and
`<!--- END AUTOGENERATED NOTES --->` will be replaced - anything outside of this will appear in the new release
notes.
:param str stop_point: the point in the git history up to which commit messages should be used - should be either "LAST_RELEASE" or "PULL_REQUEST_START"
:param str|None pull_request_url: GitHub API URL for the pull request - this can be accessed in a GitHub workflow as ${{ github.event.pull_request.url }}
Expand Down Expand Up @@ -95,8 +96,8 @@ def __init__(

logger.info(f"Using {self.stop_point!r} stop point.")

def compile_release_notes(self):
"""Compile the commit messages since the given stop point into a new set of release notes, sorting them into
def generate(self):
"""Generate a pull request description from the commit messages since the given stop point, sorting them into
headed sections according to their commit codes via the commit-codes-to-headings mapping. If the previous set
of release notes have been provided then:
Expand Down Expand Up @@ -408,7 +409,7 @@ def main(argv=None):
parser.add_argument(
"stop_point",
choices=STOP_POINTS,
help="The point in the git history to stop compiling commits into the release notes.",
help="The point in the git history to stop compiling commits into the pull request description.",
)

parser.add_argument(
Expand Down Expand Up @@ -448,14 +449,14 @@ def main(argv=None):

args = parser.parse_args(argv)

release_notes = ReleaseNotesCompiler(
release_notes = PullRequestDescriptionGenerator(
stop_point=args.stop_point,
pull_request_url=args.pull_request_url,
api_token=args.api_token,
header=args.header,
list_item_symbol=args.list_item_symbol,
include_link_to_pull_request=not args.no_link_to_pull_request,
).compile_release_notes()
).generate()

print(release_notes)

Expand Down
10 changes: 5 additions & 5 deletions mkver.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ defaults {
buildMetaDataFormat: "{Branch}.{ShortHash}"
includeBuildMetaData: false
whenNoValidCommitMessages: IncrementPatch
patches: [setup.py]
patches: [pyproject.toml]
}

patches: [
{
name: setup.py
filePatterns: ["setup.cfg"]
name: pyproject.toml
filePatterns: ["pyproject.toml"]
replacements: [
{
find: "version = {VersionRegex}"
replace: "version = {Version}"
find: "version = \"{VersionRegex}\""
replace: "version = \"{Version}\""
}
]
}
Expand Down
Loading

0 comments on commit 1b80042

Please sign in to comment.