Now catches ambiguous match exceptions #22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow will build a .NET project | |
| # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net | |
| name: Build and Release Mod | |
| on: | |
| push: | |
| branches: | |
| - "main" | |
| jobs: | |
| build-and-release: | |
| runs-on: windows-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Check version | |
| id: check | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| export LC_ALL=C.UTF-8 | |
| export LANG=C.UTF-8 | |
| die() { | |
| local MSG="$1" | |
| { | |
| printf 'version=\n' | |
| printf 'latest_tag=\n' | |
| printf 'assembly_name=\n' | |
| printf 'should_release=false\n' | |
| } >> "$GITHUB_OUTPUT" | |
| printf '%s\n' "$MSG" >&2 | |
| exit 1 | |
| } | |
| PROJECT_FILE=$(ls *.csproj | head -n1 || true) | |
| if [ -z "$PROJECT_FILE" ]; then | |
| die "No .csproj file could be found" | |
| fi | |
| printf 'Target project file: %s\n' "$PROJECT_FILE" >&2 | |
| ASSEMBLY_NAME=$(dotnet msbuild "$PROJECT_FILE" -nologo -p:Configuration=Release -getProperty:AssemblyName | tr -d '\r') | |
| if [ -z "$ASSEMBLY_NAME" ]; then | |
| die "Assembly name could not be extracted from project file $PROJECT_FILE" | |
| fi | |
| printf 'Assembly name: %s\n' "$ASSEMBLY_NAME" >&2 | |
| HINT_PATHS=$(grep -Po '<HintPath>\K[^<]+' "$PROJECT_FILE" || true) | |
| if [ -z "$HINT_PATHS" ]; then | |
| printf 'No HintPath properties found in csproj\n' >&2 | |
| else | |
| while read -r HINT; do | |
| DIR=$(dirname "$HINT") | |
| if [ ! -d "$DIR" ]; then | |
| die "Referenced directory does not exist: $DIR (from $HINT)" | |
| fi | |
| if [ ! -f "$HINT" ]; then | |
| die "Referenced assembly does not exist: $HINT" | |
| fi | |
| printf 'Validated reference: %s\n' "$HINT" >&2 | |
| done <<< "$HINT_PATHS" | |
| fi | |
| FILE="$(grep -rPl '\[BepInPlugin\s*\(' . --include='*.cs' --exclude-dir={.git,bin,obj} | head -n1)" | |
| if [ ! -f "$FILE" ]; then | |
| die "No file containing BepInPlugin attribute was found" | |
| fi | |
| printf 'Using plugin source: %s\n' "$FILE" >&2 | |
| ATTR=$(grep -m1 -Po '\[BepInPlugin\([^)]*\)\]' "$FILE" || true) | |
| if [ -z "$ATTR" ]; then | |
| die "Could not find BepInPlugin attribute" | |
| else | |
| printf 'Detected BepInPlugin attribute: %s\n' "$ATTR" >&2 | |
| ARG3=$(printf '%s' "$ATTR" | grep -Po '(?:[^,]+,\s*){2}\K([^)]+)' || true) | |
| if [ -z "$ARG3" ]; then | |
| die "Cannot find BepInPlugin argument 3 (version)" | |
| fi | |
| ARG3="$(printf '%s' "$ARG3" | xargs)" | |
| printf 'Detected BepInPlugin argument 3 (version): %s\n' "$ARG3" >&2 | |
| if [[ "$ARG3" == \"*\" ]]; then | |
| VER="${ARG3%\"}" | |
| VER="${VER#\"}" | |
| else | |
| VER=$(grep -m1 -Po "\b$ARG3\b[\s=]+\"\K[^\"]+" "$FILE" || true) | |
| if [ -z "$VER" ]; then | |
| die "Could not find BepInPlugin version variable assignment matching version formatting" | |
| fi | |
| fi | |
| fi | |
| printf 'Detected plugin version: %s\n' "$VER" >&2 | |
| VERSION_TEST_REGEX='^[0-9]+(\.[0-9]+)*$' | |
| if [[ ! "$VER" =~ $VERSION_TEST_REGEX ]]; then | |
| die "Invalid version format: $VER" | |
| fi | |
| VERSION_ZERO_REGEX='^0+(\.0+)*$' | |
| if [[ "$VER" =~ $VERSION_ZERO_REGEX ]]; then | |
| { | |
| printf 'version=%s\n' "$VER" | |
| printf 'latest_tag=\n' | |
| printf 'assembly_name=%s\n' "$ASSEMBLY_NAME" | |
| printf 'should_release=false\n' | |
| } >> "$GITHUB_OUTPUT" | |
| echo "Version is zero (no release): $VER" >&2 | |
| exit 0 | |
| fi | |
| printf 'Version passed RegEx tests\n' >&2 | |
| git fetch --tags --force | |
| LATEST_TAG_RAW="$(git tag | grep -E '^v?[0-9]+(\.[0-9]+)*$' | sort -V | tail -n1 || true)" | |
| if [ -z "$LATEST_TAG_RAW" ]; then | |
| LATEST_TAG="" | |
| SHOULD_RELEASE=true | |
| else | |
| LATEST_TAG="${LATEST_TAG_RAW#v}" | |
| NEWEST="$(printf '%s\n%s\n' "$LATEST_TAG" "$VER" | sort -V | tail -n1)" | |
| if [ "$NEWEST" = "$VER" ] && [ "$VER" != "$LATEST_TAG" ]; then | |
| SHOULD_RELEASE=true | |
| else | |
| SHOULD_RELEASE=false | |
| fi | |
| OLDEST="$(printf '%s\n%s\n' "$LATEST_TAG" "$VER" | sort -V | head -n1)" | |
| if [ "$OLDEST" = "$VER" ] && [ "$VER" != "$LATEST_TAG" ]; then | |
| die "Version downgrade has been caught: $VER is older than latest tag $LATEST_TAG" | |
| fi | |
| fi | |
| { | |
| printf 'version=%s\n' "$VER" | |
| printf 'latest_tag=%s\n' "$LATEST_TAG" | |
| printf 'assembly_name=%s\n' "$ASSEMBLY_NAME" | |
| printf 'should_release=%s\n' "$SHOULD_RELEASE" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Build mod | |
| if: steps.check.outputs.should_release == 'true' | |
| id: build | |
| env: | |
| ASSEMBLY_NAME: ${{ steps.check.outputs.assembly_name }} | |
| shell: bash | |
| run: | | |
| dotnet build -c Release | |
| if [ -d "bin/Release" ]; then | |
| ASSET_PATH=$(find bin/Release -type f -name "$ASSEMBLY_NAME.dll" | head -n1) | |
| else | |
| ASSET_PATH=$(find . -type f -name "$ASSEMBLY_NAME.dll" | head -n1) | |
| fi | |
| if [ -z "$ASSET_PATH" ]; then | |
| echo "Build DLL not found!" >&2 | |
| exit 1 | |
| fi | |
| echo "asset_path=$ASSET_PATH" >> "$GITHUB_OUTPUT" | |
| - name: Create Github Release | |
| if: steps.check.outputs.should_release == 'true' | |
| id: create_release | |
| uses: actions/create-release@v1 | |
| with: | |
| tag_name: v${{ steps.check.outputs.version }} | |
| release_name: Release v${{ steps.check.outputs.version }} | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload Release Asset | |
| if: steps.check.outputs.should_release == 'true' | |
| uses: actions/upload-release-asset@v1 | |
| with: | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| asset_path: ${{ steps.build.outputs.asset_path }} | |
| asset_name: ${{ steps.check.outputs.assembly_name }}-v${{ steps.check.outputs.version }}.dll | |
| asset_content_type: application/octet-stream | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |