diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml
new file mode 100644
index 0000000..1e9ccd1
--- /dev/null
+++ b/.forgejo/workflows/ci.yml
@@ -0,0 +1,171 @@
+name: CI/CD
+
+on:
+  push:
+    branches: [ v6 ]
+    tags:
+      - '*'
+  pull_request:
+    branches: [ v6 ]
+
+env:
+  DOTNET_VERSION: '8.0.x'
+  REGISTRY: toastielab.dev
+
+jobs:
+  test:
+    name: Run Tests
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup .NET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: ${{ env.DOTNET_VERSION }}
+
+    - name: Restore dependencies
+      run: dotnet restore
+
+    - name: Test
+      run: dotnet test -c Release --verbosity normal
+
+  build:
+    name: Build Package
+    needs: test
+    if: startsWith(github.ref, 'refs/tags/')
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        runtime: [linux-x64, linux-arm64, win-x64, win-arm64, osx-x64, osx-arm64]
+
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup .NET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: ${{ env.DOTNET_VERSION }}
+
+    - name: Publish
+      run: |
+        dotnet publish -c Release -r ${{ matrix.runtime }} \
+          --self-contained \
+          -p:Version=${{ github.ref_name }} \
+          -o ellie-${{ matrix.runtime }} src/EllieBot/EllieBot.csproj
+
+    - name: Upload Artifact
+      uses: actions/upload-artifact@v4
+      with:
+        name: ellie-${{ matrix.runtime }}
+        path: ellie-${{ matrix.runtime }}
+  
+  create-release:
+    name: Create Release
+    needs:
+      - build
+    if: startsWith(github.ref, 'refs/tags/')
+    runs-on: ubuntu-latest
+    steps:
+      - name: Download all artifacts
+        uses: actions/download-artifact@v4
+        with:
+          pattern: 'ellie-*'
+          path: artifacts
+
+      - name: Create archives
+        run: |
+          cd artifacts
+          for dir in */; do
+            runtime="${dir%/}"
+            if [[ "$runtime" == *"win"* ]]; then
+              zip -r "$runtime.zip" "$runtime"
+            else
+              chmod +x "$runtime/EllieBot"
+              tar cvf "$runtime.tar" "$runtime"
+            fi
+          done
+
+      - name: Create Release
+        id: create_release
+        uses: softprops/action-gh-release@v2
+        if: startsWith(github.ref, 'refs/tags/')
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          name: Release ${{ github.ref_name }}
+          body: |
+            [Changelog](https://toastielab.dev/toastie_t0ast/elliebot/src/branch/v6/CHANGELOG.md)
+            
+          generate_release_notes: true
+          draft: false
+          prerelease: false
+          files: |
+            artifacts/*.zip
+            artifacts/*.tar
+  
+  docker:
+    name: Build and Push Docker image
+    if: github.event_name != 'pull_request'
+    runs-on: ubuntu-latest
+    needs: build
+    permissions:
+      contents: read
+      packages: write
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3
+
+      - name: Log into registry ${{ env.REGISTRY }}
+        uses: docker/login-action@v3
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build and push Docker image
+        uses: docker/build-push-action@v6
+        with:
+          push: true
+          context: .
+          tags: toastielab.dev/toastie_t0ast/elliebot:latest,toastielab.dev/toastie_t0ast/elliebot:v6,toastielab.dev/toastie_t0ast/elliebot:${{ github.ref_name }}
+  
+  publish-medusa-package:
+    name: Publish Marmalade Package
+    needs: build
+    runs-on: ubuntu-latest
+    if: github.event_name != 'pull_request'
+    
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+      with:
+        fetch-depth: 0
+
+    - name: Setup .NET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: '8.0.x'
+
+    - name: Set version
+      run: |
+        if [[ $GITHUB_REF == refs/tags/* ]]; then
+          echo "MARMALADE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
+        else
+          LAST_TAG=$(git describe --tags --abbrev=0)
+          echo "MARMALADE_VERSION=${LAST_TAG}-alpha${GITHUB_SHA::7}" >> $GITHUB_ENV
+        fi
+
+    - name: Pack and Push
+      working-directory: src/Ellie.Marmalade
+      run: |
+        dotnet pack -c Release /p:Version=${{ env.MARMALADE_VERSION }} -o bin/Release/packed
+        dotnet nuget push bin/Release/packed/*.nupkg --source https://toastielab.dev/api/packages/toastie_t0ast/nuget/index.json --api-key ${{ secrets.TOASTIELAB_API_KEY }}
+      continue-on-error: true
\ No newline at end of file