From 6640c47c20bf62dec6d2e673370949430e750593 Mon Sep 17 00:00:00 2001 From: Jesse McFarland Date: Tue, 12 Apr 2022 17:21:48 -0400 Subject: [PATCH] Check-in Jenkinsfile and unified scripts * Add Jenkinsfile that includes a build and test pipeline, which leverages the unified build and test scripts * Supported platforms are Cheyenne, Gaea, and Orion * Supported compilers are GNU and Intel --- .cicd/Jenkinsfile | 169 +++++++++++++++++++++++++++++++++++++ .cicd/scripts/srw_build.sh | 31 +++++++ .cicd/scripts/srw_test.sh | 21 +++++ 3 files changed, 221 insertions(+) create mode 100644 .cicd/Jenkinsfile create mode 100755 .cicd/scripts/srw_build.sh create mode 100755 .cicd/scripts/srw_test.sh diff --git a/.cicd/Jenkinsfile b/.cicd/Jenkinsfile new file mode 100644 index 0000000000..265d7d445e --- /dev/null +++ b/.cicd/Jenkinsfile @@ -0,0 +1,169 @@ +pipeline { + agent none + + options { + skipDefaultCheckout(true) + } + + parameters { + // Allow job runner to filter based on platform + // choice(name: 'SRW_PLATFORM_FILTER', choices: ['all', 'cheyenne', 'gaea', 'orion', 'pcluster_noaa_v2_use1', 'azcluster_noaa', 'gcluster_noaa_v2_usc1'], description: 'Specify the platform(s) to use') + choice(name: 'SRW_PLATFORM_FILTER', choices: ['all', 'cheyenne', 'gaea', 'orion'], description: 'Specify the platform(s) to use') + // Allow job runner to filter based on compiler + choice(name: 'SRW_COMPILER_FILTER', choices: ['all', 'gnu', 'intel'], description: 'Specify the compiler(s) to use to build') + } + + stages { + /* + // Start the NOAA Parallel Works clusters, if necessary + stage('Start Parallel Works Clusters') { + matrix { + // Start all clusters by default or only the specified cluster given by SRW_PLATFORM_FILTER + when { + anyOf { + expression { params.SRW_PLATFORM_FILTER == 'all' } + expression { params.SRW_PLATFORM_FILTER == env.SRW_PLATFORM } + } + } + + axes { + axis { + name 'SRW_PLATFORM' + values 'pcluster_noaa_v2_use1', 'azcluster_noaa', 'gcluster_noaa_v2_usc1' + } + } + + stages { + // Call the parallel-works-jenkins-client/start-cluster job using SRW_PLATFORM for the + // PW_CLUSTER_NAME parameter + stage('Start Cluster') { + steps { + build job: 'parallel-works-jenkins-client/start-cluster', parameters: [string(name: 'PW_CLUSTER_NAME', value: env.SRW_PLATFORM), string(name: 'PW_CLUSTER_SSH_KEY', value: '~/.ssh/id_rsa'), string(name: 'JAVA_VERSION', value: '11')] + } + } + } + } + } + */ + + // Build and test the SRW application on all supported platforms using the supported compilers for each platform + stage('Build and Test') { + matrix { + // Run on all platform/compiler combinations by default or build and test only on the platform(s) and + // compiler(s) specified by SRW_PLATFORM_FILTER and SRW_COMPILER_FILTER + when { + allOf { + anyOf { + expression { params.SRW_PLATFORM_FILTER == 'all' } + expression { params.SRW_PLATFORM_FILTER == env.SRW_PLATFORM } + } + + anyOf { + expression { params.SRW_COMPILER_FILTER == 'all' } + expression { params.SRW_COMPILER_FILTER == env.SRW_COMPILER } + } + } + } + + axes { + axis { + name 'SRW_PLATFORM' + // values 'cheyenne', 'gaea', 'orion', 'pcluster_noaa_v2_use1', 'azcluster_noaa', 'gcluster_noaa_v2_usc1' + values 'cheyenne', 'gaea', 'orion' + } + + axis { + name 'SRW_COMPILER' + values 'gnu', 'intel' + } + } + + excludes { + // Exclude GNU from platforms that don't support it + exclude { + axis { + name 'SRW_PLATFORM' + values 'gaea', 'orion' + } + + axis { + name 'SRW_COMPILER' + values 'gnu' + } + } + } + + agent { + label env.SRW_PLATFORM + } + + environment { + BUILD_VERSION = "${env.SRW_PLATFORM}-${env.SRW_COMPILER}-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" + BUILD_NAME = "ufs-srweather-app_${env.BUILD_VERSION}" + } + + stages { + // Clean the workspace, checkout the repository, and run checkout_externals + stage('Initialize') { + steps { + echo "Initializing SRW (${env.SRW_COMPILER}) build environment on ${env.SRW_PLATFORM}" + cleanWs() + checkout scm + sh '"${WORKSPACE}/manage_externals/checkout_externals"' + } + } + + // Run the unified build script; if successful create a tarball of the build and upload to S3 + stage('Build') { + steps { + echo "Building SRW (${env.SRW_COMPILER}) on ${env.SRW_PLATFORM}" + sh 'bash --login "${WORKSPACE}/.cicd/scripts/srw_build.sh"' + } + + post { + success { + sh 'tar --create --gzip --verbose --file "${WORKSPACE}/${BUILD_NAME}.tgz" bin include lib share' + s3Upload consoleLogLevel: 'INFO', dontSetBuildResultOnFailure: false, dontWaitForConcurrentBuildCompletion: false, entries: [[bucket: 'woc-epic-jenkins-artifacts', excludedFile: '', flatten: false, gzipFiles: false, keepForever: false, managedArtifacts: true, noUploadOnFailure: true, selectedRegion: 'us-east-1', showDirectlyInBrowser: false, sourceFile: "${env.BUILD_NAME}.tgz", storageClass: 'STANDARD', uploadFromSlave: false, useServerSideEncryption: false]], pluginFailureResultConstraint: 'FAILURE', profileName: 'main', userMetadata: [] + } + } + } + + // Run the unified test script + stage('Test') { + steps { + echo "Testing SRW (${env.SRW_COMPILER}) on ${env.SRW_PLATFORM}" + sh 'bash --login "${WORKSPACE}/.cicd/scripts/srw_test.sh"' + } + } + } + } + } + } + + /* + post { + always { + // Stop any Parallel Works clusters that were started during the pipeline execution + script { + def pw_clusters = ['pcluster_noaa_v2_use1', 'azcluster_noaa', 'gcluster_noaa_v2_usc1'] + def clusters = [] + + // Determine which clusters need to be stopped, if any + if (params.SRW_PLATFORM_FILTER == 'all') { + clusters = pw_clusters + } else if (params.SRW_PLATFORM_FILTER in pw_clusters) { + clusters = [params.SRW_PLATFORM_FILTER] + } else { + echo 'No Parallel Works clusters were used in build' + } + + for (int i = 0; i < clusters.size(); ++i) { + // Call the parallel-works-jenkins-client/stop-cluster job using clusters[i] for the + // PW_CLUSTER_NAME parameter + build job: 'parallel-works-jenkins-client/stop-cluster', parameters: [string(name: 'PW_CLUSTER_NAME', value: clusters[i])] + } + } + } + } + */ +} diff --git a/.cicd/scripts/srw_build.sh b/.cicd/scripts/srw_build.sh new file mode 100755 index 0000000000..79d9211af5 --- /dev/null +++ b/.cicd/scripts/srw_build.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# A unified build script for the SRW application. This script is expected to +# build the SRW application for all supported platforms. +# +set -e -u -x + +script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)" + +# Get repository root from Jenkins WORKSPACE variable if set, otherwise, set +# relative to script directory. +declare workspace +if [[ -n "${WORKSPACE}" ]]; then + workspace="${WORKSPACE}" +else + workspace="$(cd -- "${script_dir}/../.." && pwd)" +fi + +build_dir="${workspace}/build" + +# Set build related environment variables and load required modules. +source "${workspace}/etc/lmod-setup.sh" "${SRW_PLATFORM}" +module use "${workspace}/modulefiles" +module load "build_${SRW_PLATFORM}_${SRW_COMPILER}" + +# Compile SRW application and install to repository root. +mkdir "${build_dir}" +pushd "${build_dir}" + cmake -DCMAKE_INSTALL_PREFIX="${workspace}" "${workspace}" + make -j "${MAKE_JOBS}" +popd diff --git a/.cicd/scripts/srw_test.sh b/.cicd/scripts/srw_test.sh new file mode 100755 index 0000000000..43b9935888 --- /dev/null +++ b/.cicd/scripts/srw_test.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# +# A unified test script for the SRW application. This script is expected to +# test the SRW application for all supported platforms. NOTE: At this time, +# this script is a placeholder for a more robust test framework. +# +set -e -u -x + +script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)" + +# Get repository root from Jenkins WORKSPACE variable if set, otherwise, set +# relative to script directory. +declare workspace +if [[ -n "${WORKSPACE}" ]]; then + workspace="${WORKSPACE}" +else + workspace="$(cd -- "${script_dir}/../.." && pwd)" +fi + +# Verify that there is a non-zero sized weather model executable. +[[ -s "${workspace}/bin/ufs_model" ]] || [[ -s "${workspace}/bin/NEMS.exe" ]]