diff --git a/.ci/templates/merge-private.yml b/.ci/templates/merge-private.yml
new file mode 100644
index 0000000000..a640cfbde1
--- /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 0000000000..a673c5b01b
--- /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)'