diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..e74bc14a1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,232 @@ +name: Build + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: cache node_modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: use Node.js + uses: actions/setup-node@v1 + with: + node-version: "12" + + - name: install and build + run: | + npm ci + npm run lint + npm run type-check + npm run build + npm run docs + # check that hls.js doesn't error if requiring in node + # see https://github.com/video-dev/hls.js/pull/1642 + node -e 'require("./" + require("./package.json").main)' + env: + CI: true + + - name: upload build + uses: actions/upload-artifact@v2 + with: + name: build + path: | + ** + !**/[.]*/** + !**/node_modules/ + + test_unit: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: cache node_modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: use Node.js + uses: actions/setup-node@v1 + with: + node-version: "12" + + - name: download build + uses: actions/download-artifact@v2 + with: + name: build + + - name: run unit tests + run: | + npm ci + npm run test:unit + env: + CI: true + + test_functional_required: + needs: test_unit + runs-on: ubuntu-latest + strategy: + fail-fast: true + max-parallel: 8 + matrix: + config: [chrome-win_10] + + include: + - config: chrome-win_10 + ua: chrome + os: Windows 10 + + steps: + - uses: actions/checkout@v2 + + - name: cache node_modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: use Node.js + uses: actions/setup-node@v1 + with: + node-version: "12" + + - name: download build + uses: actions/download-artifact@v2 + with: + name: build + + - name: start SauceConnect tunnel + uses: saucelabs/sauce-connect-action@a0930f1 + with: + username: ${{ secrets.SAUCE_USERNAME }} + accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} + tunnelIdentifier: ${{ github.run_id }}-${{ matrix.config }} + + - name: run functional tests + run: | + npm ci + npm run test:func + env: + CI: true + SAUCE_TUNNEL_ID: ${{ github.run_id }}-${{ matrix.config }} + SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} + SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} + UA: ${{ matrix.ua }} + UA_VERSION: ${{ matrix.uaVersion }} + OS: ${{ matrix.os }} + + test_functional_optional: + needs: test_functional_required + runs-on: ubuntu-latest + continue-on-error: true + strategy: + fail-fast: false + max-parallel: 8 + matrix: + config: + - safari-osx_10.15 + - firefox-win_10 + - chrome-osx_10.11-79.0 + - internet_explorer-win_10 + - internet_explorer-win_8.1-11.0 + - chrome-win_7-69.0 + - safari-osx_10.12-10.1 + + include: + - config: safari-osx_10.15 + ua: safari + os: OS X 10.15 + - config: firefox-win_10 + ua: firefox + os: Windows 10 + - config: chrome-osx_10.11-79.0 + ua: chrome + os: OS X 10.11 + uaVersion: "79.0" + - config: internet_explorer-win_10 + ua: internet explorer + os: Windows 10 + - config: internet_explorer-win_8.1-11.0 + ua: internet explorer + os: Windows 8.1 + uaVersion: "11.0" + - config: chrome-win_7-69.0 + ua: chrome + os: Windows 7 + uaVersion: "69.0" + - config: safari-osx_10.12-10.1 + ua: safari + os: OS X 10.12 + uaVersion: "10.1" + + steps: + - uses: actions/checkout@v2 + + - name: cache node_modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: use Node.js + uses: actions/setup-node@v1 + with: + node-version: "12" + + - name: download build + uses: actions/download-artifact@v2 + with: + name: build + + - name: start SauceConnect tunnel + uses: saucelabs/sauce-connect-action@a0930f1 + with: + username: ${{ secrets.SAUCE_USERNAME }} + accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} + tunnelIdentifier: ${{ github.run_id }}-${{ matrix.config }} + + - name: run functional tests + run: | + npm ci + npm run test:func + env: + CI: true + SAUCE_TUNNEL_ID: ${{ github.run_id }}-${{ matrix.config }} + SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} + SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} + UA: ${{ matrix.ua }} + UA_VERSION: ${{ matrix.uaVersion }} + OS: ${{ matrix.os }} diff --git a/.travis.yml b/.travis.yml index 29f68cce4..316c5ae64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,19 +4,15 @@ node_js: node # see https://github.com/video-dev/hls.js/pull/1710#discussion_r187754754 sudo: required # don't connect to sauce labs unless running functional tests -before_install: if [ "${TRAVIS_MODE}" != "funcTests" ]; then unset SAUCE_USERNAME && unset SAUCE_ACCESS_KEY; fi +before_install: unset SAUCE_USERNAME && unset SAUCE_ACCESS_KEY script: ./scripts/travis.sh stages: - buildAndTest - releaseAlpha - release - - testFuncRequired - - testFuncOptional jobs: # stage: optional is allowed to be failure fast_finish: true - allow_failures: - - stage: testFuncOptional include: # https://docs.travis-ci.com/user/build-stages/deploy-github-releases/ # publish package (and deploy gh-pages) @@ -44,22 +40,3 @@ jobs: env: TRAVIS_MODE=build - stage: buildAndTest env: TRAVIS_MODE=unitTests - - stage: testFuncRequired - env: TRAVIS_MODE=funcTests UA=chrome OS="Windows 10" - # Optional Func tests - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA=safari OS="OS X 10.15" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA=firefox OS="Windows 10" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA=chrome OS="OS X 10.11" UA_VERSION="79.0" - # - stage: testFuncOptional - # env: TRAVIS_MODE=funcTests UA=MicrosoftEdge OS="Windows 10" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA="internet explorer" OS="Windows 10" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA="internet explorer" OS="Windows 8.1" UA_VERSION="11.0" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA=chrome OS="Windows 7" UA_VERSION="69.0" - - stage: testFuncOptional - env: TRAVIS_MODE=funcTests UA=safari OS="OS X 10.12" UA_VERSION="10.1" diff --git a/scripts/travis.sh b/scripts/travis.sh index f8ccee049..27c5920e4 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -23,24 +23,6 @@ if [ "${TRAVIS_MODE}" = "build" ]; then node -e 'require("./" + require("./package.json").main)' elif [ "${TRAVIS_MODE}" = "unitTests" ]; then npm run test:unit -elif [ "${TRAVIS_MODE}" = "funcTests" ]; then - npm run build:ci - n=0 - maxRetries=1 - until [ $n -ge ${maxRetries} ] - do - if [ $n -gt 0 ]; then - echo "Retrying... Attempt: $((n+1))" - delay=$((n*60)) - echo "Waiting ${delay} seconds..." - sleep $delay - fi - npm run test:func && break - n=$[$n+1] - done - if [ ${n} = ${maxRetries} ]; then - exit 1 - fi elif [ "${TRAVIS_MODE}" = "release" ] || [ "${TRAVIS_MODE}" = "releaseAlpha" ] || [ "${TRAVIS_MODE}" = "netlifyPr" ] || [ "${TRAVIS_MODE}" = "netlifyBranch" ]; then # update the version if [[ $(git rev-parse --is-shallow-repository) = "true" ]]; then diff --git a/tests/functional/auto/setup.js b/tests/functional/auto/setup.js index ecf0a286e..71d1e4ead 100644 --- a/tests/functional/auto/setup.js +++ b/tests/functional/auto/setup.js @@ -8,8 +8,7 @@ const until = webdriver.until; require('chromedriver'); const HttpServer = require('http-server'); const streams = require('../../test-streams'); -const onTravis = !!process.env.TRAVIS; -const useSauce = !!process.env.SAUCE || onTravis; +const useSauce = !!process.env.SAUCE || !!process.env.SAUCE_TUNNEL_ID; const chai = require('chai'); const expect = chai.expect; @@ -37,6 +36,10 @@ if (useSauce) { throw new Error('No test browser platform.'); } + if (!process.env.SAUCE_ACCESS_KEY || !process.env.SAUCE_USERNAME) { + throw new Error('Missing sauce auth.'); + } + const UA_VERSION = process.env.UA_VERSION; if (UA_VERSION) { browserConfig.version = UA_VERSION; @@ -280,7 +283,7 @@ async function sauceConnect (tunnelIdentifier) { console.log(`Running sauce-connect-launcher. Tunnel id: ${tunnelIdentifier}`); sauceConnectLauncher({ tunnelIdentifier - }, function (err, sauceConnectProcess) { + }, (err, sauceConnectProcess) => { if (err) { console.error(err.message); reject(err); @@ -331,14 +334,16 @@ describe(`testing hls.js playback in the browser on "${browserDescription}"`, fu } browser = new webdriver.Builder(); - if (onTravis) { - capabilities['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER; - capabilities.build = 'HLSJS-' + process.env.TRAVIS_BUILD_NUMBER; - } else if (useSauce) { - capabilities['tunnel-identifier'] = `local-${Date.now()}`; - } if (useSauce) { - sauceConnectProcess = await sauceConnect(capabilities['tunnel-identifier']); + if (process.env.SAUCE_TUNNEL_ID) { + capabilities['tunnel-identifier'] = process.env.SAUCE_TUNNEL_ID; + capabilities.build = 'HLSJS-' + process.env.SAUCE_TUNNEL_ID; + } else { + capabilities['tunnel-identifier'] = `local-${Date.now()}`; + } + if (!process.env.SAUCE_TUNNEL_ID) { + sauceConnectProcess = await sauceConnect(capabilities['tunnel-identifier']); + } capabilities.username = process.env.SAUCE_USERNAME; capabilities.accessKey = process.env.SAUCE_ACCESS_KEY; capabilities.avoidProxy = true; @@ -408,7 +413,7 @@ describe(`testing hls.js playback in the browser on "${browserDescription}"`, fu const failed = this.currentTest.isFailed(); if (printDebugLogs || failed) { const logString = await browser.executeScript('return logString'); - console.log(`${onTravis ? 'travis_fold:start:debug_logs' : ''}\n${logString}\n${onTravis ? 'travis_fold:end:debug_logs' : ''}`); + console.log(logString); if (failed && useSauce) { browser.executeScript('sauce:job-result=failed'); }