diff --git a/.github/workflows/jenkins.yaml b/.github/workflows/jenkins.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a9ab1fba7d822ef33a11556cdc17bcdba33dfa62
--- /dev/null
+++ b/.github/workflows/jenkins.yaml
@@ -0,0 +1,11 @@
+name: Trigger Jenkins Job
+on:
+  repository_dispatch:
+    types: [start-build]
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Trigger Jenkins Job
+      run: |
+        curl -X POST "http://jenkins.epic.oarcloud.noaa.gov/job/global-workflow/EMC-Pipelines/PR-274/buildWithParameters?token=${{ secrets.JENKINS_TOKEN }}&MACINE=${{ github.event.client_payload.param_value }}"
\ No newline at end of file
diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile
index b1334e534450c78a688eb10a9326aab0b6de7f02..162d55ca92405ff8f8e9350b619065691a2a87e3 100644
--- a/ci/Jenkinsfile
+++ b/ci/Jenkinsfile
@@ -19,6 +19,7 @@ pipeline {
     stages { // This initial stage is used to get the Machine name from the GitHub labels on the PR
              // which is used to designate the Nodes in the Jenkins Controler by the agent label
              // Each Jenknis Node is connected to said machine via an JAVA agent via an ssh tunnel
+             // no op 2
 
         stage('Get Machine') {
             agent { label 'built-in' }
diff --git a/ci/Jenkinsfile_multilabel b/ci/Jenkinsfile_multilabel
new file mode 100644
index 0000000000000000000000000000000000000000..144493009c4beaf31a175bd7dfad1c5b0a050771
--- /dev/null
+++ b/ci/Jenkinsfile_multilabel
@@ -0,0 +1,311 @@
+def Machine = 'none'
+def machine = 'none'
+def HOME = 'none'
+def caseList = ''
+// no op 2 Location of the custom workspaces for each machine in the CI system.  They are persitent for each iteration of the PR.
+def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/stmp/CI/HERCULES']
+def repo_tmp = 'git@github.com:TerrenceMcGuinness-NOAA/global-workflow.git'
+def repo_url = 'https://github.com/TerrenceMcGuinness-NOAA/global-workflow.git'
+def STATUS = 'Passed'
+
+properties([
+    parameters([[
+        $class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hera-EMC', 'Orion-EMC'], defaultSlaves: ['built-in'], name: 'Node', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases'],
+        string(name: 'machine', defaultValue: 'orion', description: 'Node to run on today'),
+    ])
+])
+
+pipeline {
+
+    agent { label 'built-in' }
+
+    options {
+        skipDefaultCheckout()
+        buildDiscarder(logRotator(numToKeepStr: '3'))
+        //parallelsAlwaysFailFast()
+    }
+
+    stages { // This initial stage is used to get the Machine name from the GitHub labels on the PR
+             // which is used to designate the Nodes in the Jenkins Controler by the agent label
+             // Each Jenknis Node is connected to said machine via an JAVA agent via an ssh tunnel
+
+        stage('Get Machine') {
+            //when {
+            //    //expression { env.BUILD_CAUSE != 'UPSTREAMTRIGGER' }
+            //    expression { env.Node == 'built-in' }
+            //}
+            agent { label 'built-in' }
+            steps {
+                script {
+        //             generateBaselineNode = []
+        // .           for (label in pullRequest.labels) {
+        //                 listOfLabelNodeNames = jenkins.model.Jenkins.instance.nodes.collect {
+        //                     node -> node.getLabelString().contains(label) ? node.name : null
+
+        //                     if ((label.matches(node.getLabelString()+"-(.*)"))) {
+        //                         matchedNode += node.getLabelString()
+        //                     }
+
+        //                     if ((label.matches(node.getLabelString()+"(.*)-emc"))) {
+        //                         generateBaselineNode += node.getLabelString()
+        //                     }
+        //                 }
+        //             }
+                    echo "Debugging Information: in Get Machine"
+                    echo "====================================="
+                    echo "machine: ${machine}"
+                    echo "Node: ${env.Node}"
+                    echo "Change ID: ${env.CHANGE_ID}"
+                    echo "env.BUILD_CAUSE: ${env.BUILD_CAUSE}"
+
+                    if ( env.Node != 'built-in' ) {
+                        echo "machine being set to value passed to job"
+                        echo "passed machine: ${params.machine}"
+                        machine = params.machine
+                    } else {
+                        echo "Lanuching second build job on Hercules-EMC"
+                        build job: "/global-workflow/EMC-Pipelines/PR-${env.CHANGE_ID}", parameters: [
+                            string(name: 'machine', value: 'hercules'),
+                            string(name: 'Node', value: 'Hercules-EMC') ],
+                            wait: false
+                        echo "Continuing with build on Hera-EMC"
+                        machine = 'hera'
+                    }
+                }
+            }
+        }
+
+        stage('Get Common Workspace') {
+            agent { label "${machine}-emc" }
+            steps {
+                script {
+
+                    echo "Debugging Information: in Get Common Workspace"
+                    echo "====================================="
+                    echo "machine: ${machine}"
+                    echo "Node: ${env.Node}"
+                    echo "Change ID: ${env.CHANGE_ID}"
+                    echo "env.BUILD_CAUSE: ${env.BUILD_CAUSE}"
+
+                    Machine = machine[0].toUpperCase() + machine.substring(1)
+                    ws("${custom_workspace[machine]}/${env.CHANGE_ID}") {
+                        HOME = "${WORKSPACE}"
+                        sh(script: "mkdir -p ${HOME}/RUNTESTS;rm -Rf ${HOME}/RUNTESTS/error.logs")
+                        sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """)
+                    }
+                    echo "Building and running on ${Machine} in directory ${HOME}"
+                }
+            }
+        }
+
+        stage('Build System') {
+            matrix {
+                agent { label "${machine}-emc" }
+                //options {
+                //    throttle(['global_matrix_build'])
+                //}
+                axes {
+                    axis {
+                        name 'system'
+                        values 'gfs', 'gefs'
+                    }
+                }
+                stages {
+                    stage('build system') {
+                        steps {
+                            script {
+                                def HOMEgfs = "${HOME}/${system}" // local HOMEgfs is used to build the system on per system basis under the common workspace HOME
+                                sh(script: "mkdir -p ${HOMEgfs}")
+                                ws(HOMEgfs) {
+                                    if (fileExists("${HOMEgfs}/sorc/BUILT_semaphor")) { // if the system is already built, skip the build in the case of re-runs
+                                        sh(script: "cat ${HOMEgfs}/sorc/BUILT_semaphor", returnStdout: true).trim() // TODO: and user configurable control to manage build semphore
+                                        checkout scm
+                                        dir('sorc') {
+                                            sh(script: './link_workflow.sh')
+                                        }
+                                    } else {
+                                        if (env.CHANGE_ID) {
+                                            dir("${HOMEgfs}") {
+                                                sh(script: "cd ${HOMEgfs}")
+                                            }
+                                            try {
+                                                echo "Checkout out PR-${env.CHANGE_ID} from ${repo_url}"
+                                                echo "To also be clone in directory: ${pwd()}"
+                                                checkout scm
+                                                // no op 2
+                                                //checkout([
+                                                //    $class: 'GitSCM',
+                                                //    userRemoteConfigs: [[url: "${repo_url}", credentialsId: '4ecd9d87-9253-45b0-929c-0dab37905d69']],
+                                                //    branches: [[name: "refs/pull/${env.CHANGE_ID}/head"]],
+                                                //])
+                                            } catch (Exception e) {
+                                                echo "Failed to checkout scm: ${e.getMessage()}"
+                                            }
+                                        } else {
+                                            echo "Not a pull request, skipping checkout"
+                                        }
+                                        def gist_url = ""
+                                        def error_logs = ""
+                                        def error_logs_message = ""
+                                        def builds_file = readYaml file: 'ci/cases/yamls/build.yaml'
+                                        def build_args_list = builds_file['builds']
+                                        def build_args = build_args_list[system].join(' ').trim().replaceAll('null', '')
+                                        dir("${HOMEgfs}/sorc") {
+                                            try {
+                                                sh(script: "${build_args}")
+                                            } catch (Exception error_build) {
+                                                echo "Failed to build system: ${error_build.getMessage()}"
+                                                if ( fileExists("logs/error.logs") ) {
+                                                    def fileContent = readFile 'logs/error.logs'
+                                                    def lines = fileContent.readLines()
+                                                    for (line in lines) {
+                                                        echo "archiving: ${line}"
+                                                        if (fileExists("${line}") && readFile("${line}").length() > 0 ){
+                                                            try {
+                                                                archiveArtifacts artifacts: "${line}", fingerprint: true
+                                                                error_logs = error_logs + "${HOMEgfs}/sorc/${line} "
+                                                                error_logs_message = error_logs_message + "${HOMEgfs}/sorc/${line}\n"
+                                                            }
+                                                            catch (Exception error_arch) { echo "Failed to archive error log ${line}: ${error_arch.getMessage()}" }
+                                                        }
+                                                    }
+                                                    try {
+                                                        sh(script: "${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --repo PR_BUILD_${env.CHANGE_ID}")
+                                                        gist_url=sh(script: "${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --gist PR_BUILD_${env.CHANGE_ID}", returnStdout: true).trim()
+                                                        sh(script:  """${GH} pr comment ${env.CHANGE_ID} --repo ${repo_url} --body "Build **FAILED** on **${Machine}** with error logs:\n\\`\\`\\`${error_logs_message}\n\\`\\`\\`\n\nFollow link here to view the contents of the above file(s): [(link)](${gist_url})" """)
+                                                    } catch (Exception error_comment) {
+                                                        echo "Failed to comment on PR: ${error_comment.getMessage()}"
+                                                    }
+                                                    error("Failed to build system on ${Machine}")
+                                                }
+                                            }
+                                            sh(script: './link_workflow.sh')
+                                            sh(script: "echo ${HOMEgfs} > BUILT_semaphor")
+                                        }
+                                    }
+                                    if (env.CHANGE_ID && system == 'gfs') {
+                                        try {
+                                            sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Running" --remove-label "CI-${Machine}-Building" """)
+                                        } catch (Exception e) {
+                                            echo "Failed to update label from Buildng to Running: ${e.getMessage()}"
+                                        }
+                                    }
+                                    if (system == 'gfs') {
+                                        caseList = sh(script: "${HOMEgfs}/ci/scripts/utils/get_host_case_list.py ${machine}", returnStdout: true).trim().split()
+                                    }
+                               }
+                           }
+                        }
+                    }
+                }
+            }
+        }
+
+        stage('Run Tests') {
+            failFast false 
+            matrix {
+                agent { label "${machine}-emc" }
+                axes {
+                    axis {
+                        name 'Case'
+                        // TODO add dynamic list of cases from env vars (needs addtional plugins)
+                        values 'C48C48_ufs_hybatmDA', 'C48_ATM', 'C48_S2SW', 'C48_S2SWA_gefs', 'C48mx500_3DVarAOWCDA', 'C96C48_hybatmDA', 'C96_atm3DVar', 'C96_atmaerosnowDA'
+                    }
+                }
+                stages {
+
+                    stage('Create Experiments') {
+                        when {
+                            expression { return caseList.contains(Case) }
+                        }
+                        steps {
+                                script {
+                                    sh(script: "sed -n '/{.*}/!p' ${HOME}/gfs/ci/cases/pr/${Case}.yaml > ${HOME}/gfs/ci/cases/pr/${Case}.yaml.tmp")
+                                    def yaml_case = readYaml file: "${HOME}/gfs/ci/cases/pr/${Case}.yaml.tmp"
+                                    system = yaml_case.experiment.system
+                                    def HOMEgfs = "${HOME}/${system}"   // local HOMEgfs is used to populate the XML on per system basis
+                                    env.RUNTESTS = "${HOME}/RUNTESTS"
+                                    sh(script: "${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh create_experiment ${HOMEgfs}/ci/cases/pr/${Case}.yaml")
+                                }
+                        }
+                    }
+
+                    stage('Run Experiments') {
+                        when {
+                            expression { return caseList.contains(Case) }
+                        }
+                        failFast false
+                        steps {
+                            script {
+                                HOMEgfs = "${HOME}/gfs"  // common HOMEgfs is used to launch the scripts that run the experiments
+                                def pslot = sh(script: "${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh get_pslot ${HOME}/RUNTESTS ${Case}", returnStdout: true).trim()
+                                try {
+                                    sh(script: "${HOMEgfs}/ci/scripts/run-check_ci.sh ${HOME} ${pslot} ${system}")
+                                } catch (Exception error_experment) {
+                                    sh(script: "${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh cancel_batch_jobs ${pslot}")
+                                    ws(HOME) {
+                                        def error_logs = ""
+                                        def error_logs_message = ""
+                                        def error_file = "${HOME}/RUNTESTS/${pslot}_error.logs"
+                                        if (fileExists(error_file)) {
+                                            def fileContent = readFile error_file
+                                            def lines = fileContent.readLines()
+                                            for (line in lines) {
+                                                echo "archiving: ${line}"
+                                                if (fileExists("${HOME}/${line}") && readFile("${HOME}/${line}").length() > 0) {
+                                                    try {
+                                                        archiveArtifacts artifacts: "${line}", fingerprint: true
+                                                        error_logs = error_logs + "${HOME}/${line} "
+                                                        error_logs_message = error_logs_message + "${HOME}/${line}\n"
+                                                    } catch (Exception error_arch) {
+                                                        echo "Failed to archive error log ${line}: ${error_arch.getMessage()}"
+                                                    }
+                                                }
+                                            }
+                                            try {
+                                                gist_url = sh(script: "${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --gist PR_${env.CHANGE_ID}", returnStdout: true).trim()
+                                                sh(script: """${GH} pr comment ${env.CHANGE_ID} --repo ${repo_url} --body "Experiment ${Case} **FAILED** on ${Machine} with error logs:\n\\`\\`\\`\n${error_logs_message}\\`\\`\\`\n\nFollow link here to view the contents of the above file(s): [(link)](${gist_url})" """)
+                                                sh(script: "${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --repo PR_${env.CHANGE_ID}")
+                                            } catch (Exception error_comment) {
+                                                echo "Failed to comment on PR: ${error_comment.getMessage()}"
+                                            }
+                                        } else {
+                                            echo "No error logs found for failed cases in $HOME/RUNTESTS/${pslot}_error.logs"
+                                        }
+                                        STATUS = 'Failed'
+                                        try {
+                                            sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --remove-label "CI-${Machine}-Running" --add-label "CI-${Machine}-${STATUS}" """, returnStatus: true)
+                                        } catch (Exception e) {
+                                            echo "Failed to update label from Running to ${STATUS}: ${e.getMessage()}"
+                                        }
+                                        error("Failed to run experiments ${Case} on ${Machine}")
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        stage( 'FINALIZE' ) {
+            when { 
+                expression {
+                   STATUS == 'Passed'
+                }
+            }
+            agent { label "${machine}-emc" }
+            steps {
+                script {
+                    try {
+                        def currentDate = new Date()
+                        def date = currentDate.format('MMMM dd HH:mm')
+                        sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --remove-label "CI-${Machine}-Running" --remove-label "CI-${Machine}-Building" --add-label "CI-${Machine}-${STATUS}" """, returnStatus: true)
+                        sh(script: """${GH} pr comment ${env.CHANGE_ID} --repo ${repo_url} --body "**CI ${STATUS}** ${Machine} at ${date} Built and ran in directory<br>\\`${HOME}\\`" """, returnStatus: true)
+                    } catch (Exception e) {
+                        echo "Failed to update label from Running to ${STATUS}: ${e.getMessage()}"
+                    }
+                }
+            }
+        }   
+    }
+}