--- a
+++ b/.github/workflows/nightly-tests.yml
@@ -0,0 +1,145 @@
+name: Nightly Full AMMR tests
+
+on:
+  schedule:
+    - cron: 0 3 * * *
+  workflow_dispatch:
+    inputs:
+      force-update-durations:
+          type: boolean
+          description: 'Force creation of new .test-duration files and create a PR with them. Default is false.'
+          default: false
+
+
+concurrency: 
+  group: ci-nightly-${{ github.ref }}
+  cancel-in-progress: true
+
+
+jobs:
+  test-windows:
+    if: github.repository == 'anybody/ammr'
+    runs-on: windows-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        test_group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+    env:
+      # Triggers a warning at 20 deg muscles discretization angles
+      # I.e. wrapping on very small sharp corners
+      ShortestPathMaxAngle: 0.3491
+  
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: prefix-dev/setup-pixi@v0.8.7
+        with:
+          environments: test
+          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
+          activate-environment: test
+
+        
+      - name: Run full AMMR tests
+        run: |
+            cd Tests
+            pytest -n auto --dist worksteal `
+              --splits 10 --group ${{ matrix.test_group }} --splitting-algorithm=least_duration `
+              --durations=20 `
+              --store-durations --clean-durations `
+              --runslow
+
+        env:
+          RLM_LICENSE_PASSWORD: ${{ secrets.LICENSE_PASSWORD }}
+          RLM_LICENSE: ${{ secrets.LICENSE_SERVER }}
+      
+      - name: Upload partial durations
+        uses: actions/upload-artifact@v4
+        with:
+          name: test-durations-${{ matrix.test_group }}
+          path: | 
+            Tests\.test_durations
+          include-hidden-files: true
+          retention-days: 1
+
+  # Linux tests are currently broken due to a Wine issue with AnyBody 8.1
+  # test-linux:
+  #   if: github.repository == 'anybody/ammr'
+  #   runs-on: ubuntu-latest
+  #   container: ghcr.io/anybody/anybodycon-github-actions:8.1.0
+  #   env:
+  #     ANYBODY_SUPPRESS_DEPRECATION_MESSAGES: "Off"
+
+  #   strategy:
+  #     fail-fast: false
+  #     matrix:
+  #       test_group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+  #   steps:
+  #     - uses: actions/checkout@v4
+      
+  #     - name: Set debug env vars
+  #       run: echo ${{ github.event.inputs.debug_config }} >> $GITHUB_ENV
+      
+  #     - uses: prefix-dev/setup-pixi@v0.8.7
+  #       with:
+  #         environments: test
+  #         cache-write: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
+  #         activate-environment: test
+
+
+  #     - name: Run tests
+  #       run: |
+  #         cd Tests
+  #         pytest -n auto \
+  #           --splits 10 --group ${{ matrix.test_group }} --splitting-algorithm=least_duration \
+  #           --only-load \
+  #           --runslow
+  #       env:
+  #         RLM_LICENSE_PASSWORD: ${{ secrets.LICENSE_PASSWORD }}
+  #         RLM_LICENSE: ${{ secrets.LICENSE_SERVER }}
+    
+
+  combine-and-upload-timings:
+    runs-on: ubuntu-latest
+    needs: [test-windows]
+    if: github.repository == 'anybody/ammr'
+
+    steps:
+      - uses: actions/checkout@v4
+      
+      - name: Download artifacts
+        uses: actions/download-artifact@v4
+
+      - name: Combine test-durations
+        run: |
+          import json, pathlib
+          data = {}
+          for file in pathlib.Path.cwd().glob("test-durations-*/*"):
+              data.update(json.loads(file.read_text()))
+          data = {k: v for k, v in sorted(data.items(), key=lambda x: x[1], reverse=True)}
+          test_durations = pathlib.Path('Tests/.test_durations')
+          if set(data) != set(json.loads(test_durations.read_text())) or "${{ github.event.inputs.force-update-durations }}" == "true":
+              test_durations.write_text(json.dumps(data, indent=2))
+        shell: python
+
+      - name: Create updated durations PR
+        uses: peter-evans/create-pull-request@v7
+        with:
+          push-to-fork: anybody-bot/ammr
+          token: ${{ secrets.DURATIONS_TOKEN }}
+          branch: update-durations
+          add-paths: Tests/.test_durations
+          delete-branch: true
+          commit-message: Update test durations
+          author: AnyBody Bot <149305714+anybody-bot@users.noreply.github.com>
+          committer: AnyBody Bot <149305714+anybody-bot@users.noreply.github.com>
+          title: 🤖 Update test durations
+          body: |
+            The tests suite has changed and I have collected the newest test durations 
+            from yesterdays nightly test. This PR updates the `Tests/.test_durations` file.
+
+            [nightly-tests.yml]: ${{ github.server_url }}/${{ github.repository }}/blob/main/.github/workflows/nightly-tests.yml
+
+            This PR was created automatically by the [`nightly-tests.yml`][nightly-tests.yml] workflow.
\ No newline at end of file