Skip to content

Commit

Permalink
DEVOPS-1840 - Add version-next action (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
vgrassia authored Mar 12, 2024
1 parent 9a243de commit 3ca5c5f
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 65 deletions.
11 changes: 1 addition & 10 deletions .github/workflows/test-version-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
inputs:
version_number:
description: "New Version"
required: false
required: true

jobs:
test-version-bumps:
Expand Down Expand Up @@ -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 }}"
2 changes: 1 addition & 1 deletion version-bump/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
```
10 changes: 5 additions & 5 deletions version-bump/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
image: "Dockerfile"
67 changes: 18 additions & 49 deletions version-bump/main.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
Expand All @@ -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)

12 changes: 12 additions & 0 deletions version-next/README.md
Original file line number Diff line number Diff line change
@@ -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 }}
```
45 changes: 45 additions & 0 deletions version-next/action.yml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 3ca5c5f

Please sign in to comment.