diff --git a/.ci/scripts/check_release.py b/.ci/scripts/check_release.py index da45be6a8..9fbb13815 100755 --- a/.ci/scripts/check_release.py +++ b/.ci/scripts/check_release.py @@ -50,10 +50,15 @@ def current_version(repo, commitish): def check_pyproject_dependencies(repo, from_commit, to_commit): try: - old_pyproject = tomllib.load(repo.show("{from_commit}:pyproject.toml")) + new_pyproject = tomllib.loads(repo.git.show(f"{to_commit}:pyproject.toml")) + try: + new_dependencies = set(new_pyproject["project"]["dependencies"]) + except KeyError: + # New branch does not declare dependencies in pyproject.toml. + # Assume no release needed for this reason. + return [] + old_pyproject = tomllib.loads(repo.git.show(f"{from_commit}:pyproject.toml")) old_dependencies = set(old_pyproject["project"]["dependencies"]) - new_pyproject = tomllib.load(repo.show("{to_commit}:pyproject.toml")) - new_dependencies = set(new_pyproject["project"]["dependencies"]) if old_dependencies != new_dependencies: return ["dependencies"] else: diff --git a/.ci/scripts/validate_commit_message.py b/.ci/scripts/validate_commit_message.py index 64c4f529e..c2f93ad97 100755 --- a/.ci/scripts/validate_commit_message.py +++ b/.ci/scripts/validate_commit_message.py @@ -5,37 +5,57 @@ # # For more info visit https://github.com/pulp/plugin_template +import os import re +import subprocess import sys +import tomllib from pathlib import Path -import subprocess -import os -import warnings + from github import Github -CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc", ".deprecation"] +with open("pyproject.toml", "rb") as fp: + PYPROJECT_TOML = tomllib.load(fp) KEYWORDS = ["fixes", "closes"] +BLOCKING_REGEX = [ + r"^DRAFT", + r"^WIP", + r"^NOMERGE", + r"^DO\s*NOT\s*MERGE", + r"^EXPERIMENT", + r"^FIXUP", + r"Apply suggestions from code review", +] +try: + CHANGELOG_EXTS = [ + f".{item['directory']}" for item in PYPROJECT_TOML["tool"]["towncrier"]["type"] + ] +except KeyError: + CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc"] +NOISSUE_MARKER = "[noissue]" sha = sys.argv[1] message = subprocess.check_output(["git", "log", "--format=%B", "-n 1", sha]).decode("utf-8") +if NOISSUE_MARKER in message: + sys.exit(f"Do not add '{NOISSUE_MARKER}' in the commit message.") + +if any((re.match(pattern, message, re.IGNORECASE) for pattern in BLOCKING_REGEX)): + sys.exit("This PR is not ready for consumption.") + g = Github(os.environ.get("GITHUB_TOKEN")) repo = g.get_repo("pulp/pulp_container") -def __check_status(issue): +def check_status(issue): gi = repo.get_issue(int(issue)) if gi.pull_request: sys.exit(f"Error: issue #{issue} is a pull request.") - if gi.closed_at and "cherry picked from commit" not in message: - warnings.warn( - "When backporting, use the -x flag to append a line that says " - "'(cherry picked from commit ...)' to the original commit message." - ) + if gi.closed_at: sys.exit(f"Error: issue #{issue} is closed.") -def __check_changelog(issue): +def check_changelog(issue): matches = list(Path("CHANGES").rglob(f"{issue}.*")) if len(matches) < 1: @@ -43,21 +63,20 @@ def __check_changelog(issue): for match in matches: if match.suffix not in CHANGELOG_EXTS: sys.exit(f"Invalid extension for changelog entry '{match}'.") - if match.suffix == ".feature" and "cherry picked from commit" in message: - sys.exit(f"Can not backport '{match}' as it is a feature.") print("Checking commit message for {sha}.".format(sha=sha[0:7])) # validate the issue attached to the commit -regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS)) -pattern = re.compile(regex, re.IGNORECASE) - -issues = pattern.findall(message) +issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS)) +issues = re.findall(issue_regex, message, re.IGNORECASE) +cherry_pick_regex = r"^\s*\(cherry picked from commit [0-9a-f]*\)\s*$" +cherry_pick = re.search(cherry_pick_regex, message, re.MULTILINE) if issues: - for issue in pattern.findall(message): - __check_status(issue) - __check_changelog(issue) + for issue in issues: + if not cherry_pick: + check_status(issue) + check_changelog(issue) print("Commit message for {sha} passed.".format(sha=sha[0:7])) diff --git a/.github/template_gitref b/.github/template_gitref index 22e8d0a9d..5c888ec58 100644 --- a/.github/template_gitref +++ b/.github/template_gitref @@ -1 +1 @@ -2021.08.26-406-g5f397e3 +2021.08.26-415-g804d8f6 diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index ec114480b..e3851f98d 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -9,7 +9,13 @@ name: "Container PR static checks" on: pull_request_target: - types: ["opened", "synchronize", "reopened"] + types: + - "opened" + - "synchronize" + - "reopened" + branches: + - "main" + - "[0-9]+.[0-9]+" # This workflow runs with elevated permissions. # Do not even think about running a single bit of code from the PR. diff --git a/.github/workflows/scripts/check_commit.sh b/.github/workflows/scripts/check_commit.sh index c5dbcdbdc..53ac71bc6 100755 --- a/.github/workflows/scripts/check_commit.sh +++ b/.github/workflows/scripts/check_commit.sh @@ -15,8 +15,4 @@ set -euv for SHA in $(curl -H "Authorization: token $GITHUB_TOKEN" "$GITHUB_CONTEXT" | jq -r '.[].sha') do python3 .ci/scripts/validate_commit_message.py "$SHA" - VALUE=$? - if [ "$VALUE" -gt 0 ]; then - exit $VALUE - fi done diff --git a/.github/workflows/scripts/publish_client_gem.sh b/.github/workflows/scripts/publish_client_gem.sh index 7d5c13279..340370e35 100755 --- a/.github/workflows/scripts/publish_client_gem.sh +++ b/.github/workflows/scripts/publish_client_gem.sh @@ -14,22 +14,15 @@ cd "$(dirname "$(realpath -e "$0")")"/../../.. VERSION="$1" -if [[ -z "$VERSION" ]]; then +if [[ -z "${VERSION}" ]] +then echo "No version specified." exit 1 fi -RESPONSE="$(curl --write-out '%{http_code}' --silent --output /dev/null "https://rubygems.org/gems/pulp_container_client/versions/$VERSION")" - -if [ "$RESPONSE" == "200" ]; -then - echo "pulp_container client $VERSION has already been released. Skipping." - exit -fi - mkdir -p ~/.gem touch ~/.gem/credentials echo "--- -:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials +:rubygems_api_key: ${RUBYGEMS_API_KEY}" > ~/.gem/credentials sudo chmod 600 ~/.gem/credentials gem push "pulp_container_client-${VERSION}.gem" diff --git a/.github/workflows/scripts/publish_client_pypi.sh b/.github/workflows/scripts/publish_client_pypi.sh index f3509a61d..3bcec2081 100755 --- a/.github/workflows/scripts/publish_client_pypi.sh +++ b/.github/workflows/scripts/publish_client_pypi.sh @@ -14,18 +14,13 @@ cd "$(dirname "$(realpath -e "$0")")/../../.." VERSION="$1" -if [[ -z "$VERSION" ]]; then +if [[ -z "${VERSION}" ]] +then echo "No version specified." exit 1 fi -RESPONSE="$(curl --write-out '%{http_code}' --silent --output /dev/null "https://pypi.org/project/pulp-container-client/$VERSION/")" - -if [ "$RESPONSE" == "200" ]; -then - echo "pulp_container client $VERSION has already been released. Skipping." -else - twine upload -u __token__ -p "$PYPI_API_TOKEN" \ - "dist/pulp_container_client-$VERSION-py3-none-any.whl" \ - "dist/pulp_container-client-$VERSION.tar.gz" -fi +twine upload -u __token__ -p "${PYPI_API_TOKEN}" \ +"dist/pulp_container_client-${VERSION}-py3-none-any.whl" \ +"dist/pulp_container-client-${VERSION}.tar.gz" \ +; diff --git a/.github/workflows/scripts/publish_plugin_pypi.sh b/.github/workflows/scripts/publish_plugin_pypi.sh index bf6071bc5..071e4b3e1 100755 --- a/.github/workflows/scripts/publish_plugin_pypi.sh +++ b/.github/workflows/scripts/publish_plugin_pypi.sh @@ -14,20 +14,13 @@ cd "$(dirname "$(realpath -e "$0")")"/../../.. VERSION="$1" -if [[ -z "$VERSION" ]]; then +if [[ -z "${VERSION}" ]] +then echo "No version specified." exit 1 fi -RESPONSE="$(curl --write-out '%{http_code}' --silent --output /dev/null "https://pypi.org/project/pulp-container/$VERSION/")" - -if [ "$RESPONSE" == "200" ]; -then - echo "pulp_container $VERSION has already been released. Skipping." - exit -fi - -twine upload -u __token__ -p "$PYPI_API_TOKEN" \ -dist/pulp?container-"$VERSION"-py3-none-any.whl \ -dist/pulp?container-"$VERSION".tar.gz \ +twine upload -u __token__ -p "${PYPI_API_TOKEN}" \ +"dist/pulp?container-${VERSION}-py3-none-any.whl" \ +"dist/pulp?container-${VERSION}.tar.gz" \ ; diff --git a/.github/workflows/update_ci.yml b/.github/workflows/update_ci.yml index c7653d8a2..c83e13ad2 100644 --- a/.github/workflows/update_ci.yml +++ b/.github/workflows/update_ci.yml @@ -56,6 +56,7 @@ jobs: - name: "Create Pull Request for CI files" uses: "peter-evans/create-pull-request@v6" + id: "create_pr_main" with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp_container" @@ -65,6 +66,14 @@ jobs: branch: "update-ci/main" base: "main" delete-branch: true + - name: "Mark PR automerge" + working-directory: "pulp_container" + run: | + gh pr merge --rebase --auto "${{ steps.create_pr_main.outputs.pull-request-number }}" + if: "steps.create_pr_main.outputs.pull-request-number" + env: + GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + continue-on-error: true - uses: "actions/checkout@v4" with: fetch-depth: 0 @@ -78,6 +87,7 @@ jobs: - name: "Create Pull Request for CI files" uses: "peter-evans/create-pull-request@v6" + id: "create_pr_2_10" with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp_container" @@ -87,6 +97,14 @@ jobs: branch: "update-ci/2.10" base: "2.10" delete-branch: true + - name: "Mark PR automerge" + working-directory: "pulp_container" + run: | + gh pr merge --rebase --auto "${{ steps.create_pr_2_10.outputs.pull-request-number }}" + if: "steps.create_pr_2_10.outputs.pull-request-number" + env: + GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + continue-on-error: true - uses: "actions/checkout@v4" with: fetch-depth: 0 @@ -100,6 +118,7 @@ jobs: - name: "Create Pull Request for CI files" uses: "peter-evans/create-pull-request@v6" + id: "create_pr_2_14" with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp_container" @@ -109,6 +128,14 @@ jobs: branch: "update-ci/2.14" base: "2.14" delete-branch: true + - name: "Mark PR automerge" + working-directory: "pulp_container" + run: | + gh pr merge --rebase --auto "${{ steps.create_pr_2_14.outputs.pull-request-number }}" + if: "steps.create_pr_2_14.outputs.pull-request-number" + env: + GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + continue-on-error: true - uses: "actions/checkout@v4" with: fetch-depth: 0 @@ -122,6 +149,7 @@ jobs: - name: "Create Pull Request for CI files" uses: "peter-evans/create-pull-request@v6" + id: "create_pr_2_9" with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp_container" @@ -131,4 +159,12 @@ jobs: branch: "update-ci/2.9" base: "2.9" delete-branch: true + - name: "Mark PR automerge" + working-directory: "pulp_container" + run: | + gh pr merge --rebase --auto "${{ steps.create_pr_2_9.outputs.pull-request-number }}" + if: "steps.create_pr_2_9.outputs.pull-request-number" + env: + GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + continue-on-error: true ...