Selaa lähdekoodia

CI: Update workflow actions

PatTheMav 2 vuotta sitten
vanhempi
sitoutus
6b26cc7943

+ 106 - 0
.github/actions/build-plugin/action.yaml

@@ -0,0 +1,106 @@
+name: 'Set up and build plugin'
+description: 'Builds the plugin for specified architecture and build config'
+inputs:
+  target:
+    description: 'Target architecture for dependencies'
+    required: true
+  config:
+    description: 'Build configuration'
+    required: false
+    default: 'RelWithDebInfo'
+  codesign:
+    description: 'Enable codesigning (macOS only)'
+    required: false
+    default: 'false'
+  codesignIdent:
+    description: 'Developer ID for application codesigning (macOS only)'
+    required: false
+    default: '-'
+  workingDirectory:
+    description: 'Working directory for packaging'
+    required: false
+    default: ${{ github.workspace }}
+runs:
+  using: composite
+  steps:
+    - name: Run macOS Build
+      if: runner.os == 'macOS'
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ inputs.workingDirectory }}
+      env:
+        CODESIGN_IDENT: ${{ inputs.codesignIdent }}
+        CODESIGN_TEAM: ${{ inputs.codesignTeam }}
+      run: |
+        : Run macOS Build
+
+        local -a build_args=(--config ${{ inputs.config }})
+        if (( ${+RUNNER_DEBUG} )) build_args+=(--debug)
+
+        if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(--codesign)
+
+        .github/scripts/build-macos ${build_args}
+
+    - name: Install Dependencies 🛍️
+      if: runner.os == 'Linux'
+      shell: bash
+      run: |
+        : Install Dependencies 🛍️
+        echo ::group::Install Dependencies
+        eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
+        echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
+        brew install --quiet zsh
+        echo ::endgroup::
+
+    - name: Run Ubuntu Build
+      if: runner.os == 'Linux'
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ inputs.workingDirectory }}
+      run: |
+        : Run Ubuntu Build
+
+        local -a build_args=(
+          --target linux-${{ inputs.target }}
+          --config ${{ inputs.config }}
+        )
+        if (( ${+RUNNER_DEBUG} )) build_args+=(--debug)
+
+        .github/scripts/build-linux ${build_args}
+
+    - name: Run Windows Build
+      if: runner.os == 'Windows'
+      shell: pwsh
+      run: |
+        # Run Windows Build
+        if ( $Env:RUNNER_DEBUG -ne $null ) {
+          Set-PSDebug -Trace 1
+        }
+
+        $BuildArgs = @{
+          Target = '${{ inputs.target }}'
+          Configuration = '${{ inputs.config }}'
+        }
+
+        .github/scripts/Build-Windows.ps1 @BuildArgs
+
+    - name: Create Summary 📊
+      if: contains(fromJSON('["Linux", "macOS"]'),runner.os)
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      env:
+        CCACHE_CONFIGPATH: ${{ inputs.workingDirectory }}/.ccache.conf
+      run: |
+        : Create Summary 📊
+
+        local -a ccache_data
+        if (( ${+RUNNER_DEBUG} )) {
+          setopt XTRACE
+          ccache_data=("${(fA)$(ccache -s -vv)}")
+        } else {
+          ccache_data=("${(fA)$(ccache -s)}")
+        }
+
+        print '### ${{ runner.os }} Ccache Stats (${{ inputs.target }})' >> $GITHUB_STEP_SUMMARY
+        print '```' >> $GITHUB_STEP_SUMMARY
+        for line (${ccache_data}) {
+          print ${line} >> $GITHUB_STEP_SUMMARY
+        }
+        print '```' >> $GITHUB_STEP_SUMMARY

+ 0 - 77
.github/actions/build-plugin/action.yml

@@ -1,77 +0,0 @@
-name: 'Setup and build plugin'
-description: 'Builds the plugin for specified architecture and build config.'
-inputs:
-  target:
-    description: 'Build target for dependencies'
-    required: true
-  config:
-    description: 'Build configuration'
-    required: false
-    default: 'Release'
-  codesign:
-    description: 'Enable codesigning (macOS only)'
-    required: false
-    default: 'false'
-  codesignIdent:
-    description: 'Developer ID for application codesigning (macOS only)'
-    required: false
-    default: '-'
-  visualStudio:
-    description: 'Visual Studio version (Windows only)'
-    required: false
-    default: 'Visual Studio 16 2019'
-  workingDirectory:
-    description: 'Working directory for packaging'
-    required: false
-    default: ${{ github.workspace }}
-runs:
-  using: 'composite'
-  steps:
-    - name: Run macOS Build
-      if: ${{ runner.os == 'macOS' }}
-      shell: zsh {0}
-      env:
-        CODESIGN_IDENT: ${{ inputs.codesignIdent }}
-      run: |
-        build_args=(
-          -c ${{ inputs.config }}
-          -t macos-${{ inputs.target }}
-        )
-
-        if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
-        if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
-
-        ${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args}
-
-    - name: Run Linux Build
-      if: ${{ runner.os == 'Linux' }}
-      shell: bash
-      run: |
-        build_args=(
-          -c ${{ inputs.config }}
-          -t linux-${{ inputs.target }}
-        )
-
-        if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then
-          build_args+=(--debug)
-        fi
-
-        ${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh "${build_args[@]}"
-
-    - name: Run Windows Build
-      if: ${{ runner.os == 'Windows' }}
-      shell: pwsh
-      run: |
-        $BuildArgs = @{
-          Target = '${{ inputs.target }}'
-          Configuration = '${{ inputs.config }}'
-          CMakeGenerator = '${{ inputs.visualStudio }}'
-        }
-
-        if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) {
-          $BuildArgs += @{
-            Debug = $true
-          }
-        }
-
-        ${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs

+ 46 - 33
.github/actions/package-plugin/action.yml → .github/actions/package-plugin/action.yaml

@@ -7,7 +7,7 @@ inputs:
   config:
     description: 'Build configuration'
     required: false
-    default: 'Release'
+    default: 'RelWithDebInfo'
   codesign:
     description: 'Enable codesigning (macOS only)'
     required: false
@@ -32,8 +32,8 @@ inputs:
     description: 'Apple ID password for notarization (macOS only)'
     required: false
     default: ''
-  createInstaller:
-    description: 'Create InnoSetup installer (Windows only)'
+  package:
+    description: 'Create Windows or macOS installation package'
     required: false
     default: 'false'
   workingDirectory:
@@ -41,59 +41,72 @@ inputs:
     required: false
     default: ${{ github.workspace }}
 runs:
-  using: 'composite'
+  using: composite
   steps:
-    - name: Run macOS packaging
-      if: ${{ runner.os == 'macOS' }}
-      shell: zsh {0}
+    - name: Run macOS Packaging
+      if: runner.os == 'macOS'
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ inputs.workingDirectory }}
       env:
         CODESIGN_IDENT: ${{ inputs.codesignIdent }}
         CODESIGN_IDENT_INSTALLER: ${{ inputs.installerIdent }}
         CODESIGN_IDENT_USER: ${{ inputs.codesignUser }}
         CODESIGN_IDENT_PASS: ${{ inputs.codesignPass }}
       run: |
-        package_args=(
-          -c ${{ inputs.config }}
-          -t macos-${{ inputs.target }}
-        )
+        : Run macOS Packaging
+
+        local -a package_args=(--config ${{ inputs.config }})
+        if (( ${+RUNNER_DEBUG} )) package_args+=(--debug)
 
-        if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(-s)
-        if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(-n)
-        if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
+        if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(--codesign)
+        if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(--notarize)
+        if [[ '${{ inputs.package }}' == 'true' ]] package_args+=(--package)
 
-        ${{ inputs.workingDirectory }}/.github/scripts/package-macos.zsh ${package_args}
+        .github/scripts/package-macos ${package_args}
 
-    - name: Run Linux packaging
-      if: ${{ runner.os == 'Linux' }}
+    - name: Install Dependencies 🛍️
+      if: runner.os == 'Linux'
       shell: bash
       run: |
+        : Install Dependencies 🛍️
+        echo ::group::Install Dependencies
+        eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
+        echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
+        brew install --quiet zsh
+        echo ::endgroup::
+
+    - name: Run Ubuntu Packaging
+      if: runner.os == 'Linux'
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ inputs.workingDirectory }}
+      run: |
+        : Run Ubuntu Packaging
         package_args=(
-          -c ${{ inputs.config }}
-          -t linux-${{ inputs.target }}
+          --target linux-${{ inputs.target }}
+          --config ${{ inputs.config }}
         )
-        if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then
-          build_args+=(--debug)
-        fi
+        if (( ${+RUNNER_DEBUG} )) build_args+=(--debug)
 
-        ${{ inputs.workingDirectory }}/.github/scripts/package-linux.sh "${package_args[@]}"
+        if [[ '${{ inputs.package }}' == 'true' ]] package_args+=(--package)
 
-    - name: Run Windows packaging
-      if: ${{ runner.os == 'Windows' }}
+        .github/scripts/package-linux ${package_args}
+
+    - name: Run Windows Packaging
+      if: runner.os == 'Windows'
       shell: pwsh
       run: |
+        # Run Windows Packaging
+        if ( $Env:RUNNER_DEBUG -ne $null ) {
+          Set-PSDebug -Trace 1
+        }
+
         $PackageArgs = @{
           Target = '${{ inputs.target }}'
           Configuration = '${{ inputs.config }}'
         }
 
-        if ( '${{ inputs.createInstaller }}' -eq 'true' ) {
+        if ( '${{ inputs.package }}' -eq 'true' ) {
           $PackageArgs += @{BuildInstaller = $true}
         }
 
-        if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) {
-          $BuildArgs += @{
-            Debug = $true
-          }
-        }
-
-        ${{ inputs.workingDirectory }}/.github/scripts/Package-Windows.ps1 @PackageArgs
+        .github/scripts/Package-Windows.ps1 @PackageArgs

+ 61 - 0
.github/actions/run-clang-format/action.yaml

@@ -0,0 +1,61 @@
+name: Run clang-format
+description: Runs clang-format and checks for any changes introduced by it
+inputs:
+  failCondition:
+    description: Controls whether failed checks also fail the workflow run
+    required: false
+    default: 'never'
+  workingDirectory:
+    description: Working directory for checks
+    required: false
+    default: ${{ github.workspace }}
+runs:
+  using: composite
+  steps:
+    - name: Check Runner Operating System 🏃‍♂️
+      if: runner.os == 'Windows'
+      shell: bash
+      run: |
+        : Check Runner Operating System 🏃‍♂️
+        echo "::notice::run-clang-format action requires a macOS-based or Linux-based runner."
+        exit 2
+
+    - name: Install Dependencies 🛍️
+      if: runner.os == 'Linux'
+      shell: bash
+      run: |
+        : Install Dependencies 🛍️
+        echo ::group::Install Dependencies
+        eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
+        echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
+        echo "/home/linuxbrew/.linuxbrew/opt/clang-format@13/bin" >> $GITHUB_PATH
+        brew install --quiet zsh
+        echo ::endgroup::
+
+    - name: Run clang-format 🐉
+      id: result
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ inputs.workingDirectory }}
+      env:
+        GITHUB_EVENT_FORCED: ${{ github.event.forced }}
+        GITHUB_REF_BEFORE: ${{ github.event.before }}
+      run: |
+        : Run clang-format 🐉
+        if (( ${+RUNNER_DEBUG} )) setopt XTRACE
+
+        local -a changes=($(git diff --name-only HEAD~1 HEAD))
+        case ${GITHUB_EVENT_NAME} {
+          pull_request) changes=($(git diff --name-only origin/${GITHUB_BASE_REF} HEAD)) ;;
+          push) if [[ ${GITHUB_EVENT_FORCED} != true ]] changes=($(git diff --name-only ${GITHUB_REF_BEFORE} HEAD)) ;;
+          *) ;;
+        }
+
+        if (( ${changes[(I)(*.c|*.h|*.cpp|*.hpp|*.m|*.mm)]} )) {
+          echo ::group::Install clang-format-13
+          brew install --quiet obsproject/tools/clang-format@13
+          echo ::endgroup::
+
+          echo ::group::Run clang-format-13
+          ./build-aux/run-clang-format --fail-${{ inputs.failCondition }} --check
+          echo ::endgroup::
+        }

+ 59 - 0
.github/actions/run-cmake-format/action.yaml

@@ -0,0 +1,59 @@
+name: Run cmake-format
+description: Runs cmake-format and checks for any changes introduced by it
+inputs:
+  failCondition:
+    description: Controls whether failed checks also fail the workflow run
+    required: false
+    default: 'never'
+  workingDirectory:
+    description: Working directory for checks
+    required: false
+    default: ${{ github.workspace }}
+runs:
+  using: composite
+  steps:
+    - name: Check Runner Operating System 🏃‍♂️
+      if: runner.os == 'Windows'
+      shell: bash
+      run: |
+        : Check Runner Operating System 🏃‍♂️
+        echo "::notice::run-cmake-format action requires a macOS-based or Linux-based runner."
+        exit 2
+
+    - name: Install Dependencies 🛍️
+      if: runner.os == 'Linux'
+      shell: bash
+      run: |
+        : Install Dependencies 🛍️
+        echo ::group::Install Dependencies
+        eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
+        echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
+        brew install --quiet zsh
+        echo ::endgroup::
+
+    - name: Run cmake-format 🎛️
+      id: result
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      working-directory: ${{ github.workspace }}
+      env:
+        GITHUB_EVENT_FORCED: ${{ github.event.forced }}
+        GITHUB_REF_BEFORE: ${{ github.event.before }}
+      run: |
+        : Run cmake-format 🎛️
+        if (( ${+RUNNER_DEBUG} )) setopt XTRACE
+
+        local -a changes=($(git diff --name-only HEAD~1 HEAD))
+        case ${GITHUB_EVENT_NAME} {
+          pull_request) changes=($(git diff --name-only origin/${GITHUB_BASE_REF} HEAD)) ;;
+          push) if [[ ${GITHUB_EVENT_FORCED} != true ]] changes=($(git diff --name-only ${GITHUB_REF_BEFORE} HEAD)) ;;
+          *) ;;
+        }
+
+        if (( ${changes[(I)*.cmake|*CMakeLists.txt]} )) {
+          echo ::group::Install cmakelang
+          pip3 install cmakelang
+          echo ::endgroup::
+          echo ::group::Run cmake-format
+          ./build-aux/run-cmake-format --fail-${{ inputs.failCondition }} --check
+          echo ::endgroup::
+        }

+ 154 - 0
.github/actions/setup-macos-codesigning/action.yaml

@@ -0,0 +1,154 @@
+name: Set up macOS codesigning
+description: Sets up code signing certificates, provisioning profiles, and notarization information
+inputs:
+  codesignIdentity:
+    description: Codesigning identity
+    required: true
+  installerIdentity:
+    description: Codesigning identity for package installer
+    required: false
+  codesignCertificate:
+    description: PKCS12 certificate in base64 format
+    required: true
+  certificatePassword:
+    description: Password required to install PKCS12 certificate
+    required: true
+  keychainPassword:
+    description: Password to use for temporary keychain
+    required: false
+  notarizationUser:
+    description: Apple ID to use for notarization
+    required: false
+  notarizationPassword:
+    description: Application password for notarization
+  provisioningProfile:
+    description: Provisioning profile in base64 format
+    required: false
+outputs:
+  haveCodesignIdent:
+    description: True if necessary codesigning credentials were found
+    value: ${{ steps.codesign.outputs.haveCodesignIdent }}
+  haveProvisioningProfile:
+    description: True if necessary provisioning profile credentials were found
+    value: ${{ steps.provisioning.outputs.haveProvisioningProfile }}
+  haveNotarizationUser:
+    description: True if necessary notarization credentials were found
+    value: ${{ steps.notarization.outputs.haveNotarizationUser }}
+  codesignIdent:
+    description: Codesigning identity
+    value: ${{ steps.codesign.outputs.codesignIdent }}
+  installerIdent:
+    description: Codesigning identity for package installer
+    value: ${{ steps.codesign.outputs.installerIdent }}
+  codesignTeam:
+    description: Codesigning team
+    value: ${{ steps.codesign.outputs.codesignTeam }}
+runs:
+  using: composite
+  steps:
+    - name: Check Runner Operating System 🏃‍♂️
+      if: runner.os != 'macOS'
+      shell: bash
+      run: |
+        : Check Runner Operating System 🏃‍♂️
+        echo "setup-macos-codesigning action requires a macOS-based runner."
+        exit 2
+
+    - name: macOS Codesigning ✍️
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      id: codesign
+      env:
+        MACOS_SIGNING_IDENTITY: ${{ inputs.codesignIdentity }}
+        MACOS_SIGNING_IDENTITY_INSTALLER: ${{ inputs.installerIdentity}}
+        MACOS_SIGNING_CERT: ${{ inputs.codesignCertificate }}
+        MAOCS_SIGNING_CERT_PASSWORD: ${{ inputs.certificatePassword }}
+        MACOS_KEYCHAIN_PASSWORD: ${{ inputs.keychainPassword }}
+      run: |
+        : macOS Codesigning ✍️
+        if (( ${+RUNNER_DEBUG} )) setopt XTRACE
+
+        if [[ ${MACOS_SIGNING_IDENTITY} && ${MACOS_SIGNING_IDENTITY_INSTALLER} && ${MACOS_SIGNING_CERT} ]] {
+          print 'haveCodesignIdent=true' >> $GITHUB_OUTPUT
+
+          local -r certificate_path="${RUNNER_TEMP}/build_certificate.p12"
+          local -r keychain_path="${RUNNER_TEMP}/app-signing.keychain-db"
+
+          print -n "${MACOS_SIGNING_CERT}" | base64 --decode --output="${certificate_path}"
+
+          : "${MACOS_KEYCHAIN_PASSWORD:="$(print ${RANDOM} | sha1sum | head -c 32)"}"
+
+          print '::group::Keychain setup'
+          security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path}
+          security set-keychain-settings -lut 21600 ${keychain_path}
+          security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path}
+
+          security import "${certificate_path}" -P "${MAOCS_SIGNING_CERT_PASSWORD}" -A \
+            -t cert -f pkcs12 -k ${keychain_path} \
+            -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/xcrun
+
+          security set-key-partition-list -S 'apple-tool:,apple:' -k "${MACOS_KEYCHAIN_PASSWORD}" \
+            ${keychain_path} &> /dev/null
+
+          security list-keychain -d user -s ${keychain_path} 'login-keychain'
+          print '::endgroup::'
+
+          local -r team_id="${${MACOS_SIGNING_IDENTITY##* }//(\(|\))/}"
+
+          print "codesignIdent=${MACOS_SIGNING_IDENTITY}" >> $GITHUB_OUTPUT
+          print "installerIdent=${MACOS_SIGNING_IDENTITY_INSTALLER}" >> $GITHUB_OUTPUT
+          print "MACOS_KEYCHAIN_PASSWORD=${MACOS_KEYCHAIN_PASSWORD}" >> $GITHUB_ENV
+          print "codesignTeam=${team_id}" >> $GITHUB_OUTPUT
+        } else {
+          print 'haveCodesignIdent=false' >> $GITHUB_OUTPUT
+        }
+
+    - name: Provisioning Profile 👤
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      id: provisioning
+      if: ${{ fromJSON(steps.codesign.outputs.haveCodesignIdent) }}
+      env:
+          MACOS_SIGNING_PROVISIONING_PROFILE: ${{ inputs.provisioningProfile }}
+      run: |
+        : Provisioning Profile 👤
+        if (( ${+RUNNER_DEBUG} )) setopt XTRACE
+
+        if [[ ${MACOS_SIGNING_PROVISIONING_PROFILE} ]] {
+          print 'haveProvisioningProfile=true' >> $GITHUB_OUTPUT
+
+          local -r profile_path="${RUNNER_TEMP}/build_profile.provisionprofile"
+          print -n "${MACOS_SIGNING_PROVISIONING_PROFILE}" \
+            | base64 --decode --output ${profile_path}
+
+          print '::group::Provisioning Profile Setup'
+          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
+          security cms -D -i ${profile_path} -o ${RUNNER_TEMP}/build_profile.plist
+          local -r uuid="$(plutil -extract UUID raw ${RUNNER_TEMP}/build_profile.plist)"
+          local -r team_id="$(plutil -extract TeamIdentifier.0 raw -expect string ${RUNNER_TEMP}/build_profile.plist)"
+
+          if [[ ${team_id} != '${{ steps.codesign.codesignTeam }}' ]] {
+            print '::notice::Code Signing team in provisioning profile does not match certificate.'
+          }
+
+          cp ${profile_path} ~/Library/MobileDevice/Provisioning\ Profiles/${uuid}.provisionprofile
+          print "provisioningProfileUUID=${uuid}" >> $GITHUB_OUTPUT
+          print '::endgroup::'
+        } else {
+          print 'haveProvisioningProfile=false' >> $GITHUB_OUTPUT
+        }
+
+    - name: Notarization 🧑‍💼
+      shell: zsh --no-rcs --errexit --pipefail {0}
+      id: notarization
+      if: ${{ fromJSON(steps.codesign.outputs.haveCodesignIdent) }}
+      env:
+          MACOS_NOTARIZATION_USERNAME: ${{ inputs.notarizationUser }}
+          MACOS_NOTARIZATION_PASSWORD: ${{ inputs.notarizationPassword }}
+      run: |
+        : Notarization 🧑‍💼
+        if (( ${+RUNNER_DEBUG} )) setopt XTRACE
+
+        if [[ ${MACOS_NOTARIZATION_USERNAME} && ${MACOS_NOTARIZATION_PASSWORD} ]] {
+          print 'haveNotarizationUser=true' >> $GITHUB_OUTPUT
+        } else {
+          print 'haveNotarizationUser=false' >> $GITHUB_OUTPUT
+        }