| name: Build and release packages |
| |
| permissions: |
| contents: write |
| |
| on: |
| push: |
| pull_request: |
| workflow_dispatch: |
| |
| env: |
| ZAP_TEST_TIMEOUT: 3600000 |
| ZAP_TEMPSTATE: 1 |
| BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} |
| P12_PASSWORD: ${{ secrets.P12_PASSWORD }} |
| TRUSTED_CERTIFICATE_BASE64: ${{ secrets.TRUSTED_CERTIFICATE_BASE64 }} |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| KEYCHAIN_PASSWORD: silabs |
| |
| jobs: |
| cypress-zigbee: |
| name: Cypress UI tests with Zigbee data |
| runs-on: ${{ matrix.os }} |
| strategy: |
| matrix: |
| node-version: [20.x] |
| os: [ubuntu-22.04] |
| |
| steps: |
| - uses: actions/checkout@v4 |
| - name: Use Node.js ${{ matrix.node-version }} |
| uses: actions/setup-node@v4 |
| with: |
| node-version: ${{ matrix.node-version }} |
| cache: 'npm' |
| - uses: browser-actions/setup-chrome@v1 |
| with: |
| chrome-version: 1160321 |
| id: chrome-116 |
| - run: echo ${{steps.chrome-116.outputs.chrome-path }} |
| - run: sudo ./src-script/install-packages-ubuntu |
| - run: sudo apt-get install --fix-missing xvfb |
| - run: npm ci |
| - run: npm run version-stamp |
| - run: npm rebuild canvas --update-binary |
| - run: npm rebuild libxmljs --update-binary |
| - run: npm run build-spa |
| - run: npm run test:e2e-ci -- ${{steps.chrome-116.outputs.chrome-path }} |
| |
| cypress-matter: |
| name: Cypress UI tests with Matter data |
| runs-on: ${{ matrix.os }} |
| strategy: |
| matrix: |
| node-version: [20.x] |
| os: [ubuntu-22.04] |
| |
| steps: |
| - uses: actions/checkout@v4 |
| - name: Use Node.js ${{ matrix.node-version }} |
| uses: actions/setup-node@v4 |
| with: |
| node-version: ${{ matrix.node-version }} |
| cache: 'npm' |
| - uses: browser-actions/setup-chrome@v1 |
| with: |
| chrome-version: 1160321 |
| id: chrome-116 |
| - run: sudo ./src-script/install-packages-ubuntu |
| - run: sudo apt-get install --fix-missing xvfb |
| - run: npm ci |
| - run: npm run version-stamp |
| - run: npm rebuild canvas --update-binary |
| - run: npm rebuild libxmljs --update-binary |
| - run: npm run build-spa |
| - run: npm run test:e2e-matter-ci -- ${{steps.chrome-116.outputs.chrome-path }} |
| |
| generate-and-backend-tests: |
| name: Generation and back-end tests |
| runs-on: ${{ matrix.os }} |
| |
| strategy: |
| matrix: |
| node-version: [20.x] |
| os: [ubuntu-22.04] |
| |
| steps: |
| - uses: actions/checkout@v4 |
| - name: Use Node.js ${{ matrix.node-version }} |
| uses: actions/setup-node@v4 |
| with: |
| node-version: ${{ matrix.node-version }} |
| cache: 'npm' |
| - run: sudo ./src-script/install-packages-ubuntu |
| - run: sudo apt-get install --fix-missing libxml2-utils |
| - run: node --version |
| - run: npm --version |
| - run: npm ci |
| - run: npm run metafile-check |
| - run: npm run version-stamp |
| - run: npm rebuild canvas --update-binary |
| - run: npm rebuild libxmljs --update-binary |
| - run: npm run lic |
| - run: npm run build-spa |
| - run: npm run lint |
| - run: npm run xml-validate |
| - run: npm run self-check |
| - run: npm run test:unit |
| - name: Upload code coverage artifacts |
| uses: actions/upload-artifact@v4 |
| with: |
| name: jest-coverage |
| path: jest-coverage/coverage-final.json |
| - run: npm run test:gen |
| |
| code-coverage: |
| name: Code coverage |
| needs: [cypress-zigbee, cypress-matter, generate-and-backend-tests] |
| runs-on: ${{ matrix.os }} |
| |
| strategy: |
| matrix: |
| node-version: [20.x] |
| os: [ubuntu-22.04] |
| |
| steps: |
| - uses: actions/checkout@v4 |
| - name: Use Node.js ${{ matrix.node-version }} |
| uses: actions/setup-node@v4 |
| with: |
| node-version: ${{ matrix.node-version }} |
| cache: 'npm' |
| - name: Download jest coverage artifact |
| uses: actions/download-artifact@v4 |
| with: |
| name: jest-coverage |
| - run: sudo ./src-script/install-packages-ubuntu |
| - run: npm ci |
| - run: npm run report |
| - name: Codecov |
| uses: codecov/codecov-action@v3.1.1 |
| |
| build-zap: |
| name: Build ZAP |
| needs: [cypress-zigbee, cypress-matter, generate-and-backend-tests] |
| runs-on: ${{ matrix.os }} |
| |
| # Platforms to build on/for |
| strategy: |
| matrix: |
| os: [macos-14, ubuntu-22.04] |
| fail-fast: false |
| |
| steps: |
| - name: Check out Git repository |
| uses: actions/checkout@v4 |
| |
| - name: Install Node.js, NPM and Yarn |
| uses: actions/setup-node@v4 |
| with: |
| node-version: 20.x |
| cache: 'npm' |
| - name: pip |
| run: pip install setuptools |
| |
| - name: Prepare Linux build environment |
| if: startsWith(matrix.os, 'ubuntu') |
| run: | |
| sudo ./src-script/install-packages-ubuntu |
| |
| - name: Prepare macOS build environment |
| if: startsWith(matrix.os, 'macos') |
| run: ./src-script/install-packages-osx |
| |
| - name: Prepare macOS certificate |
| if: startsWith(matrix.os, 'macos') |
| run: | |
| # create variables |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db |
| |
| if [ -n "$P12_PASSWORD" ]; then |
| # import certificate and provisioning profile from secrets |
| echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output ${RUNNER_TEMP}/build_certificate.p12 |
| echo -n "$TRUSTED_CERTIFICATE_BASE64" | base64 --decode --output ${RUNNER_TEMP}/trusted_certificate.cer |
| |
| # create temporary keychain |
| security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH |
| security set-keychain-settings -lut 21600 $KEYCHAIN_PATH |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH |
| |
| # import certificate to keychain |
| security import ${RUNNER_TEMP}/trusted_certificate.cer -P "$P12_PASSWORD" -k $KEYCHAIN_PATH -A |
| security import ${RUNNER_TEMP}/build_certificate.p12 -P "$P12_PASSWORD" -k $KEYCHAIN_PATH -A |
| |
| security find-identity -v |
| security list-keychain -d user -s $KEYCHAIN_PATH |
| fi |
| |
| - name: Initialize... |
| run: | |
| npm rebuild canvas --update-binary |
| npm rebuild libxmljs --update-binary |
| npm ci |
| npm run version-stamp |
| |
| - name: Building frontend / backend |
| run: | |
| npm run build |
| |
| - name: Build & Release for Windows / Mac universal binary on macOS |
| if: startsWith(matrix.os, 'macos') |
| run: | |
| node src-script/build-release-package.js --platform w |
| |
| node src-script/build-release-package.js --platform m |
| |
| env: |
| GH_TOKEN: ${{ secrets.github_token }} |
| |
| # macOS notarization API key |
| # CSC_LINK: ${{ secrets.api_key_id }} |
| # CSC_KEY_PASSWORD: ${{ secrets.api_key_issuer_id }} |
| |
| - name: Build & Release for Linux |
| if: startsWith(matrix.os, 'ubuntu') |
| run: | |
| node src-script/build-release-package.js --platform l |
| |
| mv dist/zap-linux-amd64.deb dist/zap-linux-x64.deb |
| mv dist/zap-linux-x86_64.rpm dist/zap-linux-x64.rpm |
| |
| env: |
| GH_TOKEN: ${{ secrets.github_token }} |
| |
| # macOS notarization API key |
| # CSC_LINK: ${{ secrets.api_key_id }} |
| # CSC_KEY_PASSWORD: ${{ secrets.api_key_issuer_id }} |
| |
| - name: Verify zap-cli exists in Linux x64 .zip package |
| if: startsWith(matrix.os, 'ubuntu') |
| run: | |
| output=$(./node_modules/7zip-bin/linux/x64/7za l ./dist/zap-linux-x64.zip) |
| expression=zap-cli |
| if [[ $output == *"$expression"* ]]; then |
| echo "Output contains $expression" |
| else |
| echo "Output does not contain $expression" |
| exit 1 |
| fi |
| - name: Verify zap-cli exists in Linux arm64 .zip package |
| if: startsWith(matrix.os, 'ubuntu') |
| run: | |
| output=$(./node_modules/7zip-bin/linux/x64/7za l ./dist/zap-linux-arm64.zip) |
| expression=zap-cli |
| if [[ $output == *"$expression"* ]]; then |
| echo "Output contains $expression" |
| else |
| echo "Output does not contain $expression" |
| exit 1 |
| fi |
| - name: Verify zap-cli exists in Windows x64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| run: | |
| output=$(7za l ./dist/zap-win-x64.zip) |
| expression=zap-cli |
| if [[ $output == *"$expression"* ]]; then |
| echo "Output contains $expression" |
| else |
| echo "Output does not contain $expression" |
| exit 1 |
| fi |
| - name: Verify zap-cli exists in Windows arm64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| run: | |
| output=$(7za l ./dist/zap-win-arm64.zip) |
| expression=zap-cli |
| if [[ $output == *"$expression"* ]]; then |
| echo "Output contains $expression" |
| else |
| echo "Output does not contain $expression" |
| exit 1 |
| fi |
| - name: Verify zap-cli exists in macOS x64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| run: | |
| output=$(7za l ./dist/zap-mac-x64.zip | grep zap-cli) |
| expression=zap-cli |
| if [[ $output == *"$expression"* ]]; then |
| echo "Output contains $expression" |
| else |
| echo "Output does not contain $expression" |
| exit 1 |
| fi |
| |
| - name: ZAP binary check (macOS x64) - unzip |
| if: startsWith(matrix.os, 'macos') |
| run: unzip dist/zap-mac-x64.zip -d dist/zap-mac |
| - name: ZAP binary check (macOS x64) - check version is set |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: ./dist/zap-mac/zap.app/Contents/MacOS/zap --version |
| contains: '0.0.0' |
| expected_result: FAILED |
| - name: ZAP binary check (macOS x64) - check version is set via CLI |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: ./dist/zap-mac/zap-cli --version |
| contains: '0.0.0' |
| expected_result: FAILED |
| - name: ZAP binary check (macOS x64) - unzip cleanup |
| if: startsWith(matrix.os, 'macos') |
| run: rm -rf dist/zap-mac |
| |
| - name: ZAP binary check (Linux) - unzip |
| if: startsWith(matrix.os, 'ubuntu') |
| run: unzip dist/zap-linux-x64.zip -d dist/zap-linux |
| - name: ZAP binary check (Linux) - check version is set |
| if: startsWith(matrix.os, 'ubuntu') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: ./dist/zap-linux/zap --version |
| contains: '0.0.0' |
| expected_result: FAILED |
| - name: ZAP binary check (Linux) - check version is set via CLI |
| if: startsWith(matrix.os, 'ubuntu') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: ./dist/zap-linux/zap-cli --version |
| contains: '0.0.0' |
| expected_result: FAILED |
| - name: ZAP binary check (Linux) - unzip cleanup |
| if: startsWith(matrix.os, 'ubuntu') |
| run: rm -rf dist/zap-linux |
| - name: Verify apack.json exists in package's base directory |
| if: startsWith(matrix.os, 'ubuntu') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: ./node_modules/7zip-bin/linux/x64/7za l ./dist/zap-linux-x64.zip | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in package's app.asar archive |
| if: startsWith(matrix.os, 'ubuntu') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: npx asar l ./dist/linux-unpacked/resources/app.asar | grep apack.json |
| contains: 'apack.json' |
| |
| - name: Verify apack.json exists in Windows x64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: 7za l ./dist/zap-win-x64.zip | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in Windows x64 .zip package's app.asar archive |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: npx asar l ./dist/win-unpacked/resources/app.asar | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in Windows arm64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: 7za l ./dist/zap-win-arm64.zip | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in Windows arm64 .zip package's app.asar archive |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: npx asar l ./dist/win-arm64-unpacked/resources/app.asar | grep apack.json |
| contains: 'apack.json' |
| |
| - name: Verify apack.json exists in macOS x64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: 7za l ./dist/zap-mac-x64.zip | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in macOS x64 .zip package's app-x64.asar archive |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: npx asar l ./dist/mac/zap.app/Contents/Resources/app-x64.asar | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in macOS arm64 .zip package |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: 7za l ./dist/zap-mac-arm64.zip | grep apack.json |
| contains: 'apack.json' |
| - name: Verify apack.json exists in macOS arm64 .zip package's app-arm64.asar archive |
| if: startsWith(matrix.os, 'macos') |
| uses: GuillaumeFalourd/assert-command-line-output@v2.1 |
| with: |
| command_line: npx asar l ./dist/mac-arm64/zap.app/Contents/Resources/app-arm64.asar | grep apack.json |
| contains: 'apack.json' |
| |
| - name: Archive Windows (x64) .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'macos') |
| with: |
| name: zap-win-x64-zip |
| path: dist/zap-win-x64.zip |
| - name: Archive Windows (arm64) .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'macos') |
| with: |
| name: zap-win-arm64-zip |
| path: dist/zap-win-arm64.zip |
| - name: Archive macOS x64 .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'macos') |
| with: |
| name: zap-mac-x64-zip |
| path: dist/zap-mac-x64.zip |
| - name: Archive macOS arm64 .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'macos') |
| with: |
| name: zap-mac-arm64-zip |
| path: dist/zap-mac-arm64.zip |
| - name: Archive Linux (x64) .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'ubuntu') |
| with: |
| name: zap-linux-x64-zip |
| path: dist/zap-linux-x64.zip |
| - name: Archive Linux (arm64) .zip file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'ubuntu') |
| with: |
| name: zap-linux-arm64-zip |
| path: dist/zap-linux-arm64.zip |
| - name: Archive Linux .rpm file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'ubuntu') |
| with: |
| name: zap-linux-x64-rpm |
| path: dist/zap-linux-x64.rpm |
| - name: Archive Linux x64 .deb file |
| uses: actions/upload-artifact@v4 |
| if: startsWith(matrix.os, 'ubuntu') |
| with: |
| name: zap-linux-x64-deb |
| path: dist/zap-linux-x64.deb |
| |
| release: |
| if: startsWith(github.ref, 'refs/tags/') |
| needs: [build-zap] |
| name: Create Github Release |
| runs-on: ubuntu-22.04 |
| steps: |
| - uses: actions/download-artifact@v4 |
| - name: List downloaded files |
| run: ls -R |
| - name: Creating Github Release |
| uses: ncipollo/release-action@v1 |
| with: |
| generateReleaseNotes: true |
| prerelease: ${{ endsWith(github.ref, 'nightly') }} |
| artifacts: 'zap-linux-x64-deb/zap-linux-x64.deb, zap-linux-x64-rpm/zap-linux-x64.rpm, zap-linux-x64-zip/zap-linux-x64.zip, zap-linux-arm64-zip/zap-linux-arm64.zip, zap-mac-x64-zip/zap-mac-x64.zip, zap-mac-arm64-zip/zap-mac-arm64.zip, zap-win-x64-zip/zap-win-x64.zip, zap-win-arm64-zip/zap-win-arm64.zip' |