diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..52540d2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +# Ignore build directories +bin/ +obj/ + +# Ignore some project files +.git/ +.vs/ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70f2315..2a95db5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,18 +8,14 @@ jobs: runs-on: windows-latest strategy: matrix: - dotnet-version: ["7.0.x"] + dotnet-version: ["8.0.x"] steps: - uses: actions/checkout@v4 - name: Setup .NET Core SDK ${{ matrix.dotnet-version }} - uses: actions/setup-dotnet@v4.0.1 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: ${{ matrix.dotnet-version }} - # - name: Validate version consistency - # run: bash validate-version-consistency.sh - # working-directory: ./Material/Scripts - # shell: bash - name: Install dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 9a13e48..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: publish - -on: - workflow_dispatch: # Allow manual trigger - release: - types: [created] - -jobs: - publish-sardinecan: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - 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 - docker build --tag ghcr.io/merschformann/sardinecan:latest --tag ghcr.io/merschformann/sardinecan:${{ env.VERSION }} -f Dockerfile .. - docker push ghcr.io/merschformann/sardinecan:latest - docker push ghcr.io/merschformann/sardinecan:${{ env.VERSION }} - working-directory: ./SC.Service 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..c86742d --- /dev/null +++ b/Material/Scripts/release.py @@ -0,0 +1,90 @@ +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 == "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: + if "Test" in csproj_file: + continue + 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 - - - diff --git a/SC.CLI/Executor.cs b/SC.CLI/Executor.cs index c15d917..c2b1f01 100644 --- a/SC.CLI/Executor.cs +++ b/SC.CLI/Executor.cs @@ -298,9 +298,9 @@ private static void LogConfigDetails(Configuration config, Action logger else { if (toStringMethod != null) - value = toStringMethod.Invoke(field.GetValue(config), new object[] { CultureInfo.InvariantCulture }).ToString(); + value = toStringMethod.Invoke(field.GetValue(config), new object[] { CultureInfo.InvariantCulture })?.ToString(); else - value = field.GetValue(config).ToString(); + value = field.GetValue(config)?.ToString(); } } // Output it diff --git a/SC.CLI/SC.CLI.csproj b/SC.CLI/SC.CLI.csproj index cbb10e2..21ccc3d 100644 --- a/SC.CLI/SC.CLI.csproj +++ b/SC.CLI/SC.CLI.csproj @@ -1,8 +1,9 @@ - + Exe - net7.0 + net8.0 + 1.0.6 true true true diff --git a/SC.DataPreparation/SC.DataPreparation.csproj b/SC.DataPreparation/SC.DataPreparation.csproj index 6074994..2fdd743 100644 --- a/SC.DataPreparation/SC.DataPreparation.csproj +++ b/SC.DataPreparation/SC.DataPreparation.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 1.0.6 true diff --git a/SC.GUI/SC.GUI.csproj b/SC.GUI/SC.GUI.csproj index 02c2bd9..98cf58d 100644 --- a/SC.GUI/SC.GUI.csproj +++ b/SC.GUI/SC.GUI.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows + net8.0-windows true true Logo.ico diff --git a/SC.Heuristics/SC.Heuristics.csproj b/SC.Heuristics/SC.Heuristics.csproj index bae3041..a15d75d 100644 --- a/SC.Heuristics/SC.Heuristics.csproj +++ b/SC.Heuristics/SC.Heuristics.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 1.0.6 true diff --git a/SC.Linear/SC.Linear.csproj b/SC.Linear/SC.Linear.csproj index 1ab53da..e2b4b4e 100644 --- a/SC.Linear/SC.Linear.csproj +++ b/SC.Linear/SC.Linear.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 1.0.6 true diff --git a/SC.ObjectModel/SC.ObjectModel.csproj b/SC.ObjectModel/SC.ObjectModel.csproj index f7804fe..7eec983 100644 --- a/SC.ObjectModel/SC.ObjectModel.csproj +++ b/SC.ObjectModel/SC.ObjectModel.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 1.0.6 true diff --git a/SC.Playground/SC.Playground.csproj b/SC.Playground/SC.Playground.csproj index c8eb8a4..c56f25d 100644 --- a/SC.Playground/SC.Playground.csproj +++ b/SC.Playground/SC.Playground.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 1.0.6 true diff --git a/SC.Service/Dockerfile b/SC.Service/Dockerfile index efd781a..8372980 100644 --- a/SC.Service/Dockerfile +++ b/SC.Service/Dockerfile @@ -1,22 +1,14 @@ -#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. - -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base -WORKDIR /app -EXPOSE 80 - -FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src -COPY ["SC.Service/SC.Service.csproj", "SC.Service/"] -RUN dotnet restore "SC.Service/SC.Service.csproj" COPY . . +RUN dotnet restore "SC.Service/SC.Service.csproj" WORKDIR "/src/SC.Service" RUN dotnet build "SC.Service.csproj" -c Release -o /app/build - -FROM build AS publish RUN dotnet publish "SC.Service.csproj" -c Release -o /app/publish -FROM base AS final +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final LABEL org.opencontainers.image.source="https://github.com/merschformann/sardine-can" WORKDIR /app -COPY --from=publish /app/publish . +EXPOSE 80 +COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "SC.Service.dll"] diff --git a/SC.Service/SC.Service.csproj b/SC.Service/SC.Service.csproj index ca61352..251ce5c 100644 --- a/SC.Service/SC.Service.csproj +++ b/SC.Service/SC.Service.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 Linux 1.0.6 true diff --git a/SC.Tests/SC.Tests.csproj b/SC.Tests/SC.Tests.csproj index 336a1f4..8877455 100644 --- a/SC.Tests/SC.Tests.csproj +++ b/SC.Tests/SC.Tests.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable enable diff --git a/SC.Toolbox/SC.Toolbox.csproj b/SC.Toolbox/SC.Toolbox.csproj index 5b5e6ad..d5bb283 100644 --- a/SC.Toolbox/SC.Toolbox.csproj +++ b/SC.Toolbox/SC.Toolbox.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 1.0.6 true diff --git a/VERSION.txt b/VERSION.txt index b0f3d96..66c4c22 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.0.8 +1.0.9