diff --git a/.ci/scripts/merge/apply-patches-by-label-private.py b/.ci/scripts/merge/apply-patches-by-label-private.py
new file mode 100644
index 000000000..11ec60010
--- /dev/null
+++ b/.ci/scripts/merge/apply-patches-by-label-private.py
@@ -0,0 +1,41 @@
+# Download all pull requests as patches that match a specific label
+# Usage: python download-patches-by-label.py <Label to Match> <Root Path Folder to DL to>
+
+import requests, sys, json, urllib3.request, shutil, subprocess, os, traceback
+
+org = os.getenv("PrivateMergeOrg".upper(), "yuzu-emu")
+repo = os.getenv("PrivateMergeRepo".upper(), "yuzu-private")
+tagline = os.getenv("MergeTaglinePrivate".upper(), "")
+user = sys.argv[1]
+
+http = urllib3.PoolManager()
+dl_list = {}
+
+def check_individual(repo_id, pr_id):
+    url = 'https://%sdev.azure.com/%s/%s/_apis/git/repositories/%s/pullRequests/%s/labels?api-version=5.1-preview.1' % (user, org, repo, repo_id, pr_id)
+    response = requests.get(url)
+    if (response.ok):
+        j = json.loads(response.content)
+        for tg in j['value']:
+            if (tg['name'] == sys.argv[2]):
+                return True
+    return False
+
+try:
+    url = 'https://%sdev.azure.com/%s/%s/_apis/git/pullrequests?api-version=5.1' % (user, org, repo)
+    response = requests.get(url)
+    if (response.ok):
+        j = json.loads(response.content)
+        for pr in j["value"]:
+            repo_id = pr['repository']['id']
+            pr_id = pr['pullRequestId']
+            if (check_individual(repo_id, pr_id)):
+                pn = pr_id
+                ref  = pr['sourceRefName']
+                print("Matched PR# %s" % pn)
+                print(subprocess.check_output(["git", "fetch", "https://%sdev.azure.com/%s/_git/%s" % (user, org, repo), ref, "-f"]))
+                print(subprocess.check_output(["git", "merge", "--squash", 'origin/' + ref.replace('refs/heads/','')]))
+                print(subprocess.check_output(["git", "commit", "-m\"Merge %s PR %s\"" % (tagline, pn)]))
+except:
+    traceback.print_exc(file=sys.stdout)
+    sys.exit(-1)
diff --git a/.ci/scripts/merge/apply-patches-by-label.py b/.ci/scripts/merge/apply-patches-by-label.py
index b346001a5..7f1ea06cf 100644
--- a/.ci/scripts/merge/apply-patches-by-label.py
+++ b/.ci/scripts/merge/apply-patches-by-label.py
@@ -1,7 +1,9 @@
 # Download all pull requests as patches that match a specific label
 # Usage: python download-patches-by-label.py <Label to Match> <Root Path Folder to DL to>
 
-import requests, sys, json, urllib3.request, shutil, subprocess
+import requests, sys, json, urllib3.request, shutil, subprocess, os
+
+tagline = os.getenv("MergeTaglinePublic".upper(), "")
 
 http = urllib3.PoolManager()
 dl_list = {}
@@ -23,6 +25,6 @@ try:
                 print("Matched PR# %s" % pn)
                 print(subprocess.check_output(["git", "fetch", "https://github.com/yuzu-emu/yuzu.git", "pull/%s/head:pr-%s" % (pn, pn), "-f"]))
                 print(subprocess.check_output(["git", "merge", "--squash", "pr-%s" % pn]))
-                print(subprocess.check_output(["git", "commit", "-m\"Merge PR %s\"" % pn]))
+                print(subprocess.check_output(["git", "commit", "-m\"Merge %s PR %s\"" % (tagline, pn)]))
 except:
     sys.exit(-1)
diff --git a/.ci/templates/merge-private.yml b/.ci/templates/merge-private.yml
new file mode 100644
index 000000000..a640cfbde
--- /dev/null
+++ b/.ci/templates/merge-private.yml
@@ -0,0 +1,47 @@
+jobs:
+- job: merge
+  displayName: 'pull requests'
+  steps:
+  - checkout: self
+    submodules: recursive
+  - template: ./mergebot-private.yml
+    parameters:
+      matchLabel: '$(BuildName)-merge'
+      matchLabelPublic: '$(PublicBuildName)-merge'
+  - task: ArchiveFiles@2
+    displayName: 'Package Source'
+    inputs:
+      rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
+      includeRootFolder: false
+      archiveType: '7z'
+      archiveFile: '$(Build.ArtifactStagingDirectory)/yuzu-$(BuildName)-source.7z'
+  - task: PublishPipelineArtifact@1
+    displayName: 'Upload Artifacts'
+    inputs:
+      targetPath: '$(Build.ArtifactStagingDirectory)/yuzu-$(BuildName)-source.7z'
+      artifact: 'yuzu-$(BuildName)-source'
+      replaceExistingArchive: true
+- job: upload_source
+  displayName: 'upload'
+  dependsOn: merge
+  steps:
+  - template: ./sync-source.yml
+    parameters:
+      artifactSource: 'true'
+      needSubmodules: 'true'
+  - script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/yuzubot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/yuzubot-git-config.sh
+    displayName: 'Apply Git Configuration'
+  - script: git tag -a $(BuildName)-$(Build.BuildId) -m "yuzu $(BuildName) $(Build.BuildNumber) $(Build.DefinitionName)"
+    displayName: 'Tag Source'
+  - script: git remote add other $(GitRepoPushChangesURL)
+    displayName: 'Register Repository'
+  - script: git push --follow-tags --force other HEAD:$(GitPushBranch)
+    displayName: 'Update Code'
+  - script: git rev-list -n 1 $(BuildName)-$(Build.BuildId) > $(Build.ArtifactStagingDirectory)/tag-commit.sha
+    displayName: 'Calculate Release Point'
+  - task: PublishPipelineArtifact@1
+    displayName: 'Upload Release Point'
+    inputs:
+      targetPath: '$(Build.ArtifactStagingDirectory)/tag-commit.sha'
+      artifact: 'yuzu-$(BuildName)-release-point'
+      replaceExistingArchive: true
\ No newline at end of file
diff --git a/.ci/templates/mergebot-private.yml b/.ci/templates/mergebot-private.yml
new file mode 100644
index 000000000..a673c5b01
--- /dev/null
+++ b/.ci/templates/mergebot-private.yml
@@ -0,0 +1,23 @@
+parameters:
+  matchLabel: 'dummy-merge'
+  matchLabelPublic: 'dummy-merge'
+
+steps:
+  - script: mkdir $(System.DefaultWorkingDirectory)/patches && pip install requests urllib3
+    displayName: 'Prepare Environment'
+  - script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/yuzubot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/yuzubot-git-config.sh
+    displayName: 'Apply Git Configuration'
+  - task: PythonScript@0
+    displayName: 'Discover, Download, and Apply Patches'
+    inputs:
+      scriptSource: 'filePath'
+      scriptPath: '.ci/scripts/merge/apply-patches-by-label.py'
+      arguments: '${{ parameters.matchLabelPublic }} patches-public'
+      workingDirectory: '$(System.DefaultWorkingDirectory)'
+  - task: PythonScript@0
+    displayName: 'Discover, Download, and Apply Patches'
+    inputs:
+      scriptSource: 'filePath'
+      scriptPath: '.ci/scripts/merge/apply-patches-by-label-private.py'
+      arguments: '$(PrivateMergeUser) ${{ parameters.matchLabel }} patches-private'
+      workingDirectory: '$(System.DefaultWorkingDirectory)'
diff --git a/.ci/yuzu-patreon-step1.yml b/.ci/yuzu-patreon-step1.yml
new file mode 100644
index 000000000..cf30397cd
--- /dev/null
+++ b/.ci/yuzu-patreon-step1.yml
@@ -0,0 +1,8 @@
+trigger:
+- master
+
+stages:
+- stage: merge
+  displayName: 'merge'
+  jobs:
+  - template: ./templates/merge-private.yml
diff --git a/.ci/yuzu-patreon-step2.yml b/.ci/yuzu-patreon-step2.yml
new file mode 100644
index 000000000..080118224
--- /dev/null
+++ b/.ci/yuzu-patreon-step2.yml
@@ -0,0 +1,28 @@
+trigger:
+- master
+
+stages:
+- stage: format
+  displayName: 'format'
+  jobs:
+  - job: format
+    displayName: 'clang'
+    pool:
+      vmImage: ubuntu-latest
+    steps:
+    - template: ./templates/format-check.yml
+- stage: build
+  dependsOn: format
+  displayName: 'build'
+  jobs:
+  - template: ./templates/build-standard.yml
+    parameters:
+      cache: 'true'
+- stage: release
+  displayName: 'release'
+  dependsOn: build
+  jobs:
+  - job: azure
+    displayName: 'azure'
+    steps:
+    - template: ./templates/release-universal.yml
\ No newline at end of file
diff --git a/.ci/yuzu-patreon.yml b/.ci/yuzu-patreon.yml
deleted file mode 100644
index aa912913d..000000000
--- a/.ci/yuzu-patreon.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-# Starter pipeline
-# Start with a minimal pipeline that you can customize to build and deploy your code.
-# Add steps that build, run tests, deploy, and more:
-# https://aka.ms/yaml
-
-trigger:
-- master
-
-pool:
-  vmImage: 'ubuntu-latest'
-
-steps:
-- script: echo Hello, world!
-  displayName: 'Run a one-line script'
-
-- script: |
-    echo Add other tasks to build, test, and deploy your project.
-    echo See https://aka.ms/yaml
-  displayName: 'Run a multi-line script'