diff --git a/.cirrus.yml b/.cirrus.yml index c2d2ca7d94394e..34f99a75e48fc6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ # $FreeBSD$ freebsd_instance: - image: freebsd-13-2-release-amd64 + image: freebsd-14-1-release-amd64-ufs env: CIRRUS_CLONE_DEPTH: 1 @@ -9,11 +9,12 @@ env: task: install_script: - - pkg-install -y - cmake ninja binutils pkgconf curl + - pkg install -y + cmake ninja binutils pkgconf curl kf6-extra-cmake-modules ffmpeg qt6-base qt6-svg jansson libsysinfo e2fsprogs-libuuid pulseaudio alsa-lib pipewire v4l_compat libpci librist srt nlohmann-json uthash qr-code-generator websocketpp asio vlc swig luajit jackit sndio fdk-aac + libdatachannel script: - cmake -S $(pwd) @@ -23,7 +24,6 @@ task: -DENABLE_JACK:BOOL=ON -DENABLE_SNDIO:BOOL=ON -DENABLE_LIBFDK:BOOL=ON - -DENABLE_WEBRTC:BOOL=OFF - cmake --build build --config RelWithDebInfo diff --git a/.clang-format b/.clang-format index 38b431e173f125..73c5b0faaebf0d 100644 --- a/.clang-format +++ b/.clang-format @@ -44,7 +44,7 @@ BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeColon BreakStringLiterals: false # apparently unpredictable -ColumnLimit: 80 +ColumnLimit: 120 CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 8 @@ -81,6 +81,7 @@ PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: false +SkipMacroDefinitionBody: true SortIncludes: false SortUsingDeclarations: false SpaceAfterCStyleCast: false @@ -181,7 +182,7 @@ ReferenceAlignment: Right RemoveSemicolon: false RequiresClausePosition: WithPreceding RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Always +SeparateDefinitionBlocks: Leave ShortNamespaceLines: 1 SortIncludes: false #SortUsingDeclarations: LexicographicNumeric diff --git a/.cmake-format.json b/.cmake-format.json deleted file mode 100644 index 20610be23e52cc..00000000000000 --- a/.cmake-format.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "format": { - "line_width": 120, - "tab_size": 2, - "enable_sort": true, - "autosort": true - }, - "additional_commands": { - "find_qt": { - "flags": [], - "kwargs": { - "COMPONENTS": "+", - "COMPONENTS_WIN": "+", - "COMPONENTS_MACOS": "+", - "COMPONENTS_LINUX": "+" - } - }, - "set_target_properties_obs": { - "pargs": 1, - "flags": [], - "kwargs": { - "PROPERTIES": { - "kwargs": { - "PREFIX": 1, - "OUTPUT_NAME": 1, - "FOLDER": 1, - "VERSION": 1, - "SOVERSION": 1, - "FRAMEWORK": 1, - "BUNDLE": 1, - "AUTOMOC": 1, - "AUTOUIC": 1, - "AUTORCC": 1, - "AUTOUIC_SEARCH_PATHS": 1, - "BUILD_RPATH": 1, - "INSTALL_RPATH": 1, - "XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC": 1, - "XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION": 1, - "XCODE_ATTRIBUTE_GCC_WARN_SHADOW":1 , - "LIBRARY_OUTPUT_DIRECTORY": 1 - } - } - } - } - } -} diff --git a/.editorconfig b/.editorconfig index 91b004870397c9..5c9704f411edb1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -57,3 +57,7 @@ indent_size = 2 [*.ui] indent_style = space indent_size = 1 + +[{*.obt,*.oha,*.ovt}] +indent_style = space +indent_size = 4 diff --git a/.gersemirc b/.gersemirc new file mode 100644 index 00000000000000..59c4a78d2a7215 --- /dev/null +++ b/.gersemirc @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/master/gersemi/configuration.schema.json + +definitions: [] +line_length: 120 +indent: 2 +list_expansion: favour-inlining +unsafe: false +warn_about_unknown_commands: false diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 420715c58daf25..bf3a71f4372888 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -10,3 +10,5 @@ dcc07cfe4ed3f7fb60c7a0d1563236eac0a0b053 64139a6bbd6f85155c709035d82e91f52c2e36fe 7628265099724671a1682f6b298b509d2fa23855 f4733ec6a26bac21699daf3dfd6857ff5a1d3c07 +b8cfacaec38d31413b0cd82718c9dc1e36beb9af +a1fbf1015f4079b79dc9ef4f6abecf67920e93cf diff --git a/.github/actions/bouf/action.yaml b/.github/actions/bouf/action.yaml deleted file mode 100644 index 2183152c3e40e1..00000000000000 --- a/.github/actions/bouf/action.yaml +++ /dev/null @@ -1,133 +0,0 @@ -name: Run bouf -description: Generates signed OBS install files and updater files -inputs: - gcpWorkloadIdentityProvider: - description: GCP Identity Provider Pool ID - required: true - gcpServiceAccountName: - description: Google service account name - required: true - gcpManifestSigningKeyName: - description: Name of the manifest signing key in GCP KMS - required: false - version: - description: Version string (e.g., 30.0.0-rc1) - required: true - channel: - description: Update channel - required: false - default: 'stable' - -runs: - using: composite - steps: - - name: Extract Artifact - shell: pwsh - run: | - Expand-Archive -Path build\*.zip -DestinationPath build - Remove-Item build\*.zip - - - name: Setup bouf - shell: pwsh - env: - BOUF_TAG: 'v0.6.2' - BOUF_HASH: '40ca34457a8ac60b9710a41b4cde2a0fc36d8740ab21b01d702069be2e1c5fb9' - BOUF_NSIS_HASH: '88958a9e4e0f3cb6f78e8359fdfa3343d050d5c2158e3ee77cb2cc4a8785ac61' - GH_TOKEN: ${{ github.token }} - run: | - # Download bouf release - . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1 - . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1 - Ensure-Location bouf - $windows_zip = "bouf-windows-${env:BOUF_TAG}.zip" - $nsis_zip = "bouf-nsis-${env:BOUF_TAG}.zip" - Invoke-External gh release download "${env:BOUF_TAG}" -R "obsproject/bouf" -p $windows_zip -p $nsis_zip - - if ((Get-FileHash $windows_zip -Algorithm SHA256).Hash -ne "${env:BOUF_HASH}") { - throw "bouf hash does not match." - } - if ((Get-FileHash $nsis_zip -Algorithm SHA256).Hash -ne "${env:BOUF_NSIS_HASH}") { - throw "NSIS package hash does not match." - } - - Expand-Archive -Path $windows_zip -DestinationPath bin - Expand-Archive -Path $nsis_zip -DestinationPath nsis - - - name: Download Google CNG Provider - shell: pwsh - env: - CNG_TAG: 'cng-v1.0' - GH_TOKEN: ${{ github.token }} - run: | - # Download Google CNG provider release from github - . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1 - . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1 - Ensure-Location gcng - - Invoke-External gh release download "${env:CNG_TAG}" -R "GoogleCloudPlatform/kms-integrations" -p "*amd64.zip" - Expand-Archive -Path *.zip - $sigPath = Get-ChildItem *.sig -Recurse - $msiPath = Get-ChildItem *.msi -Recurse - # Verify digital signature against Google's public key - Invoke-External openssl dgst -sha384 -verify "${env:GITHUB_ACTION_PATH}/cng-release-signing-key.pem" -signature $sigPath $msiPath - # Finally, install the CNG provider - Invoke-External msiexec /i $msiPath /qn /norestart - - - name: Install pandoc and rclone - shell: pwsh - run: | - choco install rclone --version=1.64.2 -y --no-progress - choco install pandoc --version=3.1.9 -y --no-progress - - - name: Prepare Release Notes - shell: pwsh - run: | - # Release notes are just the tag body on Windows - Set-Location repo - git tag -l --format='%(contents:body)' ${{ inputs.version }} > "${{ github.workspace }}/notes.rst" - - - name: 'Authenticate to Google Cloud' - uses: 'google-github-actions/auth@5a50e581162a13f4baa8916d01180d2acbc04363' - with: - workload_identity_provider: ${{ inputs.gcpWorkloadIdentityProvider }} - service_account: ${{ inputs.gcpServiceAccountName }} - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@98ddc00a17442e89a24bbf282954a3b65ce6d200' - - - name: Download Old Builds - shell: pwsh - env: - RCLONE_GCS_ENV_AUTH: 'true' - run: | - rclone copy --transfers 100 :gcs:obs-builds "${{ github.workspace }}/old_builds" - - - name: Run bouf - shell: pwsh - run: | - . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1 - $boufArgs = @( - "--config", "${env:GITHUB_ACTION_PATH}/config.toml", - "--version", "${{ inputs.version }}" - "--branch", "${{ inputs.channel }}" - "--notes-file", "${{ github.workspace }}/notes.rst" - "-i", "${{ github.workspace }}/build" - "-p", "${{ github.workspace }}/old_builds" - "-o", "${{ github.workspace }}/output" - ) - Invoke-External "${{ github.workspace }}\bouf\bin\bouf.exe" @boufArgs - - - name: Sign Updater Manifest - shell: pwsh - if: inputs.gcpManifestSigningKeyName != '' - run: | - $gcloudArgs = @( - "--input-file", "${{ github.workspace }}/output/manifest.json" - "--signature-file", "${{ github.workspace }}/output/manifest.json.sig" - "--digest-algorithm", "sha512" - "--location", "global" - "--keyring", "production" - "--key", "${{ inputs.gcpManifestSigningKeyName }}" - "--version", "1" - ) - gcloud kms asymmetric-sign @gcloudArgs diff --git a/.github/actions/bouf/config.toml b/.github/actions/bouf/config.toml deleted file mode 100644 index 80da49a9951460..00000000000000 --- a/.github/actions/bouf/config.toml +++ /dev/null @@ -1,56 +0,0 @@ -[general] -log_level = "trace" - -[env] -# On CI these should be in %PATH% -sevenzip_path = "7z" -makensis_path = "makensis" -pandoc_path = "pandoc" -pdbcopy_path = "C:/Program Files (x86)/Windows Kits/10/Debuggers/x64/pdbcopy.exe" - -## Preparation steps -[prepare] - -[prepare.copy] -never_copy = [ - "bin/32bit", - "obs-plugins/32bit", - ".keepme", -] - -[prepare.codesign] -sign_cert_file = "repo/.github/actions/bouf/prod.crt" -sign_kms_key_id = "projects/ci-signing/locations/global/keyRings/production/cryptoKeys/release-sign-hsm/cryptoKeyVersions/1" -sign_digest = "sha384" -sign_ts_serv = "http://timestamp.digicert.com" -sign_exts = ['exe', 'dll', 'pyd'] - -[prepare.strip_pdbs] -# PDBs to not strip -exclude = [ - "obs-frontend-api.pdb", - "obs64.pdb", - "obs.pdb", -] - -## Delta patch generation -[generate] -patch_type = "zstd" -compress_files = true - -exclude_from_parallel = [ - "libcef.dll" -] - -[package] -[package.installer] -nsis_script = "bouf/nsis/mp-installer.nsi" - -[package.zip] -skip = true -name = "OBS-Studio-{version}.zip" -pdb_name = "OBS-Studio-{version}-pdbs.zip" - -[package.updater] -vc_redist_path = "bouf/nsis/VC_redist.x64.exe" -skip_sign = true diff --git a/.github/actions/check-changes/action.yaml b/.github/actions/check-changes/action.yaml index 50d1679056745e..e5690b8a78efa8 100644 --- a/.github/actions/check-changes/action.yaml +++ b/.github/actions/check-changes/action.yaml @@ -45,6 +45,11 @@ runs: shopt -s extglob shopt -s dotglob + # 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is a "hidden" sha1 hash of + # the "empty tree", retrived via 'git hash-object -t tree /dev/null', + # and used here as a last-resort fallback to always provide a valid + # git ref. + if [[ "${GIT_BASE_REF}" ]]; then if ! git cat-file -e "${GIT_BASE_REF}" &> /dev/null; then echo "::warning::Provided base reference ${GIT_BASE_REF} is invalid" diff --git a/.github/actions/compatibility-validator/action.yaml b/.github/actions/compatibility-validator/action.yaml index a133e70a1f592a..da0bd62ef715bc 100644 --- a/.github/actions/compatibility-validator/action.yaml +++ b/.github/actions/compatibility-validator/action.yaml @@ -55,7 +55,7 @@ runs: echo ::endgroup:: - name: Annotate Schema Validation Errors 🏷️ - uses: yuzutech/annotations-action@v0.4.0 + uses: yuzutech/annotations-action@0e061a6e3ac848299310b6429b60d67cafd4e7f8 if: failure() with: repo-token: ${{ inputs.repositorySecret }} diff --git a/.github/actions/flatpak-builder-lint/action.yaml b/.github/actions/flatpak-builder-lint/action.yaml index 2defa012435f8a..a6fd54f496eb89 100644 --- a/.github/actions/flatpak-builder-lint/action.yaml +++ b/.github/actions/flatpak-builder-lint/action.yaml @@ -19,16 +19,10 @@ runs: working-directory: ${{ inputs.workingDirectory }} run: | : Check artifact input - case "${{ inputs.artifact }}" in - builddir);; - repo);; - manifest);; - appstream);; - *) - echo "::error::Given artifact type is incorrect" - exit 2 - ;; - esac + if ! [[ "${{ inputs.artifact }}" =~ builddir|repo|manifest|appstream ]]; then + echo "::error::Given artifact type is incorrect" + exit 2 + fi - name: Run flatpak-builder-lint id: result @@ -36,30 +30,46 @@ runs: working-directory: ${{ inputs.workingDirectory }} run: | : Run flatpak-builder-lint - exit_code=0 - ret=$(flatpak-builder-lint --exceptions ${{ inputs.artifact }} ${{ inputs.path }}) || exit_code=$? - if [[ $exit_code != 0 && -z "$ret" ]]; then + + return=0 + result="$(flatpak-builder-lint --exceptions ${{ inputs.artifact }} ${{ inputs.path }})" || return=$? + + if [[ ${return} != 0 && -z "${result}" ]]; then echo "::error::Error while running flatpak-builder-lint" exit 2 fi - if [[ ${{ inputs.artifact }} == "appstream" ]]; then - echo $ret + if [[ "${{ inputs.artifact }}" == "appstream" ]]; then + echo "${result}" - [[ $exit_code != 0 ]] && echo "::error::Flatpak appstream info is not valid" + if [[ ${return} != 0 ]]; then echo "::error::Flatpak appstream info is not valid"; fi - exit $exit_code + exit ${return} fi - for ((i = 0 ; i < $(echo $ret | jq '.warnings | length') ; i++)); do - warning=$(echo $ret | jq ".warnings[$i]") - echo "::warning::$warning found in the Flatpak ${{ inputs.artifact }}" - done + # This jq command selects any available array under the 'warnings' key in the JSON document + # or provides an empty array as a fallback if the key is not present. This array is then + # piped to the 'map' function to apply a transformation to every element in the array, + # converting it to a string prefixed with the output level, the actual element value, and + # finally the suffix string defined in 'template'. + # + # The result of this expression is concatenated with a similar expression doing the same + # but for the 'errors' key and its associated array. + # + # The second jq invocation then selects each element of the array and outputs it directly, + # which will be strings of the formats: + # + # * '::warning::