From 45eb76e076be4e45a71dc228526671deb0316587 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 23:58:02 +0200 Subject: [PATCH 1/6] add git to pyproject --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 7ba869e50e..63e7309e51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ flake8 = "^3.7" autopep8 = "^1.4" coverage = "*" cx_freeze = "^6.6" +GitPython = "*" jedi = "^0.13" Jinja2 = "^2.11" pycodestyle = "^2.5.0" From 42a22eaaff311967b9e059f606d3fe8d891f3384 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 23:58:24 +0200 Subject: [PATCH 2/6] ci tools responsible for most versioning and releasing logic --- tools/ci_tools.py | 140 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 tools/ci_tools.py diff --git a/tools/ci_tools.py b/tools/ci_tools.py new file mode 100644 index 0000000000..28a735222b --- /dev/null +++ b/tools/ci_tools.py @@ -0,0 +1,140 @@ +import re +import sys +from semver import VersionInfo +from git import Repo +from optparse import OptionParser + + +def remove_prefix(text, prefix): + return text[text.startswith(prefix) and len(prefix):] + + +def get_last_version(match): + repo = Repo() + assert not repo.bare + version_types = { + "CI": "CI/[0-9]*", + "release": "[0-9]*" + } + tag = repo.git.describe( + '--tags', + f'--match={version_types[match]}', + '--abbrev=0' + ) + + if match == "CI": + return remove_prefix(tag, "CI/"), tag + else: + return tag, tag + + +def get_log_since_tag(version): + repo = Repo() + assert not repo.bare + return repo.git.log(f'{version}..HEAD', '--merges', '--oneline') + + +def release_type(log): + regex_minor = ["feature/", "(feat)"] + regex_patch = ["bugfix/", "fix/", "(fix)"] + for reg in regex_minor: + if re.search(reg, log): + return "minor" + for reg in regex_patch: + if re.search(reg, log): + return "patch" + return None + + +def file_regex_replace(filename, regex, version): + with open(filename, 'r+') as f: + text = f.read() + text = re.sub(regex, version, text) + # pp.pprint(f"NEW VERSION {version} INSERTED into {filename}") + f.seek(0) + f.write(text) + f.truncate() + + +def bump_file_versions(version): + + filename = "./openpypeCItest/version.py" + regex = "(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?" + file_regex_replace(filename, regex, version) + + # bump pyproject.toml + filename = "pyproject.toml" + regex = "version = \"(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?\" # OpenPype" + pyproject_version = f"version = \"{version}\" # OpenPype" + file_regex_replace(filename, regex, pyproject_version) + + +def calculate_next_nightly(token="nightly"): + last_prerelease, last_pre_tag = get_last_version("CI") + last_pre_v = VersionInfo.parse(last_prerelease) + last_pre_v_finalized = last_pre_v.finalize_version() + # print(last_pre_v_finalized) + + last_release, last_release_tag = get_last_version("release") + + last_release_v = VersionInfo.parse(last_release) + bump_type = release_type(get_log_since_tag(last_release)) + if not bump_type: + return None + + next_release_v = last_release_v.next_version(part=bump_type) + # print(next_release_v) + + if next_release_v > last_pre_v_finalized: + next_tag = next_release_v.bump_prerelease(token=token).__str__() + return next_tag + elif next_release_v == last_pre_v_finalized: + next_tag = last_pre_v.bump_prerelease(token=token).__str__() + return next_tag + + +def main(): + usage = "usage: %prog [options] arg" + parser = OptionParser(usage) + parser.add_option("-n", "--nightly", + dest="nightly", action="store_true", + help="Bump nightly version and return it") + parser.add_option("-b", "--bump", + dest="bump", action="store_true", + help="Return if there is something to bump") + parser.add_option("-v", "--version", + dest="version", action="store", + help="work with explicit version") + parser.add_option("-p", "--prerelease", + dest="prerelease", action="store", + help="define prerelease token") + + (options, args) = parser.parse_args() + + if options.bump: + last_CI, last_CI_tag = get_last_version("CI") + last_release, last_release_tag = get_last_version("release") + bump_type_CI = release_type(get_log_since_tag(last_CI_tag)) + bump_type_release = release_type(get_log_since_tag(last_release_tag)) + if bump_type_CI is None or bump_type_release is None: + print("skip") + + if options.nightly: + next_tag_v = calculate_next_nightly() + print(next_tag_v) + bump_file_versions(next_tag_v) + + if options.prerelease: + current_prerelease = VersionInfo.parse(options.prerelease) + new_prerelease = current_prerelease.bump_prerelease().__str__() + print(new_prerelease) + bump_file_versions(new_prerelease) + + if options.version: + bump_file_versions(options.version) + print(f"Injected version {options.version} into the release") + + + +if __name__ == "__main__": + main() From d76e859ded79b39519f2d505c78b4d6edfd607ed Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 23:58:37 +0200 Subject: [PATCH 3/6] workflow for production releases --- .github/workflows/release.yml | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..782c9c8dda --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,99 @@ +name: Stable Release + +on: + push: + tags: + - '*[0-9].*[0-9].*[0-9]*' + +jobs: + create_release: + runs-on: ubuntu-latest + + steps: + - name: 🚛 Checkout Code + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install Python requirements + run: pip install gitpython semver + + - name: Set env + run: | + echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + git config user.email ${{ secrets.CI_EMAIL }} + git config user.name ${{ secrets.CI_USER }} + git fetch + git checkout -b main origin/main + git tag -d ${GITHUB_REF#refs/*/} + git push origin --delete ${GITHUB_REF#refs/*/} + echo PREVIOUS_VERSION=`git describe --tags --match="[0-9]*" --abbrev=0` >> $GITHUB_ENV + + - name: 💉 Inject new version into files + id: version + if: steps.version_type.outputs.type != 'skip' + run: | + python ./tools/ci_tools.py --version ${{ env.RELEASE_VERSION }} + + - name: "✏️ Generate full changelog" + if: steps.version_type.outputs.type != 'skip' + id: generate-full-changelog + uses: heinrichreimer/github-changelog-generator-action@v2.2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + breakingLabel: '#### 💥 Breaking' + enhancementLabel: '#### 🚀 Enhancements' + bugsLabel: '#### 🐛 Bug fixes' + deprecatedLabel: '#### ⚠️ Deprecations' + addSections: '{"documentation":{"prefix":"### 📖 Documentation","labels":["documentation"]},"tests":{"prefix":"### ✅ Testing","labels":["tests"]}}' + issues: false + issuesWoLabels: false + pullRequests: true + prWoLabels: false + author: false + unreleased: true + compareLink: true + stripGeneratorNotice: true + verbose: true + futureRelease: ${{ env.RELEASE_VERSION }} + excludeTagsRegex: "CI/.+" + releaseBranch: "main" + + - name: "🖨️ Print changelog to console" + run: echo ${{ steps.generate-last-changelog.outputs.changelog }} + + - name: 💾 Commit and Tag + id: git_commit + if: steps.version_type.outputs.type != 'skip' + run: | + git add . + git commit -m "[Automated] Release" + tag_name="${{ env.RELEASE_VERSION }}" + git push + git tag -fa $tag_name -m "stable release" + git push origin $tag_name + + - name: "🚀 Github Release" + uses: docker://antonyurchenko/git-release:latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DRAFT_RELEASE: "false" + PRE_RELEASE: "false" + CHANGELOG_FILE: "CHANGELOG.md" + ALLOW_EMPTY_CHANGELOG: "false" + ALLOW_TAG_PREFIX: "true" + + + - name: 🔨 Merge main back to develop + uses: everlytic/branch-merge@1.1.0 + if: steps.version_type.outputs.type != 'skip' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + source_ref: 'main' + target_branch: 'develop' + commit_message_template: '[Automated] Merged release {source_ref} into {target_branch}' \ No newline at end of file From b09cf02baf6d82170e6f1a7a57348c379b0bedab Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 23:58:48 +0200 Subject: [PATCH 4/6] workflow for nightly pre-releases --- .github/workflows/prerelease.yml | 89 ++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/prerelease.yml diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml new file mode 100644 index 0000000000..9c8983a52d --- /dev/null +++ b/.github/workflows/prerelease.yml @@ -0,0 +1,89 @@ +name: Nightly Prerelease + +on: + push: + branches: [main] + + +jobs: + create_nightly: + runs-on: ubuntu-latest + + steps: + - name: 🚛 Checkout Code + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Install Python requirements + run: pip install gitpython semver + + - name: 🔎 Determine next version type + id: version_type + run: | + TYPE=$(python ./tools/ci_tools.py --bump) + + echo ::set-output name=type::$TYPE + + - name: 💉 Inject new version into files + id: version + if: steps.version_type.outputs.type != 'skip' + run: | + RESULT=$(python ./tools/ci_tools.py --nightly) + + echo ::set-output name=next_tag::$RESULT + + - name: "✏️ Generate full changelog" + if: steps.version_type.outputs.type != 'skip' + id: generate-full-changelog + uses: heinrichreimer/github-changelog-generator-action@v2.2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + breakingLabel: '#### 💥 Breaking' + enhancementLabel: '#### 🚀 Enhancements' + bugsLabel: '#### 🐛 Bug fixes' + deprecatedLabel: '#### ⚠️ Deprecations' + addSections: '{"documentation":{"prefix":"### 📖 Documentation","labels":["documentation"]},"tests":{"prefix":"### ✅ Testing","labels":["tests"]}}' + issues: false + issuesWoLabels: false + pullRequests: true + prWoLabels: false + author: false + unreleased: true + compareLink: true + stripGeneratorNotice: true + verbose: true + unreleasedLabel: ${{ steps.version.outputs.next_tag }} + excludeTagsRegex: "CI/.+" + releaseBranch: "main" + + - name: "🖨️ Print changelog to console" + if: steps.version_type.outputs.type != 'skip' + run: cat CHANGELOG.md + + - name: 💾 Commit and Tag + id: git_commit + if: steps.version_type.outputs.type != 'skip' + run: | + git config user.email ${{ secrets.CI_EMAIL }} + git config user.name ${{ secrets.CI_USER }} + git add . + git commit -m "[Automated] Bump version" + tag_name="CI/${{ steps.version.outputs.next_tag }}" + git tag -a $tag_name -m "nightly build" + git push + git push origin $tag_name + + - name: 🔨 Merge main back to develop + uses: everlytic/branch-merge@1.1.0 + if: steps.version_type.outputs.type != 'skip' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + source_ref: 'main' + target_branch: 'develop' + commit_message_template: '[Automated] Merged {source_ref} into {target_branch}' \ No newline at end of file From 36903efe198a5e998fd4b65371c0ff2668d1f39f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 23:59:03 +0200 Subject: [PATCH 5/6] workflow for nightly merges from dev to main --- .github/workflows/nightly_merge.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/nightly_merge.yml diff --git a/.github/workflows/nightly_merge.yml b/.github/workflows/nightly_merge.yml new file mode 100644 index 0000000000..676b00a351 --- /dev/null +++ b/.github/workflows/nightly_merge.yml @@ -0,0 +1,23 @@ +name: Nightly Merge + +on: + schedule: + - cron: '21 3 * * 3,6' + workflow_dispatch: + +jobs: + develop-to-main: + + runs-on: ubuntu-latest + + steps: + - name: 🚛 Checkout Code + uses: actions/checkout@v2 + + - name: Merge development -> main + uses: devmasx/merge-branch@v1.3.1 + with: + type: now + from_branch: develop + target_branch: main + github_token: ${{ secrets.TOKEN }} \ No newline at end of file From 97f66f87ccdd5296ce4cc12fa16053f76e8847a2 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Jun 2021 15:44:26 +0200 Subject: [PATCH 6/6] pull avalon core main --- .github/workflows/prerelease.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 9c8983a52d..0e6c7b5da9 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -72,6 +72,10 @@ jobs: run: | git config user.email ${{ secrets.CI_EMAIL }} git config user.name ${{ secrets.CI_USER }} + cd repos/avalon-core + git checkout main + git pull + cd ../.. git add . git commit -m "[Automated] Bump version" tag_name="CI/${{ steps.version.outputs.next_tag }}"