Merge pull request #18453 from gustavotrott/merge-27-into-develop-4ago2023
Merge 2.7 into Develop
This commit is contained in:
commit
dc75850f1a
408
.github/workflows/automated-tests.yml
vendored
408
.github/workflows/automated-tests.yml
vendored
@ -16,26 +16,99 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
build-install-and-test:
|
||||
build-bbb-apps-akka:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_AKKA_APPS_KEY=$(git log -1 --format=%H -- akka-bbb-apps)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_COMMON_MSG_KEY=$(git log -1 --format=%H -- bbb-common-message)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-apps-akka-${{ env.CACHE_AKKA_APPS_KEY }}-${{ env.CACHE_COMMON_MSG_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-apps-akka
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-apps-akka.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-config:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-config
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-config.tar
|
||||
path: artifacts.tar
|
||||
build-bbb-export-annotations:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-export-annotations
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-export-annotations.tar
|
||||
path: artifacts.tar
|
||||
build-bbb-learning-dashboard:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_LEARNING_DASHBOARD_KEY=$(git log -1 --format=%H -- bbb-learning-dashboard)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-learning-dashboard-${{ env.CACHE_LEARNING_DASHBOARD_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-learning-dashboard
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-learning-dashboard.tar
|
||||
path: artifacts.tar
|
||||
build-bbb-playback-record:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: ./build/get_external_dependencies.sh
|
||||
- run: ./build/setup.sh bbb-apps-akka
|
||||
- run: ./build/setup.sh bbb-config
|
||||
- run: ./build/setup.sh bbb-etherpad
|
||||
- run: ./build/setup.sh bbb-export-annotations
|
||||
- run: ./build/setup.sh bbb-freeswitch-core
|
||||
- run: ./build/setup.sh bbb-freeswitch-sounds
|
||||
- run: ./build/setup.sh bbb-fsesl-akka
|
||||
- run: ./build/setup.sh bbb-graphql-middleware
|
||||
- run: ./build/setup.sh bbb-graphql-server
|
||||
- run: ./build/setup.sh bbb-html5-nodejs
|
||||
- run: ./build/setup.sh bbb-html5
|
||||
- run: ./build/setup.sh bbb-learning-dashboard
|
||||
- run: ./build/setup.sh bbb-libreoffice-docker
|
||||
- run: ./build/setup.sh bbb-mkclean
|
||||
- run: ./build/setup.sh bbb-pads
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: ./build/setup.sh bbb-playback
|
||||
- run: ./build/setup.sh bbb-playback-notes
|
||||
- run: ./build/setup.sh bbb-playback-podcast
|
||||
@ -43,7 +116,191 @@ jobs:
|
||||
- run: ./build/setup.sh bbb-playback-screenshare
|
||||
- run: ./build/setup.sh bbb-playback-video
|
||||
- run: ./build/setup.sh bbb-record-core
|
||||
- run: ./build/setup.sh bbb-web
|
||||
- run: tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-playback-record.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-graphql-server:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: ./build/get_external_dependencies.sh
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: ./build/setup.sh bbb-graphql-middleware
|
||||
- run: ./build/setup.sh bbb-graphql-server
|
||||
- run: tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-graphql-server.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-etherpad:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_ETHERPAD_VERSION_KEY=$(git log -1 --format=%H -- bbb-etherpad.placeholder.sh)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_ETHERPAD_BUILD_KEY=$(git log -1 --format=%H -- build/packages-template/bbb-etherpad)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_URL1_KEY=$(curl -s https://api.github.com/repos/mconf/ep_pad_ttl/commits | md5sum | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_URL2_KEY=$(curl -s https://api.github.com/repos/alangecker/bbb-etherpad-plugin/commits | md5sum | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_URL3_KEY=$(curl -s https://api.github.com/repos/mconf/ep_redis_publisher/commits | md5sum | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_URL4_KEY=$(curl -s https://api.github.com/repos/alangecker/bbb-etherpad-skin/commits | md5sum | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-etherpad-${{ env.CACHE_ETHERPAD_VERSION_KEY }}-${{ env.CACHE_ETHERPAD_BUILD_KEY }}-${{ env.CACHE_URL1_KEY }}-${{ env.CACHE_URL2_KEY }}-${{ env.CACHE_URL3_KEY }}-${{ env.CACHE_URL4_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-etherpad
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-etherpad.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-bbb-web:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_BBB_WEB_KEY=$(git log -1 --format=%H -- bigbluebutton-web)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_COMMON_MSG_KEY=$(git log -1 --format=%H -- bbb-common-message)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_COMMON_WEB_KEY=$(git log -1 --format=%H -- bbb-common-web)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-web-${{ env.CACHE_BBB_WEB_KEY }}-${{ env.CACHE_COMMON_MSG_KEY }}-${{ env.CACHE_COMMON_WEB_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-web
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-web.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-fsesl-akka:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_AKKA_FSESL_KEY=$(git log -1 --format=%H -- akka-bbb-fsesl)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_COMMON_MSG_KEY=$(git log -1 --format=%H -- bbb-common-message)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-fsesl-akka-${{ env.CACHE_AKKA_FSESL_KEY }}-${{ env.CACHE_COMMON_MSG_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-fsesl-akka
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-fsesl-akka.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-html5:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_KEY=$(git log -1 --format=%H -- bigbluebutton-html5)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-html5-${{ env.CACHE_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-html5-nodejs
|
||||
./build/setup.sh bbb-html5
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-html5.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-bbb-freeswitch:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history
|
||||
- run: echo "CACHE_FREESWITCH_KEY=$(git log -1 --format=%H -- build/packages-template/bbb-freeswitch-core)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_FREESWITCH_SOUNDS_KEY=$(git log -1 --format=%H -- build/packages-template/bbb-freeswitch-sounds)" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_SOUNDS_KEY=$(curl -Is http://bigbluebutton.org/downloads/sounds.tar.gz | grep "Last-Modified" | md5sum | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- run: echo "CACHE_BBB_RELEASE_KEY=$(git log -1 --format=%H -- bigbluebutton-config/bigbluebutton-release)" >> $GITHUB_ENV
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- name: Handle cache
|
||||
id: cache-action
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: artifacts.tar
|
||||
key: ${{ runner.os }}-bbb-freeswitch-${{ env.CACHE_FREESWITCH_KEY }}-${{ env.CACHE_FREESWITCH_SOUNDS_KEY }}-${{ env.CACHE_SOUNDS_KEY }}-${{ env.CACHE_BBB_RELEASE_KEY }}
|
||||
- if: ${{ steps.cache-action.outputs.cache-hit != 'true' }}
|
||||
name: Generate artifacts
|
||||
run: |
|
||||
./build/get_external_dependencies.sh
|
||||
./build/setup.sh bbb-freeswitch-core
|
||||
./build/setup.sh bbb-freeswitch-sounds
|
||||
tar cvf artifacts.tar artifacts/
|
||||
- name: Archive packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-freeswitch.tar
|
||||
path: |
|
||||
artifacts.tar
|
||||
build-others:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: ./build/get_external_dependencies.sh
|
||||
- run: echo "FORCE_GIT_REV=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: echo "FORCE_COMMIT_DATE=0" >> $GITHUB_ENV #used by setup.sh
|
||||
- run: ./build/setup.sh bbb-mkclean
|
||||
- run: ./build/setup.sh bbb-pads
|
||||
- run: ./build/setup.sh bbb-libreoffice-docker
|
||||
- run: ./build/setup.sh bbb-webrtc-sfu
|
||||
- run: ./build/setup.sh bbb-webrtc-recorder
|
||||
- run: ./build/setup.sh bbb-transcription-controller
|
||||
@ -57,37 +314,114 @@ jobs:
|
||||
artifacts.tar
|
||||
# - name: Fake package build
|
||||
# run: |
|
||||
# sudo sh -c '
|
||||
# sudo -i <<EOF
|
||||
# set -e
|
||||
# echo "Faking a package build (to speed up installation test)"
|
||||
# cd /
|
||||
# wget -q "http://ci.bbb.imdt.dev/artifacts.tar"
|
||||
# wget -nv "http://ci.bbb.imdt.dev/artifacts.tar"
|
||||
# tar xf artifacts.tar
|
||||
# '
|
||||
# mv artifacts /home/runner/work/bigbluebutton/bigbluebutton/artifacts/
|
||||
# EOF
|
||||
install-and-run-tests:
|
||||
needs: [build-bbb-apps-akka, build-bbb-config, build-bbb-export-annotations, build-bbb-learning-dashboard, build-bbb-playback-record, build-bbb-graphql-server, build-bbb-etherpad, build-bbb-bbb-web, build-bbb-fsesl-akka, build-bbb-html5, build-bbb-freeswitch, build-others]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: ./build/get_external_dependencies.sh
|
||||
- name: Download artifacts_bbb-apps-akka
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-apps-akka.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-config
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-config.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-export-annotations
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-export-annotations.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-learning-dashboard
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-learning-dashboard.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-playback-record
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-playback-record.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-graphql-server
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-graphql-server.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-etherpad
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-etherpad.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-freeswitch
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-freeswitch.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-web
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-web.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-fsesl-akka
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-fsesl-akka.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts_bbb-html5
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts_bbb-html5.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts.tar
|
||||
- run: tar xf artifacts.tar
|
||||
- name: Extracting files .tar
|
||||
run: |
|
||||
set -e
|
||||
pwd
|
||||
echo "----ls artifacts/----"
|
||||
ls artifacts/
|
||||
echo "Done"
|
||||
- name: Generate CA
|
||||
run: |
|
||||
sudo sh -c '
|
||||
sudo -i <<EOF
|
||||
set -e
|
||||
mkdir /root/bbb-ci-ssl/
|
||||
cd /root/bbb-ci-ssl/
|
||||
openssl rand -base64 48 > /root/bbb-ci-ssl/bbb-dev-ca.pass ;
|
||||
chmod 600 /root/bbb-ci-ssl/bbb-dev-ca.pass ;
|
||||
openssl genrsa -des3 -out bbb-dev-ca.key -passout file:/root/bbb-ci-ssl/bbb-dev-ca.pass 2048 ;
|
||||
openssl req -x509 -new -nodes -key bbb-dev-ca.key -sha256 -days 1460 -passin file:/root/bbb-ci-ssl/bbb-dev-ca.pass -out bbb-dev-ca.crt -subj "/C=CA/ST=BBB/L=BBB/O=BBB/OU=BBB/CN=BBB-DEV" ;
|
||||
'
|
||||
EOF
|
||||
- name: Trust CA
|
||||
run: |
|
||||
sudo sh -c '
|
||||
sudo -i <<EOF
|
||||
set -e
|
||||
sudo mkdir /usr/local/share/ca-certificates/bbb-dev/
|
||||
sudo cp /root/bbb-ci-ssl/bbb-dev-ca.crt /usr/local/share/ca-certificates/bbb-dev/
|
||||
sudo chmod 644 /usr/local/share/ca-certificates/bbb-dev/bbb-dev-ca.crt
|
||||
sudo update-ca-certificates
|
||||
'
|
||||
EOF
|
||||
- name: Generate certificate
|
||||
run: |
|
||||
sudo sh -c '
|
||||
cd /root/bbb-ci-ssl/
|
||||
echo "$(hostname -I | cut -d" " -f1) bbb-ci.test" >> /etc/hosts
|
||||
openssl genrsa -out bbb-ci.test.key 2048
|
||||
rm bbb-ci.test.csr bbb-ci.test.crt bbb-ci.test.key
|
||||
rm -f bbb-ci.test.csr bbb-ci.test.crt bbb-ci.test.key
|
||||
cat > bbb-ci.test.ext << EOF
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
@ -107,32 +441,33 @@ jobs:
|
||||
cat /root/bbb-ci-ssl/bbb-ci.test.key > /local/certs/privkey.pem
|
||||
'
|
||||
- name: Setup local repository
|
||||
shell: bash
|
||||
run: |
|
||||
sudo sh -c '
|
||||
sudo -i <<EOF
|
||||
set -e
|
||||
apt install -yq dpkg-dev
|
||||
cd /root && wget -q http://ci.bbb.imdt.dev/cache-3rd-part-packages.tar
|
||||
cd /root && wget -nv http://ci.bbb.imdt.dev/cache-3rd-part-packages.tar
|
||||
cp -r /home/runner/work/bigbluebutton/bigbluebutton/artifacts/ /artifacts/
|
||||
cd /artifacts && tar xf /root/cache-3rd-part-packages.tar
|
||||
cd /artifacts && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
|
||||
echo "deb [trusted=yes] file:/artifacts/ ./" >> /etc/apt/sources.list
|
||||
'
|
||||
EOF
|
||||
- name: Prepare for install
|
||||
run: |
|
||||
sudo sh -c '
|
||||
apt --purge -y remove apache2-bin
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y
|
||||
'
|
||||
- name: Install BBB
|
||||
run: |
|
||||
sudo sh -c '
|
||||
sudo -i <<EOF
|
||||
set -e
|
||||
cd /root/ && wget -q https://raw.githubusercontent.com/bigbluebutton/bbb-install/v2.8.x-release/bbb-install.sh -O bbb-install.sh
|
||||
cat bbb-install.sh | sed "s|> /etc/apt/sources.list.d/bigbluebutton.list||g" | bash -s -- -v jammy-28-develop -s bbb-ci.test -j -d /certs/
|
||||
bbb-conf --salt bbbci
|
||||
echo "NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/bbb-dev/bbb-dev-ca.crt" >> /usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
||||
sed -i "s/\"minify\": true,/\"minify\": false,/" /usr/share/etherpad-lite/settings.json
|
||||
bbb-conf --restart
|
||||
'
|
||||
EOF
|
||||
- name: Install test dependencies
|
||||
working-directory: ./bigbluebutton-tests/playwright
|
||||
run: |
|
||||
@ -174,7 +509,7 @@ jobs:
|
||||
- if: failure()
|
||||
name: Prepare artifacts (configs and logs)
|
||||
run: |
|
||||
sudo sh -c '
|
||||
sudo -i <<EOF
|
||||
mkdir configs
|
||||
cp /etc/haproxy/haproxy.cfg configs/haproxy.cfg
|
||||
touch /etc/bigbluebutton/turn-stun-servers.xml
|
||||
@ -191,10 +526,11 @@ jobs:
|
||||
cp /etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml configs/bbb-webrtc-recorder-default.yml
|
||||
cp /usr/share/bigbluebutton/nginx/sip.nginx configs/nginx_sip.nginx
|
||||
cp /etc/hosts /configs/hosts
|
||||
chmod a+r -R configs
|
||||
mv configs /home/runner/work/bigbluebutton/bigbluebutton/configs
|
||||
chmod a+r -R /home/runner/work/bigbluebutton/bigbluebutton/configs
|
||||
bbb-conf --zip
|
||||
cp $(ls -t /root/*.tar.gz | head -1) ./bbb-logs.tar.gz
|
||||
'
|
||||
ls -t /root/*.tar.gz | head -1 | xargs -I '{}' cp '{}' /home/runner/work/bigbluebutton/bigbluebutton/bbb-logs.tar.gz
|
||||
EOF
|
||||
- if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
@ -24,9 +24,10 @@ const TRACE_LOGS = Meteor.settings.public.kurento.traceLogs;
|
||||
const GATHERING_TIMEOUT = Meteor.settings.public.kurento.gatheringTimeout;
|
||||
const MEDIA = Meteor.settings.public.media;
|
||||
const DEFAULT_FULLAUDIO_MEDIA_SERVER = MEDIA.audio.fullAudioMediaServer;
|
||||
const RETRY_THROUGH_RELAY = MEDIA.audio.retryThroughRelay || false;
|
||||
const LISTEN_ONLY_OFFERING = MEDIA.listenOnlyOffering;
|
||||
const MEDIA_TAG = MEDIA.mediaTag.replace(/#/g, '');
|
||||
const RECONNECT_TIMEOUT_MS = MEDIA.listenOnlyCallTimeout || 15000;
|
||||
const CONNECTION_TIMEOUT_MS = MEDIA.listenOnlyCallTimeout || 15000;
|
||||
const { audio: NETWORK_PRIORITY } = MEDIA.networkPriorities || {};
|
||||
const SENDRECV_ROLE = 'sendrecv';
|
||||
const RECV_ROLE = 'recv';
|
||||
@ -44,6 +45,9 @@ const errorCodeMap = {
|
||||
1307: 1007,
|
||||
};
|
||||
|
||||
// Error codes that are prone to a retry according to RETRY_THROUGH_RELAY
|
||||
const RETRYABLE_ERRORS = [1007, 1010];
|
||||
|
||||
const mapErrorCode = (error) => {
|
||||
const { errorCode } = error;
|
||||
const mappedErrorCode = errorCodeMap[errorCode];
|
||||
@ -76,8 +80,9 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
this.broker = null;
|
||||
this.reconnecting = false;
|
||||
this.iceServers = [];
|
||||
this.inEchoTest = false;
|
||||
this.bridgeName = BRIDGE_NAME;
|
||||
|
||||
this.handleTermination = this.handleTermination.bind(this);
|
||||
}
|
||||
|
||||
get inputStream() {
|
||||
@ -111,73 +116,104 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
return doGUM(constraints, true);
|
||||
}
|
||||
|
||||
handleTermination() {
|
||||
return this.callback({ status: this.baseCallStates.ended, bridge: this.bridgeName });
|
||||
setConnectionTimeout() {
|
||||
if (this.connectionTimeout) this.clearConnectionTimeout();
|
||||
|
||||
this.connectionTimeout = setTimeout(() => {
|
||||
const error = new Error(`ICE negotiation timeout after ${CONNECTION_TIMEOUT_MS / 1000}s`);
|
||||
error.errorCode = 1010;
|
||||
// Duplicating key-vals because I can'decide settle on an error pattern - prlanzarin again
|
||||
error.errorCause = error.message;
|
||||
error.errorMessage = error.message;
|
||||
this.handleBrokerFailure(error);
|
||||
}, CONNECTION_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
clearReconnectionTimeout() {
|
||||
this.reconnecting = false;
|
||||
if (this.reconnectionTimeout) {
|
||||
clearTimeout(this.reconnectionTimeout);
|
||||
this.reconnectionTimeout = null;
|
||||
clearConnectionTimeout() {
|
||||
if (this.connectionTimeout) {
|
||||
clearTimeout(this.connectionTimeout);
|
||||
this.connectionTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
this.broker.stop();
|
||||
this.callback({ status: this.baseCallStates.reconnecting, bridge: this.bridgeName });
|
||||
this.reconnecting = true;
|
||||
// Set up a reconnectionTimeout in case the server is unresponsive
|
||||
// for some reason. If it gets triggered, end the session and stop
|
||||
// trying to reconnect
|
||||
this.reconnectionTimeout = setTimeout(() => {
|
||||
this.callback({
|
||||
status: this.baseCallStates.failed,
|
||||
error: 1010,
|
||||
bridgeError: 'Reconnection timeout',
|
||||
bridge: this.bridgeName,
|
||||
});
|
||||
this.broker.stop();
|
||||
this.clearReconnectionTimeout();
|
||||
}, RECONNECT_TIMEOUT_MS);
|
||||
|
||||
this.joinAudio({ isListenOnly: this.isListenOnly }, this.callback).then(
|
||||
() => this.clearReconnectionTimeout(),
|
||||
).catch((error) => {
|
||||
// Error handling is a no-op because it will be "handled" in handleBrokerFailure
|
||||
logger.debug({
|
||||
logCode: 'sfuaudio_reconnect_failed',
|
||||
extraInfo: {
|
||||
errorMessage: error.errorMessage,
|
||||
reconnecting: this.reconnecting,
|
||||
bridge: this.bridgeName,
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio reconnect failed');
|
||||
dispatchAutoplayHandlingEvent(mediaElement) {
|
||||
const tagFailedEvent = new CustomEvent('audioPlayFailed', {
|
||||
detail: { mediaElement },
|
||||
});
|
||||
window.dispatchEvent(tagFailedEvent);
|
||||
this.callback({ status: this.baseCallStates.autoplayBlocked, bridge: this.bridgeName });
|
||||
}
|
||||
|
||||
reconnect(options = {}) {
|
||||
// If broker has already started, fire the reconnecting callback so the user
|
||||
// knows what's going on
|
||||
if (this.broker.started) {
|
||||
this.callback({ status: this.baseCallStates.reconnecting, bridge: this.bridgeName });
|
||||
} else {
|
||||
// Otherwise: override termination handler so the ended callback doesn't get
|
||||
// triggered - this is a retry attempt and the user shouldn't be notified
|
||||
// yet.
|
||||
this.broker.onended = () => {};
|
||||
}
|
||||
|
||||
this.broker.stop();
|
||||
this.reconnecting = true;
|
||||
this._startBroker({ isListenOnly: this.isListenOnly, ...options })
|
||||
.catch((error) => {
|
||||
// Error handling is a no-op because it will be "handled" in handleBrokerFailure
|
||||
logger.debug({
|
||||
logCode: 'sfuaudio_reconnect_failed',
|
||||
extraInfo: {
|
||||
errorMessage: error.errorMessage,
|
||||
reconnecting: this.reconnecting,
|
||||
bridge: this.bridgeName,
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio reconnect failed');
|
||||
});
|
||||
}
|
||||
|
||||
handleBrokerFailure(error) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.clearConnectionTimeout();
|
||||
mapErrorCode(error);
|
||||
const { errorMessage, errorCause, errorCode } = error;
|
||||
|
||||
if (this.broker.started && !this.reconnecting) {
|
||||
logger.error({
|
||||
logCode: 'sfuaudio_error_try_to_reconnect',
|
||||
extraInfo: {
|
||||
errorMessage,
|
||||
errorCode,
|
||||
errorCause,
|
||||
bridge: this.bridgeName,
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio failed, try to reconnect');
|
||||
this.reconnect();
|
||||
return resolve();
|
||||
if (!this.reconnecting) {
|
||||
if (this.broker.started) {
|
||||
logger.error({
|
||||
logCode: 'sfuaudio_error_try_to_reconnect',
|
||||
extraInfo: {
|
||||
errorMessage,
|
||||
errorCode,
|
||||
errorCause,
|
||||
bridge: this.bridgeName,
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio failed, try to reconnect');
|
||||
this.reconnect();
|
||||
return resolve();
|
||||
}
|
||||
|
||||
if (RETRYABLE_ERRORS.includes(errorCode) && RETRY_THROUGH_RELAY) {
|
||||
logger.error({
|
||||
logCode: 'sfuaudio_error_retry_through_relay',
|
||||
extraInfo: {
|
||||
errorMessage,
|
||||
errorCode,
|
||||
errorCause,
|
||||
bridge: this.bridgeName,
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio failed to connect, retry through relay');
|
||||
this.reconnect({ forceRelay: true });
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Already tried reconnecting once OR the user handn't succesfully
|
||||
// connected firsthand. Just finish the session and reject with error
|
||||
// connected firsthand and retrying isn't an option. Finish the session
|
||||
// and reject with the error
|
||||
logger.error({
|
||||
logCode: 'sfuaudio_error',
|
||||
extraInfo: {
|
||||
@ -189,7 +225,7 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
role: this.role,
|
||||
},
|
||||
}, 'SFU audio failed');
|
||||
this.clearReconnectionTimeout();
|
||||
this.clearConnectionTimeout();
|
||||
this.broker.stop();
|
||||
this.callback({
|
||||
status: this.baseCallStates.failed,
|
||||
@ -201,23 +237,23 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
});
|
||||
}
|
||||
|
||||
dispatchAutoplayHandlingEvent(mediaElement) {
|
||||
const tagFailedEvent = new CustomEvent('audioPlayFailed', {
|
||||
detail: { mediaElement },
|
||||
});
|
||||
window.dispatchEvent(tagFailedEvent);
|
||||
this.callback({ status: this.baseCallStates.autoplayBlocked, bridge: this.bridgeName });
|
||||
handleTermination() {
|
||||
this.clearConnectionTimeout();
|
||||
return this.callback({ status: this.baseCallStates.ended, bridge: this.bridgeName });
|
||||
}
|
||||
|
||||
handleStart() {
|
||||
const stream = this.broker.webRtcPeer.getRemoteStream();
|
||||
const mediaElement = document.getElementById(MEDIA_TAG);
|
||||
|
||||
return loadAndPlayMediaStream(stream, mediaElement, false).then(() => this
|
||||
.callback({
|
||||
return loadAndPlayMediaStream(stream, mediaElement, false).then(() => {
|
||||
this.callback({
|
||||
status: this.baseCallStates.started,
|
||||
bridge: this.bridgeName,
|
||||
})).catch((error) => {
|
||||
});
|
||||
this.clearConnectionTimeout();
|
||||
this.reconnecting = false;
|
||||
}).catch((error) => {
|
||||
// NotAllowedError equals autoplay issues, fire autoplay handling event.
|
||||
// This will be handled in audio-manager.
|
||||
if (error.name === 'NotAllowedError') {
|
||||
@ -247,9 +283,32 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
}
|
||||
|
||||
async _startBroker(options) {
|
||||
try {
|
||||
this.iceServers = await fetchWebRTCMappedStunTurnServers(this.sessionToken);
|
||||
} catch (error) {
|
||||
logger.error({ logCode: 'sfuaudio_stun-turn_fetch_failed' },
|
||||
'SFU audio bridge failed to fetch STUN/TURN info, using default servers');
|
||||
this.iceServers = getMappedFallbackStun();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const {
|
||||
isListenOnly,
|
||||
extension,
|
||||
inputStream,
|
||||
forceRelay: _forceRelay = false,
|
||||
} = options;
|
||||
|
||||
const handleInitError = (_error) => {
|
||||
mapErrorCode(_error);
|
||||
if (RETRYABLE_ERRORS.includes(_error?.errorCode)
|
||||
|| !RETRY_THROUGH_RELAY
|
||||
|| this.reconnecting) {
|
||||
reject(_error);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const { isListenOnly, extension, inputStream } = options;
|
||||
this.inEchoTest = !!extension;
|
||||
this.isListenOnly = isListenOnly;
|
||||
|
||||
@ -259,7 +318,7 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
iceServers: this.iceServers,
|
||||
mediaServer: getMediaServerAdapter(isListenOnly),
|
||||
constraints: getAudioConstraints({ deviceId: this.inputDeviceId }),
|
||||
forceRelay: shouldForceRelay(),
|
||||
forceRelay: _forceRelay || shouldForceRelay(),
|
||||
stream: (inputStream && inputStream.active) ? inputStream : undefined,
|
||||
offering: isListenOnly ? LISTEN_ONLY_OFFERING : true,
|
||||
signalCandidates: SIGNAL_CANDIDATES,
|
||||
@ -283,25 +342,19 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
this.handleStart().then(resolve).catch(reject);
|
||||
};
|
||||
|
||||
this.broker.joinAudio().catch(reject);
|
||||
// Set up a connectionTimeout in case the server or network are botching
|
||||
// negotiation or conn checks.
|
||||
this.setConnectionTimeout();
|
||||
this.broker.joinAudio().catch(handleInitError);
|
||||
} catch (error) {
|
||||
logger.warn({ logCode: 'sfuaudio_bridge_broker_init_fail' },
|
||||
'Problem when initializing SFU broker for fullaudio bridge');
|
||||
reject(error);
|
||||
handleInitError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async joinAudio(options, callback) {
|
||||
this.callback = callback;
|
||||
|
||||
try {
|
||||
this.iceServers = await fetchWebRTCMappedStunTurnServers(this.sessionToken);
|
||||
} catch (error) {
|
||||
logger.error({ logCode: 'sfuaudio_stun-turn_fetch_failed' },
|
||||
'SFU audio bridge failed to fetch STUN/TURN info, using default servers');
|
||||
this.iceServers = getMappedFallbackStun();
|
||||
}
|
||||
this.reconnecting = false;
|
||||
|
||||
return this._startBroker(options);
|
||||
}
|
||||
@ -390,7 +443,8 @@ export default class SFUAudioBridge extends BaseAudioBridge {
|
||||
exitAudio() {
|
||||
const mediaElement = document.getElementById(MEDIA_TAG);
|
||||
|
||||
this.clearReconnectionTimeout();
|
||||
this.clearConnectionTimeout();
|
||||
this.reconnecting = false;
|
||||
|
||||
if (this.broker) {
|
||||
this.broker.stop();
|
||||
|
@ -142,6 +142,7 @@ const IsTalkingWrapper = styled.div`
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin-top: 0.5rem;
|
||||
`;
|
||||
|
||||
const Speaking = styled.div`
|
||||
|
@ -20,7 +20,8 @@ import { isPresentationEnabled } from '/imports/ui/services/features';
|
||||
|
||||
const { isMobile } = deviceInfo;
|
||||
const propTypes = {
|
||||
allowDownloadable: PropTypes.bool.isRequired,
|
||||
allowDownloadOriginal: PropTypes.bool.isRequired,
|
||||
allowDownloadWithAnnotations: PropTypes.bool.isRequired,
|
||||
intl: PropTypes.shape({
|
||||
formatMessage: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
@ -804,7 +805,7 @@ class PresentationUploader extends Component {
|
||||
|
||||
renderPresentationList() {
|
||||
const { presentations } = this.state;
|
||||
const { intl, allowDownloadable } = this.props;
|
||||
const { intl } = this.props;
|
||||
|
||||
let presentationsSorted = presentations;
|
||||
|
||||
@ -846,9 +847,7 @@ class PresentationUploader extends Component {
|
||||
</tr>
|
||||
<Styled.Head>
|
||||
<th colSpan={4}>{intl.formatMessage(intlMessages.currentLabel)}</th>
|
||||
{
|
||||
allowDownloadable ? <th>{intl.formatMessage(intlMessages.actionsLabel)}</th> : null
|
||||
}
|
||||
<th>{intl.formatMessage(intlMessages.actionsLabel)}</th>
|
||||
</Styled.Head>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -978,10 +977,10 @@ class PresentationUploader extends Component {
|
||||
renderDownloadableWithAnnotationsHint() {
|
||||
const {
|
||||
intl,
|
||||
allowDownloadable,
|
||||
allowDownloadWithAnnotations,
|
||||
} = this.props;
|
||||
|
||||
return allowDownloadable ? (
|
||||
return allowDownloadWithAnnotations ? (
|
||||
<Styled.ExportHint>
|
||||
{intl.formatMessage(intlMessages.exportHint)}
|
||||
</Styled.ExportHint>
|
||||
@ -994,7 +993,8 @@ class PresentationUploader extends Component {
|
||||
const {
|
||||
intl,
|
||||
selectedToBeNextCurrent,
|
||||
allowDownloadable,
|
||||
allowDownloadOriginal,
|
||||
allowDownloadWithAnnotations,
|
||||
renderPresentationItemStatus,
|
||||
hasAnnotations,
|
||||
} = this.props;
|
||||
@ -1068,8 +1068,8 @@ class PresentationUploader extends Component {
|
||||
</Styled.TableItemStatus>
|
||||
{
|
||||
hasError ? null : (
|
||||
<Styled.TableItemActions notDownloadable={!allowDownloadable}>
|
||||
{allowDownloadable ? (
|
||||
<Styled.TableItemActions notDownloadable={!allowDownloadOriginal}>
|
||||
{allowDownloadOriginal || allowDownloadWithAnnotations ? (
|
||||
<PresentationDownloadDropdown
|
||||
hasAnnotations={hasAnyAnnotation}
|
||||
disabled={shouldDisableExportButton}
|
||||
@ -1077,6 +1077,8 @@ class PresentationUploader extends Component {
|
||||
aria-label={formattedDownloadAriaLabel}
|
||||
color="primary"
|
||||
isDownloadable={isDownloadable}
|
||||
allowDownloadOriginal={allowDownloadOriginal}
|
||||
allowDownloadWithAnnotations={allowDownloadWithAnnotations}
|
||||
handleToggleDownloadable={this.handleToggleDownloadable}
|
||||
item={item}
|
||||
closeModal={() => Session.set('showUploadPresentationView', false)}
|
||||
|
@ -8,7 +8,11 @@ import PresUploaderToast from '/imports/ui/components/presentation/presentation-
|
||||
import PresentationUploader from './component';
|
||||
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import { isDownloadPresentationWithAnnotationsEnabled, isPresentationEnabled } from '/imports/ui/services/features';
|
||||
import {
|
||||
isDownloadPresentationWithAnnotationsEnabled,
|
||||
isDownloadOriginalPresentationEnabled,
|
||||
isPresentationEnabled,
|
||||
} from '/imports/ui/services/features';
|
||||
import { hasAnnotations } from '/imports/ui/components/whiteboard/service';
|
||||
|
||||
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
|
||||
@ -44,7 +48,8 @@ export default withTracker(() => {
|
||||
fileSizeMax: PRESENTATION_CONFIG.mirroredFromBBBCore.uploadSizeMax,
|
||||
filePagesMax: PRESENTATION_CONFIG.mirroredFromBBBCore.uploadPagesMax,
|
||||
fileValidMimeTypes: PRESENTATION_CONFIG.uploadValidMimeTypes,
|
||||
allowDownloadable: isDownloadPresentationWithAnnotationsEnabled(),
|
||||
allowDownloadOriginal: isDownloadOriginalPresentationEnabled(),
|
||||
allowDownloadWithAnnotations: isDownloadPresentationWithAnnotationsEnabled(),
|
||||
handleSave: Service.handleSavePresentation,
|
||||
handleDismissToast: PresUploaderToast.handleDismissToast,
|
||||
renderToastList: Service.renderToastList,
|
||||
|
@ -74,6 +74,8 @@ class PresentationDownloadDropdown extends PureComponent {
|
||||
handleDownloadingOfPresentation,
|
||||
handleToggleDownloadable,
|
||||
isDownloadable,
|
||||
allowDownloadOriginal,
|
||||
allowDownloadWithAnnotations,
|
||||
item,
|
||||
closeModal,
|
||||
} = this.props;
|
||||
@ -88,31 +90,35 @@ class PresentationDownloadDropdown extends PureComponent {
|
||||
closeModal();
|
||||
};
|
||||
|
||||
if (!isDownloadable) {
|
||||
if (allowDownloadOriginal) {
|
||||
if (!isDownloadable) {
|
||||
this.menuItems.push({
|
||||
key: this.actionsKey[0],
|
||||
dataTest: 'enableOriginalPresentationDownload',
|
||||
label: intl.formatMessage(intlMessages.enableOriginalPresentationDownload),
|
||||
onClick: () => toggleDownloadOriginalPresentation(true),
|
||||
});
|
||||
} else {
|
||||
this.menuItems.push({
|
||||
key: this.actionsKey[0],
|
||||
dataTest: 'disableOriginalPresentationDownload',
|
||||
label: intl.formatMessage(intlMessages.disableOriginalPresentationDownload),
|
||||
onClick: () => toggleDownloadOriginalPresentation(false),
|
||||
});
|
||||
}
|
||||
}
|
||||
if (allowDownloadWithAnnotations) {
|
||||
this.menuItems.push({
|
||||
key: this.actionsKey[0],
|
||||
dataTest: 'enableOriginalPresentationDownload',
|
||||
label: intl.formatMessage(intlMessages.enableOriginalPresentationDownload),
|
||||
onClick: () => toggleDownloadOriginalPresentation(true),
|
||||
});
|
||||
} else {
|
||||
this.menuItems.push({
|
||||
key: this.actionsKey[0],
|
||||
dataTest: 'disableOriginalPresentationDownload',
|
||||
label: intl.formatMessage(intlMessages.disableOriginalPresentationDownload),
|
||||
onClick: () => toggleDownloadOriginalPresentation(false),
|
||||
key: this.actionsKey[1],
|
||||
id: 'sendCurrentStateDocument',
|
||||
dataTest: 'sendCurrentStateDocument',
|
||||
label: intl.formatMessage(intlMessages.sendCurrentStateDocument),
|
||||
onClick: () => {
|
||||
closeModal();
|
||||
handleDownloadingOfPresentation('Annotated');
|
||||
},
|
||||
});
|
||||
}
|
||||
this.menuItems.push({
|
||||
key: this.actionsKey[1],
|
||||
id: 'sendCurrentStateDocument',
|
||||
dataTest: 'sendCurrentStateDocument',
|
||||
label: intl.formatMessage(intlMessages.sendCurrentStateDocument),
|
||||
onClick: () => {
|
||||
closeModal();
|
||||
handleDownloadingOfPresentation('Annotated');
|
||||
},
|
||||
});
|
||||
return this.menuItems;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ const TimerWrapper = styled.div`
|
||||
`;
|
||||
|
||||
const Timer = styled.div`
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
max-height: ${timerPaddingXL});
|
||||
`;
|
||||
|
@ -80,7 +80,7 @@ const UserAvatar = ({
|
||||
}}
|
||||
>
|
||||
|
||||
<Styled.Talking talking={talking && !muted && avatar.length === 0} animations={animations} />
|
||||
<Styled.Talking talking={talking && !muted} animations={animations} />
|
||||
|
||||
{avatar.length !== 0 && !emoji
|
||||
? (
|
||||
|
@ -34,6 +34,11 @@ const Image = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
`;
|
||||
|
||||
const Img = styled.img`
|
||||
|
@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import Styled from './styles';
|
||||
import { notify } from '/imports/ui/services/notification';
|
||||
|
||||
const ASK_MODERATOR = 'ASK_MODERATOR';
|
||||
const ALWAYS_ACCEPT = 'ALWAYS_ACCEPT';
|
||||
@ -36,6 +37,10 @@ const intlMessages = defineMessages({
|
||||
id: 'app.guest-policy.button.alwaysDeny',
|
||||
description: 'Always deny button label',
|
||||
},
|
||||
feedbackMessage: {
|
||||
id: 'app.guest-policy.feedbackMessage',
|
||||
description: 'Feedback message for guest policy change',
|
||||
},
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
@ -47,18 +52,31 @@ const propTypes = {
|
||||
};
|
||||
|
||||
class GuestPolicyComponent extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleChangePolicy = this.handleChangePolicy.bind(this);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { setIsOpen } = this.props;
|
||||
|
||||
setIsOpen(false);
|
||||
}
|
||||
|
||||
handleChangePolicy(policyRule, messageId) {
|
||||
const { intl, changeGuestPolicy } = this.props;
|
||||
|
||||
changeGuestPolicy(policyRule);
|
||||
|
||||
notify(intl.formatMessage(intlMessages.feedbackMessage) + intl.formatMessage(messageId), 'success');
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
setIsOpen,
|
||||
intl,
|
||||
guestPolicy,
|
||||
changeGuestPolicy,
|
||||
isOpen,
|
||||
onRequestClose,
|
||||
priority,
|
||||
@ -91,7 +109,7 @@ class GuestPolicyComponent extends PureComponent {
|
||||
aria-pressed={guestPolicy === ASK_MODERATOR}
|
||||
data-test="askModerator"
|
||||
onClick={() => {
|
||||
changeGuestPolicy(ASK_MODERATOR);
|
||||
this.handleChangePolicy(ASK_MODERATOR, intlMessages.askModerator);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
/>
|
||||
@ -103,7 +121,7 @@ class GuestPolicyComponent extends PureComponent {
|
||||
aria-pressed={guestPolicy === ALWAYS_ACCEPT}
|
||||
data-test="alwaysAccept"
|
||||
onClick={() => {
|
||||
changeGuestPolicy(ALWAYS_ACCEPT);
|
||||
this.handleChangePolicy(ALWAYS_ACCEPT, intlMessages.alwaysAccept);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
/>
|
||||
@ -115,7 +133,7 @@ class GuestPolicyComponent extends PureComponent {
|
||||
aria-pressed={guestPolicy === ALWAYS_DENY}
|
||||
data-test="alwaysDeny"
|
||||
onClick={() => {
|
||||
changeGuestPolicy(ALWAYS_DENY);
|
||||
this.handleChangePolicy(ALWAYS_DENY, intlMessages.alwaysDeny);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
/>
|
||||
|
@ -61,7 +61,11 @@ export function isCustomVirtualBackgroundsEnabled() {
|
||||
}
|
||||
|
||||
export function isDownloadPresentationWithAnnotationsEnabled() {
|
||||
return getDisabledFeatures().indexOf('downloadPresentationWithAnnotations') === -1 && Meteor.settings.public.presentation.allowDownloadable;
|
||||
return getDisabledFeatures().indexOf('downloadPresentationWithAnnotations') === -1 && Meteor.settings.public.presentation.allowDownloadWithAnnotations;
|
||||
}
|
||||
|
||||
export function isDownloadOriginalPresentationEnabled() {
|
||||
return getDisabledFeatures().indexOf('downloadOriginalPresentation') === -1 && Meteor.settings.public.presentation.allowDownloadOriginal;
|
||||
}
|
||||
|
||||
export function isSnapshotOfCurrentSlideEnabled() {
|
||||
|
@ -59,13 +59,13 @@ public:
|
||||
# the default logoutUrl matches window.location.origin i.e. bigbluebutton.org for demo.bigbluebutton.org
|
||||
# in some cases we want only custom logoutUrl to be used when provided on meeting create. Default value: true
|
||||
askForConfirmationOnLeave: true
|
||||
wakeLock:
|
||||
wakeLock:
|
||||
enabled: false
|
||||
allowDefaultLogoutUrl: true
|
||||
allowUserLookup: false
|
||||
dynamicGuestPolicy: true
|
||||
enableGuestLobbyMessage: true
|
||||
guestPolicyExtraAllowOptions: true
|
||||
guestPolicyExtraAllowOptions: false
|
||||
alwaysShowWaitingRoomUI: true
|
||||
enableLimitOfViewersInWebcam: false
|
||||
enableMultipleCameras: true
|
||||
@ -169,7 +169,7 @@ public:
|
||||
enableCopyNetworkStatsButton: true
|
||||
# where should client settings be stored? if you run a single BBB server or
|
||||
# a cluster with a reverse proxy in front of it, you may set this to 'local'
|
||||
# See https://docs.bigbluebutton.org/administration/cluster-proxy
|
||||
# See See https://docs.bigbluebutton.org/administration/cluster-proxy
|
||||
# allowed values:
|
||||
# 'session' -> settings are stored in browser sessionStorage
|
||||
# 'local' -> settings are stored in browser localStorage
|
||||
@ -563,7 +563,7 @@ public:
|
||||
type_private: PRIVATE_ACCESS
|
||||
system_userid: SYSTEM_MESSAGE
|
||||
system_username: SYSTEM_MESSAGE
|
||||
public_id: MAIN-PUBLIC-GROUP-CHAT
|
||||
public_id: public
|
||||
public_group_id: MAIN-PUBLIC-GROUP-CHAT
|
||||
public_userid: public_chat_userid
|
||||
public_username: public_chat_username
|
||||
@ -639,6 +639,9 @@ public:
|
||||
path: 'bridge/sip'
|
||||
- name: fullaudio
|
||||
path: 'bridge/sfu-audio-bridge'
|
||||
# Forces a retry with iceTransportPolicy = 'relay' if the first attempt
|
||||
# fails with a few selected errors codes (eg 1007, 1010)
|
||||
retryThroughRelay: false
|
||||
stunTurnServersFetchAddress: '/bigbluebutton/api/stuns'
|
||||
cacheStunTurnServers: true
|
||||
fallbackStunServer: ''
|
||||
@ -653,7 +656,7 @@ public:
|
||||
callHangupTimeout: 2000
|
||||
callHangupMaximumRetries: 10
|
||||
echoTestNumber: 'echo'
|
||||
listenOnlyCallTimeout: 25000
|
||||
listenOnlyCallTimeout: 15000
|
||||
# Experimental. True is the canonical behavior. Flip to false to reverse
|
||||
# the negotiation flow for LO subscribers.
|
||||
listenOnlyOffering: false
|
||||
@ -742,7 +745,8 @@ public:
|
||||
- critical
|
||||
help: STATS_HELP_URL
|
||||
presentation:
|
||||
allowDownloadable: true
|
||||
allowDownloadOriginal: true
|
||||
allowDownloadWithAnnotations: true
|
||||
allowSnapshotOfCurrentSlide: true
|
||||
panZoomThrottle: 32
|
||||
restoreOnUpdate: true
|
||||
|
@ -288,7 +288,7 @@
|
||||
"app.presentationUploader.sent": "Sent",
|
||||
"app.presentationUploader.exportingTimeout": "The export is taking too long...",
|
||||
"app.presentationUploader.export": "Send to chat",
|
||||
"app.presentationUploader.exportCurrentStatePresentation": "Send out a download link for the presentation in the current state of it",
|
||||
"app.presentationUploader.exportCurrentStatePresentation": "Send out a download link for the presentation in its current state",
|
||||
"app.presentationUploader.enableOriginalPresentationDownload": "Enable download of the original presentation",
|
||||
"app.presentationUploader.disableOriginalPresentationDownload": "Disable download of the original presentation",
|
||||
"app.presentationUploader.dropdownExportOptions": "Export options",
|
||||
@ -969,6 +969,7 @@
|
||||
"app.guest-policy.button.alwaysAccept": "Always accept",
|
||||
"app.guest-policy.button.alwaysDeny": "Always deny",
|
||||
"app.guest-policy.policyBtnDesc": "Sets meeting guest policy",
|
||||
"app.guest-policy.feedbackMessage": "The guest policy is now: ",
|
||||
"app.connection-status.ariaTitle": "Connection status modal",
|
||||
"app.connection-status.title": "Connection status",
|
||||
"app.connection-status.description": "View users' connection status",
|
||||
|
@ -28,7 +28,8 @@ async function generateSettingsData(page) {
|
||||
pollEnabled: settingsData.poll.enabled,
|
||||
pollChatMessage: settingsData.poll.chatMessage,
|
||||
// Presentation
|
||||
presentationDownloadable: settingsData.presentation.allowDownloadable,
|
||||
originalPresentationDownloadable: settingsData.presentation.allowDownloadOriginal,
|
||||
presentationWithAnnotationsDownloadable: settingsData.presentation.allowDownloadWithAnnotations,
|
||||
externalVideoPlayer: settingsData.externalVideoPlayer.enabled,
|
||||
presentationHidden: settingsData.layout.hidePresentation,
|
||||
// Screensharing
|
||||
|
@ -5,8 +5,8 @@
|
||||
"test:filter": "npx playwright test -g",
|
||||
"test:headed": "npx playwright test --headed",
|
||||
"test:debug": "npx playwright test --debug -g",
|
||||
"test-chromium-ci": "export CI='true' && npx playwright test --project=chromium --grep @ci",
|
||||
"test-firefox-ci": "export CI='true' && npx playwright test --project=firefox --grep @ci",
|
||||
"test-chromium-ci": "export CI='true' && npx playwright test --project=chromium --grep @ci --grep-invert @flaky",
|
||||
"test-firefox-ci": "export CI='true' && npx playwright test --project=firefox --grep @ci --grep-invert @flaky",
|
||||
"rewrite-snapshots": "read -p 'CAUTION: You will delete ALL testing folders containing snapshots and run the tests to rewrite these files.\nProceed? (y/n) ' confirm && test $confirm = 'y' && sh core/scripts/rewrite-snapshots.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -19,4 +19,4 @@
|
||||
"sha1": "^1.1.1",
|
||||
"xml2js": "^0.6.0"
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ const { DisabledFeatures } = require('./disabledFeatures');
|
||||
const c = require('./constants');
|
||||
const { encodeCustomParams, getAllShortcutParams, hexToRgb } = require('./util');
|
||||
const { CreateParameters } = require('./createParameters');
|
||||
const { linkIssue } = require('../core/helpers');
|
||||
|
||||
test.describe.parallel('Create Parameters', () => {
|
||||
test('Record Meeting', async ({ browser, context, page }) => {
|
||||
@ -257,7 +258,7 @@ test.describe.parallel('Create Parameters', () => {
|
||||
await disabledFeatures.downloadPresentationWithAnnotationsExclude();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test.describe.serial(() => {
|
||||
test('Import Presentation With Annotations From Breakout Rooms', async ({ browser, context, page }) => {
|
||||
const disabledFeatures = new DisabledFeatures(browser, context);
|
||||
|
@ -122,8 +122,8 @@ class Presentation extends MultiUsers {
|
||||
}
|
||||
|
||||
async enableAndDisablePresentationDownload(testInfo) {
|
||||
const { presentationDownloadable } = getSettings();
|
||||
test.fail(!presentationDownloadable, 'Presentation download is disable');
|
||||
const { originalPresentationDownloadable } = getSettings();
|
||||
test.fail(!originalPresentationDownloadable, 'Presentation download is disable');
|
||||
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
// enable original presentation download
|
||||
@ -152,8 +152,8 @@ class Presentation extends MultiUsers {
|
||||
}
|
||||
|
||||
async sendPresentationToDownload(testInfo) {
|
||||
const { presentationDownloadable } = getSettings();
|
||||
test.fail(!presentationDownloadable, 'Presentation download is disable');
|
||||
const { presentationWithAnnotationsDownloadable } = getSettings();
|
||||
test.fail(!presentationWithAnnotationsDownloadable, 'Presentation download is disable');
|
||||
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
|
@ -89,7 +89,7 @@ test.describe.parallel('Presentation', () => {
|
||||
await presentation.initPages(page);
|
||||
await presentation.enableAndDisablePresentationDownload(testInfo);
|
||||
});
|
||||
|
||||
|
||||
test('Send presentation in the current state (with annotations) to chat for downloading @ci', async ({ browser, context, page }, testInfo) => {
|
||||
const presentation = new Presentation(browser, context);
|
||||
await presentation.initPages(page);
|
||||
|
@ -2,9 +2,9 @@ const { test } = require('@playwright/test');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
const { Webcam } = require('./webcam');
|
||||
|
||||
test.describe.parallel('Webcam @ci', () => {
|
||||
test.describe.parallel('Webcam', () => {
|
||||
// https://docs.bigbluebutton.org/2.6/release-tests.html#joining-webcam-automated
|
||||
test('Shares webcam', async ({ browser, page }) => {
|
||||
test('Shares webcam @ci', async ({ browser, page }) => {
|
||||
const webcam = new Webcam(browser, page);
|
||||
await webcam.init(true, true);
|
||||
await webcam.share();
|
||||
@ -49,7 +49,9 @@ test.describe.parallel('Webcam @ci', () => {
|
||||
await webcam.applyBackground();
|
||||
});
|
||||
|
||||
test('Managing new background', async ({ browser, page }) => {
|
||||
// following test is throwing failures due to mis-comparison screenshot
|
||||
// as the emulated video is not static, we may add a mask in the middle part - where it moves the most
|
||||
test('Managing new background @flaky', async ({ browser, page }) => {
|
||||
const webcam = new Webcam(browser, page);
|
||||
await webcam.init(true, true);
|
||||
await webcam.managingNewBackground();
|
||||
|
@ -432,7 +432,8 @@ endWhenNoModeratorDelayInMinutes=1
|
||||
# Available options:
|
||||
# chat, sharedNotes, polls, screenshare, externalVideos, presentation, downloadPresentationWithAnnotations
|
||||
# learningDashboard, layouts, captions, liveTranscription, virtualBackgrounds, customVirtualBackgrounds
|
||||
# breakoutRooms, importSharedNotesFromBreakoutRooms, importPresentationWithAnnotationsFromBreakoutRooms
|
||||
# breakoutRooms, importSharedNotesFromBreakoutRooms, importPresentationWithAnnotationsFromBreakoutRooms,
|
||||
# downloadOriginalPresentation
|
||||
disabledFeatures=
|
||||
|
||||
# Notify users that recording is on
|
||||
|
@ -24,6 +24,15 @@ else
|
||||
fi
|
||||
COMMIT_DATE="$(git log -n1 --pretty='format:%cd' --date=format:'%Y%m%dT%H%M%S')"
|
||||
|
||||
# FORCE_GIT_REV and FORCE_COMMIT_DATE are useful for Github Actions be able to cache previous packages
|
||||
# It sets FORCE_GIT_REV=0 and FORCE_COMMIT_DATE=0 in order to keep the same package version always
|
||||
if [ ! -z "$FORCE_GIT_REV" ]; then
|
||||
GIT_REV=$FORCE_GIT_REV
|
||||
fi
|
||||
if [ ! -z "$FORCE_COMMIT_DATE" ]; then
|
||||
COMMIT_DATE=$FORCE_COMMIT_DATE
|
||||
fi
|
||||
|
||||
# Arrange to write the docker container ID to a temp file, then run
|
||||
# the container detached and immediately attach it (without stdin) so
|
||||
# we can catch CTRL-C in this script and kill the container if so.
|
||||
|
@ -118,6 +118,7 @@ For full details on what is new in BigBlueButton 2.7, see the release notes.
|
||||
|
||||
Recent releases:
|
||||
|
||||
- [2.7.0-beta.3](https://github.com/bigbluebutton/bigbluebutton/releases/tag/v2.7.0-beta.3)
|
||||
- [2.7.0-beta.2](https://github.com/bigbluebutton/bigbluebutton/releases/tag/v2.7.0-beta.2)
|
||||
- [2.7.0-beta.1](https://github.com/bigbluebutton/bigbluebutton/releases/tag/v2.7.0-beta.1)
|
||||
- [2.7.0-alpha.3](https://github.com/bigbluebutton/bigbluebutton/releases/tag/v2.7.0-alpha.3)
|
||||
@ -130,6 +131,10 @@ Recent releases:
|
||||
|
||||
If you are using bbb-install to configure your servers, be aware that starting with BigBlueButton 2.6's version of bbb-install by default we install a local TURN server. For more information: https://github.com/bigbluebutton/bbb-install/pull/579 and https://docs.bigbluebutton.org/administration/turn-server
|
||||
|
||||
#### Changing the default setting `guestPolicyExtraAllowOptions`
|
||||
|
||||
Starting with BigBlueButton 2.7.0-beta.3 we are hiding by default a couple extra options in the guest approve panel. 'Allow all authenticated users' and 'Allow all guests' options will be hidden unless you override the option `app.public.guestPolicyExtraAllowOptions` in `bbb-html5` config file `settings.yml`. These extra options were not relevant to the vast majority of the use cases and when hidden, the interface becomes much simpler.
|
||||
|
||||
### Development
|
||||
|
||||
For information on developing in BigBlueButton, see [setting up a development environment for 2.7](/development/guide).
|
||||
|
Loading…
Reference in New Issue
Block a user