diff --git a/.github/workflows/test-version-bump.yml b/.github/workflows/test-version-bump.yml index bd54bd2a..132655f1 100644 --- a/.github/workflows/test-version-bump.yml +++ b/.github/workflows/test-version-bump.yml @@ -7,7 +7,7 @@ on: inputs: version_number: description: "New Version" - required: false + required: true jobs: test-version-bumps: @@ -53,16 +53,7 @@ jobs: - name: Validate Outputs run: | echo "${{ steps.test_json.outputs.status }}" - echo "${{ steps.test_json.outputs.version }}" - echo "${{ steps.test_plist.outputs.status }}" - echo "${{ steps.test_plist.outputs.version }}" - echo "${{ steps.test_xml.outputs.status }}" - echo "${{ steps.test_xml.outputs.version }}" - echo "${{ steps.test_props.outputs.status }}" - echo "${{ steps.test_props.outputs.version }}" - echo "${{ steps.test_csproj.outputs.status }}" - echo "${{ steps.test_csproj.outputs.version }}" diff --git a/version-bump/README.md b/version-bump/README.md index 2e5985a6..217aef10 100644 --- a/version-bump/README.md +++ b/version-bump/README.md @@ -9,6 +9,6 @@ Specifically created for interacting with AndroidManifest, iOS development plist - name: Bump Android Version uses: ./version-bump with: - version: ${{ github.event.inputs.version_number }} + version: ${{ inputs.version_number }} file_path: "./AndroidManifest.xml" ``` diff --git a/version-bump/action.yml b/version-bump/action.yml index e4fa8628..55f18dfc 100644 --- a/version-bump/action.yml +++ b/version-bump/action.yml @@ -6,16 +6,16 @@ branding: color: blue inputs: version: - description: "New version to use." - required: false + description: "Newest version to use." + default: "2023.12.1" + required: true file_path: description: "Path to the file to apply the new version." + default: "./" required: true outputs: status: description: "Status" - version: - description: "New Version" runs: using: "docker" - image: "Dockerfile" \ No newline at end of file + image: "Dockerfile" diff --git a/version-bump/main.py b/version-bump/main.py index e8b65e1c..515297ea 100644 --- a/version-bump/main.py +++ b/version-bump/main.py @@ -1,24 +1,11 @@ -from datetime import date -import json -import lxml.etree as ET import os +import json import plistlib import re +import lxml.etree as ET import yaml -def get_next_version(version): - version_split = version.split('.') - if len(version_split) < 3: - raise Exception("Version does not have year, month, and patch.") - year = int(version_split[0]) - month = int(version_split[1]) - patch = int(version_split[2]) - current_date = date(date.today().year, date.today().month, 1) - patch = 0 if year != current_date.year or month != current_date.month else patch + 1 - return f"{current_date.year}.{current_date.month}.{patch}" - - def get_file_type(file_path): file_type = os.path.splitext(file_path)[1] return file_type @@ -29,91 +16,74 @@ def get_file_name(file_path): return file_name -def update_json(file_path, version=None): +def update_json(version, file_path): with open(file_path) as json_file: data = json.load(json_file) - data["version"] = version if version is not None else get_next_version(data["version"]) + data["version"] = version try: - data["packages"][""]["version"] = version if version is not None else get_next_version(data["packages"][""]["version"]) + data["packages"][""]["version"] = version except KeyError: pass json.dump(data, open(file_path, "w"), indent=2) with open(file_path, "a") as f: f.write("\n") # Make sure we add the new line back in at EOF. - return data["version"] - -def update_plist(file_path, version=None): +def update_plist(version, file_path): with open(file_path, "rb") as plist: pl = plistlib.load(plist) - pl["CFBundleShortVersionString"] = version if version is not None else get_next_version(pl["CFBundleShortVersionString"]) + pl["CFBundleShortVersionString"] = version data = pl with open(file_path, "wb") as update_plist: plistlib.dump(data, update_plist, sort_keys=False) - return pl["CFBundleShortVersionString"] - -def update_xml(file_path, version=None): +def update_xml(version, file_path): mytree = ET.parse(file_path) myroot = mytree.getroot() # Android Manifests if myroot.tag == "manifest": - new_version = version if version is not None else get_next_version(myroot.attrib.get('{http://schemas.android.com/apk/res/android}versionName')) with open(file_path, "r") as f: data = f.read() data_new = re.sub( - r'android:versionName="[0-9]+\.[0-9]+\.[0-9]+"', - f'android:versionName="{new_version}"', + 'android:versionName="[0-9]+\.[0-9]+\.[0-9]+"', + f'android:versionName="{version}"', data, flags=re.M, ) with open(file_path, "w") as f: f.write(data_new) - return new_version - # Microsoft .NET project files elif myroot.attrib.has_key("Sdk") and "Microsoft.NET.Sdk" in myroot.attrib["Sdk"]: version_property = [x for x in myroot[0] if x.tag == "Version"][-1] - version_property.text = version if version is not None else get_next_version(version_property.text) + version_property.text = version mytree.write(file_path) - - return version_property.text # MSBuild Props else: version_property = [x for x in myroot[0] if x.tag == "Version"][-1] - version_property.text = version if version is not None else get_next_version(version_property.text) + version_property.text = version mytree.write(file_path, encoding="utf-8") - return version_property.text - # For updating Helm Charts - Chart.yaml version -def update_yaml(file_path, version=None): +def update_yaml(version, file_path): with open(file_path, "r") as f: doc = yaml.load(f, Loader=yaml.FullLoader) - doc["version"] = version if version is not None else get_next_version(doc["version"]) + doc["version"] = version with open(file_path, "w") as f: yaml.dump(doc, f) - return doc["version"] - if __name__ == "__main__": version = os.getenv("INPUT_VERSION") file_path = os.getenv("INPUT_FILE_PATH") - # This fixes GitHub passing in an empty string instead of not setting the environment variable. - if version == "": - version = None - # Throw an exception if there is no file path defined. try: os.path.isfile(file_path) @@ -125,18 +95,17 @@ def update_yaml(file_path, version=None): # Handle the file based on the extension. if file_type in {".xml", ".props", ".csproj"}: - new_version = update_xml(file_path, version) + update_xml(version, file_path) elif file_type == ".json": - new_version = update_json(file_path, version) + update_json(version, file_path) elif file_type == ".plist": - new_version = update_plist(file_path, version) + update_plist(version, file_path) elif file_name == "Chart.yaml" or file_name == "Chart.yml": - new_version = update_yaml(file_path, version) + update_yaml(version, file_path) else: raise Exception("No file was recognized as a supported format.") if "GITHUB_OUTPUT" in os.environ: with open(os.environ["GITHUB_OUTPUT"], "a") as f: print("{0}={1}".format("status", f"Updated {file_path}"), file=f) - print("{0}={1}".format("version", f"{new_version}"), file=f) diff --git a/version-next/README.md b/version-next/README.md new file mode 100644 index 00000000..ffc295b2 --- /dev/null +++ b/version-next/README.md @@ -0,0 +1,12 @@ +# Version Next Action + +A Github Action that will calcaulate the next release version based on input. + +## Usage + +```yml +- name: Get Next Release Version +uses: ./version-next +with: + version: ${{ inputs.version_number }} +``` diff --git a/version-next/action.yml b/version-next/action.yml new file mode 100644 index 00000000..5b9ee099 --- /dev/null +++ b/version-next/action.yml @@ -0,0 +1,45 @@ +name: "Version Next" +description: "Calculates the next release version based on input." +author: "Bitwarden" +branding: + icon: download + color: blue +inputs: + version: + description: "Version to use for calculation." + required: true +outputs: + version: + description: "Next release version" + value: ${{ steps.calculate-version.outputs.version }} +runs: + using: "composite" + steps: + - name: Calculate next version + id: calculate-version + shell: bash + env: + VERSION: ${{ inputs.version }} + run: | + # Check input string matches regex + if ! [[ $VERSION =~ ^20[0-9]{2}\.([1-9]|1[0-2])\.[0-9]+$ ]]; then + echo "Version string not formatted correctly" >&2 + exit 2 + fi + + # Split version string into parts + IFS='.' read -ra VERSION_SPLIT <<< "$VERSION" + YEAR=${VERSION_SPLIT[0]} + MONTH=${VERSION_SPLIT[1]} + PATCH=${VERSION_SPLIT[2]} + + CURRENT_YEAR=$(TZ=America/New_York date +%Y) + CURRENT_MONTH=$(TZ=America/New_York date +%-m) + + if [[ $YEAR != $CURRENT_YEAR ]] || [[ $MONTH != $CURRENT_MONTH ]]; then + PATCH=0 + else + PATCH=$(($PATCH + 1)) + fi + + echo "version=${CURRENT_YEAR}.${CURRENT_MONTH}.${PATCH}" >> $GITHUB_OUTPUT