obs-studio/.github/workflows/main.yml
PatTheMav dc39edb23c CI: Prevent build artifact creation for macOS without pushed tag
Pushes to master will use faster Ninja builds on macOS, which cannot
generate macOS app bundles anymore. Thus packaging will only work with
PR pushes (and the "Seeking Testers" label set) or upon pushing a
release tag to the master branch.
2023-03-26 20:22:33 -04:00

589 lines
21 KiB
YAML

name: 'BUILD'
on:
push:
paths-ignore: ['**.md']
branches:
- master
- 'release/**'
tags: ['*']
pull_request:
paths-ignore: ['**.md']
branches: [master]
env:
CACHE_REVISION: '006'
CEF_BUILD_VERSION_LINUX: '5060'
CEF_BUILD_VERSION_WIN: '5060'
QT_VERSION_MAC: '6.4.3'
QT_VERSION_WIN: '6.4.3'
DEPS_VERSION_WIN: '2023-03-20'
VLC_VERSION_WIN: '3.0.0-git'
TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }}
TWITCH_HASH: ${{ secrets.TWITCH_HASH }}
RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }}
RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }}
YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }}
YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }}
YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }}
YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }}
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
clang_check:
name: '01 - Code Format Check'
runs-on: [ubuntu-22.04]
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: 'Install clang-format'
run: sudo apt-get install -y clang-format-13
- name: 'Run clang-format'
run: |
./CI/check-format.sh
./CI/check-changes.sh
- name: 'Install cmake-format'
run: sudo pip install cmakelang
- name: 'Run cmake-format'
run: |
./CI/check-cmake.sh
config:
name: '01 - Configure Build Jobs'
runs-on: [ubuntu-22.04]
outputs:
create_artifacts: ${{ steps.config.outputs.create_artifacts }}
cache_date: ${{ steps.config.outputs.cache_date }}
steps:
- name: 'Configure Build Jobs'
id: config
run: |
if [[ "${{ github.event_name == 'pull_request' }}" == "true" ]]; then
echo "create_artifacts=${{ contains(github.event.pull_request.labels.*.name, 'Seeking Testers') }}" >> $GITHUB_OUTPUT
else
echo 'create_artifacts=true' >> $GITHUB_OUTPUT
fi
echo "cache_date=$(date +"%Y-%m-%d")" >> $GITHUB_OUTPUT
macos_build:
name: '02 - macOS'
runs-on: [macos-12]
strategy:
matrix:
arch: ['x86_64', 'arm64']
if: always()
needs: [config, clang_check]
env:
BLOCKED_FORMULAS: 'speexdsp curl php composer'
CODESIGN_IDENT: '-'
HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }}
defaults:
run:
shell: bash
working-directory: 'obs-studio'
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
submodules: 'recursive'
path: 'obs-studio'
fetch-depth: 0
- name: 'Check for GitHub Labels'
id: github-check
if: github.event_name == 'pull_request'
run: |
if [[ '${{ contains(github.event.pull_request.labels.*.name, 'Seeking Testers') }}' == 'true' ]]; then
echo "generator=Xcode" >> $GITHUB_OUTPUT
else
echo "generator=Ninja" >> $GITHUB_OUTPUT
fi
- name: 'Restore ccache from cache'
id: ccache-cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.ccache
key: ${{ runner.os }}-${{ github.ref_name }}-${{ steps.github-check.outputs.generator }}-ccache-${{ matrix.arch }}-${{ needs.config.outputs.cache_date }}
- name: 'Setup build environment'
id: setup
run: |
REMOVE_FORMULAS=""
for FORMULA in ${{ env.BLOCKED_FORMULAS }}; do
if [ -d "/usr/local/opt/${FORMULA}" ]; then
REMOVE_FORMULAS="${REMOVE_FORMULAS}${FORMULA} "
fi
done
if [ -n "${REMOVE_FORMULAS}" ]; then
brew uninstall ${REMOVE_FORMULAS}
fi
echo "commitHash=$(git rev-parse --short=9 HEAD)" >> $GITHUB_OUTPUT
- name: 'Install dependencies'
run: CI/macos/01_install_dependencies.sh --architecture "${{ matrix.arch }}"
- name: 'Install Apple Developer Certificate'
if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' }}
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
with:
p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
- name: 'Set Signing Identity'
if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' }}
run: |
echo "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_IDENTITY }}" >> $GITHUB_ENV
echo "BUILD_FOR_DISTRIBUTION=ON" >> $GITHUB_ENV
- name: 'Build OBS'
run: |
if [[ '${{ steps.github-check.outputs.generator }}' == 'Xcode' ]]; then
SEEKING_TESTERS=1 CI/macos/02_build_obs.sh --codesign --architecture "${{ matrix.arch }}"
else
CI/macos/02_build_obs.sh --codesign --architecture "${{ matrix.arch }}"
fi
- name: 'Create build artifact'
if: ${{ fromJSON(needs.config.outputs.create_artifacts) }}
run: |
: ${PACKAGE:=}
case "${GITHUB_EVENT_NAME}" in
push) if [[ ${GITHUB_REF_NAME} =~ [0-9]+.[0-9]+.[0-9]+(-(rc|beta).+)? ]]; then PACKAGE=1; fi ;;
pull_request) PACKAGE=1 ;;
esac
if [[ "${PACKAGE}" ]]; then
CI/macos/03_package_obs.sh --codesign --architecture "${{ matrix.arch }}"
ARTIFACT_NAME=$(basename $(/usr/bin/find build_${{ matrix.arch }} -type f -name "obs-studio-*.dmg" -depth 1 | head -1))
echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
fi
- name: 'Upload build Artifact'
if: ${{ fromJSON(needs.config.outputs.create_artifacts) && env.FILE_NAME != '' }}
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}'
path: '${{ github.workspace }}/obs-studio/build_${{ matrix.arch }}/${{ env.FILE_NAME }}'
linux_build:
name: '02 - Linux'
runs-on: ${{ matrix.ubuntu }}
strategy:
matrix:
ubuntu: ['ubuntu-20.04', 'ubuntu-22.04']
include:
- ubuntu: 'ubuntu-20.04'
script_options: '--disable-pipewire'
if: always()
needs: [config, clang_check]
defaults:
run:
shell: bash
working-directory: 'obs-studio'
env:
BUILD_FOR_DISTRIBUTION: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
submodules: 'recursive'
path: 'obs-studio'
fetch-depth: 0
- name: 'Restore ccache from cache'
id: ccache-cache
uses: actions/cache@v3
env:
CACHE_NAME: 'ccache-cache'
with:
path: ${{ github.workspace }}/.ccache
key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.ubuntu }}-${{ needs.config.outputs.cache_date }}
- name: 'Restore Chromium Embedded Framework from cache'
id: cef-cache
uses: actions/cache@v3
env:
CACHE_NAME: 'cef-cache'
with:
path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_LINUX }}_linux64
key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_LINUX }}-${{ env.CACHE_REVISION }}
- name: 'Setup build environment'
id: setup
run: |
echo "commitHash=$(git rev-parse --short=9 HEAD)" >> $GITHUB_OUTPUT
- name: 'Install dependencies'
env:
RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }}
run: CI/linux/01_install_dependencies.sh ${{ matrix.script_options }}
- name: 'Build OBS'
run: CI/linux/02_build_obs.sh ${{ matrix.script_options }}
- name: 'Run tests'
if: success()
run: cmake --build build -t test
- name: 'Create build artifact'
if: ${{ success() && fromJSON(needs.config.outputs.create_artifacts) }}
run: |
CI/linux/03_package_obs.sh
ARTIFACT_NAME=$(basename $(/usr/bin/find build -maxdepth 1 -type f -name "obs-studio-*.deb" | sort -rn | head -1))
echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
echo "DEBUG_FILE_NAME=${ARTIFACT_NAME//.deb/-dbgsym.ddeb}" >> $GITHUB_ENV
- name: 'Upload build Artifact'
if: ${{ success() && fromJSON(needs.config.outputs.create_artifacts) }}
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-${{ matrix.ubuntu }}-${{ steps.setup.outputs.commitHash }}'
path: '${{ github.workspace }}/obs-studio/build/${{ env.FILE_NAME }}'
- name: 'Upload debug symbol Artifact'
if: ${{ success() && fromJSON(needs.config.outputs.create_artifacts) }}
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-${{ matrix.ubuntu }}-${{ steps.setup.outputs.commitHash }}-dbgsym'
path: '${{ github.workspace }}/obs-studio/build/${{ env.DEBUG_FILE_NAME }}'
windows_build:
name: '02 - Windows'
runs-on: [windows-2022]
needs: [config, clang_check]
if: always()
strategy:
matrix:
arch: [x64, x86]
env:
CMAKE_GENERATOR: 'Visual Studio 17 2022'
CMAKE_SYSTEM_VERSION: '10.0.18363.657'
VIRTUALCAM-GUID: 'A3FCE0F5-3493-419F-958A-ABA1250EC20B'
BUILD_FOR_DISTRIBUTION: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
defaults:
run:
working-directory: 'obs-studio'
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
submodules: 'recursive'
path: 'obs-studio'
fetch-depth: 0
- name: 'Add msbuild to PATH'
uses: microsoft/setup-msbuild@v1.1
- name: 'Restore VLC dependency from cache'
id: vlc-cache
uses: actions/cache@v3
env:
CACHE_NAME: 'vlc-cache'
with:
path: ${{ github.workspace }}/obs-build-dependencies/vlc-${{ env.VLC_VERSION_WIN }}
key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION_WIN }}-${{ env.CACHE_REVISION }}
- name: 'Restore Chromium Embedded Framework from cache'
id: cef-cache
uses: actions/cache@v3
env:
CACHE_NAME: 'cef-cache'
with:
path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_WIN }}_windows_${{ matrix.arch }}
key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_WIN }}-${{ matrix.arch }}-${{ env.CACHE_REVISION }}
- name: Setup Environment
id: setup
run: |
$CommitHash = git rev-parse --short=9 HEAD
"commitHash=${CommitHash}" >> $env:GITHUB_OUTPUT
- name: 'Install dependencies'
env:
RESTORED_VLC: ${{ steps.vlc-cache.outputs.cache-hit }}
RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }}
run: CI/windows/01_install_dependencies.ps1 -BuildArch ${{ matrix.arch }}
- name: 'Build OBS'
run: CI/windows/02_build_obs.ps1 -BuildArch ${{ matrix.arch }}
- name: 'Create build artifact'
if: ${{ success() && fromJSON(needs.config.outputs.create_artifacts) }}
run: |
CI/windows/03_package_obs.ps1 -BuildArch ${{ matrix.arch }} -Package
$ArtifactName = Get-ChildItem -filter "obs-studio-*-windows-${{ matrix.arch }}.zip" -File
Write-Output "FILE_NAME=${ArtifactName}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
- name: 'Upload build artifact'
if: ${{ success() && fromJSON(needs.config.outputs.create_artifacts) }}
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-windows-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}'
path: '${{ env.FILE_NAME }}'
linux_package:
name: '02 - Flatpak'
runs-on: [ubuntu-latest]
needs: [config, clang_check]
defaults:
run:
shell: bash
container:
image: bilelmoussaoui/flatpak-github-actions:kde-6.4
options: --privileged
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
submodules: 'recursive'
fetch-depth: 0
- name: 'Setup build environment'
run: |
git config --global --add safe.directory $GITHUB_WORKSPACE
echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV
echo "OBS_GIT_HASH=$(git rev-parse --short=9 HEAD)" >> $GITHUB_ENV
echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build Flatpak Manifest
uses: flatpak/flatpak-github-actions/flatpak-builder@v5
with:
build-bundle: ${{ fromJSON(needs.config.outputs.create_artifacts) }}
bundle: obs-studio-flatpak-${{ env.OBS_GIT_HASH }}.flatpak
manifest-path: CI/flatpak/com.obsproject.Studio.json
cache-key: flatpak-builder-${{ hashFiles('CI/flatpak/com.obsproject.Studio.json') }}
windows_package:
name: '03 - Windows Installer'
runs-on: [windows-latest]
needs: [windows_build]
if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
env:
BUILD_FOR_DISTRIBUTION: 'ON'
steps:
- name: 'Checkout'
uses: actions/checkout@v3
- name: Setup Environment
id: setup
run: |
$CommitHash = git rev-parse --short=9 HEAD
"commitHash=${CommitHash}" >> $env:GITHUB_OUTPUT
- name: 'Add msbuild to PATH'
uses: microsoft/setup-msbuild@v1.1
- name: 'Download 64-bit artifact'
uses: actions/download-artifact@v3
with:
name: 'obs-studio-windows-x64-${{ steps.setup.outputs.commitHash }}'
- name: 'Download 32-bit artifact'
uses: actions/download-artifact@v3
with:
name: 'obs-studio-windows-x86-${{ steps.setup.outputs.commitHash }}'
- name: 'Unpack Windows build artifacts'
id: unpack
run: |
if (!(Test-Path install_temp)) {
$null = New-Item -ItemType Directory -Force -Path install_temp
}
Expand-Archive -Path "$(Get-ChildItem -filter "obs-studio-*-windows-x86.zip" -File)" -DestinationPath install_temp
Expand-Archive -Path "$(Get-ChildItem -filter "obs-studio-*-windows-x64.zip" -File)" -Force -DestinationPath install_temp
CI/windows/03_package_obs.ps1 -CombinedArchs -Package
$ArtifactName = (Get-ChildItem -filter "obs-studio-*-windows-x86+x64.zip" -File).Name
"filename=${ArtifactName}" >> $env:GITHUB_OUTPUT
- name: 'Upload build artifact'
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-windows-installer'
path: '${{ steps.unpack.outputs.filename }}'
macos_release:
name: '03 - macOS notarized image'
runs-on: [macos-12]
needs: [macos_build]
env:
HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }}
BUILD_FOR_DISTRIBUTION: 'ON'
HAVE_SPARKLE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY != '' }}
outputs:
run_sparkle: ${{ steps.sparkle_check.outputs.run_sparkle }}
if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
strategy:
matrix:
arch: ['x86_64', 'arm64']
defaults:
run:
shell: bash
steps:
- name: 'Checkout'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
uses: actions/checkout@v3
- name: 'Setup build environment'
id: setup
run: |
echo "commitHash=$(git rev-parse --short=9 HEAD)" >> $GITHUB_OUTPUT
- name: 'Determine if Sparkle should run'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
id: sparkle_check
run: |
echo 'run_sparkle=${{ env.HAVE_SPARKLE_KEY }}' >> $GITHUB_OUTPUT
- name: 'Download artifact'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
uses: actions/download-artifact@v3
with:
name: 'obs-studio-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}'
- name: 'Install Apple Developer Certificate'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
with:
p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
- name: 'Create disk image for distribution'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
env:
CODESIGN_IDENT: ${{ secrets.MACOS_SIGNING_IDENTITY }}
CODESIGN_IDENT_USER: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
CODESIGN_IDENT_PASS: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
run: |
ARTIFACT_NAME=$(/usr/bin/find . -type f -name "obs-studio-*.dmg" -depth 1 | head -1)
CI/macos/03_package_obs.sh --notarize-image ${ARTIFACT_NAME}
echo "FILE_NAME=$(basename ${ARTIFACT_NAME})" >> $GITHUB_ENV
- name: 'Upload build Artifact'
if: env.HAVE_CODESIGN_IDENTITY == 'true'
uses: actions/upload-artifact@v3
with:
name: 'obs-studio-macos-${{ matrix.arch }}-notarized'
path: '${{ github.workspace }}/${{ env.FILE_NAME }}'
macos_sparkle:
name: '04 - macOS Sparkle Updates'
runs-on: [macos-12]
needs: [macos_release]
if: fromJSON(needs.macos_release.outputs.run_sparkle)
strategy:
matrix:
arch: ['x86_64', 'arm64']
env:
SPARKLE_VERSION: '2.3.2'
SPARKLE_HASH: '2b3fe6918ca20a83729aad34f8f693a678b714a17d33b5f13ca2d25edfa7eed3'
defaults:
run:
shell: bash
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
path: 'repo'
ref: ${{ github.ref }}
- name: 'Download artifact'
uses: actions/download-artifact@v3
with:
name: 'obs-studio-macos-${{ matrix.arch }}-notarized'
path: 'artifacts'
- name: 'Install Python requirements'
run: pip3 install requests xmltodict
- name: 'Install Brew requirements'
run: brew install coreutils pandoc
- name: 'Setup Sparkle'
run: |
curl -L "https://github.com/sparkle-project/Sparkle/releases/download/${{ env.SPARKLE_VERSION }}/Sparkle-${{ env.SPARKLE_VERSION }}.tar.xz" -o Sparkle.tar.xz
if [[ '${{ env.SPARKLE_HASH }}' != "$(sha256sum Sparkle.tar.xz | cut -d " " -f 1)" ]]; then
echo "Sparkle download hash does not match!"
exit 1
fi
mkdir sparkle && cd sparkle
tar -xf ../Sparkle.tar.xz
- name: 'Setup folder structure'
run: |
mkdir builds
mkdir -p output/appcasts/stable
mkdir -p output/sparkle_deltas/${{ matrix.arch }}
- name: 'Determine branch and tag'
id: branch
run: |
pushd repo
GIT_TAG="$(git describe --tags --abbrev=0)"
if [[ ${GIT_TAG} == *'beta'* || ${GIT_TAG} == *'rc'* ]]; then
echo "branch=beta" >> $GITHUB_OUTPUT
echo "deltas=0" >> $GITHUB_OUTPUT
else
echo "branch=stable" >> $GITHUB_OUTPUT
echo "deltas=1" >> $GITHUB_OUTPUT
fi
# Write tag description to file
git tag -l --format='%(contents)' ${GIT_TAG} >> ../notes.rst
- name: 'Download existing Appcast and builds'
run: python3 repo/CI/macos/appcast_download.py --branch "${{ steps.branch.outputs.branch }}" --max-old-versions ${{ steps.branch.outputs.deltas }}
- name: 'Prepare release notes'
run: |
# Insert underline at line 2 to turn first line into heading
sed -i '' '2i\'$'\n''###################################################' notes.rst
pandoc -f rst -t html notes.rst -o output/appcasts/notes_${{ steps.branch.outputs.branch }}.html
- name: 'Setup Sparkle key'
run: echo -n "${{ secrets.SPARKLE_PRIVATE_KEY }}" >> eddsa_private.key
- name: 'Generate Appcast'
run: |
mv artifacts/*.dmg builds/
./sparkle/bin/generate_appcast \
--verbose \
--ed-key-file ./eddsa_private.key \
--download-url-prefix "https://cdn-fastly.obsproject.com/downloads/" \
--full-release-notes-url "https://obsproject.com/osx_update/notes_${{ steps.branch.outputs.branch }}.html" \
--maximum-versions 0 \
--maximum-deltas ${{ steps.branch.outputs.deltas }} \
--channel "${{ steps.branch.outputs.branch }}" builds/
# Move deltas, if any
if compgen -G "builds/*.delta" > /dev/null; then
mv builds/*.delta output/sparkle_deltas/${{ matrix.arch }}
fi
# Move appcasts
mv builds/*.xml output/appcasts/
- name: 'Create 1.x Appcast'
run: python3 repo/CI/macos/appcast_convert.py
- name: 'Upload Appcast and Deltas'
uses: actions/upload-artifact@v3
with:
name: 'macos-sparkle-updates'
path: '${{ github.workspace }}/output'