From 8e2d07817c19b975d595a0ab06c28ecd4c444b36 Mon Sep 17 00:00:00 2001 From: Axel Pettersson Date: Thu, 17 Feb 2022 13:32:12 +0100 Subject: [PATCH] Create release workflow and versioning utilities --- .github/workflows/ci.yml | 41 ++++++++++++++---- .github/workflows/release.yml | 68 ++++++++++++++++++++++++++++++ scala/VERSION | 1 + scala/build.sbt | 5 ++- scripts/bump_version.py | 79 +++++++++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 scala/VERSION create mode 100644 scripts/bump_version.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9891d1..5d14a84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,11 +9,13 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 + - name: Setup JDK uses: actions/setup-java@v2 with: distribution: temurin java-version: 11 + - name: Cache SBT uses: actions/cache@v2 with: @@ -21,23 +23,29 @@ jobs: ~/.ivy2/cache ~/.sbt key: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt') }} + - name: Build and test - run: sbt "scalafmtCheckAll; +test;" + run: | + sbt "scalafmtCheckAll; +test;" working-directory: scala + test-python: runs-on: ubuntu-20.04 needs: test-scala steps: - name: Checkout uses: actions/checkout@v2 + - name: Setup JDK uses: actions/setup-java@v2 with: distribution: temurin java-version: 11 + - uses: actions/setup-python@v2 with: python-version: "3.10.1" + - name: Cache SBT uses: actions/cache@v2 with: @@ -51,26 +59,43 @@ jobs: key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- + - name: Package the artifact - run: sbt +package + run: | + sbt +package working-directory: scala + - name: Install Pip dependencies - run: pip install -r requirements_dev.txt + run: | + pip install -r requirements_dev.txt working-directory: python + - name: Check linting - run: flake8 + run: | + flake8 working-directory: python if: always() + - name: Check formatting - run: black . --check + run: | + black . --check working-directory: python if: always() + - name: Check imports - run: isort . --check + run: | + isort . --check working-directory: python if: always() + + - name: Get the current package version + id: version + run: | + echo "::set-output name=jar_version::$(cat scala/VERSION)" + - name: Run Python tests env: - SCALA_PIT_JAR: ${{ github.workspace }}/scala/target/scala-2.12/spark-pit_2.12-0.1.0.jar - run: SCALA_PIT_JAR=$SCALA_PIT_JAR python -m unittest discover -s tests + SCALA_PIT_JAR: ${{ github.workspace }}/scala/target/scala-2.12/spark-pit_2.12-${{ steps.version.outputs.jar_version }}.jar + run: | + SCALA_PIT_JAR=$SCALA_PIT_JAR python -m unittest discover -s tests working-directory: python diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e6999d4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: Publish new version + +on: + workflow_dispatch: + inputs: + bump_type: + description: The type of version bump + required: true + default: patch + type: choice + options: + - major + - minor + - patch + + +jobs: + publish-scala: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup JDK + uses: actions/setup-java@v2 + with: + distribution: temurin + # TODO: Support more versions? + java-version: 11 + + - uses: actions/setup-python@v2 + with: + python-version: "3.10.1" + + - name: Cache SBT + uses: actions/cache@v2 + with: + path: | + ~/.ivy2/cache + ~/.sbt + key: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt') }} + + - name: Set the new version number + run: | + python scripts/bump_version.py -t ${{ github.event.inputs.bump_type }}" + + - name: Get the new version number + id: version + run: | + echo "::set-output name=jar_version::$(cat scala/VERSION)" + + - name: Build artifact + run: | + sbt package + working-directory: scala + + - name: Create tag + uses: actions-ecosystem/action-push-tag@v1 + with: + tag: v${{ steps.version.outputs.jar_version }} + + - name: Release + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{ steps.version.outputs.jar_version }} + files: | + LICENSE + scala/target/scala-2.12/spark-pit_2.12-${{ steps.version.outputs.jar_version }}.jar diff --git a/scala/VERSION b/scala/VERSION new file mode 100644 index 0000000..bd52db8 --- /dev/null +++ b/scala/VERSION @@ -0,0 +1 @@ +0.0.0 \ No newline at end of file diff --git a/scala/build.sbt b/scala/build.sbt index 6e514ee..67a8f89 100644 --- a/scala/build.sbt +++ b/scala/build.sbt @@ -1,4 +1,7 @@ -ThisBuild / version := "0.1.0" +val versionNumberFile = "VERSION" +val versionNumber = IO.readLines(new File(versionNumberFile)) + +ThisBuild / version := versionNumber.head ThisBuild / scalaVersion := "2.12.15" diff --git a/scripts/bump_version.py b/scripts/bump_version.py new file mode 100644 index 0000000..405d581 --- /dev/null +++ b/scripts/bump_version.py @@ -0,0 +1,79 @@ +import argparse +import re +from argparse import ArgumentParser +from enum import Enum +from typing import TypedDict +import sys + +VERSION_FILE_NAME = "scala/VERSION" + + +class VersionDict(TypedDict): + major: int + minor: int + patch: int + + +class BumpType(Enum): + MAJOR = "major" + MINOR = "minor" + PATCH = "patch" + + def __str__(self) -> str: + return self.value + + +VERSION_REGEX = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)$" + + +def validate_version(s: str) -> VersionDict: + try: + match = re.match(VERSION_REGEX, s) + if match is None: + raise Exception + group_dict = match.groupdict() + return { + "major": int(group_dict["major"]), + "minor": int(group_dict["minor"]), + "patch": int(group_dict["patch"]), + } + except: + msg = "not a valid version: {}".format(s) + raise argparse.ArgumentTypeError(msg) + + +if __name__ == "__main__": + argument_parser = ArgumentParser(description="Bump version") + + argument_parser.add_argument( + "--bump-type", + "-t", + type=BumpType, + choices=list(BumpType), + required=True, + help="Type of bump", + ) + + args = argument_parser.parse_args() + + # Get the old version + version_file = open(VERSION_FILE_NAME, "r+") + version: VersionDict = validate_version(version_file.readline()) + bump_type: BumpType = args.bump_type + + if bump_type is BumpType.MAJOR: + version["major"] += 1 + elif bump_type is BumpType.MINOR: + version["minor"] += 1 + elif bump_type is BumpType.PATCH: + version["patch"] += 1 + + new_version_string = "{}.{}.{}".format(*version.values()) + + # Check if the new version is valid + validate_version(new_version_string) + + # Overwrite the file with new version + version_file.seek(0) + version_file.write(new_version_string) + version_file.truncate()