diff --git a/plugin-template b/plugin-template index 4df95067..8c3b431d 100755 --- a/plugin-template +++ b/plugin-template @@ -107,6 +107,7 @@ DEPRECATED_FILES = { ".ci/scripts/upper_bound.py", ".github/workflows/fips.yml", ".github/workflows/scripts/create_release_from_tag.sh", + ".github/workflows/scripts/release.py", ".github/workflows/scripts/stage-changelog-for-master.py", ".github/workflows/scripts/update_ci.sh", ".travis", @@ -384,8 +385,6 @@ def write_template_section(config, name, plugin_root_dir, verbose=False): for relative_path in generate_relative_path_set(section_template_dir): if not config["stalebot"] and "stale" in relative_path: continue - if config["issue_tracker"] != "github" and "update_github" in relative_path: - continue if config["use_issue_template"] is False and "ISSUE_TEMPLATE" in relative_path: continue if config["kanban"] is False and "kanban" in relative_path: diff --git a/templates/github/.github/workflows/publish.yml.j2 b/templates/github/.github/workflows/publish.yml.j2 new file mode 100644 index 00000000..b63f7a8e --- /dev/null +++ b/templates/github/.github/workflows/publish.yml.j2 @@ -0,0 +1,270 @@ +{% include 'header.j2' %} +{% from 'macros.j2' import + set_env_vars, + checkout, + setup_python, + setup_ruby, + display_logs, + run_script, + set_secrets, + install_python_deps, + configure_git, +with context %} +--- +name: "{{ plugin_app_label | camel }} Publish Release" +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]" + +defaults: + run: + working-directory: "{{ plugin_name }}" + +jobs: + build: + uses: "./.github/workflows/build.yml" + + build-bindings-docs: + needs: + - "build-artifacts" + runs-on: "ubuntu-latest" + # Install scripts expect TEST to be set, 'docs' is most appropriate even though we don't run tests + env: + TEST: "docs" + steps: + {{ checkout(depth=1, path=plugin_name) | indent(6) }} + + {{ checkout(repository="pulp/pulp-openapi-generator", path="pulp-openapi-generator") | indent(6) }} + + {{ setup_python() | indent(6) }} + + - uses: "actions/download-artifact@v3" + with: + name: "plugin_package" + path: "{{ plugin_name }}/dist/" + + {%- if deploy_client_to_rubygems %} + {{ setup_ruby() | indent(6) }} + {%- endif %} + + {{ install_python_deps(["towncrier", "twine", "wheel", "httpie", "docker", "netaddr", "boto3", "ansible", "mkdocs"]) | indent(6) }} + + # Building the bindings and docs requires accessing the OpenAPI specs endpoint, so we need to + # setup the Pulp instance. + {{ run_script(name="Before Install", file="before_install.sh") | indent(6) }} + + {{ run_script(name="Install", file="install.sh") | indent(6) }} + + {{ run_script(name="Install Python client", file="install_python_client.sh", withenv=False) | indent(6) }} + + {%- if deploy_client_to_rubygems %} + {{ run_script(name="Install Ruby client", file="install_ruby_client.sh", withenv=False) | indent(6) }} + {%- endif %} + + {%- for plugin in plugins %} + - name: "Upload python client packages" + uses: "actions/upload-artifact@v3" + with: + name: "python-client.tar" + path: "{{ plugin_name }}/{{ plugin.app_label }}-python-client.tar" + if-no-files-found: "error" + + - name: "Upload python client docs" + uses: "actions/upload-artifact@v3" + with: + name: "python-client-docs.tar" + path: "{{ plugin_name }}/{{ plugin.app_label }}-python-client-docs.tar" + if-no-files-found: "error" + + {%- if deploy_client_to_rubygems %} + - name: "Upload ruby client packages" + uses: "actions/upload-artifact@v3" + with: + name: "ruby-client.tar" + path: "{{ plugin_name }}/{{ plugin.app_label }}-ruby-client.tar" + if-no-files-found: "error" + {%- endif %} + {%- endfor %} + + {%- if publish_docs_to_pulpprojectdotorg %} + - name: Build docs + run: | + export DJANGO_SETTINGS_MODULE=pulpcore.app.settings + export PULP_SETTINGS=$PWD/.ci/ansible/settings/settings.py + make -C docs/ PULP_URL="{{ pulp_scheme }}://pulp" diagrams html + tar -cvf docs/docs.tar docs/_build + + - name: "Upload built docs" + uses: actions/upload-artifact@v3 + with: + name: "docs.tar" + path: "{{ plugin_name }}/docs/docs.tar" + {%- endif %} + + {{ display_logs() | indent(6) }} + + {%- if deploy_to_pypi %} + publish-package: + runs-on: "ubuntu-latest" + needs: + - "build-bindings-docs" + + env: + GITHUB_TOKEN: "{{ '${{ secrets.GITHUB_TOKEN }}' }}" + + steps: + {{ checkout(depth=1, path=plugin_name) | indent(6) }} + + - uses: "actions/download-artifact@v3" + with: + name: "plugin_package" + path: "{{ plugin_name }}/dist/" + + {{ setup_python(pyversion="3.8") | indent(6) }} + + {{ install_python_deps(["twine"]) | indent(6) }} + + {{ set_secrets() | indent(6) }} + + - name: "Deploy plugin to pypi" + run: | + .github/workflows/scripts/publish_plugin_pypi.sh {{ "${{ github.ref_name }}" }} + {%- endif %} + + {%- if deploy_client_to_pypi %} + publish-python-bindings: + runs-on: "ubuntu-latest" + needs: + - "build-bindings-docs" + + env: + GITHUB_TOKEN: "{{ '${{ secrets.GITHUB_TOKEN }}' }}" + + steps: + {{ checkout(depth=1, path=plugin_name) | indent(6) }} + + - name: "Download Python client" + uses: "actions/download-artifact@v3" + with: + name: "python-client.tar" + path: "{{ plugin_name }}/" + + - name: "Untar python client packages" + run: | + {%- for plugin in plugins %} + tar -xvf {{ plugin.app_label }}-python-client.tar + {%- endfor %} + + {{ setup_python(pyversion="3.8") | indent(6) }} + + {{ install_python_deps(["twine"]) | indent(6) }} + + {{ set_secrets() | indent(6) }} + + - name: "Publish client to pypi" + run: | + bash .github/workflows/scripts/publish_client_pypi.sh {{ "${{ github.ref_name }}" }} + {%- endif %} + + {%- if deploy_client_to_rubygems %} + publish-ruby-bindings: + runs-on: "ubuntu-latest" + needs: + - "build-bindings-docs" + + env: + GITHUB_TOKEN: "{{ "${{ secrets.GITHUB_TOKEN }}" }}" + + steps: + {{ checkout(depth=1, path=plugin_name) | indent(6) }} + + - name: "Download Ruby client" + uses: "actions/download-artifact@v3" + with: + name: "ruby-client.tar" + path: "{{ plugin_name }}/" + + - name: "Untar Ruby client packages" + run: | + {%- for plugin in plugins %} + tar -xvf {{ plugin.app_label }}-ruby-client.tar + {%- endfor %} + + {{ setup_ruby() | indent(6) }} + + {{ set_secrets() | indent(6) }} + + - name: "Publish client to rubygems" + run: | + bash .github/workflows/scripts/publish_client_gem.sh {{ "${{ github.ref_name }}" }} + {%- endif %} + + {%- if publish_docs_to_pulpprojectdotorg %} + publish-docs: + runs-on: "ubuntu-latest" + needs: + - "build-bindings-docs" + + env: + GITHUB_TOKEN: "{{ "${{ secrets.GITHUB_TOKEN }}" }}" + + steps: + {{ checkout(depth=1, path=plugin_name) | indent(6) }} + + {{ setup_python(pyversion="3.8") | indent(6) }} + + {{ install_python_deps(["packaging~=21.3", "requests"]) | indent(6) }} + + {{ set_secrets() | indent(6) }} + + - name: "Download built docs" + uses: "actions/download-artifact@v3" + with: + name: "docs.tar" + path: "{{ plugin_name }}/" + + - name: "Download Python client docs" + uses: "actions/download-artifact@v3" + with: + name: "python-client-docs.tar" + path: "{{ plugin_name }}/" + + - name: "Publish docs to pulpproject.org" + run: | + tar -xvf docs.tar + .github/workflows/scripts/publish_docs.sh tag {{ "${{ github.ref_name }}" }} + {%- endif %} + + create-gh-release: + runs-on: "ubuntu-latest" + needs: + - "build-bindings-docs" + {%- if deploy_to_pypi %} + - "publish-package" + {%- endif %} + {%- if deploy_client_to_pypi %} + - "publish-python-bindings" + {%- endif %} + {%- if deploy_client_to_rubygems %} + - "publish-ruby-bindings" + {%- endif %} + {%- if publish_docs_to_pulpprojectdotorg %} + - "publish-docs" + {%- endif %} + + steps: + - name: "Create release on GitHub" + uses: "actions/github-script@v7" + env: + TAG_NAME: "{{ '${{ github.ref_name }}' }}" + with: + script: | + const { TAG_NAME } = process.env; + + await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: TAG_NAME, + make_latest: "legacy", + }); diff --git a/templates/github/.github/workflows/release.yml.j2 b/templates/github/.github/workflows/release.yml.j2 index 46d6dae0..615c5c0c 100644 --- a/templates/github/.github/workflows/release.yml.j2 +++ b/templates/github/.github/workflows/release.yml.j2 @@ -14,9 +14,6 @@ with context %} name: {{ plugin_app_label | camel }} Release Pipeline on: workflow_dispatch: - inputs: - release: - description: "Release tag (e.g. 3.2.1)" defaults: run: @@ -34,308 +31,10 @@ jobs: {{ setup_python(pyversion="3.8") | indent(6) }} - {{ install_python_deps(["packaging~=21.3", "bump2version", "gitpython", "towncrier", "wheel", "requests"]) | indent(6) }} + {{ install_python_deps(["bump2version", "towncrier"]) | indent(6) }} {{ configure_git() | indent(6) }} {{ set_secrets() | indent(6) }} - - name: "Create the release commit, tag it, create a post-release commit, and build plugin package" - run: | - python .github/workflows/scripts/release.py {{ "${{ github.event.inputs.release }}" }} - - - name: "Upload Package whl" - uses: "actions/upload-artifact@v3" - with: - name: "plugin_package" - path: "{{ plugin_name }}/dist/" - if-no-files-found: "error" - - - name: "Tar files" - run: | - tar -cvf {{ plugin_name }}.tar . - - - name: "Upload Artifact" - uses: "actions/upload-artifact@v3" - with: - name: "{{ plugin_name }}.tar" - path: "{{ plugin_name }}/{{ plugin_name }}.tar" - - - build-bindings-docs: - needs: - - "build-artifacts" - runs-on: "ubuntu-latest" - # Install scripts expect TEST to be set, 'docs' is most appropriate even though we don't run tests - env: - TEST: "docs" - - steps: - - uses: "actions/download-artifact@v3" - with: - name: "{{ plugin_name }}.tar" - path: "{{ plugin_name }}/" - - {{ checkout(repository="pulp/pulp-openapi-generator", path="pulp-openapi-generator") | indent(6) }} - - {{ setup_python() | indent(6) }} - - {%- if deploy_client_to_rubygems %} - {{ setup_ruby() | indent(6) }} - {%- endif %} - - - name: "Untar repository" - run: | - tar -xf {{ plugin_name }}.tar - - {{ install_python_deps(["towncrier", "twine", "wheel", "httpie", "docker", "netaddr", "boto3", "ansible", "mkdocs"]) | indent(6) }} - - # Building the bindings and docs requires accessing the OpenAPI specs endpoint, so we need to - # setup the Pulp instance. - {{ run_script(name="Before Install", file="before_install.sh") | indent(6) }} - - {{ run_script(name="Install", file="install.sh") | indent(6) }} - - {{ run_script(name="Install Python client", file="install_python_client.sh", withenv=False) | indent(6) }} - - {%- if deploy_client_to_rubygems %} - {{ run_script(name="Install Ruby client", file="install_ruby_client.sh", withenv=False) | indent(6) }} - {%- endif %} - - {%- for plugin in plugins %} - - name: "Upload python client packages" - uses: "actions/upload-artifact@v3" - with: - name: "python-client.tar" - path: "{{ plugin_name }}/{{ plugin.app_label }}-python-client.tar" - if-no-files-found: "error" - - - name: "Upload python client docs" - uses: "actions/upload-artifact@v3" - with: - name: "python-client-docs.tar" - path: "{{ plugin_name }}/{{ plugin.app_label }}-python-client-docs.tar" - if-no-files-found: "error" - - {%- if deploy_client_to_rubygems %} - - name: "Upload ruby client packages" - uses: "actions/upload-artifact@v3" - with: - name: "ruby-client.tar" - path: "{{ plugin_name }}/{{ plugin.app_label }}-ruby-client.tar" - if-no-files-found: "error" - {%- endif %} - {%- endfor %} - - {%- if publish_docs_to_pulpprojectdotorg %} - - name: Build docs - run: | - export DJANGO_SETTINGS_MODULE=pulpcore.app.settings - export PULP_SETTINGS=$PWD/.ci/ansible/settings/settings.py - make -C docs/ PULP_URL="{{ pulp_scheme }}://pulp" diagrams html - tar -cvf docs/docs.tar docs/_build - - - name: "Upload built docs" - uses: actions/upload-artifact@v3 - with: - name: "docs.tar" - path: "{{ plugin_name }}/docs/docs.tar" - {%- endif %} - - {{ display_logs() | indent(6) }} - - - publish-tag: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - env: - GITHUB_TOKEN: "{{ '${{ secrets.GITHUB_TOKEN }}' }}" - - steps: - - uses: "actions/download-artifact@v3" - with: - name: "{{ plugin_name }}.tar" - path: "{{ plugin_name }}/" - - - name: "Untar repository" - run: | - tar -xf {{ plugin_name }}.tar - - {{ configure_git() | indent(6) }} - - {{ set_secrets() | indent(6) }} - - - name: "Push branch and tag to GitHub" - run: | - bash .github/workflows/scripts/push_branch_and_tag_to_github.sh {{ "${{ github.event.inputs.release }}" }} - - {%- if deploy_to_pypi %} - publish-package: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - "publish-tag" - - env: - GITHUB_TOKEN: "{{ '${{ secrets.GITHUB_TOKEN }}' }}" - - steps: - {{ checkout(depth=1, path=plugin_name) | indent(6) }} - - - uses: "actions/download-artifact@v3" - with: - name: "plugin_package" - path: "{{ plugin_name }}/dist/" - - {{ setup_python(pyversion="3.8") | indent(6) }} - - {{ install_python_deps(["twine"]) | indent(6) }} - - {{ set_secrets() | indent(6) }} - - - name: "Deploy plugin to pypi" - run: | - .github/workflows/scripts/publish_plugin_pypi.sh {{ "${{ github.event.inputs.release }}" }} - {%- endif %} - - {%- if deploy_client_to_pypi %} - publish-python-bindings: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - "publish-tag" - env: - GITHUB_TOKEN: "{{ '${{ secrets.GITHUB_TOKEN }}' }}" - - steps: - {{ checkout(depth=1, path=plugin_name) | indent(6) }} - - - name: "Download Python client" - uses: "actions/download-artifact@v3" - with: - name: "python-client.tar" - path: "{{ plugin_name }}/" - - - name: "Untar python client packages" - run: | - {%- for plugin in plugins %} - tar -xvf {{ plugin.app_label }}-python-client.tar - {%- endfor %} - - {{ setup_python(pyversion="3.8") | indent(6) }} - - {{ install_python_deps(["twine"]) | indent(6) }} - - {{ set_secrets() | indent(6) }} - - - name: "Publish client to pypi" - run: | - bash .github/workflows/scripts/publish_client_pypi.sh {{ "${{ github.event.inputs.release }}" }} - {%- endif %} - - {%- if deploy_client_to_rubygems %} - publish-ruby-bindings: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - "publish-tag" - - env: - GITHUB_TOKEN: "{{ "${{ secrets.GITHUB_TOKEN }}" }}" - - steps: - {{ checkout(depth=1, path=plugin_name) | indent(6) }} - - - name: "Download Ruby client" - uses: "actions/download-artifact@v3" - with: - name: "ruby-client.tar" - path: "{{ plugin_name }}/" - - - name: "Untar Ruby client packages" - run: | - {%- for plugin in plugins %} - tar -xvf {{ plugin.app_label }}-ruby-client.tar - {%- endfor %} - - {{ setup_ruby() | indent(6) }} - - {{ set_secrets() | indent(6) }} - - - name: "Publish client to rubygems" - run: | - bash .github/workflows/scripts/publish_client_gem.sh {{ "${{ github.event.inputs.release }}" }} - {%- endif %} - - {%- if publish_docs_to_pulpprojectdotorg %} - publish-docs: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - "publish-tag" - - env: - GITHUB_TOKEN: "{{ "${{ secrets.GITHUB_TOKEN }}" }}" - - steps: - {{ checkout(depth=1, path=plugin_name) | indent(6) }} - - {{ setup_python(pyversion="3.8") | indent(6) }} - - {{ install_python_deps(["packaging~=21.3", "requests"]) | indent(6) }} - - {{ set_secrets() | indent(6) }} - - - name: "Download built docs" - uses: "actions/download-artifact@v3" - with: - name: "docs.tar" - path: "{{ plugin_name }}/" - - - name: "Download Python client docs" - uses: "actions/download-artifact@v3" - with: - name: "python-client-docs.tar" - path: "{{ plugin_name }}/" - - - name: "Publish docs to pulpproject.org" - run: | - tar -xvf docs.tar - .github/workflows/scripts/publish_docs.sh tag {{ "${{ github.event.inputs.release }}" }} - {%- endif %} - - create-gh-release: - runs-on: "ubuntu-latest" - needs: - - "build-bindings-docs" - - "publish-tag" - {%- if deploy_to_pypi %} - - "publish-package" - {%- endif %} - {%- if deploy_client_to_pypi %} - - "publish-python-bindings" - {%- endif %} - {%- if deploy_client_to_rubygems %} - - "publish-ruby-bindings" - {%- endif %} - {%- if publish_docs_to_pulpprojectdotorg %} - - "publish-docs" - {%- endif %} - - steps: - - name: "Create release on GitHub" - uses: "actions/github-script@v7" - env: - TAG_NAME: "{{ '${{ inputs.release }}' }}" - with: - script: | - const { TAG_NAME } = process.env; - - await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: TAG_NAME, - make_latest: "legacy", - }); + {{ run_script(name="Tag the release", file="release.sh") | indent(6) }} diff --git a/templates/github/.github/workflows/scripts/release.py.j2 b/templates/github/.github/workflows/scripts/release.py.j2 deleted file mode 100644 index c14ea4c4..00000000 --- a/templates/github/.github/workflows/scripts/release.py.j2 +++ /dev/null @@ -1,172 +0,0 @@ -{% include 'header.j2' %} - -import argparse -import re -import os -import textwrap -import requests -import subprocess - -from git import Repo -from pathlib import Path - - -def get_package_from_pypi(version, plugin_path): - """ - Download a package from PyPI. - - :param version: version of the package to download from PyPI - :return: True/False if download was successful - """ - os.makedirs(os.path.join(plugin_path, "dist"), exist_ok=True) - r = requests.get(f"https://pypi.org/pypi/{{ plugin_name | dash }}/{version}/json") - if r.status_code == 200: - metadata = r.json() - for url_data in metadata["urls"]: - filename = url_data["filename"] - r2 = requests.get(url_data["url"]) - if r2.status_code != 200: - raise RuntimeError(f"Failed to download released artifact {filename}") - with open(os.path.join(plugin_path, "dist", filename), "wb") as f: - f.write(r2.content) - return True - return False - - -def create_release_commits(repo, release_version, plugin_path): - """Build changelog, set version, commit, bump to next dev version, commit.""" - issues_to_close = set() - for filename in Path(f"{plugin_path}/CHANGES").rglob("*"): - if filename.stem.isdigit(): - issue = filename.stem - issues_to_close.add(issue) - - issues = ",".join(issues_to_close) - # First commit: changelog - os.system(f"towncrier build --yes --version {release_version}") - git = repo.git - git.add("CHANGES.rst") - git.add("CHANGES/*") - git.commit("-m", f"Add changelog for {release_version}\n\n[noissue]") - - # Second commit: release version - os.system("bump2version release --allow-dirty") - - git.add(f"{plugin_path}") - git.commit("-m", f"Release {release_version}\nGH Issues: {issues}\n\n[noissue]") - sha = repo.head.object.hexsha - short_sha = git.rev_parse(sha, short=7) - - os.system("bump2version patch --allow-dirty") - - new_dev_version = None - with open(f"{plugin_path}/setup.py") as fp: - for line in fp.readlines(): - if "version=" in line: - new_dev_version = re.split("\"|'", line)[1] - if not new_dev_version: - raise RuntimeError("Could not detect new dev version ... aborting.") - - git.add(f"{plugin_path}") - git.commit("-m", f"Bump to {new_dev_version}\n\n[noissue]") - print(f"Release commit == {short_sha}") - print(f"All changes were committed on branch: release_{release_version}") - return sha - - -def create_tag_and_build_package(repo, desired_tag, commit_sha, plugin_path): - """Create a tag if one is needed and build a package if one is not on PyPI.""" - # Remove auth header config - with repo.config_writer() as conf: - conf.remove_section('http "https://github.com/"') - conf.release() - - # Determine if a tag exists and if it matches the specified commit sha - tag = None - for existing_tag in repo.tags: - if existing_tag.name == desired_tag: - if existing_tag.commit.hexsha == commit_sha: - tag = existing_tag - else: - raise RuntimeError( - f"The '{desired_tag}' tag already exists, but the commit sha does not match " - f"'{commit_sha}'." - ) - - # Create a tag if one does not exist - if not tag: - tag = repo.create_tag(desired_tag, ref=commit_sha) - - # Checkout the desired tag and reset the tree - repo.head.reference = tag.commit - repo.head.reset(index=True, working_tree=True) - - # Check if Package is available on PyPI - if not get_package_from_pypi(tag.name, plugin_path): - os.system("python3 setup.py sdist bdist_wheel --python-tag py3") - - -def main(): - helper = textwrap.dedent( - """\ - Start the release process. - - Example: - setup.py on plugin before script: - version="2.0.0.dev" - - $ python .ci/scripts/release.py - - setup.py on plugin after script: - version="2.0.1.dev" - - - """ - ) - parser = argparse.ArgumentParser( - formatter_class=argparse.RawTextHelpFormatter, description=helper - ) - - parser.add_argument( - "release_version", - type=str, - help="The version string for the release.", - nargs="?", - ) - - args = parser.parse_args() - - release_version_arg = args.release_version - - release_path = os.path.dirname(os.path.abspath(__file__)) - plugin_path = release_path.split("/.github")[0] - - output = subprocess.check_output(["bump2version", "--dry-run", "--list", "release"]) - release_version = re.findall(r"\nnew_version=([0-9.]*)\n", output.decode())[0] - - print(f"\n\nRepo path: {plugin_path}") - repo = Repo(plugin_path) - - release_commit = None - if release_version_arg and release_version != release_version_arg: - # Look for a commit with the requested release version - for commit in repo.iter_commits(): - if f"Release {release_version_arg}\n" in commit.message: - release_commit = commit - release_version = release_version_arg - break - if not release_commit: - raise RuntimeError( - f"The release version {release_version_arg} does not match the .dev version at " - "HEAD. A release commit for such version does not exist." - ) - - if not release_commit: - release_commit_sha = create_release_commits(repo, release_version, plugin_path) - else: - release_commit_sha = release_commit.hexsha - create_tag_and_build_package(repo, release_version, release_commit_sha, plugin_path) - - -if __name__ == "__main__": - main() diff --git a/templates/github/.github/workflows/scripts/release.sh b/templates/github/.github/workflows/scripts/release.sh new file mode 100755 index 00000000..9525f229 --- /dev/null +++ b/templates/github/.github/workflows/scripts/release.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -eu -o pipefail + +BRANCH=$(git branch --show-current) + +if ! [[ "${BRANCH}" =~ ^[0-9]+\.[0-9]+$ ]] +then + echo ERROR: This is not a release branch! + exit 1 +fi + +NEW_VERSION="$(bump2version --dry-run --list release | sed -ne 's/^new_version=//p')" +echo "Release ${NEW_VERSION}" + +if ! [[ "${NEW_VERSION}" == "${BRANCH}"* ]] +then + echo ERROR: Version does not match release branch + exit 1 +fi + +towncrier build --yes --version "${NEW_VERSION}" +bump2version release --commit --message "Release {new_version}" --tag --tag-name "{new_version}" --tag-message "Release {new_version}" --allow-dirty +bump2version patch --commit + +git push origin "${BRANCH}" "${NEW_VERSION}"