From 4b5c95d7fe045912f2935e6c6f6a666726cf38fd Mon Sep 17 00:00:00 2001 From: Peter Jonas Date: Thu, 10 Jun 2021 16:52:24 +0100 Subject: [PATCH] Move GitHub Actions CI scripts into separate files Break the workflow into smaller stages (Configure, Build, Install, Package, etc.) so that you can see exactly which stage failed in the GitHub Actions run log. Create a separate Bash CI script for each job stage (configure.sh, build.sh, install.sh, package.sh, etc.) to reduce the size of the main YAML workflow file and enable Bash syntax highlighting. Close #917 --- .github/workflows/cmake_build.yml | 252 ++++-------------- CMakeLists.txt | 7 +- .../cmake-modules/AudacityFunctions.cmake | 9 + cmake-proxies/cmake-modules/Package.cmake | 25 ++ linux/audacity.sh | 8 + scripts/ci/build.sh | 22 ++ scripts/ci/configure.sh | 32 +++ scripts/ci/dependencies.sh | 49 ++++ scripts/ci/environment.sh | 25 ++ scripts/ci/install.sh | 8 + scripts/ci/package.sh | 8 + src/CMakeLists.txt | 13 +- 12 files changed, 257 insertions(+), 201 deletions(-) create mode 100644 cmake-proxies/cmake-modules/Package.cmake create mode 100755 linux/audacity.sh create mode 100755 scripts/ci/build.sh create mode 100755 scripts/ci/configure.sh create mode 100755 scripts/ci/dependencies.sh create mode 100644 scripts/ci/environment.sh create mode 100755 scripts/ci/install.sh create mode 100755 scripts/ci/package.sh diff --git a/.github/workflows/cmake_build.yml b/.github/workflows/cmake_build.yml index 0d30d7599..3592f95eb 100644 --- a/.github/workflows/cmake_build.yml +++ b/.github/workflows/cmake_build.yml @@ -1,92 +1,60 @@ -# -# CMake based build for Audacity -# name: CMake Build -# -# Only execute on "git push" actions -# on: push: - # Remove the "#" from the next 2 lines if you need to disable this action - #branches: - # - disable pull_request: - # Remove the "#" from the next 2 lines if you need to disable this action - #branches: - # - disable -# -# Global environment variables -# -env: - WXURL: https://github.com/audacity/wxWidgets - WXREF: audacity-fixes-3.1.3 - WXWIN: ${{ github.workspace }}/wxwin - # As of 2021/01/01, github is using Xcode 12.2 as the default and - # it has a bug in the install_name_tool. So explicitly use 12.3 - # instead. - DEVELOPER_DIR: /Applications/Xcode_12.3.app/Contents/Developer - CONAN_USER_HOME: "${{ github.workspace }}/conan-home/" - CONAN_USER_HOME_SHORT: "${{ github.workspace }}/conan-home/short" -# -# Define our job(s) -# +defaults: + run: + shell: bash + jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} + env: + AUDACITY_CMAKE_GENERATOR: ${{ matrix.config.generator }} + AUDACITY_ARCH_LABEL: ${{ matrix.config.arch }} strategy: fail-fast: false matrix: config: - - { - name: "Windows_32bit", - os: windows-latest, - generator: "Visual Studio 16 2019", - platform: "Win32" - } - - { - name: "Windows_64bit", - os: windows-latest, - generator: "Visual Studio 16 2019", - platform: "x64" - } - - { - name: "Ubuntu_18.04", - os: ubuntu-18.04, - generator: "Unix Makefiles" - } - - { - name: "macOS", - os: macos-latest, - generator: "Xcode" - } + + - name: Ubuntu_18.04 + os: ubuntu-18.04 + arch: x86_64 # as reported by `arch` or `uname -m` + generator: Unix Makefiles + + - name: macOS_Intel + os: macos-latest + arch: Intel # as reported by Apple menu > About This Mac + generator: Xcode + + - name: Windows_32bit + os: windows-latest + arch: 32bit # as reported by Windows Settings > System > About + generator: Visual Studio 16 2019 + + - name: Windows_64bit + os: windows-latest + arch: 64bit # as reported by Windows Settings > System > About + generator: Visual Studio 16 2019 steps: - # ========================================================================= - # SHARED: Checkout source - # ========================================================================= + - name: Checkout uses: actions/checkout@v2 - # with: - # ref: master - # ========================================================================= - # SHARED: Checkout source - # ========================================================================= - - name: Calculate short hash - shell: bash - run: | - set -x - # Get the short hash - shorthash=$(git show -s --format='%h') - # Export the short hash for the upload step - echo "SHORTHASH=${shorthash}" >> ${GITHUB_ENV} - # Export the destination directory name - echo "DEST=${{matrix.config.name}}_${shorthash}" >> ${GITHUB_ENV} - - name: GitHub Action Cache for .conan - id: github-cache-conan + - name: Dependencies + run: | + exec bash "scripts/ci/dependencies.sh" + + - name: Environment + run: | + source "scripts/ci/environment.sh" + + - name: Cache for .conan + id: cache-conan uses: actions/cache@v2 env: cache-name: cache-conan-modules @@ -95,146 +63,32 @@ jobs: key: host-${{ matrix.config.name }}-${{ hashFiles('cmake-proxies/CMakeLists.txt') }} restore-keys: | host-${{ matrix.config.name }}- - - name: Check Sentry secrets + + - name: Configure env: SENTRY_DSN_KEY: ${{ secrets.SENTRY_DSN_KEY }} SENTRY_HOST: ${{ secrets.SENTRY_HOST }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - if: ${{ env.SENTRY_DSN_KEY != '' && env.SENTRY_HOST != '' && env.SENTRY_PROJECT != '' }} - shell: bash run: | - echo "SENTRY_PARAMETERS<> $GITHUB_ENV - echo "-DSENTRY_DSN_KEY=${SENTRY_DSN_KEY} -DSENTRY_HOST=${SENTRY_HOST} -DSENTRY_PROJECT=${SENTRY_PROJECT}" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV + exec bash "scripts/ci/configure.sh" - # ========================================================================= - # WINDOWS: Build (for all versions of Windows) - # ========================================================================= - - name: Build for Windows - if: startswith( matrix.config.os, 'windows' ) - shell: bash + - name: Build run: | - set -x - pip install conan - conan --version + exec bash "scripts/ci/build.sh" - # Configure Audacity - # - cmake -S . \ - -B build \ - -G "${{matrix.config.generator}}" \ - -A ${{matrix.config.platform}} \ - -D audacity_use_pch=no \ - -D audacity_has_networking=yes ${{ env.SENTRY_PARAMETERS }} - - # Build Audacity - cmake --build build --config Release --verbose - - # "Install" Audacity - mkdir -p "${DEST}" - cp -a build/bin/Release/* "${DEST}" - rm -f "${DEST}"/{*.iobj,*.ipdb} - - # Create artifact (zipped as Github actions don't preserve permissions) - cmake -E tar c "${GITHUB_SHA}.zip" --format=zip "${DEST}" - - # ========================================================================= - # MACOS: Build (for all versions of MacOS) - # ========================================================================= - - name: Build for macOS - if: startswith( matrix.config.os, 'macos' ) - shell: bash + - name: Install run: | - set -x + exec bash "scripts/ci/install.sh" - # Setup environment - export PATH="/usr/local/bin:${PATH}" - export DYLD_LIBRARY_PATH="/usr/local/lib" - - # Install required packages - brew install gettext - brew link --force gettext - - brew install conan - conan --version - - # Configure Audacity - cmake -S . \ - -B build \ - -T buildsystem=1 \ - -G "${{matrix.config.generator}}" \ - -D audacity_use_pch=no \ - -D audacity_has_networking=yes ${{ env.SENTRY_PARAMETERS }} - - # Build Audacity - cmake --build build --config Release - - # "Install" Audacity - mkdir -p "${DEST}" - cp -a build/bin/Release/ "${DEST}" - - # Create artifact (zipped as Github actions don't preserve permissions) - cmake -E tar c "${GITHUB_SHA}.zip" --format=zip "${DEST}" - - # ========================================================================= - # UBUNTU: Build (for all versions of Ubuntu) - # ========================================================================= - - name: Build for Ubuntu - if: startswith( matrix.config.os, 'ubuntu' ) - shell: bash + - name: Package run: | - set -x + exec bash "scripts/ci/package.sh" - # Setup environment - export PATH="/usr/local/bin:${PATH}" - export LD_LIBRARY_PATH="/usr/local/lib" - - # Install required packages - sudo apt-get update -y - sudo apt-get install -y libgtk2.0-dev libasound2-dev gettext python3-pip - sudo apt-get remove -y ccache - - pip3 install wheel setuptools - pip3 install conan - - conan --version - - # Configure Audacity - cmake -S . \ - -B build \ - -G "${{matrix.config.generator}}" \ - -D audacity_use_pch=no \ - -D audacity_has_networking=yes ${{ env.SENTRY_PARAMETERS }} - - # Build Audacity - cmake --build build --config Release - - # "Install" Audacity - cmake --install build --config Release --prefix "${DEST}" - - # Create the lib directory - mkdir -p ${DEST}/lib - - # Create wrapper script - cat >"${DEST}/audacity" <<"EOF" - #!/bin/sh - lib="${0%/*}/lib/audacity" - export LD_LIBRARY_PATH="${lib}:${LD_LIBRARY_PATH}" - export AUDACITY_MODULES_PATH="${lib}/modules" - "${0%/*}/bin/audacity" - - EOF - chmod +x "${DEST}/audacity" - - # Create artifact (zipped as Github actions don't preserve permissions) - cmake -E tar c "${GITHUB_SHA}.zip" --format=zip "${DEST}" - - # ========================================================================= - # SHARED: Attach the artifact to the workflow results - # ========================================================================= - name: Upload artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: - name: ${{ matrix.config.name }}_${{ env.SHORTHASH }} - path: ${{ github.sha }}.zip - + name: Audacity_${{ matrix.config.name }}_${{ github.run_id }}_${{ env.GIT_HASH_SHORT }} + path: | + build/package/* + !build/package/_CPack_Packages + if-no-files-found: error diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e50bb0f..fee909b3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,8 +168,12 @@ include( CMakePushCheckState ) include( GNUInstallDirs ) include( TestBigEndian ) +set_from_env(SENTRY_DSN_KEY) +set_from_env(SENTRY_HOST) +set_from_env(SENTRY_PROJECT) + cmake_dependent_option( - ${_OPT}has_sentry_reporting + ${_OPT}has_sentry_reporting "Build support for sending errors to Sentry" On "${_OPT}has_networking;DEFINED SENTRY_DSN_KEY;DEFINED SENTRY_HOST;DEFINED SENTRY_PROJECT" @@ -525,3 +529,4 @@ execute_process( COMMAND print_properties( TARGET "wxWidgets" ) #]] +include( Package ) # do this last diff --git a/cmake-proxies/cmake-modules/AudacityFunctions.cmake b/cmake-proxies/cmake-modules/AudacityFunctions.cmake index 165101289..199fcb878 100644 --- a/cmake-proxies/cmake-modules/AudacityFunctions.cmake +++ b/cmake-proxies/cmake-modules/AudacityFunctions.cmake @@ -74,6 +74,15 @@ macro( set_cache_value var value ) set_property( CACHE ${var} PROPERTY VALUE "${value}" ) endmacro() +# Set a CMake variable to the value of the corresponding environment variable +# if the CMake variable is not already defined. Any addition arguments after +# the variable name are passed through to set(). +macro( set_from_env var ) + if( NOT DEFINED ${var} AND NOT "$ENV{${var}}" STREQUAL "" ) + set( ${var} "$ENV{${var}}" ${ARGN} ) # pass additional args (e.g. CACHE) + endif() +endmacro() + # Set the given property and its config specific brethren to the same value function( set_target_property_all target property value ) set_target_properties( "${target}" PROPERTIES "${property}" "${value}" ) diff --git a/cmake-proxies/cmake-modules/Package.cmake b/cmake-proxies/cmake-modules/Package.cmake new file mode 100644 index 000000000..84b95e969 --- /dev/null +++ b/cmake-proxies/cmake-modules/Package.cmake @@ -0,0 +1,25 @@ + +set(CPACK_PACKAGE_VERSION_MAJOR "${AUDACITY_VERSION}") # X +set(CPACK_PACKAGE_VERSION_MINOR "${AUDACITY_RELEASE}") # Y +set(CPACK_PACKAGE_VERSION_PATCH "${AUDACITY_REVISION}") # Z + +# X.Y.Z-alpha-20210615 +set(CPACK_PACKAGE_VERSION "${AUDACITY_VERSION}.${AUDACITY_RELEASE}.${AUDACITY_REVISION}${AUDACITY_SUFFIX}") + +if(NOT AUDACITY_BUILD_LEVEL EQUAL 2) + # X.Y.Z-alpha-20210615+a1b2c3d + set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}+${GIT_COMMIT_SHORT}") +endif() + +# Audacity-X.Y.Z-alpha-20210615 +set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}") + +if(NOT "$ENV{AUDACITY_ARCH_LABEL}" STREQUAL "") + # Audacity-X.Y.Z-alpha-20210615-x86_64 + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-$ENV{AUDACITY_ARCH_LABEL}") +endif() +set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package") + +set(CPACK_GENERATOR ZIP) + +include(CPack) # do this last diff --git a/linux/audacity.sh b/linux/audacity.sh new file mode 100755 index 000000000..aab7bb102 --- /dev/null +++ b/linux/audacity.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +lib="${0%/*}/lib/audacity" + +export LD_LIBRARY_PATH="${lib}:${LD_LIBRARY_PATH}" +export AUDACITY_MODULES_PATH="${lib}/modules" + +exec "${0%/*}/bin/audacity" "$@" diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh new file mode 100755 index 000000000..48262b3f2 --- /dev/null +++ b/scripts/ci/build.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } + +set -euxo pipefail + +if [[ "${OSTYPE}" == msys* ]]; then # Windows + + cpus="${NUMBER_OF_PROCESSORS}" + +elif [[ "${OSTYPE}" == darwin* ]]; then # macOS + + cpus="$(sysctl -n hw.ncpu)" + +else # Linux & others + + cpus="$(nproc)" + +fi + +# Build Audacity +cmake --build build -j "${cpus}" --config "${AUDACITY_BUILD_TYPE}" diff --git a/scripts/ci/configure.sh b/scripts/ci/configure.sh new file mode 100755 index 000000000..a01644f50 --- /dev/null +++ b/scripts/ci/configure.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } + +set -euxo pipefail + +conan --version # check it works + +cmake_args=( + -S . + -B build + -G "${AUDACITY_CMAKE_GENERATOR}" + -D audacity_use_pch=no + -D audacity_has_networking=yes + -D CMAKE_BUILD_TYPE="${AUDACITY_BUILD_TYPE}" + -D CMAKE_INSTALL_PREFIX="${AUDACITY_INSTALL_PREFIX}" +) + +if [[ "${AUDACITY_CMAKE_GENERATOR}" == "Visual Studio"* ]]; then + case "${AUDACITY_ARCH_LABEL}" in + 32bit) cmake_args+=( -A Win32 ) ;; + 64bit) cmake_args+=( -A x64 ) ;; + *) echo >&2 "$0: Unrecognised arch label '${AUDACITY_ARCH_LABEL}'" ; exit 1 ;; + esac +elif [[ "${AUDACITY_CMAKE_GENERATOR}" == Xcode* ]]; then + cmake_args+=( + -T buildsystem=1 + ) +fi + +# Configure Audacity +cmake "${cmake_args[@]}" diff --git a/scripts/ci/dependencies.sh b/scripts/ci/dependencies.sh new file mode 100755 index 000000000..b96eb40eb --- /dev/null +++ b/scripts/ci/dependencies.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +((${BASH_VERSION%%.*} >= 4)) || echo >&2 "$0: Warning: Using ancient Bash version ${BASH_VERSION}." + +set -euxo pipefail + +if [[ "${OSTYPE}" == msys* ]]; then # Windows + + # Python packages + pip_packages=( + conan + ) + pip3 install "${pip_packages[@]}" + +elif [[ "${OSTYPE}" == darwin* ]]; then # macOS + + # Homebrew packages + brew_packages=( + bash # macOS ships with Bash v3 for licensing reasons so upgrade it now + conan + ) + brew install "${brew_packages[@]}" + +else # Linux & others + + # Distribution packages + if which apt-get; then + apt_packages=( + libasound2-dev + libgtk2.0-dev + gettext + python3-pip + ) + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends "${apt_packages[@]}" + sudo apt-get remove -y ccache + else + echo >&2 "$0: Error: You don't have a recognized package manager installed." + exit 1 + fi + + # Python packages + pip_packages=( + conan + ) + pip3 install wheel setuptools # need these first to install other packages (e.g. conan) + pip3 install "${pip_packages[@]}" + +fi diff --git a/scripts/ci/environment.sh b/scripts/ci/environment.sh new file mode 100644 index 000000000..fd426eccc --- /dev/null +++ b/scripts/ci/environment.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +if [[ "$0" == "${BASH_SOURCE}" ]]; then + echo >&2 "$0: Please source this script instead of running it." + exit 1 +fi + +((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "${BASH_SOURCE}: Error: Please upgrade Bash."; return 1; } + +function gh_export() +{ + [[ "${GITHUB_ENV-}" ]] || local -r GITHUB_ENV="/dev/null" + export -- "$@" && printf "%s\n" "$@" >> "${GITHUB_ENV}" +} + +repository_root="$(cd "$(dirname "${BASH_SOURCE}")/../.."; echo "${PWD}")" + +gh_export CONAN_USER_HOME="${repository_root}/conan-home/" +gh_export CONAN_USER_HOME_SHORT="${repository_root}/conan-home/short" + +gh_export GIT_HASH="$(git show -s --format='%H')" +gh_export GIT_HASH_SHORT="$(git show -s --format='%h')" + +gh_export AUDACITY_BUILD_TYPE="Release" +gh_export AUDACITY_INSTALL_PREFIX="${repository_root}/build/install" diff --git a/scripts/ci/install.sh b/scripts/ci/install.sh new file mode 100755 index 000000000..d302b0ef5 --- /dev/null +++ b/scripts/ci/install.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } + +set -euxo pipefail + +# Install Audacity +cmake --install build --config "${AUDACITY_BUILD_TYPE}" --verbose diff --git a/scripts/ci/package.sh b/scripts/ci/package.sh new file mode 100755 index 000000000..38d6e80a7 --- /dev/null +++ b/scripts/ci/package.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } + +set -euxo pipefail + +cd build +cpack -C "${AUDACITY_BUILD_TYPE}" --verbose diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 90a878c61..b35934665 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1339,7 +1339,15 @@ if( CMAKE_VERSION VERSION_GREATER_EQUAL "3.16" AND NOT CCACHE_PROGRAM ) endif() endif() -if( NOT "${CMAKE_GENERATOR}" MATCHES "Xcode|Visual Studio*" ) +if( "${CMAKE_GENERATOR}" MATCHES "Xcode|Visual Studio*" ) + install( + DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/" + DESTINATION "." + USE_SOURCE_PERMISSIONS + PATTERN "*.pdb" EXCLUDE + PATTERN "*.ilk" EXCLUDE + ) +else() if( CMAKE_SYSTEM_NAME MATCHES "Darwin" ) install( TARGETS ${TARGET} DESTINATION "." @@ -1358,6 +1366,9 @@ if( NOT "${CMAKE_GENERATOR}" MATCHES "Xcode|Visual Studio*" ) DESTINATION "${_DATADIR}/mime/packages" ) install( FILES "${topdir}/presets/EQDefaultCurves.xml" DESTINATION "${_PKGDATA}" ) + install( PROGRAMS "${PROJECT_SOURCE_DIR}/linux/audacity.sh" + DESTINATION "." + RENAME "audacity" ) endif() endif()