diff --git a/.checkmarx/config.yml b/.checkmarx/config.yml new file mode 100644 index 0000000000..e45e83fcac --- /dev/null +++ b/.checkmarx/config.yml @@ -0,0 +1,12 @@ +version: 1 + +# Checkmarx configuration file +# +# https://checkmarx.com/resource/documents/en/34965-68549-configuring-projects-using-config-as-code-files.html +checkmarx: + scan: + configs: + sast: + presetName: "BW ASA Premium" + # Exclude spec files, and test specific files + filter: "!*.spec.ts,!**/spec/**,!apps/desktop/native-messaging-test-runner/**" diff --git a/.codescene/code-health-rules.json b/.codescene/code-health-rules.json new file mode 100644 index 0000000000..bafdb1188e --- /dev/null +++ b/.codescene/code-health-rules.json @@ -0,0 +1,14 @@ +{ + "usage": "Documentation: https://codescene.io/docs/guides/technical/code-health.html. Template: https://codescene.io/projects/26215/config/codehealth/export/code-health-rules.json", + "rule_sets": [ + { + "matching_content_path": "**/*.spec.ts", + "rules": [ + { + "name": "Code Duplication", + "weight": 0.0 + } + ] + } + ] +} diff --git a/.eslintignore b/.eslintignore index e1fbda3813..68d426174a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -12,14 +12,12 @@ storybook-static apps/browser/config/config.js apps/browser/src/auth/scripts/duo.js -apps/browser/src/autofill/content/autofill.js apps/desktop/desktop_native apps/desktop/src/auth/scripts/duo.js apps/web/config.js apps/web/scripts/*.js -apps/web/src/theme.js apps/web/tailwind.config.js apps/cli/config/config.js diff --git a/.eslintrc.json b/.eslintrc.json index afa134a65e..671e7b2fab 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -20,7 +20,8 @@ "plugin:import/recommended", "plugin:import/typescript", "prettier", - "plugin:rxjs/recommended" + "plugin:rxjs/recommended", + "plugin:storybook/recommended" ], "settings": { "import/parsers": { @@ -33,20 +34,15 @@ } }, "rules": { - "@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled - "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], "@typescript-eslint/explicit-member-accessibility": [ "error", - { - "accessibility": "no-public" - } - ], - "@typescript-eslint/no-this-alias": [ - "error", - { - "allowedNames": ["self"] - } + { "accessibility": "no-public" } ], + "@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-misused-promises": ["error", { "checksVoidReturn": false }], + "@typescript-eslint/no-this-alias": ["error", { "allowedNames": ["self"] }], + "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], "no-console": "error", "import/no-unresolved": "off", // TODO: Look into turning off once each package is an actual package. "import/order": [ @@ -71,7 +67,7 @@ "pathGroupsExcludedImportTypes": ["builtin"] } ], - "rxjs-angular/prefer-takeuntil": "error", + "rxjs-angular/prefer-takeuntil": ["error", { "alias": ["takeUntilDestroyed"] }], "rxjs/no-exposed-subjects": ["error", { "allowProtected": true }], "no-restricted-syntax": [ "error", @@ -103,16 +99,26 @@ // Import/export "./libs/importer/**/*", - "./libs/exporter/**/*" + "./libs/tools/export/vault-export/vault-export-core/**/*" ] + }, + { + // avoid import of unexported state objects + "target": [ + "!(libs)/**/*", + "libs/!(common)/**/*", + "libs/common/!(src)/**/*", + "libs/common/src/!(platform)/**/*", + "libs/common/src/platform/!(state)/**/*" + ], + "from": ["./libs/common/src/platform/state/**/*"], + // allow module index import + "except": ["**/state/index.ts"] } ] } ], - "no-restricted-imports": [ - "error", - { "patterns": ["src/**/*"], "paths": ["@fluffy-spoon/substitute"] } - ] + "no-restricted-imports": ["error", { "patterns": ["src/**/*"] }] } }, { @@ -134,6 +140,15 @@ "tailwindcss/no-contradicting-classname": "error" } }, + { + "files": ["libs/admin-console/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { "patterns": ["@bitwarden/admin-console/*", "src/**/*"] } + ] + } + }, { "files": ["libs/angular/src/**/*.ts"], "rules": { @@ -146,6 +161,12 @@ "no-restricted-imports": ["error", { "patterns": ["@bitwarden/auth/*", "src/**/*"] }] } }, + { + "files": ["libs/billing/src/**/*.ts"], + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@bitwarden/billing/*", "src/**/*"] }] + } + }, { "files": ["libs/common/src/**/*.ts"], "rules": { @@ -155,13 +176,28 @@ { "files": ["libs/components/src/**/*.ts"], "rules": { - "no-restricted-imports": ["error", { "patterns": ["@bitwarden/components/*", "src/**/*"] }] + "no-restricted-imports": [ + "error", + { "patterns": ["@bitwarden/components/*", "src/**/*", "@bitwarden/angular/*"] } + ] } }, { - "files": ["libs/exporter/src/**/*.ts"], + "files": ["libs/tools/export/vault-export/vault-export-core/src/**/*.ts"], "rules": { - "no-restricted-imports": ["error", { "patterns": ["@bitwarden/exporter/*", "src/**/*"] }] + "no-restricted-imports": [ + "error", + { "patterns": ["@bitwarden/vault-export-core/*", "src/**/*"] } + ] + } + }, + { + "files": ["libs/tools/export/vault-export/vault-export-ui/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { "patterns": ["@bitwarden/vault-export-ui/*", "src/**/*"] } + ] } }, { @@ -175,6 +211,41 @@ "rules": { "no-restricted-imports": ["error", { "patterns": ["@bitwarden/node/*", "src/**/*"] }] } + }, + { + "files": ["libs/platform/src/**/*.ts"], + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@bitwarden/platform/*", "src/**/*"] }] + } + }, + { + "files": ["libs/vault/src/**/*.ts"], + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@bitwarden/vault/*", "src/**/*"] }] + } + }, + { + "files": ["apps/browser/src/**/*.ts", "libs/**/*.ts"], + "excludedFiles": [ + "apps/browser/src/autofill/{content,notification}/**/*.ts", + "apps/browser/src/**/background/**/*.ts", // It's okay to have long lived listeners in the background + "apps/browser/src/platform/background.ts" + ], + "rules": { + "no-restricted-syntax": [ + "error", + { + "message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead", + // This selector covers events like chrome.storage.onChange & chrome.runtime.onMessage + "selector": "CallExpression > [object.object.object.name='chrome'][property.name='addListener']" + }, + { + "message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead", + // This selector covers events like chrome.storage.local.onChange + "selector": "CallExpression > [object.object.object.object.name='chrome'][property.name='addListener']" + } + ] + } } ] } diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 9dd7b5c2e6..c0d1e0eb8a 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -22,3 +22,6 @@ 193434461dbd9c48fe5dcbad95693470aec422ac # Jslib: Monorepository https://github.com/bitwarden/clients/pull/2824/commits/d7492e3cf320410e74ebd0e0675ab994e64bd01a d7492e3cf320410e74ebd0e0675ab994e64bd01a + +# All Clients: Apply Prettier https://github.com/bitwarden/clients/pull/7014 +28de9439beb87133c8683434df952a0c0be94100 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1aed9c1be8..e9c1f229a5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,11 +1,9 @@ -# Please sort lines alphabetically, this will ensure we don't accidentally add duplicates. +# Please sort into logical groups with comment headers. Sort groups in order of specificity. +# For example, default owners should always be the first group. +# Sort lines alphabetically within these groups to avoid accidentally adding duplicates. # # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners -# The following owners will be the default owners for everything in the repo. -# Unless a later match takes precedence -* @bitwarden/team-leads-eng - ## Secrets Manager team files ## bitwarden_license/bit-web/src/app/secrets-manager @bitwarden/team-secrets-manager-dev @@ -29,8 +27,15 @@ apps/web/src/app/tools @bitwarden/team-tools-dev libs/angular/src/tools @bitwarden/team-tools-dev libs/common/src/models/export @bitwarden/team-tools-dev libs/common/src/tools @bitwarden/team-tools-dev -libs/exporter @bitwarden/team-tools-dev libs/importer @bitwarden/team-tools-dev +libs/tools @bitwarden/team-tools-dev + +## Localization/Crowdin (Tools team) +apps/browser/src/_locales @bitwarden/team-tools-dev +apps/browser/store/locales @bitwarden/team-tools-dev +apps/cli/src/locales @bitwarden/team-tools-dev +apps/desktop/src/locales @bitwarden/team-tools-dev +apps/web/src/locales @bitwarden/team-tools-dev ## Vault team files ## apps/browser/src/vault @bitwarden/team-vault-dev @@ -39,6 +44,7 @@ apps/desktop/src/vault @bitwarden/team-vault-dev apps/web/src/app/vault @bitwarden/team-vault-dev libs/angular/src/vault @bitwarden/team-vault-dev libs/common/src/vault @bitwarden/team-vault-dev +libs/vault @bitwarden/team-vault-dev ## Admin Console team files ## apps/browser/src/admin-console @bitwarden/team-admin-console-dev @@ -48,11 +54,14 @@ apps/web/src/app/admin-console @bitwarden/team-admin-console-dev bitwarden_license/bit-web/src/app/admin-console @bitwarden/team-admin-console-dev libs/angular/src/admin-console @bitwarden/team-admin-console-dev libs/common/src/admin-console @bitwarden/team-admin-console-dev +libs/admin-console @bitwarden/team-admin-console-dev ## Billing team files ## apps/web/src/app/billing @bitwarden/team-billing-dev libs/angular/src/billing @bitwarden/team-billing-dev libs/common/src/billing @bitwarden/team-billing-dev +libs/billing @bitwarden/team-billing-dev +bitwarden_license/bit-web/src/app/billing @bitwarden/team-billing-dev ## Platform team files ## apps/browser/src/platform @bitwarden/team-platform-dev @@ -61,6 +70,9 @@ apps/desktop/src/platform @bitwarden/team-platform-dev apps/web/src/app/platform @bitwarden/team-platform-dev libs/angular/src/platform @bitwarden/team-platform-dev libs/common/src/platform @bitwarden/team-platform-dev +libs/common/spec @bitwarden/team-platform-dev +libs/common/src/state-migrations @bitwarden/team-platform-dev +libs/platform @bitwarden/team-platform-dev # Node-specifc platform files libs/node @bitwarden/team-platform-dev # Web utils used across app and connectors @@ -72,34 +84,29 @@ apps/web/src/translation-constants.ts @bitwarden/team-platform-dev ## Autofill team files ## apps/browser/src/autofill @bitwarden/team-autofill-dev +apps/desktop/src/autofill @bitwarden/team-autofill-dev +libs/common/src/autofill @bitwarden/team-autofill-dev ## Component Library ## -libs/components @bitwarden/team-platform-dev +.storybook @bitwarden/team-component-library +libs/components @bitwarden/team-component-library +apps/web/src/app/layouts/header ## Desktop native module ## apps/desktop/desktop_native @bitwarden/team-platform-dev -## Multiple file owners ## -apps/browser/package.json -apps/browser/src/manifest.json -apps/browser/src/manifest.v3.json +## DevOps team files ## +/.github/workflows @bitwarden/dept-devops -apps/cli/package.json +# DevOps for Docker changes. +**/Dockerfile @bitwarden/dept-devops +**/*.Dockerfile @bitwarden/dept-devops +**/.dockerignore @bitwarden/dept-devops +**/entrypoint.sh @bitwarden/dept-devops -apps/desktop/package.json -apps/desktop/src/package-lock.json -apps/desktop/src/package.json - -/apps/web/config -/apps/web/package.json - -package-lock.json - -## Locales ## +## Locales ## apps/browser/src/_locales/en/messages.json +apps/browser/store/locales/en apps/cli/src/locales/en/messages.json apps/desktop/src/locales/en/messages.json apps/web/src/locales/en/messages.json - -## DevOps team files ## -/.github/workflows @bitwarden/dept-devops diff --git a/.github/ISSUE_TEMPLATE/desktop.yml b/.github/ISSUE_TEMPLATE/desktop.yml index 8da7b28588..6fd6f1d1c2 100644 --- a/.github/ISSUE_TEMPLATE/desktop.yml +++ b/.github/ISSUE_TEMPLATE/desktop.yml @@ -90,4 +90,4 @@ body: description: | Issue tracking information options: - - label: I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress. + - label: I understand that work is tracked outside of GitHub. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress. diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 0000000000..b477440720 --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,2 @@ +ignore: + - "**/*.spec.ts" # Tests diff --git a/.github/renovate.json b/.github/renovate.json index 81dea67731..95fd2dc11e 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,55 +1,266 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base", - ":combinePatchMinorReleases", - ":dependencyDashboard", - ":maintainLockFilesWeekly", - ":pinAllExceptPeerDependencies", - ":rebaseStalePrs", - "schedule:weekends", - ":separateMajorReleases" - ], - "prConcurrentLimit": 3, + "extends": ["github>bitwarden/renovate-config"], "enabledManagers": ["cargo", "github-actions", "npm"], "packageRules": [ - { - "groupName": "cargo minor", - "matchManagers": ["cargo"], - "matchUpdateTypes": ["minor", "patch"] - }, { "groupName": "gh minor", "matchManagers": ["github-actions"], "matchUpdateTypes": ["minor", "patch"] }, { - "groupName": "npm minor", - "matchManagers": ["npm"], - "matchUpdateTypes": ["minor", "patch"] + "matchManagers": ["github-actions"], + "commitMessagePrefix": "[deps] DevOps:" }, { - "matchPackageNames": ["typescript"], + "matchManagers": ["cargo"], + "commitMessagePrefix": "[deps] Platform:" + }, + { + "groupName": "napi", + "matchPackageNames": ["napi", "napi-build", "napi-derive"] + }, + { + "matchPackageNames": ["typescript", "zone.js"], "matchUpdateTypes": ["major", "minor"], + "description": "Determined by Angular", "enabled": false }, { - "matchPackageNames": ["typescript"], + "matchPackageNames": ["typescript", "zone.js"], "matchUpdateTypes": "patch" }, { "groupName": "jest", "matchPackageNames": ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], "matchUpdateTypes": "major" + }, + { + "matchPackageNames": [ + "@ngtools/webpack", + "base64-loader", + "buffer", + "bufferutil", + "copy-webpack-plugin", + "core-js", + "css-loader", + "html-loader", + "html-webpack-injector", + "html-webpack-plugin", + "mini-css-extract-plugin", + "ngx-infinite-scroll", + "postcss", + "postcss-loader", + "process", + "sass", + "sass-loader", + "style-loader", + "ts-loader", + "tsconfig-paths-webpack-plugin", + "url", + "util", + "webpack", + "webpack-cli", + "webpack-dev-server", + "webpack-node-externals" + ], + "description": "Admin Console owned dependencies", + "commitMessagePrefix": "[deps] AC:", + "reviewers": ["team:team-admin-console-dev"] + }, + { + "matchPackageNames": [ + "@types/duo_web_sdk", + "@types/node-ipc", + "duo_web_sdk", + "node-ipc", + "qrious", + "regedit" + ], + "description": "Auth owned dependencies", + "commitMessagePrefix": "[deps] Auth:", + "reviewers": ["team:team-auth-dev"] + }, + { + "matchPackageNames": [ + "@webcomponents/custom-elements", + "concurrently", + "cross-env", + "del", + "gulp", + "gulp-filter", + "gulp-if", + "gulp-json-editor", + "gulp-replace", + "gulp-zip", + "nord", + "patch-package", + "prettier", + "prettier-plugin-tailwindcss", + "rimraf", + "tabbable", + "tldts", + "wait-on" + ], + "description": "Autofill owned dependencies", + "commitMessagePrefix": "[deps] Autofill:", + "reviewers": ["team:team-autofill-dev"] + }, + { + "matchPackageNames": ["braintree-web-drop-in"], + "description": "Billing owned dependencies", + "commitMessagePrefix": "[deps] Billing:", + "reviewers": ["team:team-billing-dev"] + }, + { + "matchPackageNames": [ + "@angular-devkit/build-angular", + "@angular/animations", + "@angular/cdk", + "@angular/cli", + "@angular/common", + "@angular/compiler", + "@angular/compiler-cli", + "@angular/core", + "@angular/forms", + "@angular/platform", + "@angular/compiler", + "@angular/router", + "@types/argon2-browser", + "@types/chrome", + "@types/firefox-webext-browser", + "@types/jquery", + "@types/node", + "@types/node-forge", + "argon2", + "argon2-browser", + "big-integer", + "bootstrap", + "jquery", + "node-forge", + "popper.js", + "rxjs", + "type-fest", + "typescript", + "zone.js" + ], + "description": "Platform owned dependencies", + "commitMessagePrefix": "[deps] Platform:", + "reviewers": ["team:team-platform-dev"] + }, + { + "matchPackageNames": [ + "@compodoc/compodoc", + "@ng-select/ng-select", + "@storybook/addon-a11y", + "@storybook/addon-actions", + "@storybook/addon-designs", + "@storybook/addon-essentials", + "@storybook/addon-links", + "@storybook/angular", + "@types/react", + "autoprefixer", + "chromatic", + "ngx-toastr", + "react", + "react-dom", + "remark-gfm", + "storybook", + "tailwindcss" + ], + "description": "Component library owned dependencies", + "commitMessagePrefix": "[deps] Platform (CL):", + "reviewers": ["team:team-component-library"] + }, + { + "matchPackageNames": [ + "@angular-eslint/eslint-plugin", + "@angular-eslint/eslint-plugin-template", + "@angular-eslint/template-parser", + "@types/jest", + "@typescript-eslint/eslint-plugin", + "@typescript-eslint/parser", + "eslint", + "eslint-config-prettier", + "eslint-import-resolver-typescript", + "eslint-plugin-import", + "eslint-plugin-rxjs", + "eslint-plugin-rxjs-angular", + "eslint-plugin-storybook", + "eslint-plugin-tailwindcss", + "husky", + "jest-junit", + "jest-mock-extended", + "jest-preset-angular", + "lint-staged", + "ts-jest" + ], + "description": "Secrets Manager owned dependencies", + "commitMessagePrefix": "[deps] SM:", + "reviewers": ["team:team-secrets-manager-dev"] + }, + { + "matchPackageNames": [ + "@electron/notarize", + "@electron/rebuild", + "@microsoft/signalr-protocol-msgpack", + "@microsoft/signalr", + "@types/jsdom", + "@types/papaparse", + "@types/zxcvbn", + "electron-builder", + "electron-log", + "electron-reload", + "electron-store", + "electron-updater", + "electron", + "jsdom", + "jszip", + "oidc-client-ts", + "papaparse", + "utf-8-validate", + "zxcvbn" + ], + "description": "Tools owned dependencies", + "commitMessagePrefix": "[deps] Tools:", + "reviewers": ["team:team-tools-dev"] + }, + { + "matchPackageNames": [ + "@koa/multer", + "@koa/router", + "@types/inquirer", + "@types/koa", + "@types/koa__multer", + "@types/koa__router", + "@types/koa-bodyparser", + "@types/koa-json", + "@types/lowdb", + "@types/lunr", + "@types/node-fetch", + "@types/proper-lockfile", + "@types/retry", + "chalk", + "commander", + "form-data", + "https-proxy-agent", + "inquirer", + "koa", + "koa-bodyparser", + "koa-json", + "lowdb", + "lunr", + "multer", + "node-fetch", + "open", + "pkg", + "proper-lockfile", + "qrcode-parser" + ], + "description": "Vault owned dependencies", + "commitMessagePrefix": "[deps] Vault:", + "reviewers": ["team:team-vault-dev"] } ], - "ignoreDeps": [ - "@types/koa-bodyparser", - "bootstrap", - "electron-builder", - "electron", - "node-ipc", - "regedit", - "zone.js" - ] + "ignoreDeps": ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm", "regedit"] } diff --git a/.github/secrets/appstore-app-cert.p12.gpg b/.github/secrets/appstore-app-cert.p12.gpg deleted file mode 100644 index 284add80d5..0000000000 Binary files a/.github/secrets/appstore-app-cert.p12.gpg and /dev/null differ diff --git a/.github/secrets/appstore-installer-cert.p12.gpg b/.github/secrets/appstore-installer-cert.p12.gpg deleted file mode 100644 index cd1f58eca1..0000000000 Binary files a/.github/secrets/appstore-installer-cert.p12.gpg and /dev/null differ diff --git a/.github/secrets/bitwarden-desktop-key.p12.gpg b/.github/secrets/bitwarden-desktop-key.p12.gpg deleted file mode 100644 index 76ee0cbb5e..0000000000 Binary files a/.github/secrets/bitwarden-desktop-key.p12.gpg and /dev/null differ diff --git a/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg b/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg deleted file mode 100644 index d55f405517..0000000000 Binary files a/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg and /dev/null differ diff --git a/.github/secrets/devid-app-cert.p12.gpg b/.github/secrets/devid-app-cert.p12.gpg deleted file mode 100644 index 8e2e2146e2..0000000000 Binary files a/.github/secrets/devid-app-cert.p12.gpg and /dev/null differ diff --git a/.github/secrets/devid-installer-cert.p12.gpg b/.github/secrets/devid-installer-cert.p12.gpg deleted file mode 100644 index f379fc214f..0000000000 Binary files a/.github/secrets/devid-installer-cert.p12.gpg and /dev/null differ diff --git a/.github/secrets/macdev-cert.p12.gpg b/.github/secrets/macdev-cert.p12.gpg deleted file mode 100644 index f89cfb82a1..0000000000 Binary files a/.github/secrets/macdev-cert.p12.gpg and /dev/null differ diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 17047f4333..99ce80376d 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -2,10 +2,7 @@ ./apps/browser/src/safari/desktop/Assets.xcassets/AccentColor.colorset ./apps/browser/src/safari/desktop/Assets.xcassets/AppIcon.appiconset ./apps/browser/src/safari/desktop/Base.lproj -./apps/browser/src/services/vaultTimeout ./apps/browser/store/windows/Assets -./libs/common/src/abstractions/vaultTimeout -./libs/common/src/services/vaultTimeout ./bitwarden_license/README.md ./libs/angular/src/directives/cipherListVirtualScroll.directive.ts ./libs/angular/src/scss/webfonts/Open_Sans-italic-700.woff @@ -18,20 +15,13 @@ ./libs/angular/src/scss/webfonts/Open_Sans-normal-600.woff ./libs/angular/src/scss/webfonts/Open_Sans-normal-800.woff ./libs/angular/src/scss/webfonts/Open_Sans-normal-400.woff -./libs/angular/src/validators/inputsFieldMatch.validator.ts -./libs/angular/src/validators/notAllowedValueAsync.validator.ts -./libs/angular/src/services/theming/themeBuilder.ts -./libs/common/src/misc/nodeUtils.ts -./libs/common/src/misc/linkedFieldOption.decorator.ts -./libs/common/src/misc/serviceUtils.ts -./libs/common/src/misc/serviceUtils.spec.ts -./libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts -./libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts -./libs/common/src/abstractions/anonymousHub.service.ts -./libs/common/src/services/vaultTimeout/vaultTimeoutSettings.service.ts -./libs/common/src/services/vaultTimeout/vaultTimeout.service.ts -./libs/common/src/services/anonymousHub.service.ts +./libs/admin-console/README.md ./libs/auth/README.md +./libs/billing/README.md +./libs/platform/README.md +./libs/tools/README.md +./libs/tools/export/vault-export/README.md +./libs/vault/README.md ./README.md ./LICENSE_BITWARDEN.txt ./CONTRIBUTING.md @@ -54,15 +44,6 @@ ./apps/browser/README.md ./apps/browser/store/windows/AppxManifest.xml ./apps/browser/src/background/nativeMessaging.background.ts -./apps/browser/src/background/models/addLoginRuntimeMessage.ts -./apps/browser/src/background/models/addChangePasswordQueueMessage.ts -./apps/browser/src/background/models/addLoginQueueMessage.ts -./apps/browser/src/background/models/changePasswordRuntimeMessage.ts -./apps/browser/src/background/models/notificationQueueMessage.ts -./apps/browser/src/background/models/notificationQueueMessageType.ts -./apps/browser/src/background/models/lockedVaultPendingNotificationsItem.ts -./apps/browser/src/background/webRequest.background.ts -./apps/browser/src/popup/services/debounceNavigationService.ts ./apps/browser/src/models/browserComponentState.ts ./apps/browser/src/models/browserSendComponentState.ts ./apps/browser/src/models/browserGroupingsComponentState.ts @@ -78,5 +59,4 @@ ./apps/browser/src/safari/safari/SafariWebExtensionHandler.swift ./apps/browser/src/safari/safari/Info.plist ./apps/browser/src/safari/desktop.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist -./apps/browser/src/services/vaultTimeout/vaultTimeout.service.ts ./SECURITY.md diff --git a/.github/workflows/auto-branch-updater.yml b/.github/workflows/auto-branch-updater.yml index fee2ad958f..90376c9956 100644 --- a/.github/workflows/auto-branch-updater.yml +++ b/.github/workflows/auto-branch-updater.yml @@ -4,7 +4,7 @@ name: Auto Update Branch on: push: branches: - - 'master' + - 'main' - 'rc' paths: - 'apps/web/**' @@ -29,7 +29,7 @@ jobs: run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: 'eu-web-${{ steps.setup.outputs.branch }}' fetch-depth: 0 diff --git a/.github/workflows/automatic-issue-responses.yml b/.github/workflows/automatic-issue-responses.yml index 90d561c922..289b8bd662 100644 --- a/.github/workflows/automatic-issue-responses.yml +++ b/.github/workflows/automatic-issue-responses.yml @@ -7,7 +7,7 @@ on: jobs: close-issue: name: 'Close issue with automatic response' - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 permissions: issues: write steps: diff --git a/.github/workflows/automatic-pull-request-responses.yml b/.github/workflows/automatic-pull-request-responses.yml index 261cd5c255..16e1a46c05 100644 --- a/.github/workflows/automatic-pull-request-responses.yml +++ b/.github/workflows/automatic-pull-request-responses.yml @@ -7,7 +7,7 @@ on: jobs: close-issue: name: 'Close pull request with automatic response' - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 permissions: pull-requests: write steps: diff --git a/.github/workflows/brew-bump-cli.yml b/.github/workflows/brew-bump-cli.yml index 438e74c942..33c6b7c368 100644 --- a/.github/workflows/brew-bump-cli.yml +++ b/.github/workflows/brew-bump-cli.yml @@ -14,22 +14,22 @@ defaults: jobs: update-desktop-cask: name: Update Bitwarden CLI Formula - runs-on: macos-11 + runs-on: macos-13 steps: - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "brew-bump-workflow-pat" - name: Update Homebrew formula - uses: dawidd6/action-homebrew-bump-formula@d3667e5ae14df19579e4414897498e3e88f2f458 # v3.10.0 + uses: dawidd6/action-homebrew-bump-formula@baf2b60c51fc1f8453c884b0c61052668a71bd1d # v3.11.0 with: # Required, custom GitHub access token with the 'public_repo' and 'workflow' scopes token: ${{ steps.retrieve-secrets.outputs.brew-bump-workflow-pat }} @@ -38,4 +38,4 @@ jobs: formula: bitwarden-cli tag: ${{ github.ref }} revision: ${{ github.sha }} - force: false + force: true diff --git a/.github/workflows/brew-bump-desktop.yml b/.github/workflows/brew-bump-desktop.yml index b724f3562a..31239aa9b2 100644 --- a/.github/workflows/brew-bump-desktop.yml +++ b/.github/workflows/brew-bump-desktop.yml @@ -14,16 +14,16 @@ defaults: jobs: update-desktop-cask: name: Update Bitwarden Desktop Cask - runs-on: macos-11 + runs-on: macos-13 steps: - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "brew-bump-workflow-pat" @@ -38,5 +38,5 @@ jobs: cask: bitwarden tag: ${{ github.ref }} revision: ${{ github.sha }} - force: false + force: true dryrun: true diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 8e4fc6d4f7..585a888ae1 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -10,19 +10,17 @@ on: - 'apps/browser/**' - 'libs/**' - '*' - - '!libs/importer' - '!*.md' - '!*.txt' push: branches: - - 'master' + - 'main' - 'rc' - 'hotfix-rc-browser' paths: - 'apps/browser/**' - 'libs/**' - '*' - - '!libs/importer' - '!*.md' - '!*.txt' - '.github/workflows/build-browser.yml' @@ -36,29 +34,17 @@ defaults: shell: bash jobs: - cloc: - name: CLOC - runs-on: ubuntu-20.04 - steps: - - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Set up cloc - run: | - sudo apt update - sudo apt -y install cloc - - - name: Print lines of code - run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git - - setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 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 }} steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Get Package Version id: gen_vars run: | @@ -68,10 +54,18 @@ jobs: echo "repo_url=$repo_url" >> $GITHUB_OUTPUT echo "adj_build_number=$adj_build_num" >> $GITHUB_OUTPUT + - name: Get Node Version + id: retrieve-node-version + working-directory: ./ + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + locales-test: name: Locales Test - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - setup defaults: @@ -79,7 +73,7 @@ jobs: working-directory: apps/browser steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Testing locales - extName length run: | @@ -108,121 +102,123 @@ jobs: build: name: Build - runs-on: windows-2019 + runs-on: ubuntu-22.04 needs: - setup - locales-test env: _BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }} - defaults: - run: - working-directory: apps/browser + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | node --version npm --version + - name: Build sources for reviewers + run: | + # Include hidden files in glob copy + shopt -s dotglob + + # Remove ".git" directory + rm -r .git + + # Copy root level files to source directory + mkdir browser-source + FILES=$(find . -maxdepth 1 -type f) + for FILE in $FILES; do cp "$FILE" browser-source/; done + + # Copy patches to the Browser source directory + mkdir -p browser-source/patches + cp -r patches/* browser-source/patches + + # Copy apps/browser to the Browser source directory + mkdir -p browser-source/apps/browser + cp -r apps/browser/* browser-source/apps/browser + + # Copy libs to Browser source directory + mkdir browser-source/libs + cp -r libs/* browser-source/libs + + zip -r browser-source.zip browser-source + - name: NPM setup run: npm ci - working-directory: ./ + working-directory: browser-source/ - name: Build run: npm run dist + working-directory: browser-source/apps/browser # - name: Build Manifest v3 # run: npm run dist:mv3 + # working-directory: browser-source/apps/browser - name: Gulp run: gulp ci - - - name: Build sources for reviewers - shell: cmd - run: | - REM Remove ".git" directory - rmdir /S /Q ".git" - - REM Copy root level files to source directory - mkdir browser-source - copy * browser-source - - REM Copy apps\browser to Browser source directory - mkdir browser-source\apps\browser - xcopy apps\browser\* browser-source\apps\browser /E - - REM Copy libs to Browser source directory - mkdir browser-source\libs - xcopy libs\* browser-source\libs /E - - call 7z a browser-source.zip "browser-source\*" - working-directory: ./ + working-directory: browser-source/apps/browser - name: Upload Opera artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: dist-opera-${{ env._BUILD_NUMBER }}.zip - path: apps/browser/dist/dist-opera.zip + path: browser-source/apps/browser/dist/dist-opera.zip if-no-files-found: error # - name: Upload Opera MV3 artifact # uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 # with: # name: dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip - # path: apps/browser/dist/dist-opera-mv3.zip + # path: browser-source/apps/browser/dist/dist-opera-mv3.zip # if-no-files-found: error - name: Upload Chrome artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: dist-chrome-${{ env._BUILD_NUMBER }}.zip - path: apps/browser/dist/dist-chrome.zip + path: browser-source/apps/browser/dist/dist-chrome.zip if-no-files-found: error # - name: Upload Chrome MV3 artifact # uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 # with: # name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip - # path: apps/browser/dist/dist-chrome-mv3.zip + # path: browser-source/apps/browser/dist/dist-chrome-mv3.zip # if-no-files-found: error - name: Upload Firefox artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: dist-firefox-${{ env._BUILD_NUMBER }}.zip - path: apps/browser/dist/dist-firefox.zip + path: browser-source/apps/browser/dist/dist-firefox.zip if-no-files-found: error - name: Upload Edge artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: dist-edge-${{ env._BUILD_NUMBER }}.zip - path: apps/browser/dist/dist-edge.zip + path: browser-source/apps/browser/dist/dist-edge.zip if-no-files-found: error # - name: Upload Edge MV3 artifact # uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 # with: # name: dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip - # path: apps/browser/dist/dist-edge-mv3.zip + # path: browser-source/apps/browser/dist/dist-edge-mv3.zip # if-no-files-found: error - name: Upload browser source - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: browser-source-${{ env._BUILD_NUMBER }}.zip path: browser-source.zip @@ -230,88 +226,103 @@ jobs: - name: Upload coverage artifact if: false - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: coverage-${{ env._BUILD_NUMBER }}.zip - path: apps/browser/coverage/coverage-${{ env._BUILD_NUMBER }}.zip + path: browser-source/apps/browser/coverage/coverage-${{ env._BUILD_NUMBER }}.zip if-no-files-found: error build-safari: name: Build Safari - runs-on: macos-11 + runs-on: macos-13 needs: - setup - locales-test env: _BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | node --version npm --version - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: NPM setup @@ -330,7 +341,7 @@ jobs: ls -la - name: Upload Safari artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: dist-safari-${{ env._BUILD_NUMBER }}.zip path: apps/browser/dist/dist-safari.zip @@ -338,45 +349,44 @@ jobs: crowdin-push: name: Crowdin Push - if: github.ref == 'refs/heads/master' - runs-on: ubuntu-20.04 + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-22.04 needs: - build - build-safari steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0 + uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} CROWDIN_PROJECT_ID: "268134" with: config: apps/browser/crowdin.yml - crowdin_branch_name: master + crowdin_branch_name: main upload_sources: true upload_translations: false check-failures: name: Check for failures if: always() - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - - cloc - setup - locales-test - build @@ -384,31 +394,11 @@ jobs: - crowdin-push steps: - name: Check if any job failed - if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }} - env: - CLOC_STATUS: ${{ needs.cloc.result }} - SETUP_STATUS: ${{ needs.setup.result }} - LOCALES_TEST_STATUS: ${{ needs.locales-test.result }} - BUILD_STATUS: ${{ needs.build.result }} - SAFARI_BUILD_STATUS: ${{ needs.build-safari.result }} - CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }} - run: | - if [ "$CLOC_STATUS" = "failure" ]; then - exit 1 - elif [ "$SETUP_STATUS" = "failure" ]; then - exit 1 - elif [ "$LOCALES_TEST_STATUS" = "failure" ]; then - exit 1 - elif [ "$BUILD_STATUS" = "failure" ]; then - exit 1 - elif [ "$SAFARI_BUILD_STATUS" = "failure" ]; then - exit 1 - elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then - exit 1 - fi + if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure') + run: exit 1 - name: Login to Azure - Prod Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 if: failure() with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} @@ -416,7 +406,7 @@ jobs: - name: Retrieve secrets id: retrieve-secrets if: failure() - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "devops-alerts-slack-webhook-url" diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index b0cc27e0ea..2c3ea3982a 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/build-cli.yml' push: branches: - - 'master' + - 'main' - 'rc' - 'hotfix-rc-cli' paths: @@ -33,53 +33,47 @@ defaults: working-directory: apps/cli jobs: - cloc: - name: CLOC - runs-on: ubuntu-20.04 - steps: - - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Set up cloc - run: | - sudo apt update - sudo apt -y install cloc - - - name: Print lines of code - run: cloc --include-lang TypeScript,JavaScript --vcs git - - setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: - package_version: ${{ steps.retrieve-version.outputs.package_version }} + package_version: ${{ steps.retrieve-package-version.outputs.package_version }} + node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Get Package Version - id: retrieve-version + id: retrieve-package-version run: | PKG_VERSION=$(jq -r .version package.json) echo "package_version=$PKG_VERSION" >> $GITHUB_OUTPUT + - name: Get Node Version + id: retrieve-node-version + working-directory: ./ + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + cli: name: Build CLI ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04, macos-11] + os: [ubuntu-22.04, macos-11] runs-on: ${{ matrix.os }} needs: - setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} _WIN_PKG_FETCH_VERSION: 18.5.0 _WIN_PKG_VERSION: 3.4 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup Unix Vars run: | @@ -88,16 +82,11 @@ jobs: awk '{print tolower($0)}')" >> $GITHUB_ENV - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Install run: npm ci @@ -129,14 +118,14 @@ jobs: | awk '{split($0, a); print a[1]}' > bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt - name: Upload unix zip asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload unix checksum asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt @@ -144,16 +133,17 @@ jobs: cli-windows: name: Build CLI Windows - runs-on: windows-2019 + runs-on: windows-2022 needs: - setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} _WIN_PKG_FETCH_VERSION: 18.5.0 _WIN_PKG_VERSION: 3.4 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup Windows builder run: | @@ -162,16 +152,11 @@ jobs: choco install nasm --no-progress - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Get pkg-fetch shell: pwsh @@ -264,28 +249,28 @@ jobs: -t sha256 | Out-File -Encoding ASCII ./dist/bw-windows-sha256-${env:_PACKAGE_VERSION}.txt - name: Upload windows zip asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw-windows-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/bw-windows-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload windows checksum asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw-windows-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/bw-windows-sha256-${{ env._PACKAGE_VERSION }}.txt if-no-files-found: error - name: Upload Chocolatey asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg path: apps/cli/dist/chocolatey/bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg if-no-files-found: error - name: Upload NPM Build Directory asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip path: apps/cli/build @@ -293,13 +278,16 @@ jobs: snap: name: Build Snap - runs-on: ubuntu-20.04 + # Note, before updating the ubuntu version of the workflow, ensure the snap base image + # is equal or greater than the new version. Otherwise there might be GLIBC version issues. + # The snap base for CLI is defined in `apps/cli/stores/snap/snapcraft.yaml` + runs-on: ubuntu-22.04 needs: [setup, cli] env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Print environment run: | @@ -309,7 +297,7 @@ jobs: echo "BW Package Version: $_PACKAGE_VERSION" - name: Get bw linux cli - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: name: bw-linux-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/snap @@ -322,7 +310,7 @@ jobs: ls -alth - name: Build snap - uses: snapcore/action-build@3457752ec9b1c79a8290b5167fce2d14df0997c1 # v1.1.2 + uses: snapcore/action-build@2096990827aa966f773676c8a53793c723b6b40f # v1.2.0 with: path: apps/cli/dist/snap @@ -351,14 +339,14 @@ jobs: run: sudo snap remove bw - name: Upload snap asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/cli/dist/snap/bw_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload snap checksum asset - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt @@ -368,9 +356,8 @@ jobs: check-failures: name: Check for failures if: always() - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - - cloc - setup - cli - cli-windows @@ -378,25 +365,11 @@ jobs: steps: - name: Check if any job failed working-directory: ${{ github.workspace }} - if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }} - env: - CLOC_STATUS: ${{ needs.cloc.result }} - SETUP_STATUS: ${{ needs.setup.result }} - CLI_STATUS: ${{ needs.cli.result }} - SNAP_STATUS: ${{ needs.snap.result }} - run: | - if [ "$CLOC_STATUS" = "failure" ]; then - exit 1 - elif [ "$SETUP_STATUS" = "failure" ]; then - exit 1 - elif [ "$CLI_STATUS" = "failure" ]; then - exit 1 - elif [ "$SNAP_STATUS" = "failure" ]; then - exit 1 - fi + if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure') + run: exit 1 - name: Login to Azure - Prod Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 if: failure() with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} @@ -404,7 +377,7 @@ jobs: - name: Retrieve secrets id: retrieve-secrets if: failure() - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "devops-alerts-slack-webhook-url" diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 60949f3d69..e73f882bb4 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -10,20 +10,18 @@ on: - 'apps/desktop/**' - 'libs/**' - '*' - - '!libs/importer' - '!*.md' - '!*.txt' - '.github/workflows/build-desktop.yml' push: branches: - - 'master' + - 'main' - 'rc' - 'hotfix-rc-desktop' paths: - 'apps/desktop/**' - 'libs/**' - '*' - - '!libs/importer' - '!*.md' - '!*.txt' - '.github/workflows/build-desktop.yml' @@ -35,27 +33,12 @@ defaults: shell: bash jobs: - cloc: - name: CLOC - runs-on: ubuntu-20.04 - steps: - - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Set up cloc - run: | - sudo apt-get update - sudo apt-get -y install cloc - - - name: Print lines of code - run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git - electron-verify: name: Verify Electron Version - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Verify run: | @@ -71,19 +54,20 @@ jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: package_version: ${{ steps.retrieve-version.outputs.package_version }} release_channel: ${{ steps.release-channel.outputs.channel }} build_number: ${{ steps.increment-version.outputs.build_number }} 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 }} defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Get Package Version id: retrieve-version @@ -130,35 +114,40 @@ jobs: echo "hotfix_branch_exists=0" >> $GITHUB_OUTPUT fi + - name: Get Node Version + id: retrieve-node-version + working-directory: ./ + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT linux: name: Linux Build + # Note, before updating the ubuntu version of the workflow, ensure the snap base image + # is equal or greater than the new version. Otherwise there might be GLIBC version issues. + # The snap base for desktop is defined in `apps/desktop/electron-builder.json` + # We are currently running on 20.04 until the Ubuntu 24.04 release is available, as moving + # to 22.04 now breaks users who are on 20.04 due to mismatched GLIBC versions. runs-on: ubuntu-20.04 - needs: - - setup + needs: setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Set up environment run: | @@ -180,7 +169,7 @@ jobs: working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: | @@ -204,42 +193,42 @@ jobs: run: npm run dist:lin - name: Upload .deb artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb if-no-files-found: error - name: Upload .rpm artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm if-no-files-found: error - name: Upload .freebsd artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd if-no-files-found: error - name: Upload .snap artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload .AppImage artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release_channel }}-linux.yml path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml @@ -248,36 +237,29 @@ jobs: windows: name: Windows Build - runs-on: windows-2019 - needs: - - setup + runs-on: windows-2022 + needs: setup defaults: run: shell: pwsh working-directory: apps/desktop env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Install AST - uses: bitwarden/gh-actions/install-ast@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + run: dotnet tool install --global AzureSignTool --version 4.0.1 - name: Set up environmentF run: choco install checksum --no-progress @@ -296,13 +278,13 @@ jobs: rustup show - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "code-signing-vault-url, @@ -316,7 +298,7 @@ jobs: working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: apps/desktop/desktop_native/*.node @@ -369,91 +351,91 @@ jobs: -NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z - name: Upload portable exe artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload installer exe artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload appx ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx if-no-files-found: error - name: Upload store appx ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx if-no-files-found: error - name: Upload NSIS ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z if-no-files-found: error - name: Upload appx x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx if-no-files-found: error - name: Upload store appx x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx if-no-files-found: error - name: Upload NSIS x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z if-no-files-found: error - name: Upload appx ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx if-no-files-found: error - name: Upload store appx ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx if-no-files-found: error - name: Upload NSIS ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z if-no-files-found: error - name: Upload nupkg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release_channel }}.yml path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml @@ -462,32 +444,28 @@ jobs: macos-build: name: MacOS Build + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 - needs: - - setup + needs: setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Rust shell: pwsh @@ -503,70 +481,84 @@ jobs: - name: Cache Build id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Cache Safari id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -582,13 +574,14 @@ jobs: $package = Get-Content -Raw -Path electron-builder.json | ConvertFrom-Json $package | Add-Member -MemberType NoteProperty -Name buildVersion -Value "$env:BUILD_NUMBER" $package | ConvertTo-Json -Depth 32 | Set-Content -Path electron-builder.json + "### MacOS build number: $env:BUILD_NUMBER" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - name: Install Node dependencies run: npm ci working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: apps/desktop/desktop_native/*.node @@ -612,6 +605,9 @@ jobs: macos-package-github: name: MacOS Package GitHub Release Assets + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: - browser-build @@ -619,27 +615,21 @@ jobs: - setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Rust shell: pwsh @@ -655,70 +645,84 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -734,13 +738,14 @@ jobs: $package = Get-Content -Raw -Path electron-builder.json | ConvertFrom-Json $package | Add-Member -MemberType NoteProperty -Name buildVersion -Value "$env:BUILD_NUMBER" $package | ConvertTo-Json -Depth 32 | Set-Content -Path electron-builder.json + "### MacOS GitHub build number: $env:BUILD_NUMBER" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - name: Install Node dependencies run: npm ci working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: apps/desktop/desktop_native/*.node @@ -756,7 +761,7 @@ jobs: run: npm run build - name: Download Browser artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: path: ${{ github.workspace }}/browser-build-artifacts @@ -779,28 +784,28 @@ jobs: run: npm run pack:mac - name: Upload .zip artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip if-no-files-found: error - name: Upload .dmg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg if-no-files-found: error - name: Upload .dmg blockmap artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release_channel }}-mac.yml path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml @@ -809,6 +814,9 @@ jobs: macos-package-mas: name: MacOS Package Prod Release Asset + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: - browser-build @@ -816,27 +824,21 @@ jobs: - setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Rust shell: pwsh @@ -852,70 +854,84 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -931,13 +947,14 @@ jobs: $package = Get-Content -Raw -Path electron-builder.json | ConvertFrom-Json $package | Add-Member -MemberType NoteProperty -Name buildVersion -Value "$env:BUILD_NUMBER" $package | ConvertTo-Json -Depth 32 | Set-Content -Path electron-builder.json + "### MacOS App Store build number: $env:BUILD_NUMBER" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - name: Install Node dependencies run: npm ci working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: apps/desktop/desktop_native/*.node @@ -953,7 +970,7 @@ jobs: run: npm run build - name: Download Browser artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: path: ${{ github.workspace }}/browser-build-artifacts @@ -976,7 +993,7 @@ jobs: CSC_FOR_PULL_REQUEST: true - name: Upload .pkg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg @@ -987,7 +1004,7 @@ jobs: APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} if: | - (github.ref == 'refs/heads/master' + (github.ref == 'refs/heads/main' && needs.setup.outputs.rc_branch_exists == 0 && needs.setup.outputs.hotfix_branch_exists == 0) || (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0) @@ -998,6 +1015,9 @@ jobs: macos-package-dev: name: MacOS Package Dev Release Asset if: false # We need to look into how code signing works for dev + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: - browser-build @@ -1005,27 +1025,21 @@ jobs: - setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | @@ -1036,70 +1050,84 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -1115,13 +1143,14 @@ jobs: $package = Get-Content -Raw -Path electron-builder.json | ConvertFrom-Json $package | Add-Member -MemberType NoteProperty -Name buildVersion -Value "$env:BUILD_NUMBER" $package | ConvertTo-Json -Depth 32 | Set-Content -Path electron-builder.json + "### MacOS Dev build number: $env:BUILD_NUMBER" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append - name: Install Node dependencies run: npm ci working-directory: ./ - name: Cache Native Module - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 id: cache with: path: apps/desktop/desktop_native/*.node @@ -1137,7 +1166,7 @@ jobs: run: npm run build - name: Download Browser artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: path: ${{ github.workspace }}/browser-build-artifacts @@ -1163,7 +1192,7 @@ jobs: run: zip -r Bitwarden-${{ env.PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app - name: Upload masdev artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip @@ -1172,38 +1201,38 @@ jobs: crowdin-push: name: Crowdin Push - if: github.ref == 'refs/heads/master' + if: github.ref == 'refs/heads/main' needs: - linux - windows - macos-package-github - macos-package-mas - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0 + uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} CROWDIN_PROJECT_ID: "299360" with: config: apps/desktop/crowdin.yml - crowdin_branch_name: master + crowdin_branch_name: main upload_sources: true upload_translations: false @@ -1211,9 +1240,8 @@ jobs: check-failures: name: Check for failures if: always() - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - - cloc - electron-verify - browser-build - setup @@ -1225,43 +1253,11 @@ jobs: - crowdin-push steps: - name: Check if any job failed - if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }} - env: - CLOC_STATUS: ${{ needs.cloc.result }} - ELECTRON_VERIFY_STATUS: ${{ needs.electron-verify.result }} - BROWSER_BUILD_STATUS: ${{ needs.browser-build.result }} - SETUP_STATUS: ${{ needs.setup.result }} - LINUX_STATUS: ${{ needs.linux.result }} - WINDOWS_STATUS: ${{ needs.windows.result }} - MACOS_BUILD_STATUS: ${{ needs.macos-build.result }} - MACOS_PKG_GITHUB_STATUS: ${{ needs.macos-package-github.result }} - MACOS_PKG_MAS_STATUS: ${{ needs.macos-package-mas.result }} - CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }} - run: | - if [ "$CLOC_STATUS" = "failure" ]; then - exit 1 - elif [ "$ELECTRON_VERIFY_STATUS" = "failure" ]; then - exit 1 - elif [ "$BROWSER_BUILD_STATUS" = "failure" ]; then - exit 1 - elif [ "$SETUP_STATUS" = "failure" ]; then - exit 1 - elif [ "$LINUX_STATUS" = "failure" ]; then - exit 1 - elif [ "$WINDOWS_STATUS" = "failure" ]; then - exit 1 - elif [ "$MACOS_BUILD_STATUS" = "failure" ]; then - exit 1 - elif [ "$MACOS_PKG_GITHUB_STATUS" = "failure" ]; then - exit 1 - elif [ "$MACOS_PKG_MAS_STATUS" = "failure" ]; then - exit 1 - elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then - exit 1 - fi + if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure') + run: exit 1 - name: Login to Azure - Prod Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 if: failure() with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} @@ -1269,7 +1265,7 @@ jobs: - name: Retrieve secrets id: retrieve-secrets if: failure() - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "devops-alerts-slack-webhook-url" diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 9c670f01c6..8576fb6760 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/build-web.yml' push: branches: - - 'master' + - 'main' - 'rc' - 'hotfix-rc-web' paths: @@ -25,50 +25,46 @@ on: - '!*.md' - '!*.txt' - '.github/workflows/build-web.yml' + release: + types: [published] workflow_dispatch: inputs: custom_tag_extension: description: "Custom image tag extension" required: false +env: + _AZ_REGISTRY: bitwardenprod.azurecr.io + jobs: - cloc: - name: CLOC - runs-on: ubuntu-22.04 - steps: - - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Set up cloc - run: | - sudo apt update - sudo apt -y install cloc - - - name: Print lines of code - working-directory: apps/web - run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git - - setup: name: Setup runs-on: ubuntu-22.04 outputs: version: ${{ steps.version.outputs.value }} + node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Get GitHub sha as version id: version run: echo "value=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT + - name: Get Node Version + id: retrieve-node-version + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + build-artifacts: name: Build artifacts runs-on: ubuntu-22.04 - needs: - - setup + needs: setup env: _VERSION: ${{ needs.setup.outputs.version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} strategy: matrix: include: @@ -80,23 +76,29 @@ jobs: npm_command: "dist:bit:selfhost" - name: "cloud-QA" npm_command: "build:bit:qa" + git_metadata: true - name: "ee" npm_command: "build:bit:ee" + git_metadata: true - name: "cloud-euprd" npm_command: "build:bit:euprd" - name: "cloud-euqa" npm_command: "build:bit:euqa" + git_metadata: true + - name: "cloud-usdev" + npm_command: "build:bit:usdev" + git_metadata: true steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: "16" + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | @@ -111,9 +113,9 @@ jobs: - name: Install dependencies run: npm ci - - name: Setup QA metadata + - name: Add Git metadata to build version working-directory: apps/web - if: matrix.name == 'cloud-QA' + if: matrix.git_metadata run: | VERSION=$( jq -r ".version" package.json) jq --arg version "$VERSION+${GITHUB_SHA:0:7}" '.version = $version' package.json > package.json.tmp @@ -128,7 +130,7 @@ jobs: run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build - name: Upload ${{ matrix.name }} artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: web-${{ env._VERSION }}-${{ matrix.name }}.zip path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip @@ -146,23 +148,20 @@ jobs: matrix: include: - artifact_name: cloud-QA - registries: [bitwardenprod.azurecr.io, bitwardenqa.azurecr.io] image_name: web-qa-cloud - artifact_name: ee - registries: [bitwardenprod.azurecr.io, bitwardenqa.azurecr.io] image_name: web-ee - artifact_name: selfhosted-COMMERCIAL - registries: [bitwarden, bitwardenprod.azurecr.io, bitwardenqa.azurecr.io] image_name: web env: _VERSION: ${{ needs.setup.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Check Branch to Publish env: - PUBLISH_BRANCHES: "master,rc,hotfix-rc-web" + PUBLISH_BRANCHES: "main,rc,hotfix-rc-web" id: publish-branch-check run: | IFS="," read -a publish_branches <<< $PUBLISH_BRANCHES @@ -174,24 +173,28 @@ jobs: fi ########## ACRs ########## - - name: Login to Azure - QA - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 - with: - creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} - - - name: Log into QA container registry - run: az acr login -n bitwardenqa - - - name: Login to Azure - Prod - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + - name: Login to Prod Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - name: Log into Prod container registry run: az acr login -n bitwardenprod + - name: Login to Azure - CI Subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Retrieve github PAT secrets + id: retrieve-secret-pat + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: "bitwarden-ci" + secrets: "github-pat-bitwarden-devops-bot-repo-scope" + - name: Download ${{ matrix.artifact_name }} artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: name: web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip path: apps/web @@ -203,10 +206,10 @@ jobs: if [[ $(grep "pull" <<< "${GITHUB_REF}") ]]; then IMAGE_TAG=$(echo "${GITHUB_HEAD_REF}" | sed "s#/#-#g") else - IMAGE_TAG=$(echo "${GITHUB_REF:11}" | sed "s#/#-#g") + IMAGE_TAG=$(echo "${GITHUB_REF_NAME}" | sed "s#/#-#g") fi - if [[ "$IMAGE_TAG" == "master" ]]; then + if [[ "$IMAGE_TAG" == "main" ]]; then IMAGE_TAG=dev fi @@ -218,135 +221,117 @@ jobs: echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT - - name: Generate tag list - id: tag-list - env: - IMAGE_TAG: ${{ steps.tag.outputs.image_tag }} - PROJECT_NAME: ${{ matrix.image_name }} - run: echo "tags=bitwardenqa.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG},bitwardenprod.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - ########## Build Image ########## - name: Extract artifact working-directory: apps/web run: unzip web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip - - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 - with: - creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - - - name: Retrieve github PAT secrets - id: retrieve-secret-pat - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - keyvault: "bitwarden-ci" - secrets: "github-pat-bitwarden-devops-bot-repo-scope" - - - name: Setup DCT - if: ${{ env.is_publish_branch == 'true' }} - id: setup-dct - uses: bitwarden/gh-actions/setup-docker-trust@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - azure-creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - azure-keyvault-name: "bitwarden-ci" + - name: Generate image full name + id: image-name + env: + IMAGE_TAG: ${{ steps.tag.outputs.image_tag }} + PROJECT_NAME: ${{ matrix.image_name }} + run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - name: Build Docker image - uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1 + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 with: context: apps/web file: apps/web/Dockerfile platforms: linux/amd64 push: true - tags: ${{ steps.tag-list.outputs.tags }} + tags: ${{ steps.image-name.outputs.name }} secrets: | "GH_PAT=${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}" - - name: Push to DockerHub - if: contains(matrix.registries, 'bitwarden') && env.is_publish_branch == 'true' - env: - IMAGE_TAG: ${{ steps.tag.outputs.image_tag }} - PROJECT_NAME: ${{ matrix.image_name }} - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.setup-dct.outputs.dct-delegate-repo-passphrase }} - run: | - docker tag bitwardenprod.azurecr.io/$PROJECT_NAME:$IMAGE_TAG bitwarden/$PROJECT_NAME:$IMAGE_TAG - docker push bitwarden/$PROJECT_NAME:$IMAGE_TAG - - name: Log out of Docker run: docker logout crowdin-push: name: Crowdin Push - if: github.ref == 'refs/heads/master' - needs: - - build-artifacts + if: github.ref == 'refs/heads/main' + needs: build-artifacts runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0 + uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} CROWDIN_PROJECT_ID: "308189" with: config: apps/web/crowdin.yml - crowdin_branch_name: master + crowdin_branch_name: main upload_sources: true upload_translations: false + trigger-web-vault-deploy: + name: Trigger web vault deploy + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-22.04 + needs: build-artifacts + steps: + - name: Login to Azure - CI Subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Retrieve github PAT secrets + id: retrieve-secret-pat + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: "bitwarden-ci" + secrets: "github-pat-bitwarden-devops-bot-repo-scope" + + - name: Trigger web vault deploy using GitHub Run ID + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: 'bitwarden', + repo: 'clients', + workflow_id: 'deploy-web.yml', + ref: 'main', + inputs: { + 'environment': 'USDEV', + 'build-web-run-id': '${{ github.run_id }}' + } + }) check-failures: name: Check for failures if: always() runs-on: ubuntu-22.04 needs: - - cloc - setup - build-artifacts - build-containers - crowdin-push + - trigger-web-vault-deploy steps: - name: Check if any job failed - if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }} - env: - CLOC_STATUS: ${{ needs.cloc.result }} - SETUP_STATUS: ${{ needs.setup.result }} - ARTIFACT_STATUS: ${{ needs.build-artifacts.result }} - BUILD_CONTAINERS_STATUS: ${{ needs.build-containers.result }} - CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }} - run: | - if [ "$CLOC_STATUS" = "failure" ]; then - exit 1 - elif [ "$SETUP_STATUS" = "failure" ]; then - exit 1 - elif [ "$ARTIFACT_STATUS" = "failure" ]; then - exit 1 - elif [ "$BUILD_SELFHOST_STATUS" = "failure" ]; then - exit 1 - elif [ "$BUILD_CONTAINERS_STATUS" = "failure" ]; then - exit 1 - elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then - exit 1 - fi + if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure') + run: exit 1 - name: Login to Azure - Prod Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 if: failure() with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} @@ -354,7 +339,7 @@ jobs: - name: Retrieve secrets id: retrieve-secrets if: failure() - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "devops-alerts-slack-webhook-url" diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index eda9f8d0f7..ab08d509b3 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -3,45 +3,54 @@ name: Chromatic on: push: + branches-ignore: + - 'renovate/**' paths-ignore: - '.github/workflows/**' jobs: chromatic: name: Chromatic - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version: "16" - - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: fetch-depth: 0 + - name: Get Node Version + id: retrieve-node-version + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + + - name: Set up Node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ steps.retrieve-node-version.outputs.node_version }} + - name: Cache npm id: npm-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: "~/.npm" key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }} - name: Install Node dependencies run: npm ci - + # Manual build the storybook to resolve a chromatic/storybook bug related to TurboSnap - name: Build Storybook run: npm run build-storybook:ci - name: Publish to Chromatic - uses: chromaui/action@44caff7e88d584b04f79f04e31e819f9a95d4d8f + uses: chromaui/action@c9067691aca4a28d6fbb40d9eea6e144369fbcae # v10.9.5 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} storybookBuildDir: ./storybook-static exitOnceUploaded: true onlyChanged: true - externals: "[\"libs/components/**/*.scss\", \"libs/components/tailwind.config*.js\"]" + externals: "[\"libs/components/**/*.scss\", \"libs/components/**/*.css\", \"libs/components/tailwind.config*.js\"]" diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index 28498461d3..b6c2e27646 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -10,7 +10,7 @@ on: jobs: crowdin-sync: name: Autosync - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -23,29 +23,29 @@ jobs: crowdin_project_id: "308189" steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase" - name: Download translations - uses: bitwarden/gh-actions/crowdin@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/crowdin@main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} CROWDIN_PROJECT_ID: ${{ matrix.crowdin_project_id }} with: config: crowdin.yml - crowdin_branch_name: master + crowdin_branch_name: main upload_sources: false upload_translations: false download_translations: true diff --git a/.github/workflows/deploy-eu-prod-web.yml b/.github/workflows/deploy-eu-prod-web.yml deleted file mode 100644 index d2cadd295b..0000000000 --- a/.github/workflows/deploy-eu-prod-web.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: Deploy Web to EU-PRD Cloud - -on: - workflow_dispatch: - inputs: - tag: - description: "Branch name to deploy (examples: 'master', 'feature/sm')" - required: true - type: string - default: master - -jobs: - azure-deploy: - name: Deploy to Azure - runs-on: ubuntu-22.04 - env: - _WEB_ARTIFACT: "web-*-cloud-euprd.zip" - steps: - - name: Login to Azure - EU Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 - with: - creds: ${{ secrets.AZURE_KV_EU_PRD_SERVICE_PRINCIPAL }} - - - name: Retrieve Storage Account connection string - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - keyvault: webvault-westeurope-prod - secrets: "sa-bitwarden-web-vault-dev-key-temp" - - - name: Download latest cloud asset - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - workflow: build-web.yml - path: apps/web - workflow_conclusion: success - branch: ${{ github.event.inputs.tag }} - artifacts: ${{ env._WEB_ARTIFACT }} - - - name: Unzip build asset - working-directory: apps/web - run: unzip ${{ env._WEB_ARTIFACT }} - - - name: Empty container in Storage Account - run: | - az storage blob delete-batch \ - --source '$web' \ - --pattern '*' \ - --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" - - - name: Deploy to Azure Storage Account - working-directory: apps/web - run: | - az storage blob upload-batch \ - --source "./build" \ - --destination '$web' \ - --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \ - --overwrite \ - --no-progress diff --git a/.github/workflows/deploy-eu-qa-web.yml b/.github/workflows/deploy-eu-qa-web.yml deleted file mode 100644 index a5b161e5da..0000000000 --- a/.github/workflows/deploy-eu-qa-web.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: Deploy Web to EU-QA Cloud - -on: - workflow_dispatch: - inputs: - tag: - description: "Branch name to deploy (examples: 'master', 'feature/sm')" - required: true - type: string - default: master - -jobs: - azure-deploy: - name: Deploy to Azure - runs-on: ubuntu-22.04 - env: - _WEB_ARTIFACT: "web-*-cloud-euqa.zip" - steps: - - name: Login to Azure - EU Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 - with: - creds: ${{ secrets.AZURE_KV_EU_QA_SERVICE_PRINCIPAL }} - - - name: Retrieve Storage Account connection string - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - keyvault: webvaulteu-westeurope-qa - secrets: "sa-bitwarden-web-vault-dev-key-temp" - - - name: Download latest cloud asset - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - workflow: build-web.yml - path: apps/web - workflow_conclusion: success - branch: ${{ github.event.inputs.tag }} - artifacts: ${{ env._WEB_ARTIFACT }} - - - name: Unzip build asset - working-directory: apps/web - run: unzip ${{ env._WEB_ARTIFACT }} - - - name: Empty container in Storage Account - run: | - az storage blob delete-batch \ - --source '$web' \ - --pattern '*' \ - --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" - - - name: Deploy to Azure Storage Account - working-directory: apps/web - run: | - az storage blob upload-batch \ - --source "./build" \ - --destination '$web' \ - --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \ - --overwrite \ - --no-progress diff --git a/.github/workflows/deploy-non-prod-web.yml b/.github/workflows/deploy-non-prod-web.yml deleted file mode 100644 index 512fefb534..0000000000 --- a/.github/workflows/deploy-non-prod-web.yml +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: Deploy Web - Non-Prod -run-name: Deploy Web ${{ inputs.environment }} - -on: - workflow_dispatch: - inputs: - environment: - description: 'Environment' - default: 'QA' - type: choice - options: - - QA - - workflow_call: - inputs: - environment: - description: 'Environment' - default: 'QA' - type: string - -jobs: - setup: - name: Setup - runs-on: ubuntu-20.04 - outputs: - environment: ${{ steps.config.outputs.environment }} - environment-url: ${{ steps.config.outputs.environment-url }} - environment-name: ${{ steps.config.outputs.environment-name }} - environment-branch: ${{ steps.config.outputs.environment-branch }} - environment-artifact: ${{ steps.config.outputs.environment-artifact }} - steps: - - name: Configure - id: config - run: | - ENV_NAME_LOWER=$(echo "${{ inputs.environment }}" | awk '{print tolower($0)}') - echo "configuring the Web deploy for ${{ inputs.environment }}" - echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT - echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT - echo "environment-name=Web Vault - ${{ inputs.environment }}" >> $GITHUB_OUTPUT - echo "environment-branch=cf-pages-$ENV_NAME_LOWER" >> $GITHUB_OUTPUT - echo "environment-artifact=web-*-cloud-${{ inputs.environment }}.zip" >> $GITHUB_OUTPUT - - - cfpages-deploy: - name: Deploy Web Vault to ${{ inputs.environment }} CloudFlare Pages branch - needs: setup - runs-on: ubuntu-20.04 - env: - _ENVIRONMENT: ${{ needs.setup.outputs.environment }} - _ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }} - _ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }} - _ENVIRONMENT_BRANCH: ${{ needs.setup.outputs.environment-branch }} - _ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }} - steps: - - name: Create GitHub deployment - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 - id: deployment - with: - token: '${{ secrets.GITHUB_TOKEN }}' - initial-status: 'in_progress' - environment-url: ${{ env._ENVIRONMENT_URL }} - environment: ${{ env._ENVIRONMENT_NAME }} - description: 'Deployment from branch ${{ github.ref_name }}' - - - name: Checkout Repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Download latest cloud asset - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - workflow: build-web.yml - path: apps/web - workflow_conclusion: success - branch: ${{ github.ref_name }} - artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} - - - name: Unzip cloud asset - working-directory: apps/web - run: unzip ${{ env._ENVIRONMENT_ARTIFACT }} - - - name: Checkout Repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env._ENVIRONMENT_BRANCH }} - path: deployment - - - name: Setup git config - run: | - git config --global user.name "GitHub Action Bot" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global url."https://github.com/".insteadOf ssh://git@github.com/ - git config --global url."https://".insteadOf ssh:// - - - name: Deploy CloudFlare Pages - run: | - rm -rf ./* - cp -R ../apps/web/build/* . - working-directory: deployment - - - name: Push new ver to ${{ env._ENVIRONMENT_BRANCH }} - run: | - if [ -n "$(git status --porcelain)" ]; then - git add . - git commit -m "Deploy ${{ github.ref_name }} to ${{ env._ENVIRONMENT }} Cloudflare pages" - git push -u origin ${{ env._ENVIRONMENT_BRANCH }} - else - echo "No changes to commit!"; - fi - working-directory: deployment - - - name: Update deployment status to Success - if: ${{ success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 - with: - token: '${{ secrets.GITHUB_TOKEN }}' - environment-url: ${{ env._ENVIRONMENT_URL }} - state: 'success' - deployment-id: ${{ steps.deployment.outputs.deployment_id }} - - - name: Update deployment status to Failure - if: ${{ failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 - with: - token: '${{ secrets.GITHUB_TOKEN }}' - environment-url: ${{ env._ENVIRONMENT_URL }} - state: 'failure' - deployment-id: ${{ steps.deployment.outputs.deployment_id }} diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml new file mode 100644 index 0000000000..769e700588 --- /dev/null +++ b/.github/workflows/deploy-web.yml @@ -0,0 +1,367 @@ +--- +name: Deploy Web Vault +run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }} + +on: + workflow_dispatch: + inputs: + environment: + description: 'Environment' + default: 'QA' + type: choice + options: + - USQA + - EUQA + - USPROD + - EUPROD + - USDEV + branch-or-tag: + description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')" + type: string + default: main + force-delete-destination: + description: "Delete remote files that are not found locally" + type: boolean + default: false + debug: + description: "Debug mode" + type: boolean + default: true + build-web-run-id: + description: "Build-web workflow Run ID to use for artifact download" + type: string + required: false + + workflow_call: + inputs: + environment: + description: 'Environment' + default: 'USQA' + type: string + branch-or-tag: + description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')" + type: string + default: main + force-delete-destination: + description: "Delete remote files that are not found locally" + type: boolean + default: false + debug: + description: "Debug mode" + type: boolean + default: true + build-web-run-id: + description: "Build-web workflow Run ID to use for artifact download" + type: string + required: false + +permissions: + deployments: write + +jobs: + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + environment: ${{ steps.config.outputs.environment }} + environment-url: ${{ steps.config.outputs.environment-url }} + environment-name: ${{ steps.config.outputs.environment-name }} + environment-artifact: ${{ steps.config.outputs.environment-artifact }} + azure-login-creds: ${{ steps.config.outputs.azure-login-creds }} + retrieve-secrets-keyvault: ${{ steps.config.outputs.retrieve-secrets-keyvault }} + sync-utility: ${{ steps.config.outputs.sync-utility }} + sync-delete-destination-files: ${{ steps.config.outputs.sync-delete-destination-files }} + steps: + - name: Configure + id: config + run: | + ENV_NAME_LOWER=$(echo "${{ inputs.environment }}" | awk '{print tolower($0)}') + echo "configuring the Web deploy for ${{ inputs.environment }}" + echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT + + case ${{ inputs.environment }} in + "USQA") + echo "azure-login-creds=AZURE_KV_US_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT + echo "retrieve-secrets-keyvault=bw-webvault-rlktusqa-kv" >> $GITHUB_OUTPUT + echo "environment-artifact=web-*-cloud-QA.zip" >> $GITHUB_OUTPUT + echo "environment-name=Web Vault - US QA Cloud" >> $GITHUB_OUTPUT + echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + ;; + "EUQA") + echo "azure-login-creds=AZURE_KV_EU_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT + echo "retrieve-secrets-keyvault=webvaulteu-westeurope-qa" >> $GITHUB_OUTPUT + echo "environment-artifact=web-*-cloud-euqa.zip" >> $GITHUB_OUTPUT + echo "environment-name=Web Vault - EU QA Cloud" >> $GITHUB_OUTPUT + echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + ;; + "USPROD") + echo "azure-login-creds=AZURE_KV_US_PROD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT + echo "retrieve-secrets-keyvault=bw-webvault-klrt-kv" >> $GITHUB_OUTPUT + echo "environment-artifact=web-*-cloud-COMMERCIAL.zip" >> $GITHUB_OUTPUT + echo "environment-name=Web Vault - US Production Cloud" >> $GITHUB_OUTPUT + echo "environment-url=http://vault.bitwarden.com" >> $GITHUB_OUTPUT + ;; + "EUPROD") + echo "azure-login-creds=AZURE_KV_EU_PRD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT + echo "retrieve-secrets-keyvault=webvault-westeurope-prod" >> $GITHUB_OUTPUT + echo "environment-artifact=web-*-cloud-euprd.zip" >> $GITHUB_OUTPUT + echo "environment-name=Web Vault - EU Production Cloud" >> $GITHUB_OUTPUT + echo "environment-url=http://vault.bitwarden.eu" >> $GITHUB_OUTPUT + ;; + "USDEV") + echo "azure-login-creds=AZURE_KV_US_DEV_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT + echo "retrieve-secrets-keyvault=webvault-eastus-dev" >> $GITHUB_OUTPUT + echo "environment-artifact=web-*-cloud-usdev.zip" >> $GITHUB_OUTPUT + echo "environment-name=Web Vault - US Development Cloud" >> $GITHUB_OUTPUT + echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + ;; + esac + # Set the sync utility to use for deployment to the environment (az-sync or azcopy) + echo "sync-utility=azcopy" >> $GITHUB_OUTPUT + + approval: + name: Approval for Deployment to ${{ needs.setup.outputs.environment-name }} + needs: setup + runs-on: ubuntu-22.04 + environment: ${{ needs.setup.outputs.environment-name }} + steps: + - name: Success Code + run: exit 0 + + get-branch-or-tag-sha: + name: Get Branch or Tag SHA + runs-on: ubuntu-22.04 + outputs: + branch-or-tag-sha: ${{ steps.get-branch-or-tag-sha.outputs.sha }} + steps: + - name: Checkout Branch + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ inputs.branch-or-tag }} + fetch-depth: 0 + + - name: Get Branch or Tag SHA + id: get-branch-or-tag-sha + run: | + echo "sha=$(git rev-parse origin/${{ inputs.branch-or-tag }})" >> $GITHUB_OUTPUT + + notify-start: + name: Notify Slack with start message + needs: + - approval + - setup + - get-branch-or-tag-sha + runs-on: ubuntu-22.04 + if: ${{ always() && contains( inputs.environment , 'QA' ) }} + outputs: + channel_id: ${{ steps.slack-message.outputs.channel_id }} + ts: ${{ steps.slack-message.outputs.ts }} + steps: + - uses: bitwarden/gh-actions/report-deployment-status-to-slack@main + id: slack-message + with: + project: Clients + environment: ${{ needs.setup.outputs.environment-name }} + tag: ${{ inputs.branch-or-tag }} + slack-channel: team-eng-qa-devops + event: 'start' + commit-sha: ${{ needs.get-branch-or-tag-sha.outputs.branch-or-tag-sha }} + url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }} + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + artifact-check: + name: Check if Web artifact is present + runs-on: ubuntu-22.04 + needs: setup + env: + _ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }} + steps: + - name: 'Download latest cloud asset using GitHub Run ID: ${{ inputs.build-web-run-id }}' + if: ${{ inputs.build-web-run-id }} + uses: bitwarden/gh-actions/download-artifacts@main + id: download-latest-artifacts + continue-on-error: true + with: + workflow: build-web.yml + path: apps/web + workflow_conclusion: success + run_id: ${{ inputs.build-web-run-id }} + artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} + + - name: 'Download latest cloud asset from branch/tag: ${{ inputs.branch-or-tag }}' + if: ${{ !inputs.build-web-run-id }} + uses: bitwarden/gh-actions/download-artifacts@main + id: download-artifacts + continue-on-error: true + with: + workflow: build-web.yml + path: apps/web + workflow_conclusion: success + branch: ${{ inputs.branch-or-tag }} + artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} + + - name: Login to Azure + if: ${{ steps.download-artifacts.outcome == 'failure' }} + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Retrieve secrets for Build trigger + if: ${{ steps.download-artifacts.outcome == 'failure' }} + id: retrieve-secret + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: "bitwarden-ci" + secrets: "github-pat-bitwarden-devops-bot-repo-scope" + + - name: 'Trigger build web for missing branch/tag ${{ inputs.branch-or-tag }}' + if: ${{ steps.download-artifacts.outcome == 'failure' }} + uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be # v1.6.5 + with: + owner: bitwarden + repo: clients + github_token: ${{ steps.retrieve-secret.outputs.github-pat-bitwarden-devops-bot-repo-scope }} + workflow_file_name: build-web.yml + ref: ${{ inputs.branch-or-tag }} + wait_interval: 100 + + azure-deploy: + name: Deploy Web Vault to ${{ inputs.environment }} Storage Account + needs: + - setup + - artifact-check + - approval + runs-on: ubuntu-22.04 + env: + _ENVIRONMENT: ${{ needs.setup.outputs.environment }} + _ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }} + _ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }} + _ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }} + steps: + - name: Create GitHub deployment + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 + id: deployment + with: + token: '${{ secrets.GITHUB_TOKEN }}' + initial-status: 'in_progress' + environment-url: ${{ env._ENVIRONMENT_URL }} + environment: ${{ env._ENVIRONMENT_NAME }} + task: 'deploy' + description: 'Deployment from branch/tag: ${{ inputs.branch-or-tag }}' + + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets[needs.setup.outputs.azure-login-creds] }} + + - name: Retrieve Storage Account connection string for az sync + if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }} + id: retrieve-secrets-az-sync + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }} + secrets: "sa-bitwarden-web-vault-dev-key-temp" + + - name: Retrieve Storage Account name and SPN credentials for azcopy + if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }} + id: retrieve-secrets-azcopy + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }} + secrets: "sa-bitwarden-web-vault-name,sp-bitwarden-web-vault-password,sp-bitwarden-web-vault-appid,sp-bitwarden-web-vault-tenant" + + - name: 'Download latest cloud asset using GitHub Run ID: ${{ inputs.build-web-run-id }}' + if: ${{ inputs.build-web-run-id }} + uses: bitwarden/gh-actions/download-artifacts@main + id: download-latest-artifacts + continue-on-error: true + with: + workflow: build-web.yml + path: apps/web + workflow_conclusion: success + run_id: ${{ inputs.build-web-run-id }} + artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} + + - name: 'Download cloud asset from branch/tag: ${{ inputs.branch-or-tag }}' + if: ${{ !inputs.build-web-run-id }} + uses: bitwarden/gh-actions/download-artifacts@main + with: + workflow: build-web.yml + path: apps/web + workflow_conclusion: success + branch: ${{ inputs.branch-or-tag }} + artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} + + - name: Unzip build asset + working-directory: apps/web + run: unzip ${{ env._ENVIRONMENT_ARTIFACT }} + + - name: Sync to Azure Storage Account using az storage blob sync + if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }} + working-directory: apps/web + run: | + az storage blob sync \ + --source "./build" \ + --container '$web' \ + --connection-string "${{ steps.retrieve-secrets-az-sync.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \ + --delete-destination=${{ inputs.force-delete-destination }} + + - name: Sync to Azure Storage Account using azcopy + if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }} + working-directory: apps/web + env: + AZCOPY_AUTO_LOGIN_TYPE: SPN + AZCOPY_SPA_APPLICATION_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-appid }} + AZCOPY_SPA_CLIENT_SECRET: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-password }} + AZCOPY_TENANT_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-tenant }} + run: | + azcopy sync ./build 'https://${{ steps.retrieve-secrets-azcopy.outputs.sa-bitwarden-web-vault-name }}.blob.core.windows.net/$web/' \ + --delete-destination=${{ inputs.force-delete-destination }} --compare-hash="MD5" + + - name: Debug sync logs + if: ${{ inputs.debug }} + run: cat /home/runner/.azcopy/*.log + + - name: Debug index.html + if: ${{ inputs.debug }} + run: cat apps/web/build/index.html + + - name: Update deployment status to Success + if: success() + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 + with: + token: '${{ secrets.GITHUB_TOKEN }}' + environment-url: ${{ env._ENVIRONMENT_URL }} + state: 'success' + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + + - name: Update deployment status to Failure + if: failure() + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 + with: + token: '${{ secrets.GITHUB_TOKEN }}' + environment-url: ${{ env._ENVIRONMENT_URL }} + state: 'failure' + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + + notify: + name: Notify Slack with result + runs-on: ubuntu-22.04 + if: ${{ always() && contains( inputs.environment , 'QA' ) }} + needs: + - notify-start + - azure-deploy + - setup + - get-branch-or-tag-sha + steps: + - uses: bitwarden/gh-actions/report-deployment-status-to-slack@main + with: + project: Clients + environment: ${{ needs.setup.outputs.environment-name }} + tag: ${{ inputs.branch-or-tag }} + slack-channel: ${{ needs.notify-start.outputs.channel_id }} + event: ${{ needs.azure-deploy.result }} + url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }} + commit-sha: ${{ needs.get-branch-or-tag-sha.outputs.branch-or-tag-sha }} + update-ts: ${{ needs.notify-start.outputs.ts }} + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} diff --git a/.github/workflows/enforce-labels.yml b/.github/workflows/enforce-labels.yml index 73092bb2e0..a98c4ae1be 100644 --- a/.github/workflows/enforce-labels.yml +++ b/.github/workflows/enforce-labels.yml @@ -8,7 +8,7 @@ on: jobs: enforce-label: name: EnforceLabel - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Enforce Label uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2 diff --git a/.github/workflows/label-issue-pull-request.yml b/.github/workflows/label-issue-pull-request.yml index a83e9e569b..e52bba36d6 100644 --- a/.github/workflows/label-issue-pull-request.yml +++ b/.github/workflows/label-issue-pull-request.yml @@ -1,5 +1,5 @@ # Runs creation of Pull Requests -# If the PR destination branch is master, add a needs-qa label +# If the PR destination branch is main, add a needs-qa label unless created by renovate[bot] --- name: Label Issue Pull Request @@ -10,11 +10,12 @@ on: paths-ignore: - .github/workflows/** # We don't need QA on workflow changes branches: - - 'master' # We only want to check when PRs target master + - 'main' # We only want to check when PRs target main jobs: add-needs-qa-label: runs-on: ubuntu-latest + if: ${{ github.actor != 'renovate[bot]' }} steps: - name: Add label to pull request uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a3c3efdd19..ed5ada527c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,10 +18,10 @@ defaults: jobs: lint: name: Lint - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Lint filenames (no capital characters) run: | @@ -38,12 +38,19 @@ jobs: > tmp.txt diff <(sort .github/whitelist-capital-letters.txt) <(sort tmp.txt) + - name: Get Node Version + id: retrieve-node-version + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' + node-version: ${{ steps.retrieve-node-version.outputs.node_version }} - name: Run linter run: | diff --git a/.github/workflows/release-browser.yml b/.github/workflows/release-browser.yml index 11447afa7d..c260f19581 100644 --- a/.github/workflows/release-browser.yml +++ b/.github/workflows/release-browser.yml @@ -22,12 +22,12 @@ defaults: jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: release-version: ${{ steps.version.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -41,7 +41,7 @@ jobs: - name: Check Release Version id: version - uses: bitwarden/gh-actions/release-version-check@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/release-version-check@main with: release-type: ${{ github.event.inputs.release_type }} project-type: ts @@ -52,11 +52,11 @@ jobs: locales-test: name: Locales Test - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Testing locales - extName length run: | @@ -86,13 +86,13 @@ jobs: release: name: Create GitHub Release - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - setup - locales-test steps: - name: Create GitHub deployment - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 id: deployment with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -103,7 +103,7 @@ jobs: - name: Download latest Release build artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-browser.yml workflow_conclusion: success @@ -114,13 +114,13 @@ jobs: dist-firefox-*.zip, dist-edge-*.zip' - - name: Dry Run - Download latest master build artifacts + - name: Dry Run - Download latest build artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-browser.yml workflow_conclusion: success - branch: master + branch: main artifacts: 'browser-source-*.zip, dist-chrome-*.zip, dist-opera-*.zip, @@ -139,7 +139,7 @@ jobs: - name: Create release if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0 + uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 with: artifacts: 'browser-source-${{ needs.setup.outputs.release-version }}.zip, dist-chrome-${{ needs.setup.outputs.release-version }}.zip, @@ -155,7 +155,7 @@ jobs: - name: Update deployment status to Success if: ${{ success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'success' @@ -163,7 +163,7 @@ jobs: - name: Update deployment status to Failure if: ${{ failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'failure' diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 6186f0d6df..add0c539e9 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -15,12 +15,12 @@ on: - Redeploy - Dry Run snap_publish: - description: 'Publish to snap store' + description: 'Publish to Snap store' required: true default: true type: boolean choco_publish: - description: 'Publish to chocolatey store' + description: 'Publish to Chocolatey store' required: true default: true type: boolean @@ -38,12 +38,12 @@ defaults: jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: release-version: ${{ steps.version.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -57,7 +57,7 @@ jobs: - name: Check Release Version id: version - uses: bitwarden/gh-actions/release-version-check@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/release-version-check@main with: release-type: ${{ github.event.inputs.release_type }} project-type: ts @@ -67,7 +67,7 @@ jobs: - name: Create GitHub deployment if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 id: deployment with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -78,7 +78,7 @@ jobs: - name: Download all Release artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli @@ -87,16 +87,16 @@ jobs: - name: Dry Run - Download all artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli workflow_conclusion: success - branch: master + branch: main - name: Create release if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0 + uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 env: PKG_VERSION: ${{ steps.version.outputs.version }} with: @@ -118,7 +118,7 @@ jobs: - name: Update deployment status to Success if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'success' @@ -126,7 +126,7 @@ jobs: - name: Update deployment status to Failure if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'failure' @@ -134,35 +134,33 @@ jobs: snap: name: Deploy Snap - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup if: inputs.snap_publish env: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "snapcraft-store-token" - name: Install Snap uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1 - with: - snapcraft_token: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }} - name: Download artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli @@ -172,39 +170,41 @@ jobs: - name: Dry Run - Download artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli workflow_conclusion: success - branch: master + branch: main artifacts: bw_${{ env._PKG_VERSION }}_amd64.snap - name: Publish Snap & logout if: ${{ github.event.inputs.release_type != 'Dry Run' }} + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }} run: | - snapcraft push bw_${{ env._PKG_VERSION }}_amd64.snap --release stable + snapcraft upload bw_${{ env._PKG_VERSION }}_amd64.snap --release stable snapcraft logout choco: name: Deploy Choco - runs-on: windows-2019 + runs-on: windows-2022 needs: setup if: inputs.choco_publish env: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "cli-choco-api-key" @@ -220,7 +220,7 @@ jobs: - name: Download artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli/dist @@ -230,12 +230,12 @@ jobs: - name: Dry Run - Download artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli/dist workflow_conclusion: success - branch: master + branch: main artifacts: bitwarden-cli.${{ env._PKG_VERSION }}.nupkg - name: Push to Chocolatey @@ -247,30 +247,30 @@ jobs: npm: name: Publish NPM - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup if: inputs.npm_publish env: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "npm-api-key" - name: Download artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli/build @@ -280,12 +280,12 @@ jobs: - name: Dry Run - Download artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-cli.yml path: apps/cli/build workflow_conclusion: success - branch: master + branch: main artifacts: bitwarden-cli-${{ env._PKG_VERSION }}-npm-build.zip - name: Setup NPM diff --git a/.github/workflows/release-desktop-beta.yml b/.github/workflows/release-desktop-beta.yml index cf2ab64a56..b9e2d7a8c8 100644 --- a/.github/workflows/release-desktop-beta.yml +++ b/.github/workflows/release-desktop-beta.yml @@ -15,21 +15,22 @@ defaults: jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: release-version: ${{ steps.version.outputs.version }} release-channel: ${{ steps.release-channel.outputs.channel }} branch-name: ${{ steps.branch.outputs.branch-name }} build_number: ${{ steps.increment-version.outputs.build_number }} + node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Branch check run: | - if [[ "$GITHUB_REF" != "refs/heads/master" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then + if [[ "$GITHUB_REF" != "refs/heads/main" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then echo "===================================" - echo "[!] Can only release from the 'master', 'rc' or 'hotfix-rc' branches" + echo "[!] Can only release from the 'main', 'rc' or 'hotfix-rc' branches" echo "===================================" exit 1 fi @@ -47,7 +48,7 @@ jobs: - name: Check Release Version id: version - uses: bitwarden/gh-actions/release-version-check@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/release-version-check@main with: release-type: 'Initial Release' project-type: ts @@ -104,35 +105,36 @@ jobs: echo "branch-name=$branch_name" >> $GITHUB_OUTPUT + - name: Get Node Version + id: retrieve-node-version + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + linux: name: Linux Build - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.setup.outputs.branch-name }} - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Set up environment run: | @@ -157,42 +159,42 @@ jobs: run: npm run dist:lin - name: Upload .deb artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb if-no-files-found: error - name: Upload .rpm artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm if-no-files-found: error - name: Upload .freebsd artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd if-no-files-found: error - name: Upload .snap artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload .AppImage artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release-channel }}-linux.yml path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml @@ -201,7 +203,7 @@ jobs: windows: name: Windows Build - runs-on: windows-2019 + runs-on: windows-2022 needs: setup defaults: run: @@ -209,29 +211,23 @@ jobs: working-directory: apps/desktop env: _PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.setup.outputs.branch-name }} - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Install AST - uses: bitwarden/gh-actions/install-ast@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + run: dotnet tool install --global AzureSignTool --version 4.0.1 - name: Set up environment run: choco install checksum --no-progress @@ -243,13 +239,13 @@ jobs: choco --version - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "code-signing-vault-url, @@ -304,91 +300,91 @@ jobs: -NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z - name: Upload portable exe artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload installer exe artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload appx ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx if-no-files-found: error - name: Upload store appx ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx if-no-files-found: error - name: Upload NSIS ia32 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z if-no-files-found: error - name: Upload appx x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx if-no-files-found: error - name: Upload store appx x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx if-no-files-found: error - name: Upload NSIS x64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z if-no-files-found: error - name: Upload appx ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx if-no-files-found: error - name: Upload store appx ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx if-no-files-found: error - name: Upload NSIS ARM64 artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z if-no-files-found: error - name: Upload nupkg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release-channel }}.yml path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml @@ -397,33 +393,30 @@ jobs: macos-build: name: MacOS Build + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: setup env: _PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.setup.outputs.branch-name }} - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | @@ -434,70 +427,78 @@ jobs: - name: Cache Build id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Cache Safari id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -524,35 +525,32 @@ jobs: macos-package-github: name: MacOS Package GitHub Release Assets + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: - setup - macos-build env: _PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.setup.outputs.branch-name }} - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | @@ -563,70 +561,84 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -653,7 +665,7 @@ jobs: - name: Download artifact from hotfix-rc if: github.ref == 'refs/heads/hotfix-rc' - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success @@ -662,20 +674,20 @@ jobs: - name: Download artifact from rc if: github.ref == 'refs/heads/rc' - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success branch: rc path: ${{ github.workspace }}/browser-build-artifacts - - name: Download artifact from master + - name: Download artifacts from main if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }} - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success - branch: master + branch: main path: ${{ github.workspace }}/browser-build-artifacts - name: Unzip Safari artifact @@ -696,28 +708,28 @@ jobs: run: npm run pack:mac - name: Upload .zip artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip if-no-files-found: error - name: Upload .dmg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg if-no-files-found: error - name: Upload .dmg blockmap artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ${{ needs.setup.outputs.release-channel }}-mac.yml path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml @@ -726,35 +738,32 @@ jobs: macos-package-mas: name: MacOS Package Prod Release Asset + # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina, + # as the newer versions will case the native modules to be incompatible with older macOS systems + # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules runs-on: macos-11 needs: - setup - macos-build env: _PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + NODE_OPTIONS: --max_old_space_size=4096 defaults: run: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ needs.setup.outputs.branch-name }} - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' - - - name: Set Node options - run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV - - - name: Install node-gyp - run: | - npm install -g node-gyp - node-gyp install $(node -v) + node-version: ${{ env._NODE_VERSION }} - name: Print environment run: | @@ -765,70 +774,79 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - - name: Decrypt secrets + - name: Download Provisioning Profiles secrets env: - DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + ACCOUNT_NAME: bitwardenci + CONTAINER_NAME: profiles run: | mkdir -p $HOME/secrets - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden-desktop-key.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/appstore-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-app-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/devid-installer-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/macdev-cert.p12" \ - "$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg" - gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \ - --output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \ - "$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg" + + az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ + --name bitwarden_desktop_appstore.provisionprofile \ + --file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ + --output none + + - name: Get certificates + run: | + mkdir -p $HOME/certificates + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key | + jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert | + jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12 + + az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert | + jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }} - DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }} - APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }} - MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: | security create-keychain -p $KEYCHAIN_PASSWORD build.keychain security default-keychain -s build.keychain security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain security set-keychain-settings -lut 1200 build.keychain - security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \ + + security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \ + + security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \ + + security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild - security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \ + + security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \ -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles @@ -855,7 +873,7 @@ jobs: - name: Download artifact from hotfix-rc if: github.ref == 'refs/heads/hotfix-rc' - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success @@ -864,20 +882,20 @@ jobs: - name: Download artifact from rc if: github.ref == 'refs/heads/rc' - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success branch: rc path: ${{ github.workspace }}/browser-build-artifacts - - name: Download artifact from master + - name: Download artifact from main if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }} - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 + uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2 with: workflow: build-browser.yml workflow_conclusion: success - branch: master + branch: main path: ${{ github.workspace }}/browser-build-artifacts - name: Unzip Safari artifact @@ -898,7 +916,7 @@ jobs: APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - name: Upload .pkg artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg @@ -906,7 +924,7 @@ jobs: release: name: Release beta channel to S3 - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - setup - linux @@ -916,7 +934,7 @@ jobs: - macos-package-mas steps: - name: Create GitHub deployment - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 id: deployment with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -926,13 +944,13 @@ jobs: task: release - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, @@ -944,7 +962,7 @@ jobs: cf-prod-account" - name: Download all artifacts - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: path: apps/desktop/artifacts @@ -983,7 +1001,7 @@ jobs: - name: Update deployment status to Success if: ${{ success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'success' @@ -991,7 +1009,7 @@ jobs: - name: Update deployment status to Failure if: ${{ failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'failure' @@ -999,7 +1017,7 @@ jobs: remove-branch: name: Remove branch - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: always() needs: - setup @@ -1011,7 +1029,7 @@ jobs: - release steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup git config run: | diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 2dc8bb3b31..cf857d7177 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -30,12 +30,12 @@ on: default: true type: boolean electron_publish: - description: 'Publish electron to S3 bucket' + description: 'Publish Electron to S3 bucket' required: true default: true type: boolean github_release: - description: 'Publish github release' + description: 'Publish GitHub release' required: true default: true type: boolean @@ -47,13 +47,13 @@ defaults: jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: release-version: ${{ steps.version.outputs.version }} release-channel: ${{ steps.release-channel.outputs.channel }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -67,9 +67,9 @@ jobs: - name: Check Release Version id: version - uses: bitwarden/gh-actions/release-version-check@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/release-version-check@main with: - release-type: ${{ github.event.inputs.release_type }} + release-type: ${{ inputs.release_type }} project-type: ts file: apps/desktop/src/package.json monorepo: true @@ -94,7 +94,7 @@ jobs: - name: Create GitHub deployment if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 id: deployment with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -104,13 +104,13 @@ jobs: task: release - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, @@ -123,7 +123,7 @@ jobs: - name: Download all artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success @@ -132,11 +132,11 @@ jobs: - name: Dry Run - Download all artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success - branch: master + branch: main path: apps/desktop/artifacts - name: Rename .pkg to .pkg.archive @@ -146,17 +146,17 @@ jobs: run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive - name: Set staged rollout percentage - if: ${{ github.event.inputs.electron_publish }} + if: ${{ github.event.inputs.electron_publish == 'true' }} env: RELEASE_CHANNEL: ${{ steps.release-channel.outputs.channel }} - ROLLOUT_PCT: ${{ github.event.inputs.rollout_percentage }} + ROLLOUT_PCT: ${{ inputs.rollout_percentage }} run: | echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}.yml echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-linux.yml echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-mac.yml - name: Publish artifacts to S3 - if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish }} + if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }} env: AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }} AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }} @@ -170,7 +170,7 @@ jobs: --quiet - name: Publish artifacts to R2 - if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish }} + if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }} env: AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }} AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }} @@ -185,14 +185,14 @@ jobs: --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - name: Get checksum files - uses: bitwarden/gh-actions/get-checksum@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-checksum@main with: packages_dir: "apps/desktop/artifacts" file_path: "apps/desktop/artifacts/sha256-checksums.txt" - name: Create Release - uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0 - if: ${{ steps.release-channel.outputs.channel == 'latest' && github.event.inputs.release_type != 'Dry Run' && inputs.github_release }} + uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + if: ${{ steps.release-channel.outputs.channel == 'latest' && github.event.inputs.release_type != 'Dry Run' && github.event.inputs.github_release == 'true' }} env: PKG_VERSION: ${{ steps.version.outputs.version }} RELEASE_CHANNEL: ${{ steps.release-channel.outputs.channel }} @@ -231,7 +231,7 @@ jobs: - name: Update deployment status to Success if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'success' @@ -239,7 +239,7 @@ jobs: - name: Update deployment status to Failure if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' state: 'failure' @@ -247,31 +247,29 @@ jobs: snap: name: Deploy Snap - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup - if: inputs.snap_publish + if: ${{ github.event.inputs.snap_publish == 'true' }} env: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout Repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "snapcraft-store-token" - name: Install Snap uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1 - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }} - name: Setup run: mkdir dist @@ -279,7 +277,7 @@ jobs: - name: Download Snap artifact if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success @@ -289,11 +287,11 @@ jobs: - name: Dry Run - Download Snap artifact if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success - branch: master + branch: main artifacts: bitwarden_${{ env._PKG_VERSION }}_amd64.snap path: apps/desktop/dist @@ -302,20 +300,20 @@ jobs: env: SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }} run: | - /snap/bin/snapcraft upload bitwarden_${{ env._PKG_VERSION }}_amd64.snap --release stable - /snap/bin/snapcraft logout + snapcraft upload bitwarden_${{ env._PKG_VERSION }}_amd64.snap --release stable + snapcraft logout working-directory: apps/desktop/dist choco: name: Deploy Choco - runs-on: windows-2019 + runs-on: windows-2022 needs: setup - if: inputs.choco_publish + if: ${{ github.event.inputs.choco_publish == 'true' }} env: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout Repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Print Environment run: | @@ -323,13 +321,13 @@ jobs: dotnet nuget --version - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "cli-choco-api-key" @@ -347,7 +345,7 @@ jobs: - name: Download choco artifact if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success @@ -357,11 +355,11 @@ jobs: - name: Dry Run - Download choco artifact if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-desktop.yml workflow_conclusion: success - branch: master + branch: main artifacts: bitwarden.${{ env._PKG_VERSION }}.nupkg path: apps/desktop/dist diff --git a/.github/workflows/release-web.yml b/.github/workflows/release-web.yml index 601d788449..2da6daaa19 100644 --- a/.github/workflows/release-web.yml +++ b/.github/workflows/release-web.yml @@ -15,16 +15,19 @@ on: - Redeploy - Dry Run +env: + _AZ_REGISTRY: bitwardenprod.azurecr.io + jobs: setup: name: Setup - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: release_version: ${{ steps.version.outputs.version }} tag_version: ${{ steps.version.outputs.tag }} steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -38,7 +41,7 @@ jobs: - name: Check Release Version id: version - uses: bitwarden/gh-actions/release-version-check@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/release-version-check@main with: release-type: ${{ github.event.inputs.release_type }} project-type: ts @@ -46,10 +49,9 @@ jobs: monorepo: true monorepo-project: web - self-host: name: Release self-host docker - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: setup env: _BRANCH_NAME: ${{ github.ref_name }} @@ -65,195 +67,74 @@ jobs: echo "Github Release Option: $_RELEASE_OPTION" - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - ########## DockerHub ########## - - name: Setup DCT - id: setup-dct - uses: bitwarden/gh-actions/setup-docker-trust@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - azure-creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - azure-keyvault-name: "bitwarden-ci" - - - name: Pull branch image - run: | - if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then - docker pull bitwarden/web:latest - else - docker pull bitwarden/web:$_BRANCH_NAME - fi - - - name: Docker Tag version - run: | - if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then - docker tag bitwarden/web:latest bitwarden/web:$_RELEASE_VERSION - else - docker tag bitwarden/web:$_BRANCH_NAME bitwarden/web:$_RELEASE_VERSION - fi - - - name: Docker Push version - if: ${{ github.event.inputs.release_type != 'Dry Run' }} - env: - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.setup-dct.outputs.dct-delegate-repo-passphrase }} - run: docker push bitwarden/web:$_RELEASE_VERSION - - - name: Log out of Docker and disable Docker Notary - run: | - docker logout - echo "DOCKER_CONTENT_TRUST=0" >> $GITHUB_ENV + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 ########## ACR ########## - name: Login to Azure - PROD Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - name: Login to Azure ACR run: az acr login -n bitwardenprod - - name: Tag version - env: - REGISTRY: bitwardenprod.azurecr.io + - name: Pull branch image run: | if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then - docker tag bitwarden/web:latest $REGISTRY/web:$_RELEASE_VERSION - - docker tag bitwarden/web:latest $REGISTRY/web-sh:$_RELEASE_VERSION + docker pull $_AZ_REGISTRY/web:latest else - docker tag bitwarden/web:$_BRANCH_NAME $REGISTRY/web:$_RELEASE_VERSION + docker pull $_AZ_REGISTRY/web:$_BRANCH_NAME + fi - docker tag bitwarden/web:$_BRANCH_NAME $REGISTRY/web-sh:$_RELEASE_VERSION + - name: Tag version + run: | + if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then + docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web:dryrun + docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web-sh:dryrun + else + docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:$_RELEASE_VERSION + docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION + docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:latest + docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:latest fi - name: Push version - if: ${{ github.event.inputs.release_type != 'Dry Run' }} - env: - REGISTRY: bitwardenprod.azurecr.io run: | - docker push $REGISTRY/web:$_RELEASE_VERSION - - docker push $REGISTRY/web-sh:$_RELEASE_VERSION + if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then + docker push $_AZ_REGISTRY/web:dryrun + docker push $_AZ_REGISTRY/web-sh:dryrun + else + docker push $_AZ_REGISTRY/web:$_RELEASE_VERSION + docker push $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION + docker push $_AZ_REGISTRY/web:latest + docker push $_AZ_REGISTRY/web-sh:latest + fi - name: Log out of Docker run: docker logout - - ghpages-deploy: - name: Deploy to GitHub Pages - runs-on: ubuntu-20.04 - needs: - - setup - env: - _RELEASE_VERSION: ${{ needs.setup.outputs.release_version }} - _TAG_VERSION: ${{ needs.setup.outputs.tag_version }} - _BRANCH: "v${{ needs.setup.outputs.release_version }}-deploy" - steps: - - name: Login to Azure - CI Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 - with: - creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - - - name: Retrieve bot secrets - id: retrieve-bot-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - keyvault: bitwarden-ci - secrets: "github-pat-bitwarden-devops-bot-repo-scope" - - - name: Checkout GH pages repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - repository: bitwarden/web-vault-pages - path: ghpages-deployment - token: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }} - - - name: Download latest cloud asset - if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - workflow: build-web.yml - path: assets - workflow_conclusion: success - branch: ${{ github.ref_name }} - artifacts: web-*-cloud-COMMERCIAL.zip - - - name: Dry Run - Download latest cloud asset - if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c - with: - workflow: build-web.yml - path: assets - workflow_conclusion: success - branch: master - artifacts: web-*-cloud-COMMERCIAL.zip - - - name: Unzip build asset - working-directory: assets - run: unzip web-*-cloud-COMMERCIAL.zip - - - name: Create new branch - run: | - cd ${{ github.workspace }}/ghpages-deployment - git config user.name = "GitHub Action Bot" - git config user.email = "<>" - git config --global url."https://github.com/".insteadOf ssh://git@github.com/ - git config --global url."https://".insteadOf ssh:// - git checkout -b ${_BRANCH} - - - name: Copy build files - run: | - rm -rf ${{ github.workspace }}/ghpages-deployment/* - cp -Rf ${{ github.workspace }}/assets/build/* ghpages-deployment/ - - - name: Commit and push changes - working-directory: ghpages-deployment - run: | - git add . - git commit -m "Deploy Web v${_RELEASE_VERSION} to GitHub Pages" - git push --set-upstream origin ${_BRANCH} --force - - - name: Create GitHub Pages Deploy PR - working-directory: ghpages-deployment - env: - GITHUB_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }} - run: | - if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then - gh pr create --title "Deploy v${_RELEASE_VERSION} to GitHub Pages" \ - --draft \ - --body "Deploying v${_RELEASE_VERSION}" \ - --base master \ - --head "${_BRANCH}" - else - gh pr create --title "Deploy v${_RELEASE_VERSION} to GitHub Pages" \ - --body "Deploying v${_RELEASE_VERSION}" \ - --base master \ - --head "${_BRANCH}" - fi - release: name: Create GitHub Release - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - setup - self-host - - ghpages-deploy steps: - name: Create GitHub deployment if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5 + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 id: deployment with: token: '${{ secrets.GITHUB_TOKEN }}' initial-status: 'in_progress' environment-url: http://vault.bitwarden.com - environment: 'Web Vault - Production' + environment: 'Web Vault - US Production Cloud' description: 'Deployment ${{ needs.setup.outputs.release_version }} from branch ${{ github.ref_name }}' task: release - name: Download latest build artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-web.yml path: apps/web/artifacts @@ -264,12 +145,12 @@ jobs: - name: Dry Run - Download latest build artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-web.yml path: apps/web/artifacts workflow_conclusion: success - branch: master + branch: main artifacts: "web-*-selfhosted-COMMERCIAL.zip, web-*-selfhosted-open-source.zip" @@ -281,7 +162,7 @@ jobs: - name: Create release if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0 + uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 with: name: "Web v${{ needs.setup.outputs.release_version }}" commit: ${{ github.sha }} @@ -294,7 +175,7 @@ jobs: - name: Update deployment status to Success if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' environment-url: http://vault.bitwarden.com @@ -303,7 +184,7 @@ jobs: - name: Update deployment status to Failure if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }} - uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 with: token: '${{ secrets.GITHUB_TOKEN }}' environment-url: http://vault.bitwarden.com diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml new file mode 100644 index 0000000000..9aa6745faa --- /dev/null +++ b/.github/workflows/scan.yml @@ -0,0 +1,78 @@ +name: Scan + +on: + workflow_dispatch: + push: + branches: + - "main" + - "rc" + - "hotfix-rc" + pull_request_target: + types: [opened, synchronize] + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + sast: + name: SAST scan + runs-on: ubuntu-22.04 + needs: check-run + permissions: + contents: read + pull-requests: write + security-events: write + + steps: + - name: Check out repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Scan with Checkmarx + uses: checkmarx/ast-github-action@749fec53e0db0f6404a97e2e0807c3e80e3583a7 #2.0.23 + env: + INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}" + with: + project_name: ${{ github.repository }} + cx_tenant: ${{ secrets.CHECKMARX_TENANT }} + base_uri: https://ast.checkmarx.net/ + cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }} + cx_client_secret: ${{ secrets.CHECKMARX_SECRET }} + additional_params: | + --report-format sarif \ + --filter "state=TO_VERIFY;PROPOSED_NOT_EXPLOITABLE;CONFIRMED;URGENT" \ + --output-path . ${{ env.INCREMENTAL }} + + - name: Upload Checkmarx results to GitHub + uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + with: + sarif_file: cx_result.sarif + + quality: + name: Quality scan + runs-on: ubuntu-22.04 + needs: check-run + permissions: + contents: read + pull-requests: write + + steps: + - name: Check out repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Scan with SonarCloud + uses: sonarsource/sonarcloud-github-action@49e6cd3b187936a73b8280d59ffd9da69df63ec9 # v2.1.1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: > + -Dsonar.organization=${{ github.repository_owner }} + -Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }} + -Dsonar.test.inclusions=**/*.spec.ts + -Dsonar.tests=. diff --git a/.github/workflows/staged-rollout-desktop.yml b/.github/workflows/staged-rollout-desktop.yml index 477192b505..a5b5fc69b1 100644 --- a/.github/workflows/staged-rollout-desktop.yml +++ b/.github/workflows/staged-rollout-desktop.yml @@ -20,13 +20,13 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Login to Azure - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 98f3b9d172..4d3085ce00 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -8,10 +8,10 @@ on: jobs: stale: name: 'Check for stale issues and PRs' - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: 'Run stale action' - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0 + uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0 with: stale-issue-label: 'needs-reply' stale-pr-label: 'needs-changes' @@ -27,4 +27,4 @@ jobs: If you’re still working on this, please respond here after you’ve made the changes we’ve requested and our team will re-open it for further review. - Please make sure to resolve any conflicts with the master branch before requesting another review. + Please make sure to resolve any conflicts with the main branch before requesting another review. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 55363a329e..3c650d8a62 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,17 +3,12 @@ name: Run tests on: workflow_dispatch: + push: + branches: + - "main" + - "rc" + - "hotfix-rc-*" pull_request: - branches-ignore: - - 'l10n_master' - - 'cf-pages' - paths: - - 'apps/**' - - 'libs/**' - - '*' - - '!*.md' - - '!*.txt' - - '.github/workflows/test.yml' defaults: run: @@ -25,14 +20,21 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get Node Version + id: retrieve-node-version + run: | + NODE_NVMRC=$(cat .nvmrc) + NODE_VERSION=${NODE_NVMRC/v/''} + echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT - name: Set up Node - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: cache: 'npm' cache-dependency-path: '**/package-lock.json' - node-version: '18' + node-version: ${{ steps.retrieve-node-version.outputs.node_version }} - name: Print environment run: | @@ -46,13 +48,13 @@ jobs: # Tests in apps/ are typechecked when their app is built, so we just do it here for libs/ # See https://bitwarden.atlassian.net/browse/EC-497 - name: Run typechecking - run: npm run test:types + run: npm run test:types --coverage - name: Run tests - run: npm run test + run: npm run test --coverage - name: Report test results - uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226 # v1.6.0 + uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0 if: always() with: name: Test Results @@ -60,6 +62,11 @@ jobs: reporter: jest-junit fail-on-error: true + - name: Upload to codecov.io + uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + rust: name: rust - ${{ matrix.os }} runs-on: ${{ matrix.os || 'ubuntu-latest' }} @@ -82,7 +89,7 @@ jobs: sudo apt-get install -y gnome-keyring dbus-x11 - name: Checkout repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Build working-directory: ./apps/desktop/desktop_native diff --git a/.github/workflows/version-auto-bump.yml b/.github/workflows/version-auto-bump.yml index 2c13ec05b3..d0d028e570 100644 --- a/.github/workflows/version-auto-bump.yml +++ b/.github/workflows/version-auto-bump.yml @@ -1,49 +1,35 @@ --- -name: Version Auto Bump +name: Auto Bump Desktop Version on: push: tags: - desktop-v** -defaults: - run: - shell: bash - jobs: - setup: - name: "Setup" + bump-version: + name: Bump Desktop Version runs-on: ubuntu-22.04 - outputs: - version_number: ${{ steps.version.outputs.new-version }} steps: - - name: Checkout Branch - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Login to Azure - CI Subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - - name: Calculate bumped version - id: version + - name: Retrieve bot secrets + id: retrieve-bot-secrets + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: bitwarden-ci + secrets: "github-pat-bitwarden-devops-bot-repo-scope" + + - name: Trigger Version Bump workflow env: - RELEASE_TAG: ${{ github.ref }} + GH_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }} run: | - CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/[a-z]*-v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/') - CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/[a-z]*-v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/') - echo "Current Major: $CURR_MAJOR" - echo "Current Patch: $CURR_PATCH" - - NEW_PATCH=$((CURR_PATCH+1)) - - echo "New patch: $NEW_PATCH" - - NEW_VER=$CURR_MAJOR.$NEW_PATCH - echo "New Version: $NEW_VER" - echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT - - trigger_version_bump: - name: Bump version to ${{ needs.setup.outputs.version_number }} - needs: setup - uses: ./.github/workflows/version-bump.yml - secrets: - AZURE_PROD_KV_CREDENTIALS: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - with: - version_number: ${{ needs.setup.outputs.version_number }} - client: "Desktop" + echo '{"cut_rc_branch": "false", \ + "bump_browser": "false", \ + "bump_cli": "false", \ + "bump_desktop": "true", \ + "bump_web": "false"}' | \ + gh workflow run version-bump.yml --json --repo bitwarden/clients diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index f30a935c4b..246ca9a533 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -4,141 +4,391 @@ name: Version Bump on: workflow_dispatch: inputs: - client: - description: "Client Project" - required: true - type: choice - options: - - Browser - - CLI - - Desktop - - Web - - All - version_number: - description: "New Version" - required: true - - workflow_call: - inputs: - version_number: - required: true + bump_browser: + description: "Bump Browser?" + type: boolean + default: false + bump_cli: + description: "Bump CLI?" + type: boolean + default: false + bump_desktop: + description: "Bump Desktop?" + type: boolean + default: false + bump_web: + description: "Bump Web?" + type: boolean + default: false + version_number_override: + description: "New version override (leave blank for automatic calculation, example: '2024.1.0')" + required: false type: string - client: - required: true - type: string - secrets: - AZURE_PROD_KV_CREDENTIALS: - required: true - -defaults: - run: - shell: bash + cut_rc_branch: + description: "Cut RC branch?" + default: true + type: boolean jobs: bump_version: - name: "Bump ${{ github.event.inputs.client }} Version" - runs-on: ubuntu-20.04 + name: Bump Version + runs-on: ubuntu-22.04 + outputs: + version_browser: ${{ steps.set-final-version-output.outputs.version_browser }} + version_cli: ${{ steps.set-final-version-output.outputs.version_cli }} + version_desktop: ${{ steps.set-final-version-output.outputs.version_desktop }} + version_web: ${{ steps.set-final-version-output.outputs.version_web }} steps: - - name: Checkout Branch - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Login to Azure - Prod Subscription - uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 + - name: Validate version input + if: ${{ inputs.version_number_override != '' }} + uses: bitwarden/gh-actions/version-check@main with: - creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + version: ${{ inputs.version_number_override }} + + - name: Checkout Branch + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: main + + - name: Check if RC branch exists + if: ${{ inputs.cut_rc_branch == true }} + run: | + remote_rc_branch_check=$(git ls-remote --heads origin rc | wc -l) + if [[ "${remote_rc_branch_check}" -gt 0 ]]; then + echo "Remote RC branch exists." + echo "Please delete current RC branch before running again." + exit 1 + fi + + - name: Login to Azure - CI Subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" - secrets: "github-gpg-private-key, github-gpg-private-key-passphrase" + secrets: "github-gpg-private-key, + github-gpg-private-key-passphrase, + github-pat-bitwarden-devops-bot-repo-scope" - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@72b6676b71ab476b77e676928516f6982eef7a41 # v5.3.0 + uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 with: gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }} passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }} git_user_signingkey: true git_commit_gpgsign: true - - name: Create Version Branch - id: branch - env: - CLIENT_NAME: ${{ github.event.inputs.client }} - VERSION: ${{ github.event.inputs.version_number }} + - name: Setup git run: | - CLIENT=$(python -c "print('$CLIENT_NAME'.lower())") - echo "client=$CLIENT" >> $GITHUB_OUTPUT + git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com" + git config --local user.name "bitwarden-devops-bot" - git switch -c ${CLIENT}_version_bump_${VERSION} + - name: Create Version Branch + id: create-branch + run: | + CLIENTS=() + if [[ ${{ inputs.bump_browser }} == true ]]; then + CLIENTS+=("browser") + fi + if [[ ${{ inputs.bump_cli }} == true ]]; then + CLIENTS+=("cli") + fi + if [[ ${{ inputs.bump_desktop }} == true ]]; then + CLIENTS+=("desktop") + fi + if [[ ${{ inputs.bump_web }} == true ]]; then + CLIENTS+=("web") + fi + printf -v joined '%s,' "${CLIENTS[@]}" + echo "client=${joined%,}" >> $GITHUB_OUTPUT + + NAME=version_bump_${{ github.ref_name }}_$(date +"%Y-%m-%d") + git switch -c $NAME + echo "name=$NAME" >> $GITHUB_OUTPUT ######################## # VERSION BUMP SECTION # ######################## ### Browser - - name: Bump Browser Version - if: ${{ github.event.inputs.client == 'Browser' || github.event.inputs.client == 'All' }} + - name: Get current Browser version + if: ${{ inputs.bump_browser == true }} + id: current-browser-version + run: | + CURRENT_VERSION=$(cat package.json | jq -r '.version') + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + working-directory: apps/browser + + - name: Browser - Verify input version + if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }} env: - VERSION: ${{ github.event.inputs.version_number }} - run: npm version --workspace=@bitwarden/browser ${VERSION} + CURRENT_VERSION: ${{ steps.current-browser-version.outputs.version }} + NEW_VERSION: ${{ inputs.version_number_override }} + run: | + # Error if version has not changed. + if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then + echo "Version has not changed." + exit 1 + fi - - name: Bump Browser Version - Manifest - if: ${{ github.event.inputs.client == 'Browser' || github.event.inputs.client == 'All' }} - uses: bitwarden/gh-actions/version-bump@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + # Check if version is newer. + printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V + if [ $? -eq 0 ]; then + echo "Version check successful." + else + echo "Version check failed." + exit 1 + fi + working-directory: apps/browser + + - name: Calculate next Browser release version + if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }} + id: calculate-next-browser-version + uses: bitwarden/gh-actions/version-next@main + with: + version: ${{ steps.current-browser-version.outputs.version }} + + - name: Bump Browser Version - Version Override + if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }} + id: bump-browser-version-override + run: npm version --workspace=@bitwarden/browser ${{ inputs.version_number_override }} + + - name: Bump Browser Version - Automatic Calculation + if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }} + id: bump-browser-version-automatic + env: + VERSION: ${{ steps.calculate-next-browser-version.outputs.version }} + run: npm version --workspace=@bitwarden/browser $VERSION + + - name: Bump Browser Version - Manifest - Version Override + if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }} + uses: bitwarden/gh-actions/version-bump@main with: - version: ${{ github.event.inputs.version_number }} file_path: "apps/browser/src/manifest.json" + version: ${{ inputs.version_number_override }} - - name: Bump Browser Version - Manifest v3 - if: ${{ github.event.inputs.client == 'Browser' || github.event.inputs.client == 'All' }} - uses: bitwarden/gh-actions/version-bump@a30e9c3d658dc97c4c2e61ec749fdab64b83386c + - name: Bump Browser Version - Manifest - Automatic Calculation + if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }} + uses: bitwarden/gh-actions/version-bump@main + with: + file_path: "apps/browser/src/manifest.json" + version: ${{ steps.calculate-next-browser-version.outputs.version }} + + - name: Bump Browser Version - Manifest v3 - Version Override + if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }} + uses: bitwarden/gh-actions/version-bump@main with: - version: ${{ github.event.inputs.version_number }} file_path: "apps/browser/src/manifest.v3.json" + version: ${{ inputs.version_number_override }} + + - name: Bump Browser Version - Manifest v3 - Automatic Calculation + if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }} + uses: bitwarden/gh-actions/version-bump@main + with: + file_path: "apps/browser/src/manifest.v3.json" + version: ${{ steps.calculate-next-browser-version.outputs.version }} - name: Run Prettier after Browser Version Bump - if: ${{ github.event.inputs.client == 'Browser' || github.event.inputs.client == 'All' }} + if: ${{ inputs.bump_browser == true }} run: | npm install -g prettier prettier --write apps/browser/src/manifest.json prettier --write apps/browser/src/manifest.v3.json ### CLI - - name: Bump CLI Version - if: ${{ github.event.inputs.client == 'CLI' || github.event.inputs.client == 'All' }} + - name: Get current CLI version + if: ${{ inputs.bump_cli == true }} + id: current-cli-version + run: | + CURRENT_VERSION=$(cat package.json | jq -r '.version') + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + working-directory: apps/cli + + - name: CLI - Verify input version + if: ${{ inputs.bump_cli == true && inputs.version_number_override != '' }} env: - VERSION: ${{ github.event.inputs.version_number }} - run: npm version --workspace=@bitwarden/cli ${VERSION} + CURRENT_VERSION: ${{ steps.current-cli-version.outputs.version }} + NEW_VERSION: ${{ inputs.version_number_override }} + run: | + # Error if version has not changed. + if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then + echo "Version has not changed." + exit 1 + fi + + # Check if version is newer. + printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V + if [ $? -eq 0 ]; then + echo "Version check successful." + else + echo "Version check failed." + exit 1 + fi + working-directory: apps/cli + + - name: Calculate next CLI release version + if: ${{ inputs.bump_cli == true && inputs.version_number_override == '' }} + id: calculate-next-cli-version + uses: bitwarden/gh-actions/version-next@main + with: + version: ${{ steps.current-cli-version.outputs.version }} + + - name: Bump CLI Version - Version Override + if: ${{ inputs.bump_cli == true && inputs.version_number_override != '' }} + id: bump-cli-version-override + run: npm version --workspace=@bitwarden/cli ${{ inputs.version_number_override }} + + - name: Bump CLI Version - Automatic Calculation + if: ${{ inputs.bump_cli == true && inputs.version_number_override == '' }} + id: bump-cli-version-automatic + env: + VERSION: ${{ steps.calculate-next-cli-version.outputs.version }} + run: npm version --workspace=@bitwarden/cli $VERSION ### Desktop - - name: Bump Desktop Version - Root - if: ${{ github.event.inputs.client == 'Desktop' || github.event.inputs.client == 'All' }} - env: - VERSION: ${{ github.event.inputs.version_number }} - run: npm version --workspace=@bitwarden/desktop ${VERSION} + - name: Get current Desktop version + if: ${{ inputs.bump_desktop == true }} + id: current-desktop-version + run: | + CURRENT_VERSION=$(cat package.json | jq -r '.version') + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + working-directory: apps/desktop - - name: Bump Desktop Version - App - if: ${{ github.event.inputs.client == 'Desktop' || github.event.inputs.client == 'All' }} + - name: Desktop - Verify input version + if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }} env: - VERSION: ${{ github.event.inputs.version_number }} - run: npm version ${VERSION} + CURRENT_VERSION: ${{ steps.current-desktop-version.outputs.version }} + NEW_VERSION: ${{ inputs.version_number_override }} + run: | + # Error if version has not changed. + if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then + echo "Version has not changed." + exit 1 + fi + + # Check if version is newer. + printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V + if [ $? -eq 0 ]; then + echo "Version check successful." + else + echo "Version check failed." + exit 1 + fi + working-directory: apps/desktop + + - name: Calculate next Desktop release version + if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }} + id: calculate-next-desktop-version + uses: bitwarden/gh-actions/version-next@main + with: + version: ${{ steps.current-desktop-version.outputs.version }} + + - name: Bump Desktop Version - Root - Version Override + if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }} + id: bump-desktop-version-override + run: npm version --workspace=@bitwarden/desktop ${{ inputs.version_number_override }} + + - name: Bump Desktop Version - Root - Automatic Calculation + if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }} + id: bump-desktop-version-automatic + env: + VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }} + run: npm version --workspace=@bitwarden/desktop $VERSION + + - name: Bump Desktop Version - App - Version Override + if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }} + run: npm version ${{ inputs.version_number_override }} + working-directory: "apps/desktop/src" + + - name: Bump Desktop Version - App - Automatic Calculation + if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }} + env: + VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }} + run: npm version $VERSION working-directory: "apps/desktop/src" ### Web - - name: Bump Web Version - if: ${{ github.event.inputs.client == 'Web' || github.event.inputs.client == 'All' }} + - name: Get current Web version + if: ${{ inputs.bump_web == true }} + id: current-web-version + run: | + CURRENT_VERSION=$(cat package.json | jq -r '.version') + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + working-directory: apps/web + + - name: Web - Verify input version + if: ${{ inputs.bump_web == true && inputs.version_number_override != '' }} env: - VERSION: ${{ github.event.inputs.version_number }} - run: npm version --workspace=@bitwarden/web-vault ${VERSION} + CURRENT_VERSION: ${{ steps.current-web-version.outputs.version }} + NEW_VERSION: ${{ inputs.version_number_override }} + run: | + # Error if version has not changed. + if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then + echo "Version has not changed." + exit 1 + fi + + # Check if version is newer. + printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V + if [ $? -eq 0 ]; then + echo "Version check successful." + else + echo "Version check failed." + exit 1 + fi + working-directory: apps/web + + - name: Calculate next Web release version + if: ${{ inputs.bump_web == true && inputs.version_number_override == '' }} + id: calculate-next-web-version + uses: bitwarden/gh-actions/version-next@main + with: + version: ${{ steps.current-web-version.outputs.version }} + + - name: Bump Web Version - Version Override + if: ${{ inputs.bump_web == true && inputs.version_number_override != '' }} + id: bump-web-version-override + run: npm version --workspace=@bitwarden/web-vault ${{ inputs.version_number_override }} + + - name: Bump Web Version - Automatic Calculation + if: ${{ inputs.bump_web == true && inputs.version_number_override == '' }} + id: bump-web-version-automatic + env: + VERSION: ${{ steps.calculate-next-web-version.outputs.version }} + run: npm version --workspace=@bitwarden/web-vault $VERSION ######################## - - name: Setup git + - name: Set final version output + id: set-final-version-output run: | - git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com" - git config --local user.name "bitwarden-devops-bot" + if [[ "${{ steps.bump-browser-version-override.outcome }}" = "success" ]]; then + echo "version_browser=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.bump-browser-version-automatic.outcome }}" = "success" ]]; then + echo "version_browser=${{ steps.calculate-next-browser-version.outputs.version }}" >> $GITHUB_OUTPUT + fi + + if [[ "${{ steps.bump-cli-version-override.outcome }}" = "success" ]]; then + echo "version_cli=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.bump-cli-version-automatic.outcome }}" = "success" ]]; then + echo "version_cli=${{ steps.calculate-next-cli-version.outputs.version }}" >> $GITHUB_OUTPUT + fi + + if [[ "${{ steps.bump-desktop-version-override.outcome }}" = "success" ]]; then + echo "version_desktop=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.bump-desktop-version-automatic.outcome }}" = "success" ]]; then + echo "version_desktop=${{ steps.calculate-next-desktop-version.outputs.version }}" >> $GITHUB_OUTPUT + fi + + if [[ "${{ steps.bump-web-version-override.outcome }}" = "success" ]]; then + echo "version_web=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.bump-web-version-automatic.outcome }}" = "success" ]]; then + echo "version_web=${{ steps.calculate-next-web-version.outputs.version }}" >> $GITHUB_OUTPUT + fi - name: Check if version changed id: version-changed @@ -153,27 +403,26 @@ jobs: - name: Commit files if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} env: - CLIENT: ${{ steps.branch.outputs.client }} - VERSION: ${{ github.event.inputs.version_number }} + CLIENT: ${{ steps.create-branch.outputs.client }} + VERSION: ${{ steps.set-final-version-output.outputs.version }} run: git commit -m "Bumped ${CLIENT} version to ${VERSION}" -a - name: Push changes if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} env: - CLIENT: ${{ steps.branch.outputs.client }} - VERSION: ${{ github.event.inputs.version_number }} - run: git push -u origin ${CLIENT}_version_bump_${VERSION} + PR_BRANCH: ${{ steps.create-branch.outputs.name }} + run: git push -u origin $PR_BRANCH - - name: Create Bump Version PR + - name: Create Version PR if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} + id: create-pr env: - PR_BRANCH: "${{ steps.branch.outputs.client }}_version_bump_${{ github.event.inputs.version_number }}" - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - BASE_BRANCH: master - TITLE: "Bump ${{ github.event.inputs.client }} version to ${{ github.event.inputs.version_number }}" + GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }} + PR_BRANCH: ${{ steps.create-branch.outputs.name }} + TITLE: "Bump ${{ steps.create-branch.outputs.client }} version to ${{ steps.set-final-version-output.outputs.version }}" run: | - gh pr create --title "$TITLE" \ - --base "$BASE" \ + PR_URL=$(gh pr create --title "$TITLE" \ + --base "main" \ --head "$PR_BRANCH" \ --label "version update" \ --label "automated pr" \ @@ -186,5 +435,107 @@ jobs: - [X] Other ## Objective - Automated ${{ github.event.inputs.client }} version bump to ${{ github.event.inputs.version_number }}" + Automated ${{ steps.create-branch.outputs.client }} version bump to ${{ steps.set-final-version-output.outputs.version }}") + echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT + - name: Approve PR + if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }} + run: gh pr review $PR_NUMBER --approve + + - name: Merge PR + if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} + env: + GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }} + PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }} + run: gh pr merge $PR_NUMBER --squash --auto --delete-branch + + cut_rc: + name: Cut RC branch + if: ${{ inputs.cut_rc_branch == true }} + needs: bump_version + runs-on: ubuntu-22.04 + steps: + - name: Checkout Branch + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: main + + ### Browser + - name: Browser - Verify version has been updated + if: ${{ inputs.bump_browser == true }} + env: + NEW_VERSION: ${{ needs.bump_version.outputs.version_browser }} + run: | + # Wait for version to change. + while : ; do + echo "Waiting for version to be updated..." + git pull --force + CURRENT_VERSION=$(cat package.json | jq -r '.version') + + # If the versions don't match we continue the loop, otherwise we break out of the loop. + [[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break + sleep 10 + done + working-directory: apps/browser + + ### CLI + - name: CLI - Verify version has been updated + if: ${{ inputs.bump_cli == true }} + env: + NEW_VERSION: ${{ needs.bump_version.outputs.version_cli }} + run: | + # Wait for version to change. + while : ; do + echo "Waiting for version to be updated..." + git pull --force + CURRENT_VERSION=$(cat package.json | jq -r '.version') + + # If the versions don't match we continue the loop, otherwise we break out of the loop. + [[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break + sleep 10 + done + working-directory: apps/cli + + ### Desktop + - name: Desktop - Verify version has been updated + if: ${{ inputs.bump_desktop == true }} + env: + NEW_VERSION: ${{ needs.bump_version.outputs.version_desktop }} + run: | + # Wait for version to change. + while : ; do + echo "Waiting for version to be updated..." + git pull --force + CURRENT_VERSION=$(cat package.json | jq -r '.version') + + # If the versions don't match we continue the loop, otherwise we break out of the loop. + [[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break + sleep 10 + done + working-directory: apps/desktop + + ### Web + - name: Web - Verify version has been updated + if: ${{ inputs.bump_web == true }} + env: + NEW_VERSION: ${{ needs.bump_version.outputs.version_web }} + run: | + # Wait for version to change. + while : ; do + echo "Waiting for version to be updated..." + git pull --force + CURRENT_VERSION=$(cat package.json | jq -r '.version') + + # If the versions don't match we continue the loop, otherwise we break out of the loop. + [[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break + sleep 10 + done + working-directory: apps/web + + - name: Cut RC branch + run: | + git switch --quiet --create rc + git push --quiet --set-upstream origin rc diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml deleted file mode 100644 index 9dced5ee53..0000000000 --- a/.github/workflows/workflow-linter.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: Workflow Linter - -on: - pull_request: - paths: - - .github/workflows/** - -jobs: - call-workflow: - uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@a30e9c3d658dc97c4c2e61ec749fdab64b83386c diff --git a/.gitignore b/.gitignore index 11a4d4c80f..6dea4b43f1 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ junit.xml documentation.json .eslintcache storybook-static + +# Local app configuration +apps/**/config/local.json diff --git a/.husky/pre-commit b/.husky/pre-commit index 36af219892..2312dc587f 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - npx lint-staged diff --git a/.prettierignore b/.prettierignore index 986cadd3d5..cd8eb201f3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,7 +9,6 @@ storybook-static # External libraries / auto synced locales apps/browser/src/_locales apps/browser/src/auth/scripts/duo.js -apps/browser/src/autofill/content/autofill.js apps/browser/src/safari apps/desktop/src/locales diff --git a/.storybook/main.ts b/.storybook/main.ts index a7f12f469b..c71a74c2a7 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -4,6 +4,7 @@ import remarkGfm from "remark-gfm"; const config: StorybookConfig = { stories: [ + "../libs/auth/src/**/*.stories.@(js|jsx|ts|tsx)", "../libs/components/src/**/*.mdx", "../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)", "../apps/web/src/**/*.mdx", @@ -15,6 +16,8 @@ const config: StorybookConfig = { "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-a11y", + "@storybook/addon-designs", + "@storybook/addon-interactions", { name: "@storybook/addon-docs", options: { @@ -35,9 +38,7 @@ const config: StorybookConfig = { }, env: (config) => ({ ...config, - FLAGS: JSON.stringify({ - secretsManager: true, - }), + FLAGS: JSON.stringify({}), }), webpackFinal: async (config, { configType }) => { if (config.resolve) { diff --git a/.storybook/manager.js b/.storybook/manager.js new file mode 100644 index 0000000000..89a69bf942 --- /dev/null +++ b/.storybook/manager.js @@ -0,0 +1,63 @@ +import { addons } from "@storybook/addons"; +import { create } from "@storybook/theming/create"; + +const lightTheme = create({ + base: "light", + //logo and Title + brandTitle: "Bitwarden Component Library", + brandUrl: "/", + brandImage: + "https://github.com/bitwarden/brand/blob/51942f8d6e55e96a078a524e0f739efbf1997bcf/logos/logo-horizontal-blue.png?raw=true", + brandTarget: "_self", + + //Colors + colorPrimary: "#6D757E", + colorSecondary: "#175DDC", + + // UI + appBg: "#f9fBff", + appContentBg: "#ffffff", + appBorderColor: "#CED4DC", + + // Text colors + textColor: "#212529", + textInverseColor: "#ffffff", + + // Toolbar default and active colors + barTextColor: "#6D757E", + barSelectedColor: "#175DDC", + barBg: "#ffffff", + + // Form colors + inputBg: "#ffffff", + inputBorder: "#6D757E", + inputTextColor: "#6D757E", +}); + +const darkTheme = create({ + base: "dark", + + //logo and Title + brandTitle: "Bitwarden Component Library", + brandUrl: "/", + brandImage: + "https://github.com/bitwarden/brand/blob/51942f8d6e55e96a078a524e0f739efbf1997bcf/logos/logo-horizontal-white.png?raw=true", + brandTarget: "_self", + + //Colors + colorSecondary: "#6A99F0", + barSelectedColor: "#6A99F0", +}); + +export const getPreferredColorScheme = () => { + if (!globalThis || !globalThis.matchMedia) return "light"; + + const isDarkThemePreferred = globalThis.matchMedia("(prefers-color-scheme: dark)").matches; + if (isDarkThemePreferred) return "dark"; + + return "light"; +}; + +addons.setConfig({ + theme: getPreferredColorScheme() === "dark" ? darkTheme : lightTheme, +}); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 0bc9fc5bac..af20dcad74 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -48,7 +48,7 @@ const decorator = componentWrapperDecorator( }, ({ globals }) => { return { theme: `${globals["theme"]}` }; - } + }, ); const preview: Preview = { diff --git a/.vscode/settings.json b/.vscode/settings.json index 07423dd18b..27e3a9b293 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,9 @@ { - "cSpell.words": ["Csprng", "decryptable", "Popout", "Reprompt", "takeuntil"] + "cSpell.words": ["Csprng", "decryptable", "Popout", "Reprompt", "takeuntil"], + "search.exclude": { + "**/locales/[^e]*/messages.json": true, + "**/locales/*[^n]/messages.json": true, + "**/_locales/[^e]*/messages.json": true, + "**/_locales/*[^n]/messages.json": true + } } diff --git a/README.md b/README.md index df1f22a094..da31a2d489 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,12 @@
- +
- - - - - - - - - - - - - - - + + + + +
--- @@ -39,6 +29,6 @@ Interested in contributing in a big way? Consider joining our team! We're hiring # Contribute -Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution. +Code contributions are welcome! Please commit any pull requests against the `main` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution. Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file. diff --git a/apps/browser/.eslintrc.json b/apps/browser/.eslintrc.json new file mode 100644 index 0000000000..ba96051183 --- /dev/null +++ b/apps/browser/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "env": { + "browser": true, + "webextensions": true + }, + "overrides": [ + { + "files": ["src/**/*.ts"], + "excludedFiles": [ + "src/**/{content,popup,spec}/**/*.ts", + "src/**/autofill/{notification,overlay}/**/*.ts", + "src/**/autofill/**/{autofill-overlay-content,collect-autofill-content,dom-element-visibility,insert-autofill-content}.service.ts", + "src/**/*.spec.ts" + ], + "rules": { + "no-restricted-globals": [ + "error", + { + "name": "window", + "message": "The `window` object is not available in service workers and may not be available within the background script. Consider using `self`, `globalThis`, or another global property instead." + } + ] + } + } + ] +} diff --git a/apps/browser/.gitignore b/apps/browser/.gitignore index 7a689bdb9f..87b21b9730 100644 --- a/apps/browser/.gitignore +++ b/apps/browser/.gitignore @@ -1,3 +1,5 @@ +config/local.json + # Safari dist-safari !src/safari/safari/app/popup/index.html diff --git a/apps/browser/README.md b/apps/browser/README.md index 2cd1615a11..c99d0844a0 100644 --- a/apps/browser/README.md +++ b/apps/browser/README.md @@ -4,13 +4,13 @@ # Bitwarden Browser Extension - + - - + + The Bitwarden browser extension is written using the Web Extension API and Angular. diff --git a/apps/browser/config/base.json b/apps/browser/config/base.json index 81b11cd38b..8a3ccc14d3 100644 --- a/apps/browser/config/base.json +++ b/apps/browser/config/base.json @@ -1,6 +1,8 @@ { "dev_flags": {}, "flags": { - "showPasswordless": true + "showPasswordless": true, + "enableCipherKeyEncryption": false, + "accountSwitching": false } } diff --git a/apps/browser/config/development.json b/apps/browser/config/development.json index 972812a9c5..1b628c173c 100644 --- a/apps/browser/config/development.json +++ b/apps/browser/config/development.json @@ -6,6 +6,8 @@ } }, "flags": { - "showPasswordless": true + "showPasswordless": true, + "enableCipherKeyEncryption": false, + "accountSwitching": true } } diff --git a/apps/browser/config/production.json b/apps/browser/config/production.json index b04d1531a2..027003f6c7 100644 --- a/apps/browser/config/production.json +++ b/apps/browser/config/production.json @@ -1,3 +1,6 @@ { - "flags": {} + "flags": { + "enableCipherKeyEncryption": false, + "accountSwitching": true + } } diff --git a/apps/browser/gulpfile.js b/apps/browser/gulpfile.js index 2f672ffcdd..6a0980fc27 100644 --- a/apps/browser/gulpfile.js +++ b/apps/browser/gulpfile.js @@ -1,13 +1,11 @@ const child = require("child_process"); const fs = require("fs"); -const del = require("del"); +const { rimraf } = require("rimraf"); const gulp = require("gulp"); -const filter = require("gulp-filter"); const gulpif = require("gulp-if"); const jeditor = require("gulp-json-editor"); const replace = require("gulp-replace"); -const zip = require("gulp-zip"); const manifest = require("./src/manifest.json"); @@ -47,7 +45,10 @@ function distFileName(browserName, ext) { return `dist-${browserName}${buildString()}.${ext}`; } -function dist(browserName, manifest) { +async function dist(browserName, manifest) { + const { default: zip } = await import("gulp-zip"); + const { default: filter } = await import("gulp-filter"); + return gulp .src(paths.build + "**/*") .pipe(filter(["**"].concat(filters.fonts).concat(filters.safari))) @@ -60,6 +61,10 @@ function dist(browserName, manifest) { function distFirefox() { return dist("firefox", (manifest) => { delete manifest.storage; + delete manifest.sandbox; + manifest.optional_permissions = manifest.optional_permissions.filter( + (permission) => permission !== "privacy", + ); return manifest; }); } @@ -123,13 +128,13 @@ function distSafariApp(cb, subBuildPath) { "--sign", subBuildPath === "mas" ? "3rd Party Mac Developer Application: Bitwarden Inc" - : "E661AB6249AEB60B0F47ABBD7326B2877D2575B0", + : "E7C9978F6FBCE0553429185C405E61F5380BE8EB", "--entitlements", entitlementsPath, ]; } - return del([buildPath + "**/*"]) + return rimraf([buildPath + "**/*"], { glob: true }) .then(() => safariCopyAssets(paths.safari + "**/*", buildPath)) .then(() => safariCopyBuild(paths.build + "**/*", buildPath + "safari/app")) .then(() => { @@ -143,7 +148,9 @@ function distSafariApp(cb, subBuildPath) { stdOutProc(proc); return new Promise((resolve) => proc.on("close", resolve)); }) - .then(() => { + .then(async () => { + const { default: filter } = await import("gulp-filter"); + const libs = fs .readdirSync(builtAppexFrameworkPath) .filter((p) => p.endsWith(".dylib")) @@ -167,7 +174,7 @@ function distSafariApp(cb, subBuildPath) { }, () => { return cb; - } + }, ); } @@ -178,7 +185,7 @@ function safariCopyAssets(source, dest) { .on("error", reject) .pipe(gulpif("safari/Info.plist", replace("0.0.1", manifest.version))) .pipe( - gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version)) + gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version)), ) .pipe(gulpif("desktop.xcodeproj/project.pbxproj", replace("../../../build", "../safari/app"))) .pipe(gulp.dest(dest)) @@ -186,7 +193,9 @@ function safariCopyAssets(source, dest) { }); } -function safariCopyBuild(source, dest) { +async function safariCopyBuild(source, dest) { + const { default: filter } = await import("gulp-filter"); + return new Promise((resolve, reject) => { gulp .src(source) @@ -202,8 +211,8 @@ function safariCopyBuild(source, dest) { delete manifest.optional_permissions; manifest.permissions.push("nativeMessaging"); return manifest; - }) - ) + }), + ), ) .pipe(gulp.dest(dest)) .on("end", resolve); @@ -215,7 +224,10 @@ function stdOutProc(proc) { proc.stderr.on("data", (data) => console.error(data.toString())); } -function ciCoverage(cb) { +async function ciCoverage(cb) { + const { default: zip } = await import("gulp-zip"); + const { default: filter } = await import("gulp-filter"); + return gulp .src(paths.coverage + "**/*") .pipe(filter(["**", "!coverage/coverage*.zip"])) diff --git a/apps/browser/jest.config.js b/apps/browser/jest.config.js index cde02cd995..73f5ada287 100644 --- a/apps/browser/jest.config.js +++ b/apps/browser/jest.config.js @@ -9,7 +9,10 @@ module.exports = { ...sharedConfig, preset: "jest-preset-angular", setupFilesAfterEnv: ["= accountLimit && + availableAccounts[availableAccounts.length - 1].id !== specialAddAccountId + " + > + {{ "accountLimitReached" | i18n }} +
+{{ "newAroundHere" | i18n }} - {{ "createAccount" | i18n }} + {{ "createAccount" | i18n }}