diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..255e8fd22 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +{ + "name": "nwn.anvil", + "build": { + "dockerfile": "../dockerfile", + "context": "../" + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/NWN.Anvil,type=bind", + "workspaceFolder": "/workspaces/NWN.Anvil", + "mounts": [ + "source=${localWorkspaceFolder}/test_results,target=/nwn/home/anvil/PluginData/NWN.Anvil.TestRunner,type=bind" + ], + "features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "8.0" + }, + "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": { + "packages": "curl,unzip,procps,git" + } + }, + "appPort": ["5121:5121/udp"], + "containerEnv": { + "NWNX_DOTNET_ASSEMBLY": "/workspaces/NWN.Anvil/NWN.Anvil/bin/Debug/net8.0/NWN.Anvil", + "ANVIL_ADD_PLUGIN_PATHS": "/workspaces/NWN.Anvil/NWN.Anvil.TestRunner/bin/Debug:/workspaces/NWN.Anvil/NWN.Anvil.Tests/bin/Debug" + } +} diff --git a/.env b/.env deleted file mode 100644 index 2a1350b61..000000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -NWNX_VERSION=a6c5f09 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c2b51c32..662645358 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,86 +22,55 @@ on: jobs: compile: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'skip ci')" permissions: security-events: write steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive - - name: Check Line Endings - uses: erclu/check-crlf@v1 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - path: NWN.Anvil - - - name: Setup .NET Core - uses: actions/setup-dotnet@v1.9.0 - with: - dotnet-version: '8.0.x' + global-json-file: global.json - name: Build run: dotnet build --configuration Debug - - name: Prepare Outputs - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - - name: Code Analysis Cache - uses: actions/cache@v2 - with: - path: ~/.local/share/JetBrains - key: analysis-cache-${{ steps.vars.outputs.sha_short }} - restore-keys: | - analysis-cache - - name: Code Analysis - uses: JetBrains/ReSharper-InspectCode@v0.3 + uses: JetBrains/ReSharper-InspectCode@v0.8 with: solution: ./NWN.Anvil.sln - tool-version: 2024.1.0 + tool-version: 2024.3.0 test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'skip ci')" steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive - - name: Setup .NET Core - uses: actions/setup-dotnet@v1.9.0 - with: - dotnet-version: '8.0.x' - - - name: Build - run: dotnet build --configuration Release - - - name: Load Environment Variables - id: env_vars - uses: falti/dotenv-action@v0.2.7 - - - name: Run Tests + - name: Create Output Directories run: | - docker compose --project-directory . -f NWN.Anvil.Tests/bin/Release/docker-compose.yml build --build-arg NWNX_VERSION=${{ steps.env_vars.outputs.nwnx_version }} --build-arg BINARY_PATH=NWN.Anvil/bin/Release/net8.0 - docker compose --project-directory . -f NWN.Anvil.Tests/bin/Release/docker-compose.yml up - - - name: Install NUnit - run: nuget install NUnit.Console -Version 3.12.0 - - - name: Fetch transform code - run: wget https://raw.githubusercontent.com/nunit/nunit-transforms/master/nunit3-junit/nunit3-junit.xslt - shell: bash + mkdir -p test_results - - name: Transform NUnit3 to JUnit - run: | - $xslt = New-Object System.Xml.Xsl.XslCompiledTransform; - $xslt.Load("nunit3-junit.xslt"); - $xslt.Transform("NWN.Anvil.Tests/bin/Release/results/NWN.Anvil.Tests/TestResult.xml", "TestResult.junit.xml"); - shell: pwsh + - name: Build and Run Tests + uses: devcontainers/ci@v0.3 + with: + push: never + env: | + NWNX_DOTNET_ASSEMBLY=/workspaces/NWN.Anvil/NWN.Anvil/bin/Release/net8.0/NWN.Anvil + ANVIL_ADD_PLUGIN_PATHS=/workspaces/NWN.Anvil/NWN.Anvil.TestRunner/bin/Release:/workspaces/NWN.Anvil/NWN.Anvil.Tests/bin/Release + runCmd: | + git config --global --add safe.directory /workspaces/NWN.Anvil + dotnet build --configuration Release + cd /nwn/data/bin/linux-amd64 + /nwn/run-server.sh - name: Upload Event File uses: actions/upload-artifact@v4 @@ -115,29 +84,29 @@ jobs: if: always() with: name: Test Results - path: TestResult.junit.xml + path: test_results/NWN.Anvil.Tests/*.xml build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' needs: [compile, test] outputs: - version: ${{ steps.vars.outputs.version }} - tag: ${{ steps.vars.outputs.tag }} - sha_short: ${{ steps.vars.outputs.sha_short }} - image_repository: ${{ steps.vars.outputs.image_repository }} - created: ${{ steps.build.outputs.created }} + version: ${{ steps.vars.outputs.VERSION }} + tag: ${{ steps.vars.outputs.TAG }} + sha_short: ${{ steps.vars.outputs.SHA_SHORT }} + image_repository: ${{ steps.vars.outputs.IMAGE_REPOSITORY }} + created: ${{ steps.build.outputs.CREATED }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 submodules: recursive - - name: Setup .NET Core - uses: actions/setup-dotnet@v1.9.0 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' + global-json-file: global.json - name: Tag Commit if: github.event.inputs.tag != '' @@ -147,24 +116,24 @@ jobs: id: vars run: | if [[ "${{github.base_ref}}" == "main" || "${{github.ref}}" == "refs/heads/main" ]]; then - echo "::set-output name=tag::$(git describe --tags)" - echo "::set-output name=version::$(git describe --tags | sed 's/^v//')" + echo "TAG=$(git describe --tags)" >> "$GITHUB_OUTPUT" + echo "VERSION=$(git describe --tags | sed 's/^v//')" >> "$GITHUB_OUTPUT" else DESCRIBE=`git describe --tags --long` - VERSION=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[1]}'` + BASE_VERSION=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[1]}'` META=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[2]}'` BUILD=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[3]}'` COMMIT=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[4]}'` - echo "::set-output name=version::$(echo ${VERSION}-${META}.${BUILD}.r${COMMIT:1} | sed 's/^v//')" + echo "VERSION=$(echo ${BASE_VERSION}-${META}.${BUILD}.r${COMMIT:1} | sed 's/^v//')" >> "$GITHUB_OUTPUT" fi - echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - echo "::set-output name=image_repository::$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" + echo "SHA_SHORT=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + echo "IMAGE_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" - name: Build Release Binaries id: build run: | - dotnet build --configuration Release -p:Version=${{ steps.vars.outputs.version }} - echo "::set-output name=created::$(echo date -u +'%Y-%m-%dT%H:%M:%SZ')" + dotnet build --configuration Release -p:Version=${{ steps.vars.outputs.VERSION }} + echo "CREATED=$(echo date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_OUTPUT" - name: Upload NuGet Artifacts uses: actions/upload-artifact@v4 @@ -198,10 +167,15 @@ jobs: if-no-files-found: error release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' needs: build + permissions: + contents: write steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Download Release Artifacts uses: actions/download-artifact@v4 with: @@ -212,37 +186,25 @@ jobs: run: zip -r ../NWN.Anvil.zip ./* working-directory: binaries - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - release_name: Release ${{ needs.build.outputs.version }} - draft: false - prerelease: false - tag_name: ${{ needs.build.outputs.tag }} - - name: Upload Release Binaries - id: upload-release-asset - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./NWN.Anvil.zip - asset_name: NWN.Anvil.zip - asset_content_type: application/zip + run: | + gh release create ${{ needs.build.outputs.tag }} --title "Release ${{ needs.build.outputs.version }}" --generate-notes + gh release upload ${{ needs.build.outputs.tag }} NWN.Anvil.zip nuget: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' needs: build steps: - - name: Setup .NET Core - uses: actions/setup-dotnet@v1.9.0 + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' + global-json-file: global.json - name: Download Release Artifacts uses: actions/download-artifact@v4 @@ -257,12 +219,12 @@ jobs: run: dotnet nuget push 'binaries/**/*.nupkg' --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/nwn-dotnet/index.json docker: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' needs: build steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive @@ -273,31 +235,26 @@ jobs: path: binaries - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Load Environment Variables - id: env_vars - uses: falti/dotenv-action@v0.2.7 - - name: Build and push id: docker_build - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v6 with: context: ./ file: ./dockerfile push: true build-args: | - NWNX_VERSION=${{ steps.env_vars.outputs.nwnx_version }} BINARY_PATH=/binaries/net8.0 labels: | org.opencontainers.image.title=Anvil diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1b679a6ac..9db39e86b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,16 +7,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Doxygen Action - uses: mattnotmitt/doxygen-action@v1.3.1 + uses: mattnotmitt/doxygen-action@v1 with: doxyfile-path: "./docs/Doxyfile" working-directory: "." - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/html diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml index ecd44881a..f41d4c96e 100644 --- a/.github/workflows/test-report.yml +++ b/.github/workflows/test-report.yml @@ -5,31 +5,27 @@ on: workflows: ['Continuous Integration'] types: - completed +permissions: {} jobs: test-results: name: Test Results - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: github.event.workflow_run.conclusion != 'skipped' + permissions: + checks: write + pull-requests: write + actions: read steps: - name: Download and Extract Artifacts - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - run: | - mkdir -p artifacts && cd artifacts - - artifacts_url=${{ github.event.workflow_run.artifacts_url }} - - gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact - do - IFS=$'\t' read name url <<< "$artifact" - gh api $url > "$name.zip" - unzip -d "$name" "$name.zip" - done + uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d + with: + run_id: ${{ github.event.workflow_run.id }} + path: artifacts - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action@v1.25 + uses: EnricoMi/publish-unit-test-result-action@v2.18.0 with: check_name: "Test Results" comment_title: "Test Results" @@ -37,4 +33,4 @@ jobs: commit: ${{ github.event.workflow_run.head_sha }} event_file: artifacts/Event File/event.json event_name: ${{ github.event.workflow_run.event }} - files: "artifacts/Test Results/**/*.xml" \ No newline at end of file + files: "artifacts/Test Results/**/*.xml" diff --git a/NWN.Anvil.Tests/NWN.Anvil.Tests.csproj b/NWN.Anvil.Tests/NWN.Anvil.Tests.csproj index 8ae2e0255..f0ba4c304 100644 --- a/NWN.Anvil.Tests/NWN.Anvil.Tests.csproj +++ b/NWN.Anvil.Tests/NWN.Anvil.Tests.csproj @@ -47,8 +47,4 @@ - - - - diff --git a/NWN.Anvil.Tests/src/docker/config/nlog.config b/NWN.Anvil.Tests/src/docker/config/nlog.config deleted file mode 100644 index c9ed14f6d..000000000 --- a/NWN.Anvil.Tests/src/docker/config/nlog.config +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/NWN.Anvil.Tests/src/docker/config/nwserver.env b/NWN.Anvil.Tests/src/docker/config/nwserver.env deleted file mode 100644 index 3ce8e83c4..000000000 --- a/NWN.Anvil.Tests/src/docker/config/nwserver.env +++ /dev/null @@ -1,32 +0,0 @@ -# Server Config -NWN_PUBLICSERVER=0 -NWN_MAXCLIENTS=1 -NWN_MINLEVEL=1 -NWN_MAXLEVEL=40 -NWN_PAUSEANDPLAY=0 -NWN_PVP=2 -NWN_SERVERVAULT=1 -NWN_ELC=1 -NWN_ILR=0 -NWN_GAMETYPE=3 -NWN_ONEPARTY=0 -NWN_DIFFICULTY=4 -NWN_AUTOSAVEINTERVAL=0 -NWN_RELOADWHENEMPTY=0 - -# NWNX - Plugins -NWNX_CORE_SKIP_ALL=y -NWNX_DOTNET_SKIP=n -NWNX_SWIG_DOTNET_SKIP=n - -# NWNX - Log Settings -NWNX_CORE_LOG_LEVEL=7 - -# Anvil -NWNX_DOTNET_ASSEMBLY=/nwn/anvil/NWN.Anvil -ANVIL_NLOG_CONFIG=/nwn/nwnm/Plugins/Test/nlog.config -ANVIL_RELOAD_ENABLED=false -ANVIL_LOG_MODE=Redirect - -#Trace/Logging -COREHOST_TRACE=1 diff --git a/NWN.Anvil.Tests/src/docker/docker-compose.yml b/NWN.Anvil.Tests/src/docker/docker-compose.yml deleted file mode 100644 index 520b8278d..000000000 --- a/NWN.Anvil.Tests/src/docker/docker-compose.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: '3' -services: - anvil: - build: - context: . - dockerfile: dockerfile - env_file: - - ./NWN.Anvil.Tests/bin/Release/config/nwserver.env - volumes: - - ./NWN.Anvil.Tests/bin/Release/config/nlog.config:/nwn/run/anvil/nlog.config - - ./NWN.Anvil.Tests/bin/Release/NWN.Anvil.Tests:/nwn/run/anvil/Plugins/NWN.Anvil.Tests - - ./NWN.Anvil.TestRunner/bin/Release/NWN.Anvil.TestRunner:/nwn/run/anvil/Plugins/NWN.Anvil.TestRunner - - ./NWN.Anvil.Tests/bin/Release/results:/nwn/run/anvil/PluginData/NWN.Anvil.TestRunner diff --git a/NWN.Anvil/NWN.Anvil.csproj b/NWN.Anvil/NWN.Anvil.csproj index e81f0a83c..d5c5d07d7 100644 --- a/NWN.Anvil/NWN.Anvil.csproj +++ b/NWN.Anvil/NWN.Anvil.csproj @@ -4,7 +4,8 @@ net8.0 linux-x64 diff --git a/dockerfile b/dockerfile index 069c8d3dd..6d9500fdf 100644 --- a/dockerfile +++ b/dockerfile @@ -1,6 +1,5 @@ # Load nwnx image to import nwserver + nwnx plugins -ARG NWNX_VERSION -FROM nwnxee/unified:${NWNX_VERSION} as nwnx +FROM nwnxee/unified:a6c5f09 as nwnx # Remove incompatible plugins RUN rm -rf /nwn/nwnx/NWNX_Ruby.so \ diff --git a/global.json b/global.json new file mode 100644 index 000000000..3fea262b1 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestFeature" + } +}