diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..312e040 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,93 @@ +name: publish + +on: + workflow_dispatch: + inputs: + VERSION: + description: "The version to release (e.g. 1.0.0)" + required: true + +jobs: + release: + runs-on: ubuntu-latest + env: + VERSION: ${{ inputs.VERSION }} + GH_TOKEN: ${{ github.token }} + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + permissions: + contents: write + steps: + - name: configure git with the bot credentials + run: | + mkdir -p ~/.ssh + ssh-keyscan github.com >> ~/.ssh/known_hosts + ssh-agent -a $SSH_AUTH_SOCK > /dev/null + ssh-add - <<< "${{ secrets.BOT_SSH_KEY }}" + + echo "${{ secrets.BOT_SIGNING_KEY }}" > ~/.ssh/signing.key + chmod 600 ~/.ssh/signing.key + + git config --global user.name "Merschbotmann" + git config --global user.email "bot.merschformann@gmail.com" + git config --global gpg.format ssh + git config --global user.signingkey ~/.ssh/signing.key + + git clone git@github.com:merschformann/sardine-can.git + + cd sardine-can + git checkout ${{ github.ref_name }} + + git rev-parse --short HEAD + + - name: bump version in project + run: | + python Material/Scripts/release.py --version $VERSION + working-directory: ./sardine-can + + - name: commit version bump + run: | + git commit -am "Bumping version to $VERSION" + git push origin ${{ github.ref_name }} + working-directory: ./sardine-can + + - name: push release tag + run: | + git tag $VERSION + git push origin $VERSION + working-directory: ./sardine-can + + - name: create release + run: | + gh release create $VERSION \ + --verify-tag \ + --generate-notes \ + --title $VERSION + working-directory: ./sardine-can + + docker-image: + runs-on: ubuntu-24.04 + needs: release + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.VERSION }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Get version + run: | + echo "VERSION=$(cat VERSION.txt)" >> $GITHUB_ENV + + - name: Build the SardineCan Docker image + run: | + echo "Building SardineCan docker in ${{ env.VERSION }}" + echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin + export LATEST_TAG="ghcr.io/merschformann/sardinecan:latest" + export VERSION_TAG="ghcr.io/merschformann/sardinecan:${{ env.VERSION }}" + docker buildx build --platform linux/amd64,linux/arm64 --push -t $LATEST_TAG -t $VERSION_TAG -f Dockerfile .. + working-directory: ./SC.Service diff --git a/Material/Scripts/release.py b/Material/Scripts/release.py new file mode 100644 index 0000000..e222c26 --- /dev/null +++ b/Material/Scripts/release.py @@ -0,0 +1,88 @@ +import argparse +import glob +import os +import re +import xml.etree.ElementTree as ET + +VERSION_FILE = os.path.join(os.path.dirname(__file__), "..", "..", "VERSION.txt") + + +def parse_args() -> argparse.Namespace: + """ + Parse command line arguments. + """ + parser = argparse.ArgumentParser(description="Bump the version of the project.") + parser.add_argument("--version", required=True, help="The version to bump to.") + return parser.parse_args() + + +def check_version(version: str) -> bool: + """ + Check whether a given version is in expected format and actually newer than the + current version. + """ + if not re.match(r"^\d+\.\d+\.\d+$", version): + raise Exception(f"Version {version} is not in the format x.y.z") + + with open(VERSION_FILE, "r") as f: + current_version = f.read().strip() + + version = version.strip("v") + current_version = current_version.strip("v") + + def parse_version(version: str): + return tuple(map(int, version.split("."))) + + if parse_version(version) <= parse_version(current_version): + raise Exception( + f"New version {version} is not newer than current version {current_version}" + ) + + +def bump_version_csproj(csproj_file: str, version: str) -> None: + """ + Bump the version of a csproj file. + """ + try: + tree = ET.parse(csproj_file) + root = tree.getroot() + + bumped = False + for elem in root.iter(): + if elem.tag.endswith("Version"): + elem.text = version + bumped = True + + if not bumped: + raise Exception("No version element found") + + tree.write(csproj_file) + except Exception as e: + print(f"Error bumping version in {csproj_file}: {e}") + + +def bump_version_main(version: str) -> None: + """ + Bump the main version file. + """ + with open(VERSION_FILE, "w") as f: + f.write(version) + + +def main() -> None: + args = parse_args() + version = args.version + + check_version(version) + + csproj_files = glob.glob( + os.path.join(os.path.dirname(__file__), "..", "..", "**", "*.csproj"), + recursive=True, + ) + for csproj_file in csproj_files: + bump_version_csproj(csproj_file, version) + bump_version_main(version) + + +if __name__ == "__main__": + main() diff --git a/Material/Scripts/validate-version-consistency.sh b/Material/Scripts/validate-version-consistency.sh deleted file mode 100755 index d00e0a6..0000000 --- a/Material/Scripts/validate-version-consistency.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -version_file="../../VERSION.txt" -projects=$( find ../../ -name "*.csproj" ) - -for project in $projects -do - echo "Checking ${project} ..." - case `grep -f ${version_file} ${project} >/dev/null; echo $?` in - 0) - # code if found - echo "Versions are consistent - SUCCESS" - ;; - 1) - # code if not found - echo "Version in ${project} does not match the one in ${version_file} - ERROR" - exit 1 - ;; - *) - # code if an error occurred - echo "Error occurred while validating version consistency - ERROR" - exit -1 - ;; - esac -done - - -