diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 99bea676bfb..e9360c73ab9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -85,9 +85,13 @@ apps/web/src/app/shared @bitwarden/team-platform-dev apps/web/src/translation-constants.ts @bitwarden/team-platform-dev # Workflows .github/workflows/brew-bump-desktop.yml @bitwarden/team-platform-dev +.github/workflows/build-browser-target.yml @bitwarden/team-platform-dev .github/workflows/build-browser.yml @bitwarden/team-platform-dev +.github/workflows/build-cli-target.yml @bitwarden/team-platform-dev .github/workflows/build-cli.yml @bitwarden/team-platform-dev +.github/workflows/build-desktop-target.yml @bitwarden/team-platform-dev .github/workflows/build-desktop.yml @bitwarden/team-platform-dev +.github/workflows/build-web-target.yml @bitwarden/team-platform-dev .github/workflows/build-web.yml @bitwarden/team-platform-dev .github/workflows/chromatic.yml @bitwarden/team-platform-dev .github/workflows/lint.yml @bitwarden/team-platform-dev diff --git a/.github/workflows/build-browser-target.yml b/.github/workflows/build-browser-target.yml new file mode 100644 index 00000000000..12a08cf50a3 --- /dev/null +++ b/.github/workflows/build-browser-target.yml @@ -0,0 +1,39 @@ +name: Build Browser on PR Target + +on: + pull_request_target: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/browser/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + workflow_call: + inputs: {} + workflow_dispatch: + inputs: + sdk_branch: + description: "Custom SDK branch" + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Browser on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-browser.yml + secrets: inherit + diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 7740e418e7b..56a980bf0f9 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -1,7 +1,7 @@ name: Build Browser on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -38,19 +38,14 @@ defaults: shell: bash jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: repo_url: ${{ steps.gen_vars.outputs.repo_url }} adj_build_number: ${{ steps.gen_vars.outputs.adj_build_number }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -74,6 +69,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + locales-test: name: Locales Test @@ -281,6 +284,7 @@ jobs: needs: - setup - locales-test + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: _BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }} _NODE_VERSION: ${{ needs.setup.outputs.node_version }} diff --git a/.github/workflows/build-cli-target.yml b/.github/workflows/build-cli-target.yml new file mode 100644 index 00000000000..89f8b63b525 --- /dev/null +++ b/.github/workflows/build-cli-target.yml @@ -0,0 +1,39 @@ +name: Build CLI on PR Target + +on: + pull_request_target: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/cli/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-cli.yml' + - 'bitwarden_license/bit-cli/**' + workflow_dispatch: + inputs: + sdk_branch: + description: "Custom SDK branch" + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build CLI on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-cli.yml + secrets: inherit + diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index d480879fb15..35970a8b307 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -1,7 +1,7 @@ name: Build CLI on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -27,6 +27,8 @@ on: - '!*.txt' - '.github/workflows/build-cli.yml' - 'bitwarden_license/bit-cli/**' + workflow_call: + inputs: {} workflow_dispatch: inputs: sdk_branch: @@ -39,18 +41,13 @@ defaults: working-directory: apps/cli jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: package_version: ${{ steps.retrieve-package-version.outputs.package_version }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -71,6 +68,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + cli: name: CLI ${{ matrix.os.base }} - ${{ matrix.license_type.readable }} strategy: @@ -117,7 +122,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -130,7 +135,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -272,7 +277,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -285,7 +290,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ diff --git a/.github/workflows/build-desktop-target.yml b/.github/workflows/build-desktop-target.yml new file mode 100644 index 00000000000..b9ea9cacb8d --- /dev/null +++ b/.github/workflows/build-desktop-target.yml @@ -0,0 +1,38 @@ +name: Build Desktop on PR Target + +on: + pull_request_target: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/desktop/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-desktop.yml' + workflow_dispatch: + inputs: + sdk_branch: + description: "Custom SDK branch" + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Desktop on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-desktop.yml + secrets: inherit + diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index bc9bdec396a..e35dee54e08 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -1,7 +1,7 @@ name: Build Desktop on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -25,6 +25,8 @@ on: - '!*.md' - '!*.txt' - '.github/workflows/build-desktop.yml' + workflow_call: + inputs: {} workflow_dispatch: inputs: sdk_branch: @@ -37,15 +39,9 @@ defaults: shell: bash jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - electron-verify: name: Verify Electron Version runs-on: ubuntu-22.04 - needs: - - check-run steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -67,8 +63,6 @@ jobs: setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: package_version: ${{ steps.retrieve-version.outputs.package_version }} release_channel: ${{ steps.release-channel.outputs.channel }} @@ -76,6 +70,7 @@ jobs: rc_branch_exists: ${{ steps.branch-check.outputs.rc_branch_exists }} hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} defaults: run: working-directory: apps/desktop @@ -138,6 +133,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + linux: name: Linux Build # Note, before updating the ubuntu version of the workflow, ensure the snap base image @@ -333,12 +336,14 @@ jobs: rustup show - name: Login to Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" @@ -353,7 +358,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -366,7 +371,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -386,7 +391,17 @@ jobs: working-directory: apps/desktop/desktop_native run: node build.js cross-platform - - name: Build & Sign (dev) + - name: Build + run: | + npm run build + + - name: Pack + if: ${{ needs.setup.outputs.has_secrets == 'false' }} + run: | + npm run pack:win + + - name: Pack & Sign (dev) + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: ELECTRON_BUILDER_SIGN: 1 SIGNING_VAULT_URL: ${{ steps.retrieve-secrets.outputs.code-signing-vault-url }} @@ -395,10 +410,10 @@ jobs: SIGNING_CLIENT_SECRET: ${{ steps.retrieve-secrets.outputs.code-signing-client-secret }} SIGNING_CERT_NAME: ${{ steps.retrieve-secrets.outputs.code-signing-cert-name }} run: | - npm run build npm run pack:win - name: Rename appx files for store + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Copy-Item "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx" ` -Destination "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx" @@ -408,6 +423,7 @@ jobs: -Destination "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx" - name: Package for Chocolatey + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Copy-Item -Path ./stores/chocolatey -Destination ./dist/chocolatey -Recurse Copy-Item -Path ./dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe ` @@ -419,6 +435,7 @@ jobs: choco pack ./dist/chocolatey/bitwarden.nuspec --version "$env:_PACKAGE_VERSION" --out ./dist/chocolatey - name: Fix NSIS artifact names for auto-updater + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Rename-Item -Path .\dist\nsis-web\Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z ` -NewName bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z @@ -435,6 +452,7 @@ jobs: if-no-files-found: error - name: Upload installer exe artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe @@ -442,6 +460,7 @@ jobs: if-no-files-found: error - name: Upload appx ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx @@ -449,6 +468,7 @@ jobs: if-no-files-found: error - name: Upload store appx ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx @@ -456,6 +476,7 @@ jobs: if-no-files-found: error - name: Upload NSIS ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z @@ -463,6 +484,7 @@ jobs: if-no-files-found: error - name: Upload appx x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx @@ -470,6 +492,7 @@ jobs: if-no-files-found: error - name: Upload store appx x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx @@ -477,6 +500,7 @@ jobs: if-no-files-found: error - name: Upload NSIS x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z @@ -484,6 +508,7 @@ jobs: if-no-files-found: error - name: Upload appx ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx @@ -491,6 +516,7 @@ jobs: if-no-files-found: error - name: Upload store appx ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx @@ -498,6 +524,7 @@ jobs: if-no-files-found: error - name: Upload NSIS ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z @@ -505,6 +532,7 @@ jobs: if-no-files-found: error - name: Upload nupkg artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg @@ -512,6 +540,7 @@ jobs: if-no-files-found: error - name: Upload auto-update artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: ${{ needs.setup.outputs.release_channel }}.yml @@ -574,11 +603,13 @@ jobs: key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - name: Login to Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Download Provisioning Profiles secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: ACCOUNT_NAME: bitwardenci CONTAINER_NAME: profiles @@ -591,6 +622,7 @@ jobs: --output none - name: Get certificates + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | mkdir -p $HOME/certificates @@ -613,6 +645,7 @@ jobs: jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | @@ -642,6 +675,7 @@ jobs: security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | cp $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ $GITHUB_WORKSPACE/apps/desktop/bitwarden_desktop_appstore.provisionprofile @@ -661,7 +695,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -674,7 +708,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -701,6 +735,7 @@ jobs: browser-build: name: Browser Build needs: setup + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: ./.github/workflows/build-browser.yml secrets: inherit @@ -708,6 +743,7 @@ jobs: macos-package-github: name: MacOS Package GitHub Release Assets runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build @@ -949,6 +985,7 @@ jobs: macos-package-mas: name: MacOS Package Prod Release Asset runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build @@ -1216,6 +1253,7 @@ jobs: macos-package-dev: name: MacOS Package Dev Release Asset runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build diff --git a/.github/workflows/build-web-target.yml b/.github/workflows/build-web-target.yml new file mode 100644 index 00000000000..9a9cd735435 --- /dev/null +++ b/.github/workflows/build-web-target.yml @@ -0,0 +1,41 @@ +name: Build Web on PR Target + +on: + pull_request_target: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/web/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-web.yml' + workflow_dispatch: + inputs: + custom_tag_extension: + description: "Custom image tag extension" + required: false + sdk_branch: + description: "Custom SDK branch" + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Web on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-web.yml + secrets: inherit + diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 6e5e11c3361..2360f876826 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -1,7 +1,7 @@ name: Build Web on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -27,6 +27,8 @@ on: - '.github/workflows/build-web.yml' release: types: [published] + workflow_call: + inputs: {} workflow_dispatch: inputs: custom_tag_extension: @@ -41,18 +43,13 @@ env: _AZ_REGISTRY: bitwardenprod.azurecr.io jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: version: ${{ steps.version.outputs.value }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -70,6 +67,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + build-artifacts: name: Build artifacts runs-on: ubuntu-22.04 @@ -128,7 +133,7 @@ jobs: run: npm ci - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -141,7 +146,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -210,19 +215,23 @@ jobs: ########## ACRs ########## - name: Login to Prod Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - name: Log into Prod container registry + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: az acr login -n bitwardenprod - name: Login to Azure - CI Subscription + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve github PAT secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} id: retrieve-secret-pat uses: bitwarden/gh-actions/get-keyvault-secrets@main with: @@ -270,6 +279,7 @@ jobs: run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - name: Build Docker image + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 with: context: apps/web diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9dc72c7fdda..1b738bd7bcf 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,12 +1,20 @@ name: Lint on: - push: + pull_request: + types: [opened, synchronize] branches-ignore: - 'l10n_master' - 'cf-pages' paths-ignore: - '.github/workflows/**' + push: + branches: + - 'main' + - 'rc' + - 'hotfix-rc-*' + paths-ignore: + - '.github/workflows/**' workflow_dispatch: inputs: {} diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs index a74c1205b57..ae03421a425 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs @@ -65,7 +65,9 @@ impl BitwardenDesktopAgent { "[SSH Agent Native Module] Could not remove existing socket file: {}", e ); - return; + if e.kind() != std::io::ErrorKind::NotFound { + return; + } } match UnixListener::bind(sockname) { diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 38f11a97a8b..898ad086b29 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -20,7 +20,7 @@ "**/node_modules/@bitwarden/desktop-napi/index.js", "**/node_modules/@bitwarden/desktop-napi/desktop_napi.${platform}-${arch}*.node" ], - "electronVersion": "32.1.1", + "electronVersion": "33.2.1", "generateUpdatesFilesForAllChannels": true, "publish": { "provider": "generic", diff --git a/apps/desktop/package.json b/apps/desktop/package.json index f546563ed18..101e968ad6d 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.12.0", + "version": "2024.12.1", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 641af8db0ad..52a8615a1da 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -64,9 +64,8 @@ export class TrayMain { } setupWindowListeners(win: BrowserWindow) { - win.on("minimize", async (e: Event) => { + win.on("minimize", async () => { if (await firstValueFrom(this.desktopSettingsService.minimizeToTray$)) { - e.preventDefault(); // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.hideToTray(); diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 0300b0b93cc..201f563db2d 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.12.0", + "version": "2024.12.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.12.0", + "version": "2024.12.1", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native/napi" diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 9a3c56cf17c..29ee5dc47ef 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.12.0", + "version": "2024.12.1", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts b/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts index 59b68ceef83..b40902112c8 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts @@ -12,7 +12,6 @@ import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { DialogService, ToastService } from "@bitwarden/components"; @Component({ @@ -35,7 +34,6 @@ export class SponsoringOrgRowComponent implements OnInit { private apiService: ApiService, private i18nService: I18nService, private logService: LogService, - private platformUtilsService: PlatformUtilsService, private dialogService: DialogService, private toastService: ToastService, private configService: ConfigService, @@ -87,14 +85,21 @@ export class SponsoringOrgRowComponent implements OnInit { }); } - get isSentAwaitingSync() { - return this.isSelfHosted && !this.sponsoringOrg.familySponsorshipLastSyncDate; - } - private async doRevokeSponsorship() { + const content = this.sponsoringOrg.familySponsorshipValidUntil + ? this.i18nService.t( + "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship", + this.sponsoringOrg.familySponsorshipFriendlyName, + formatDate(this.sponsoringOrg.familySponsorshipValidUntil, "MM/dd/yyyy", this.locale), + ) + : this.i18nService.t( + "updatedRevokeSponsorshipConfirmationForSentSponsorship", + this.sponsoringOrg.familySponsorshipFriendlyName, + ); + const confirmed = await this.dialogService.openSimpleDialog({ - title: `${this.i18nService.t("remove")} ${this.sponsoringOrg.familySponsorshipFriendlyName}?`, - content: { key: "revokeSponsorshipConfirmation" }, + title: `${this.i18nService.t("removeSponsorship")}?`, + content, acceptButtonText: { key: "remove" }, type: "warning", }); diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index b1203230688..aca22376132 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -6156,9 +6156,6 @@ "emailSent": { "message": "Email sent" }, - "revokeSponsorshipConfirmation": { - "message": "After removing this account, the Families plan sponsorship will expire at the end of the billing period. You will not be able to redeem a new sponsorship offer until the existing one expires. Are you sure you want to continue?" - }, "removeSponsorshipSuccess": { "message": "Sponsorship removed" }, @@ -9959,5 +9956,27 @@ "example": "bitwarden.com" } } + }, + "updatedRevokeSponsorshipConfirmationForSentSponsorship": { + "message": "If you remove $EMAIL$, the sponsorship for this Family plan cannot be redeemed. Are you sure you want to continue?", + "placeholders": { + "email": { + "content": "$1", + "example": "sponsored@organization.com" + } + } + }, + "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship": { + "message": "If you remove $EMAIL$, the sponsorship for this Family plan will end and the saved payment method will be charged $40 + applicable tax on $DATE$. You will not be able to redeem a new sponsorship until $DATE$. Are you sure you want to continue?", + "placeholders": { + "email": { + "content": "$1", + "example": "sponsored@organization.com" + }, + "date": { + "content": "$2", + "example": "12/10/2024" + } + } } } diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/vnext-clients.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/vnext-clients.component.ts index ba56ce872b2..2be38477d4c 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/vnext-clients.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/vnext-clients.component.ts @@ -53,8 +53,8 @@ const DisallowedPlanTypes = [ ], }) export class vNextClientsComponent { - providerId: string; - addableOrganizations: Organization[]; + providerId: string = ""; + addableOrganizations: Organization[] = []; loading = true; manageOrganizations = false; showAddExisting = false; @@ -79,8 +79,8 @@ export class vNextClientsComponent { this.searchControl.setValue(queryParams.search); }); - this.activatedRoute.parent.params - .pipe( + this.activatedRoute.parent?.params + ?.pipe( switchMap((params) => { this.providerId = params.providerId; return this.providerService.get$(this.providerId).pipe( @@ -125,7 +125,7 @@ export class vNextClientsComponent { await this.webProviderService.detachOrganization(this.providerId, organization.id); this.toastService.showToast({ variant: "success", - title: null, + title: "", message: this.i18nService.t("detachedOrganization", organization.organizationName), }); await this.load(); diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/vnext-manage-clients.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/vnext-manage-clients.component.ts index 5ee7817f34e..4c0837d6da2 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/vnext-manage-clients.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/vnext-manage-clients.component.ts @@ -51,15 +51,15 @@ import { vNextNoClientsComponent } from "./vnext-no-clients.component"; ], }) export class vNextManageClientsComponent { - providerId: string; - provider: Provider; + providerId: string = ""; + provider: Provider | undefined; loading = true; isProviderAdmin = false; dataSource: TableDataSource = new TableDataSource(); protected searchControl = new FormControl("", { nonNullable: true }); - protected plans: PlanResponse[]; + protected plans: PlanResponse[] = []; constructor( private billingApiService: BillingApiServiceAbstraction, @@ -76,8 +76,8 @@ export class vNextManageClientsComponent { this.searchControl.setValue(queryParams.search); }); - this.activatedRoute.parent.params - .pipe( + this.activatedRoute.parent?.params + ?.pipe( switchMap((params) => { this.providerId = params.providerId; return this.providerService.get$(this.providerId).pipe( @@ -110,12 +110,12 @@ export class vNextManageClientsComponent { async load() { this.provider = await firstValueFrom(this.providerService.get$(this.providerId)); - this.isProviderAdmin = this.provider.type === ProviderUserType.ProviderAdmin; + this.isProviderAdmin = this.provider?.type === ProviderUserType.ProviderAdmin; const clients = (await this.billingApiService.getProviderClientOrganizations(this.providerId)) .data; - clients.forEach((client) => (client.plan = client.plan.replace(" (Monthly)", ""))); + clients.forEach((client) => (client.plan = client.plan?.replace(" (Monthly)", ""))); this.dataSource.data = clients; @@ -146,7 +146,7 @@ export class vNextManageClientsComponent { organization: { id: organization.id, name: organization.organizationName, - seats: organization.seats, + seats: organization.seats ? organization.seats : 0, }, }, }); @@ -164,7 +164,7 @@ export class vNextManageClientsComponent { const dialogRef = openManageClientSubscriptionDialog(this.dialogService, { data: { organization, - provider: this.provider, + provider: this.provider!, }, }); @@ -190,7 +190,7 @@ export class vNextManageClientsComponent { await this.webProviderService.detachOrganization(this.providerId, organization.id); this.toastService.showToast({ variant: "success", - title: null, + title: "", message: this.i18nService.t("detachedOrganization", organization.organizationName), }); await this.load(); diff --git a/package-lock.json b/package-lock.json index 64a7c926ca2..ff7dac2c461 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,7 +132,7 @@ "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", "css-loader": "7.1.2", - "electron": "32.1.1", + "electron": "33.2.1", "electron-builder": "24.13.3", "electron-log": "5.2.4", "electron-reload": "2.0.0-alpha.1", @@ -230,7 +230,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.12.0", + "version": "2024.12.1", "hasInstallScript": true, "license": "GPL-3.0" }, @@ -15745,9 +15745,9 @@ } }, "node_modules/electron": { - "version": "32.1.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-32.1.1.tgz", - "integrity": "sha512-NlWvG6kXOJbZbELmzP3oV7u50I3NHYbCeh+AkUQ9vGyP7b74cFMx9HdTzejODeztW1jhr3SjIBbUZzZ45zflfQ==", + "version": "33.2.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-33.2.1.tgz", + "integrity": "sha512-SG/nmSsK9Qg1p6wAW+ZfqU+AV8cmXMTIklUL18NnOKfZLlum4ZsDoVdmmmlL39ZmeCaq27dr7CgslRPahfoVJg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -15986,9 +15986,9 @@ } }, "node_modules/electron/node_modules/@types/node": { - "version": "20.17.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", - "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", + "version": "20.17.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.8.tgz", + "integrity": "sha512-ahz2g6/oqbKalW9sPv6L2iRbhLnojxjYWspAqhjvqSWBgGebEJT5GvRmk0QXPj3sbC6rU0GTQjPLQkmR8CObvA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 5573332db1a..aa567f18df6 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", "css-loader": "7.1.2", - "electron": "32.1.1", + "electron": "33.2.1", "electron-builder": "24.13.3", "electron-log": "5.2.4", "electron-reload": "2.0.0-alpha.1",